2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
25 * $XConsortium: obj.c /main/4 1996/10/02 16:11:56 drk $
27 * @(#)obj.c 3.46 11 Feb 1994 cde_app_builder/src/libABobj
29 * RESTRICTED CONFIDENTIAL INFORMATION:
31 * The information in this document is subject to special restrictions in a
32 * confidential disclosure agreement between HP, IBM, Sun, USL, SCO and
33 * Univel. Do not distribute this document outside HP, IBM, Sun, USL, SCO,
34 * or Univel without Sun's specific written approval. This document and all
35 * copies and derivative works thereof must be returned or destroyed at Sun's
38 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
44 * ABObj.c - manipulations of one gobj structure
50 #if !defined(CSRG_BASED)
54 #include <sys/param.h>
56 #include "objP.h" /* include first! */
57 #include <ab_private/trav.h>
58 #include <ab_private/util.h>
59 #include "obj_names_listP.h"
60 #include "obj_notifyP.h"
63 objP_or_tree_update_clients_with_data(
68 UpdateDataFreeFunc free_func
72 * Gets the item for this object with index which_item
75 obj_get_item(ABObj obj, int which_item)
79 int item_num = -1; /* must be -1 */
81 for (trav_open(&trav, obj, AB_TRAV_ITEMS_FOR_OBJ);
82 (item = trav_next(&trav)) != NULL;)
85 if (item_num == which_item)
95 * Return the Help Item for a given menubar
98 obj_get_menubar_help_item(
103 ABObj help_item = NULL;
106 if (!obj_is_menubar(obj))
109 for (trav_open(&trav, obj, AB_TRAV_ITEMS_FOR_OBJ);
110 (item = trav_next(&trav)) != NULL;)
112 if (obj_is_help_item(item) == TRUE)
124 * Returns the number of this object, as a child of it's parent.
127 obj_get_child_num(ABObj obj)
132 if (obj->parent == NULL)
137 for (child = obj->parent->first_child;
138 child != NULL; child = child->next_sibling)
153 obj_get_container_child(ABObj obj)
156 for (child = obj->first_child; child != NULL;
157 child = child->next_sibling)
159 if (obj_is_container(child))
169 * Returns the item number of this object, with reference to it's parent
172 obj_get_item_num(ABObj obj)
176 for (item = obj->parent->first_child;
177 item != NULL; item = item->next_sibling)
179 if (!obj_is_item(item))
194 obj_get_menu(ABObj obj)
197 for (child = obj->first_child; child != NULL; child = child->next_sibling)
199 if (obj_is_menu(child))
209 obj_get_pane_child(ABObj obj)
212 for (child = obj->first_child; child != NULL;
213 child = child->next_sibling)
215 if (obj_is_pane(child))
225 obj_has_menu(ABObj obj)
227 if (!util_strempty(obj_get_menu_name(obj)))
235 * Moves the children only if *all* the children can be moved.
238 obj_move_children(ABObj to, ABObj from)
241 int iRC = 0;/* return code */
245 * Get permission for all children
247 for (child = from->first_child;
248 child != NULL; child = child->next_sibling)
250 if ((iRC = objP_notify_send_allow_reparent(child, to)) < 0)
257 while ((child = from->first_child) != NULL)
261 * Don't send reparent to NULL
264 objP_notify_push_mode();
265 objP_notify_clear_mode(OBJEV_MODE_SEND_NOTIFY_EVS);
267 obj_append_child(to, child);
268 objP_notify_pop_mode();
270 objP_notify_send_reparent(child, from);
278 * maxlen < 1 means no max.
281 obj_ensure_unique_name(ABObj obj, ABObj root, int maxlen)
285 BOOL name_changed = FALSE;
292 ABObj other_obj = NULL;
296 if (obj->name == NULL)
304 strncpy(obj_name, istr_string(obj->name), maxlen);
308 if (obj_is_module(obj))
310 trav_type = AB_TRAV_MODULES;
314 trav_type = AB_TRAV_UI;
316 while ((!unique) && (!error))
319 for (trav_open(&trav, root, trav_type);
320 (other_obj = trav_next(&trav)) != NULL;)
322 if ((other_obj != obj)
323 && (other_obj->name != NULL)
324 && (strncmp(istr_string(other_obj->name), obj_name, maxlen)
329 sprintf(mod_name, "%d", ++modifier);
330 if ((strlen(mod_name) + 1) > (unsigned) maxlen)
335 oldlen = istr_len(obj->name);
336 modlen = strlen(mod_name);
337 newlen = oldlen + modlen;
341 oldlen = newlen - modlen;
343 strncpy(obj_name, istr_string(obj->name),
345 obj_name[oldlen] = 0;
346 strcat(obj_name, mod_name);
351 if (name_changed && (!error))
353 /* printf("CHANGED %s -> %s\n", obj->name, obj_name); */
356 * REMIND: CHANGE ALL BY-NAME REFS TO THIS OBJECT!
358 obj_set_name(obj, obj_name);
361 return error ? -1 : 0;
366 * Munges name, as necessary to get uniqueness
369 obj_set_unique_name_istr(ABObj obj, ISTRING name)
371 int rc = 0; /* return code */
372 ISTRING newName = obj_alloc_unique_name_istr(obj, name, -1);
373 rc = obj_set_name_istr(obj, newName);
374 istr_destroy(newName);
380 obj_set_unique_name(ABObj obj, STRING strName)
382 int return_value = 0;
383 ISTRING name = istr_create(strName);
385 return_value = obj_set_unique_name_istr(obj, name);
393 obj_alloc_unique_name(
399 ABObj parent = obj->parent;
400 if ( (parent == NULL)
401 || (obj_find_by_name(parent, name) == obj) )
405 return obj_alloc_unique_name_for_child(parent, name, maxNameLen);
410 obj_alloc_unique_name_istr(
416 ABObj parent = obj->parent;
417 if ( (parent == NULL)
418 || (obj_find_by_name(parent, istr_string(name)) == obj) )
420 return istr_dup(name);
422 return obj_alloc_unique_name_istr_for_child(parent, name, maxNameLen);
434 ABObj parent = obj->parent;
435 if ( (parent == NULL)
436 || (obj_find_by_name(parent, name) == obj) )
440 return obj_get_unique_name_for_child(parent, name, maxNameLen-1, nameOutBuf);
445 * maxlen < 1 means no max.
448 obj_alloc_unique_name_for_child(
455 STRING unique_name = NULL;
464 * The USL specific changes were added ifdef due to time constraints
465 * They should be removed in the next release
467 maxlen = util_min(8191,maxlen); /* don't overrun buf */
469 maxlen = util_min(8192,maxlen); /* don't overrun buf */
473 * Alloc space and copy-in the unique name
475 unique_name = strdup(
476 obj_get_unique_name_for_child(obj, name, maxlen-1, nameBuf));
483 obj_alloc_unique_name_istr_for_child(
490 ISTRING unique_name = NULL;
498 maxlen = util_min(8191,maxlen);
500 maxlen = util_min(8192,maxlen);
502 unique_name = istr_create(
503 obj_get_unique_name_for_child(obj, istr_string(name), maxlen-1, nameBuf));
510 obj_get_unique_name_for_child(
517 STRING returnName = NULL;
518 int nameOutBufSize = maxlen+1;
519 StringList namesList = NULL;
524 int objNumberStart = 0;
527 namesList = objP_get_names_scope_for_children(obj);
528 if (namesList == NULL)
534 unique = !strlist_str_exists(namesList, name);
542 * Determine trailing number
544 util_strncpy(nameOutBuf, name, nameOutBufSize);
545 nameLen = strlen(nameOutBuf);
546 for (i = nameLen-1; i >= 0; --i)
548 if (!isdigit(nameOutBuf[i]))
553 objNumberStart = i + 1;
554 objNumber = atoi(&(nameOutBuf[objNumberStart]));
557 * Search for a unique name by incrementing trailing #
563 if (++objNumber == 1)
565 /* skip 1 - name w/no # is implied 1 */
568 sprintf(&(nameOutBuf[objNumberStart]), "%d", objNumber);
569 unique = !strlist_str_exists(namesList, nameOutBuf);
574 returnName = nameOutBuf;
583 * Don't run this on a project!!! It's a severe dog, and can take many
584 * seconds to complete.
586 * Run it on each module (root = an module) instead.
589 obj_tree_ensure_unique_names(ABObj root, int maxnamelen)
594 for (trav_open(&trav, root, AB_TRAV_UI);
595 (obj = trav_next(&trav)) != NULL;)
597 obj_ensure_unique_name(obj, root, maxnamelen);
605 * Calls obj_tree_ensure_unique_names on each module in the given tree.
608 obj_tree_ensure_unique_names_in_modules(ABObj root, int maxnamelen)
613 for (trav_open(&trav, root, AB_TRAV_MODULES);
614 (module = trav_next(&trav)) != NULL;)
616 obj_tree_ensure_unique_names(module, maxnamelen);
623 * Gives an object a name by munging it's parent's name with it's own label.
624 * Used for item children, which aren't given names directly.
626 * actual_parent overrides the parent of the object. If actual_parent is NULL,
627 * the "normal" parent of the object is used.
630 obj_set_name_from_label(ABObj obj, STRING parent_name_in)
632 STRING parent_name = NULL;
633 STRING item_label = NULL;
634 STRING new_name = NULL;
637 (parent_name_in == NULL ?
638 (obj->parent == NULL ?
641 istr_string(obj->parent->name)
646 if (parent_name == NULL)
651 if (istr_len(obj->label) > 0)
653 item_label = istr_string(obj->label);
660 obj_set_unique_name(obj,
661 ab_ident_from_name_and_label(parent_name, item_label));
667 obj_set_name_from_parent(ABObj obj, STRING suffix)
670 STRING new_name = NULL;
672 parent_name = (obj->parent == NULL ?
675 istr_string(obj->parent->name)
678 if (parent_name == NULL)
683 obj_set_unique_name(obj,
684 ab_ident_from_name_and_label(parent_name,
692 * Gets a name for an object. Object may be NULL, or have a NULL name
694 * Copies name into passed-in buffer name, guarantees 0 termination. returns
698 obj_get_safe_name(ABObj obj, STRING name, int name_size)
707 strncpy(name, "(nil ABObj)", name_size);
709 else if (obj_get_name(obj) == NULL)
712 sprintf(buf, "(ABObj:0x%08lx)", (unsigned long) obj);
713 strncpy(name, buf, name_size);
717 strncpy(name, obj_get_name(obj), name_size);
720 name[name_size - 1] = 0;
725 /*************************************************************************
727 ** UPDATE_CLIENTS METHODS **
729 *************************************************************************/
732 obj_update_clients(ABObj obj)
734 return objP_notify_send_update(obj, FALSE);
739 obj_tree_update_clients(ABObj tree)
742 return objP_notify_send_update(tree, TRUE);
747 obj_update_clients_with_data(
751 UpdateDataFreeFunc free_func)
753 return objP_or_tree_update_clients_with_data(
754 obj, FALSE, update_code, update_data, free_func);
759 obj_tree_update_clients_with_data(ABObj obj,
762 UpdateDataFreeFunc free_func)
764 return objP_or_tree_update_clients_with_data(
765 obj, TRUE, update_code, update_data, free_func);
770 objP_or_tree_update_clients_with_data(
775 UpdateDataFreeFunc free_func
781 * event notification will only free the data if the notify events are
782 * batched. It's pretty smart about it, so we're going to go to batch
783 * mode and let it handle it.
785 objP_notify_push_mode();
786 objP_notify_set_mode(OBJEV_MODE_BATCH_NOTIFY_EVS);
788 iReturn = objP_notify_send_update_with_data(
789 obj, update_subtree, update_code, update_data, free_func);
791 objP_notify_pop_mode();