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 librararies 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
52 #include <sys/param.h>
54 #include "objP.h" /* include first! */
55 #include <ab_private/trav.h>
56 #include <ab_private/util.h>
57 #include "obj_names_listP.h"
58 #include "obj_notifyP.h"
61 objP_or_tree_update_clients_with_data(
66 UpdateDataFreeFunc free_func
70 * Gets the item for this object with index which_item
73 obj_get_item(ABObj obj, int which_item)
77 int item_num = -1; /* must be -1 */
79 for (trav_open(&trav, obj, AB_TRAV_ITEMS_FOR_OBJ);
80 (item = trav_next(&trav)) != NULL;)
83 if (item_num == which_item)
93 * Return the Help Item for a given menubar
96 obj_get_menubar_help_item(
101 ABObj help_item = NULL;
104 if (!obj_is_menubar(obj))
107 for (trav_open(&trav, obj, AB_TRAV_ITEMS_FOR_OBJ);
108 (item = trav_next(&trav)) != NULL;)
110 if (obj_is_help_item(item) == TRUE)
122 * Returns the number of this object, as a child of it's parent.
125 obj_get_child_num(ABObj obj)
130 if (obj->parent == NULL)
135 for (child = obj->parent->first_child;
136 child != NULL; child = child->next_sibling)
151 obj_get_container_child(ABObj obj)
154 for (child = obj->first_child; child != NULL;
155 child = child->next_sibling)
157 if (obj_is_container(child))
167 * Returns the item number of this object, with reference to it's parent
170 obj_get_item_num(ABObj obj)
174 for (item = obj->parent->first_child;
175 item != NULL; item = item->next_sibling)
177 if (!obj_is_item(item))
192 obj_get_menu(ABObj obj)
195 for (child = obj->first_child; child != NULL; child = child->next_sibling)
197 if (obj_is_menu(child))
207 obj_get_pane_child(ABObj obj)
210 for (child = obj->first_child; child != NULL;
211 child = child->next_sibling)
213 if (obj_is_pane(child))
223 obj_has_menu(ABObj obj)
225 if (!util_strempty(obj_get_menu_name(obj)))
233 * Moves the children only if *all* the children can be moved.
236 obj_move_children(ABObj to, ABObj from)
239 int iRC = 0;/* return code */
243 * Get permission for all children
245 for (child = from->first_child;
246 child != NULL; child = child->next_sibling)
248 if ((iRC = objP_notify_send_allow_reparent(child, to)) < 0)
255 while ((child = from->first_child) != NULL)
259 * Don't send reparent to NULL
262 objP_notify_push_mode();
263 objP_notify_clear_mode(OBJEV_MODE_SEND_NOTIFY_EVS);
265 obj_append_child(to, child);
266 objP_notify_pop_mode();
268 objP_notify_send_reparent(child, from);
276 * maxlen < 1 means no max.
279 obj_ensure_unique_name(ABObj obj, ABObj root, int maxlen)
283 BOOL name_changed = FALSE;
290 ABObj other_obj = NULL;
294 if (obj->name == NULL)
302 strncpy(obj_name, istr_string(obj->name), maxlen);
306 if (obj_is_module(obj))
308 trav_type = AB_TRAV_MODULES;
312 trav_type = AB_TRAV_UI;
314 while ((!unique) && (!error))
317 for (trav_open(&trav, root, trav_type);
318 (other_obj = trav_next(&trav)) != NULL;)
320 if ((other_obj != obj)
321 && (other_obj->name != NULL)
322 && (strncmp(istr_string(other_obj->name), obj_name, maxlen)
327 sprintf(mod_name, "%d", ++modifier);
328 if ((strlen(mod_name) + 1) > (unsigned) maxlen)
333 oldlen = istr_len(obj->name);
334 modlen = strlen(mod_name);
335 newlen = oldlen + modlen;
339 oldlen = newlen - modlen;
341 strncpy(obj_name, istr_string(obj->name),
343 obj_name[oldlen] = 0;
344 strcat(obj_name, mod_name);
349 if (name_changed && (!error))
351 /* printf("CHANGED %s -> %s\n", obj->name, obj_name); */
354 * REMIND: CHANGE ALL BY-NAME REFS TO THIS OBJECT!
356 obj_set_name(obj, obj_name);
359 return error ? -1 : 0;
364 * Munges name, as necessary to get uniqueness
367 obj_set_unique_name_istr(ABObj obj, ISTRING name)
369 int rc = 0; /* return code */
370 ISTRING newName = obj_alloc_unique_name_istr(obj, name, -1);
371 rc = obj_set_name_istr(obj, newName);
372 istr_destroy(newName);
378 obj_set_unique_name(ABObj obj, STRING strName)
380 int return_value = 0;
381 ISTRING name = istr_create(strName);
383 return_value = obj_set_unique_name_istr(obj, name);
391 obj_alloc_unique_name(
397 ABObj parent = obj->parent;
398 if ( (parent == NULL)
399 || (obj_find_by_name(parent, name) == obj) )
403 return obj_alloc_unique_name_for_child(parent, name, maxNameLen);
408 obj_alloc_unique_name_istr(
414 ABObj parent = obj->parent;
415 if ( (parent == NULL)
416 || (obj_find_by_name(parent, istr_string(name)) == obj) )
418 return istr_dup(name);
420 return obj_alloc_unique_name_istr_for_child(parent, name, maxNameLen);
432 ABObj parent = obj->parent;
433 if ( (parent == NULL)
434 || (obj_find_by_name(parent, name) == obj) )
438 return obj_get_unique_name_for_child(parent, name, maxNameLen-1, nameOutBuf);
443 * maxlen < 1 means no max.
446 obj_alloc_unique_name_for_child(
453 STRING unique_name = NULL;
460 #if defined (USL) || defined(__uxp__)
462 * The USL specific changes were added ifdef due to time constraints
463 * They should be removed in the next release
465 maxlen = util_min(8191,maxlen); /* don't overrun buf */
467 maxlen = util_min(8192,maxlen); /* don't overrun buf */
471 * Alloc space and copy-in the unique name
473 unique_name = strdup(
474 obj_get_unique_name_for_child(obj, name, maxlen-1, nameBuf));
481 obj_alloc_unique_name_istr_for_child(
488 ISTRING unique_name = NULL;
495 #if defined (USL) || defined(__uxp__)
496 maxlen = util_min(8191,maxlen);
498 maxlen = util_min(8192,maxlen);
500 unique_name = istr_create(
501 obj_get_unique_name_for_child(obj, istr_string(name), maxlen-1, nameBuf));
508 obj_get_unique_name_for_child(
515 STRING returnName = NULL;
516 int nameOutBufSize = maxlen+1;
517 StringList namesList = NULL;
522 int objNumberStart = 0;
525 namesList = objP_get_names_scope_for_children(obj);
526 if (namesList == NULL)
532 unique = !strlist_str_exists(namesList, name);
540 * Determine trailing number
542 util_strncpy(nameOutBuf, name, nameOutBufSize);
543 nameLen = strlen(nameOutBuf);
544 for (i = nameLen-1; i >= 0; --i)
546 if (!isdigit(nameOutBuf[i]))
551 objNumberStart = i + 1;
552 objNumber = atoi(&(nameOutBuf[objNumberStart]));
555 * Search for a unique name by incrementing trailing #
561 if (++objNumber == 1)
563 /* skip 1 - name w/no # is implied 1 */
566 sprintf(&(nameOutBuf[objNumberStart]), "%d", objNumber);
567 unique = !strlist_str_exists(namesList, nameOutBuf);
572 returnName = nameOutBuf;
581 * Don't run this on a project!!! It's a severe dog, and can take many
582 * seconds to complete.
584 * Run it on each module (root = an module) instead.
587 obj_tree_ensure_unique_names(ABObj root, int maxnamelen)
592 for (trav_open(&trav, root, AB_TRAV_UI);
593 (obj = trav_next(&trav)) != NULL;)
595 obj_ensure_unique_name(obj, root, maxnamelen);
603 * Calls obj_tree_ensure_unique_names on each module in the given tree.
606 obj_tree_ensure_unique_names_in_modules(ABObj root, int maxnamelen)
611 for (trav_open(&trav, root, AB_TRAV_MODULES);
612 (module = trav_next(&trav)) != NULL;)
614 obj_tree_ensure_unique_names(module, maxnamelen);
621 * Gives an object a name by munging it's parent's name with it's own label.
622 * Used for item children, which aren't given names directly.
624 * actual_parent overrides the parent of the object. If actual_parent is NULL,
625 * the "normal" parent of the object is used.
628 obj_set_name_from_label(ABObj obj, STRING parent_name_in)
630 STRING parent_name = NULL;
631 STRING item_label = NULL;
632 STRING new_name = NULL;
635 (parent_name_in == NULL ?
636 (obj->parent == NULL ?
639 istr_string(obj->parent->name)
644 if (parent_name == NULL)
649 if (istr_len(obj->label) > 0)
651 item_label = istr_string(obj->label);
658 obj_set_unique_name(obj,
659 ab_ident_from_name_and_label(parent_name, item_label));
665 obj_set_name_from_parent(ABObj obj, STRING suffix)
668 STRING new_name = NULL;
670 parent_name = (obj->parent == NULL ?
673 istr_string(obj->parent->name)
676 if (parent_name == NULL)
681 obj_set_unique_name(obj,
682 ab_ident_from_name_and_label(parent_name,
690 * Gets a name for an object. Object may be NULL, or have a NULL name
692 * Copies name into passed-in buffer name, guarantees 0 termination. returns
696 obj_get_safe_name(ABObj obj, STRING name, int name_size)
705 strncpy(name, "(nil ABObj)", name_size);
707 else if (obj_get_name(obj) == NULL)
710 sprintf(buf, "(ABObj:0x%08lx)", obj);
711 strncpy(name, buf, name_size);
715 strncpy(name, obj_get_name(obj), name_size);
718 name[name_size - 1] = 0;
723 /*************************************************************************
725 ** UPDATE_CLIENTS METHODS **
727 *************************************************************************/
730 obj_update_clients(ABObj obj)
732 return objP_notify_send_update(obj, FALSE);
737 obj_tree_update_clients(ABObj tree)
740 return objP_notify_send_update(tree, TRUE);
745 obj_update_clients_with_data(
749 UpdateDataFreeFunc free_func)
751 return objP_or_tree_update_clients_with_data(
752 obj, FALSE, update_code, update_data, free_func);
757 obj_tree_update_clients_with_data(ABObj obj,
760 UpdateDataFreeFunc free_func)
762 return objP_or_tree_update_clients_with_data(
763 obj, TRUE, update_code, update_data, free_func);
768 objP_or_tree_update_clients_with_data(
773 UpdateDataFreeFunc free_func
779 * event notification will only free the data if the notify events are
780 * batched. It's pretty smart about it, so we're going to go to batch
781 * mode and let it handle it.
783 objP_notify_push_mode();
784 objP_notify_set_mode(OBJEV_MODE_BATCH_NOTIFY_EVS);
786 iReturn = objP_notify_send_update_with_data(
787 obj, update_subtree, update_code, update_data, free_func);
789 objP_notify_pop_mode();