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
24 * $XConsortium: pal_panedwin.c /main/3 1995/11/06 17:41:05 rswiston $
26 * @(#)pal_panedwin.c 1.10 01 May 1995
28 * RESTRICTED CONFIDENTIAL INFORMATION:
30 * The information in this document is subject to special
31 * restrictions in a confidential disclosure agreement between
32 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
33 * document outside HP, IBM, Sun, USL, SCO, or Univel without
34 * Sun's specific written approval. This document and all copies
35 * and derivative works thereof must be returned or destroyed at
38 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
44 * panedwin.c - functions for Paned Window prop sheet.
50 #include <sys/param.h> /* MAXPATHLEN */
53 #include <ab/util_types.h>
54 #include <ab_private/ab.h>
55 #include <ab_private/obj.h>
56 #include <ab_private/pal.h>
57 #include <ab_private/prop.h>
58 #include <ab_private/proj.h>
59 #include <ab_private/brws.h>
60 #include <ab_private/abobj.h>
61 #include <ab_private/abobj_set.h>
62 #include <ab_private/abobj_list.h>
63 #include <ab_private/ui_util.h>
64 #include <ab_private/obj_notify.h>
65 #include <ab_private/objxm.h>
66 #include "panedwin_ed_ui.h"
68 typedef struct PROP_PANEDWIN_SETTINGS
71 PropFieldSettingRec name;
72 PropCheckboxSettingRec init_state;
76 PropGeometrySettingRec min_max_geo;
78 ABObj current_pane_obj;
79 } PropPanedWinSettingsRec, *PropPanedWinSettings;
82 /*************************************************************************
84 ** Private Function Declarations **
86 **************************************************************************/
88 static int panedwin_initialize(
91 static Widget panedwin_prop_init(
95 static int panedwin_prop_load(
100 static int panedwin_load_panes(
104 static int panedwin_prop_clear(
107 static int panedwin_prop_clear_geom(
110 static int panedwin_prop_activate(
114 static int panedwin_prop_apply(
117 static BOOL panedwin_prop_pending(
120 static void panedwinEdP_init();
121 static BOOL pw_child_test_func(
124 static BOOL verify_props(
127 static void turnoff_changebars(
131 static int position_compare(
132 const void *leftEntry,
133 const void *rightEntry
136 static int east_compare(
137 const void *leftEntry,
138 const void *rightEntry
141 static int west_compare(
142 const void *leftEntry,
143 const void *rightEntry
149 static int pw_obj_reparentedOCB(
150 ObjEvReparentInfo info
152 static int pw_obj_destroyedOCB(
153 ObjEvDestroyInfo info
155 static int pw_obj_renamedOCB(
156 ObjEvAttChangeInfo info
158 static void pw_panelist_selectCB(
160 XtPointer client_data,
161 XmListCallbackStruct *listdata
164 /*************************************************************************
168 **************************************************************************/
170 PalItemInfo panedwin_palitem_rec = {
171 /* type */ AB_TYPE_CONTAINER,
172 /* name */ "Paned Window",
173 /* animation pixmaps*/ NULL,
174 /* number of pixmaps*/ 0,
175 /* rev_prop_frame */ NULL,
176 /* fix_prop_dialog */ NULL,
177 /* initialize */ panedwin_initialize,
178 /* is_a_test */ obj_is_paned_win,
179 /* prop_initialize */ panedwin_prop_init,
180 /* prop_active */ panedwin_prop_activate,
181 /* prop_clear */ panedwin_prop_clear,
182 /* prop_load */ panedwin_prop_load,
183 /* prop_apply */ panedwin_prop_apply,
184 /* prop_pending */ panedwin_prop_pending
187 PalItemInfo *ab_panedwin_palitem = &panedwin_palitem_rec;
188 PropPanedWinSettingsRec prop_pw_settings_rec[AB_PROP_TYPE_NUM_VALUES];
190 /*************************************************************************
192 ** Function Definitions **
194 **************************************************************************/
200 if (!obj_is_paned_win(obj))
203 obj_set_unique_name(obj, "panedwin");
204 obj_set_is_initially_active(obj, True);
215 DtbPanedwinEdDialogInfoRec rev_panedwin_prop_dialog;
216 DtbPanedwinEdDialogInfo cgen = &dtb_panedwin_ed_dialog; /* Codegen structure */
217 DtbRevolvPropDialogInfo rpd = &(dtb_revolv_prop_dialog);
218 PropPanedWinSettingsRec *pws = &(prop_pw_settings_rec[type]);
223 if (type == AB_PROP_REVOLVING)
226 * Only the Attributes ControlPanel needs to be created within
227 * the existing Revolving Prop dialog, so fill out all other
228 * fields with the Revolving Prop dialog equivelents, so the
229 * dtb initialize proc will skip those non-NULL fields...
231 dtbPanedwinEdDialogInfo_clear(&rev_panedwin_prop_dialog);
233 cgen = &(rev_panedwin_prop_dialog);
234 cgen->dialog = rpd->prop_dialog;
235 cgen->dialog_shellform = rpd->prop_dialog_shellform;
236 cgen->dialog_panedwin = rpd->prop_dialog_panedwin;
237 cgen->dialog_form = rpd->prop_dialog_form;
238 cgen->objlist_panel = rpd->objlist_panel;
239 cgen->objlist_label = rpd->objlist_label2;
240 cgen->objlist_scrolledwin = rpd->objlist_scrolledwin;
241 cgen->objlist = rpd->objlist;
242 cgen->attrs_ctrlpanel_frame = rpd->attrs_ctrlpanel_frame;
243 cgen->activate_panel = rpd->activate_panel;
244 cgen->apply_button = rpd->apply_button;
245 cgen->ok_button = rpd->ok_button;
246 cgen->cancel_button = rpd->cancel_button;
247 cgen->reset_button = rpd->reset_button;
248 cgen->help_button = rpd->help_button;
250 else /* AB_PROP_FIXED */
251 cgen = &dtb_panedwin_ed_dialog;
253 if (dtb_panedwin_ed_dialog_initialize(cgen, parent) == 0)
255 pws->prop_sheet = cgen->attrs_ctrlpanel;
256 pws->panelist = cgen->panelist;
257 pws->current_pw_obj = NULL;
258 pws->current_pane_obj = NULL;
259 pws->width = cgen->width_value;
260 pws->height = cgen->height_value;
262 /* Add Update, Rename, and Destroy object callbacks */
265 /* Add Callback to load pane children values when a pane
266 * is selected from the "Panes" list.
268 XtAddCallback(cgen->panelist,
269 XmNbrowseSelectionCallback,
270 (XtCallbackProc)pw_panelist_selectCB, (XtPointer)type);
272 if (type == AB_PROP_REVOLVING)
273 XtVaSetValues(parent,
274 XmNuserData, pws->current_pw_obj,
277 /* Dialog/Object List */
278 if (type == AB_PROP_FIXED)
280 prop_fixed_dialog_init(ab_panedwin_palitem,
281 cgen->dialog_shellform, cgen->objlist);
282 prop_activate_panel_init(type, ab_panedwin_palitem,
283 cgen->ok_button, cgen->apply_button,
284 cgen->reset_button, cgen->cancel_button,
288 /* Alternate Editor Buttons */
289 /* Alternate Editor Buttons */
290 prop_editors_panel_init(type, ab_panedwin_palitem,
291 cgen->attach_button, cgen->conn_button, cgen->helptxt_button);
294 * Prop Sheet Settings....
298 prop_field_init(&(pws->name), cgen->name_field_label,
299 cgen->name_field, cgen->name_cb);
303 item[n] = cgen->init_state_cbox_items.Visible_item;
304 item_val[n] = AB_STATE_VISIBLE; n++;
305 item[n] = cgen->init_state_cbox_items.Active_item;
306 item_val[n] = AB_STATE_ACTIVE; n++;
307 prop_checkbox_init(&(pws->init_state),cgen->init_state_cbox_label,
308 cgen->init_state_cbox, n, item, item_val,
309 cgen->init_state_cb);
311 /* Pane Minimum/Maximum Setting */
312 prop_geomfield_init(&(pws->min_max_geo), cgen->pane_height_lbl,
313 NULL, NULL, NULL, NULL,
314 cgen->min_height_field_label, cgen->min_height_field,
315 cgen->max_height_field_label, cgen->max_height_field,
318 prop_changebars_cleared(pws->prop_sheet);
320 return (cgen->dialog_shellform);
327 panedwin_prop_activate(
332 ui_set_active(prop_pw_settings_rec[type].prop_sheet, active);
342 PropPanedWinSettingsRec *pws = &(prop_pw_settings_rec[type]);
344 /* Clear Name Field */
345 prop_field_set_value(&(pws->name), "", False);
347 /* Clear Initial State */
348 prop_checkbox_set_value(&(pws->init_state), AB_STATE_VISIBLE,
350 prop_checkbox_set_value(&(pws->init_state), AB_STATE_ACTIVE,
353 /* Clear pane information */
354 panedwin_prop_clear_geom(type);
356 pws->current_pw_obj = NULL;
357 pws->current_pane_obj = NULL;
359 turnoff_changebars(type);
365 panedwin_prop_clear_geom(
369 PropPanedWinSettingsRec *pws = &(prop_pw_settings_rec[type]);
371 /* Clear Pane Geometry Setting */
372 XtVaSetValues(pws->width,
373 XtVaTypedArg, XmNlabelString, XtRString,
374 " 0", strlen(" 0")+1,
376 XtVaSetValues(pws->height,
377 XtVaTypedArg, XmNlabelString, XtRString,
378 " 0", strlen(" 0")+1,
381 /* Clear Pane Minimum/Maximum Setting */
382 prop_geomfield_clear(&(pws->min_max_geo), GEOM_WIDTH);
383 prop_geomfield_clear(&(pws->min_max_geo), GEOM_HEIGHT);
392 unsigned long loadkey
395 PropPanedWinSettingsRec *pws = &(prop_pw_settings_rec[type]);
396 BOOL load_all = (loadkey & LoadAll);
400 if (pws->current_pw_obj != NULL)
401 obj = pws->current_pw_obj;
405 else if (!obj_is_paned_win(obj))
408 pws->current_pw_obj = obj;
411 /* Load Name of paned window object */
412 if (load_all || loadkey & LoadName)
413 prop_field_set_value(&(pws->name), obj_get_name(obj), False);
417 /* Load Initial State */
418 prop_checkbox_set_value(&(pws->init_state), AB_STATE_VISIBLE,
419 obj_is_initially_visible(obj), False);
420 prop_checkbox_set_value(&(pws->init_state), AB_STATE_ACTIVE,
421 obj_is_initially_active(obj), False);
423 /* Load children of the paned window */
424 panedwin_load_panes(obj, type);
426 turnoff_changebars(type);
438 PropPanedWinSettingsRec *pws = &(prop_pw_settings_rec[type]);
440 if (obj == NULL || !obj_is_paned_win(obj))
443 /* Clear out the panes list first */
444 XmListDeleteAllItems(pws->panelist);
446 /* Populate the panes list in the prop sheet */
447 abobj_list_update(pws->panelist, obj, pw_child_test_func);
453 panedwin_pane_prop_load(
458 PropPanedWinSettingsRec *pws = &(prop_pw_settings_rec[type]);
459 char width[MAXPATHLEN],
466 if (pws->current_pane_obj != NULL)
467 obj = pws->current_pane_obj;
471 else if (!obj_is_pane(obj) && !obj_is_layers(obj))
474 pws->current_pane_obj = obj;
476 /* Pane Geometry Setting */
477 sprintf(width, "%d", abobj_get_actual_width(obj));
478 sprintf(height,"%d", abobj_get_actual_height(obj));
479 XtVaSetValues(pws->width,
480 XtVaTypedArg, XmNlabelString, XtRString,
481 width, strlen(width)+1,
483 XtVaSetValues(pws->height,
484 XtVaTypedArg, XmNlabelString, XtRString,
485 height, strlen(height)+1,
488 /* Pane Minimum/Maximum Setting */
489 prop_geomfield_set_value(&(pws->min_max_geo), GEOM_WIDTH,
490 obj_get_pane_min(obj),False);
491 prop_geomfield_set_value(&(pws->min_max_geo), GEOM_HEIGHT,
492 obj_get_pane_max(obj),False);
494 turnoff_changebars(type);
499 /* This routine is called when the "Apply" button is
500 * pressed. It sets all the values of attributes that
501 * have changed to their new values.
508 PropPanedWinSettingsRec *pws = &(prop_pw_settings_rec[type]);
512 if (!verify_props(type))
515 if (prop_changed(pws->name.changebar))
517 value = prop_field_get_value(&(pws->name));
518 abobj_set_name(pws->current_pw_obj, value);
521 if (prop_changed(pws->init_state.changebar))
523 abobj_set_visible(pws->current_pw_obj,
524 prop_checkbox_get_value(&(pws->init_state), AB_STATE_VISIBLE));
525 abobj_set_active(pws->current_pw_obj,
526 prop_checkbox_get_value(&(pws->init_state), AB_STATE_ACTIVE));
528 if (prop_changed(pws->min_max_geo.changebar))
530 geom = prop_geomfield_get_value(&(pws->min_max_geo), GEOM_WIDTH);
531 abobj_set_pane_min(pws->current_pane_obj, geom);
532 geom = prop_geomfield_get_value(&(pws->min_max_geo), GEOM_HEIGHT);
533 abobj_set_pane_max(pws->current_pane_obj, geom);
536 if (pws->current_pw_obj != NULL)
537 abobj_instantiate_changes(pws->current_pw_obj);
539 if (pws->current_pane_obj != NULL)
540 abobj_instantiate_changes(pws->current_pane_obj);
542 turnoff_changebars(type);
548 panedwin_prop_pending(
552 return(prop_changebars_pending(prop_pw_settings_rec[type].prop_sheet));
560 PropPanedWinSettingsRec *pws = &(prop_pw_settings_rec[type]);
562 if (prop_changed(pws->name.changebar) &&
563 !prop_name_ok(pws->current_pw_obj, pws->name.field))
566 if (prop_changed(pws->min_max_geo.changebar) &&
567 (!prop_number_ok(pws->min_max_geo.w_field, "Pane Height Min Field", 1, SHRT_MAX) ||
568 !prop_number_ok(pws->min_max_geo.h_field, "Pane Height Max Field", 1, SHRT_MAX)))
579 PropPanedWinSettingsRec *pws = &(prop_pw_settings_rec[type]);
581 prop_set_changebar(pws->name.changebar, PROP_CB_OFF);
582 prop_set_changebar(pws->init_state.changebar, PROP_CB_OFF);
583 prop_set_changebar(pws->min_max_geo.changebar, PROP_CB_OFF);
585 prop_changebars_cleared(pws->prop_sheet);
589 /* This routine is called when an item in the "Panes" list is
590 * selected. It takes care of loading in the pane child width/
591 * height and pane min/max values.
594 pw_panelist_selectCB(
596 XtPointer client_data,
597 XmListCallbackStruct *listdata
601 ABObj selected_obj = NULL;
605 PropPanedWinSettingsRec *pws;
607 type = (AB_PROP_TYPE) client_data;
608 pws = &(prop_pw_settings_rec[type]);
609 name = objxm_xmstr_to_str(listdata->item);
612 ret = abobj_moduled_name_extract(name, &module, &selected_obj);
613 pws->current_pane_obj = selected_obj;
614 panedwin_pane_prop_load(selected_obj, type);
619 /* Test whether the object is a module and if so test
620 * if it is mapped (showing).
627 if (!obj_is_module(test_obj))
630 if (obj_has_flag(test_obj, MappedFlag))
639 * Test whether an object should be loaded into the
640 * list of panes in the Paned Window Editor.
650 if ((module = obj_get_module(test_obj)) == NULL)
653 parent = obj_get_parent(test_obj);
654 if ( (obj_is_pane(test_obj) || obj_is_layers(test_obj))
655 && obj_is_paned_win(parent) && obj_has_flag(module, MappedFlag))
664 * obj-callback: object is being destroyed - remove from Paned
665 * Window Editor object list.
669 ObjEvDestroyInfo info
674 PropPanedWinSettingsRec *pws;
676 if ( !obj_is_pane(info->obj) && !obj_is_layers(info->obj) )
679 parent = obj_get_parent(info->obj);
680 if ( ((parent = obj_get_parent(info->obj)) != NULL) &&
681 obj_is_paned_win(parent))
683 for (i = 0; i < AB_PROP_TYPE_NUM_VALUES; ++i)
685 pws = &(prop_pw_settings_rec[i]);
687 if (pws->current_pane_obj == info->obj)
689 panedwin_prop_clear_geom((AB_PROP_TYPE) i);
690 pws->current_pane_obj = NULL;
692 ret = abobj_list_obj_destroyed(pws->panelist, info->obj,
701 ObjEvAttChangeInfo info
705 STRING mod_name = NULL;
707 PropPanedWinSettingsRec *pws;
709 if (!obj_is_module(info->obj) && !obj_is_pane(info->obj)
710 && !obj_is_layers(info->obj))
713 if (obj_is_module(info->obj))
715 mod_name = obj_get_name(info->obj);
716 if (mod_name == NULL)
719 if (info->old_name != NULL)
721 /* Change the module prefix in the panes list */
722 for (i = 0; i < AB_PROP_TYPE_NUM_VALUES; ++i)
724 pws = &(prop_pw_settings_rec[i]);
725 abobj_list_obj_renamed(pws->panelist, info->obj,
726 istr_string(info->old_name), module_test_func);
730 else /* obj is a pane OR a layer */
732 if (info->old_name == NULL)
734 /* This is a new pane dropped on an existing
735 * paned window object OR this is a new layer
736 * being created. To make sure, check the
739 parent = obj_get_parent(info->obj);
740 if ( (parent != NULL) && obj_is_paned_win(parent) )
742 for (i = 0; i < AB_PROP_TYPE_NUM_VALUES; ++i)
744 pws = &(prop_pw_settings_rec[i]);
745 if (parent == pws->current_pw_obj)
747 ret = abobj_list_update(pws->panelist, parent,
753 /* The pane's name has changed */
755 for (i = 0; i < AB_PROP_TYPE_NUM_VALUES; ++i)
757 pws = &(prop_pw_settings_rec[i]);
758 ret = abobj_list_obj_renamed(pws->panelist, info->obj,
759 istr_string(info->old_name), pw_child_test_func);
765 /* This callback gets called when a pane child is being
766 * parented to a different object, as when "Unmake Paned
767 * Window" or "Make Paned Window" is chosen from the floating
771 pw_obj_reparentedOCB(
772 ObjEvReparentInfo info
777 PropPanedWinSettingsRec *pws;
779 if (!obj_is_pane(info->obj) && !obj_is_layers(info->obj))
782 /* If the pane name is NULL, then that means it is a
783 * new pane, one which was dragged from the palette
784 * onto an existing paned window. In that case, let
785 * the pw_obj_renamedOCB callback handle it (i.e. add
786 * it to the pane list).
788 parent = obj_get_parent(info->obj);
789 if (obj_get_name(info->obj) != NULL)
791 /* Either a new paned window obj was created (via
792 * the "Make Paned Window" popup menu OR a paned
793 * window obj is being destroyed (via the "Unmake
794 * Paned Window" popup menu) and therefore its
795 * children are being reparented to the paned window's
796 * parent. If a new paned window was created, we don't
797 * need to update the panes list because that will happen
798 * when the new paned window obj is selected.
800 if ((info->old_parent != NULL) &&
801 obj_is_paned_win(info->old_parent))
803 for (i = 0; i < AB_PROP_TYPE_NUM_VALUES; ++i)
805 pws = &(prop_pw_settings_rec[i]);
806 if (pws->current_pane_obj == info->obj)
807 panedwin_prop_clear_geom((AB_PROP_TYPE) i);
808 ret = abobj_list_obj_reparented(pws->panelist, info,
819 obj_add_reparent_callback(pw_obj_reparentedOCB, "panedwinEdP_init");
820 obj_add_rename_callback(pw_obj_renamedOCB, "panedwinEdP_init");
821 obj_add_destroy_callback(pw_obj_destroyedOCB, "panedwinEdP_init");
826 * Create a paned window out of the selected group of objects.
832 ABObj project = proj_get_project();
833 ABObj obj = (ABObj) NULL;
834 ABObj pw_obj = (ABObj) NULL;
835 ABObj obj_parent = (ABObj) NULL;
837 int i, xpos = 0, ypos = 0;
838 AB_ATTACH_TYPE attach_type = AB_ATTACH_UNDEF,
839 next_attach_type = AB_ATTACH_UNDEF;
840 void *attach_val = NULL,
841 *next_attach_val = NULL;
842 int attach_offset = 0;
843 BOOL AttachTypesEqual;
845 /* Creation may take awhile, so set busy cursor */
846 ab_set_busy_cursor(True);
848 /* Get handle to the selected objects */
849 abobj_get_selected(project, False, False, &sel);
851 /* Get the parent for all the selected objects */
852 obj_parent = obj_get_parent(sel.list[0]);
854 /* Set the SaveNeeded flag on the module */
855 abobj_set_save_needed(obj_get_module(obj_parent), TRUE);
857 /* Deselect any objects that happen to be selected */
858 abobj_deselect_all(project);
859 aob_deselect_all_objects(project);
861 /* Create a new panedWindow obj as a child of the
862 * parent of the selected objects.
864 pw_obj = obj_create(AB_TYPE_CONTAINER, obj_parent);
865 obj_set_subtype(pw_obj, AB_CONT_PANED);
867 pal_initialize_obj(pw_obj);
869 /* Sort the selected object list in the order in
870 * which the panes will be placed once they are part
871 * of a panedWindow (order is based on y coordinate).
873 qsort(sel.list, sel.count, sizeof(ABObj *), position_compare);
875 /* Set the paned window object's NORTH and SOUTH attachments */
876 attach_type = obj_get_attach_type(sel.list[0], AB_CP_NORTH);
877 attach_val = obj_get_attach_value(sel.list[0], AB_CP_NORTH);
878 attach_offset = obj_get_attach_offset(sel.list[0], AB_CP_NORTH);
879 obj_set_attachment(pw_obj,
885 attach_type = obj_get_attach_type(sel.list[sel.count-1], AB_CP_SOUTH);
886 attach_val = obj_get_attach_value(sel.list[sel.count-1], AB_CP_SOUTH);
887 attach_offset = obj_get_attach_offset(sel.list[sel.count-1], AB_CP_SOUTH);
888 obj_set_attachment(pw_obj,
894 /* Reparent the selected objects to be children of the
895 * new panedWindow obj, in the *correct* order.
897 for (i = 0; i < sel.count; i++)
900 obj_reparent(obj, pw_obj);
903 /* Sort the selected object list from rightmost object
904 * to leftmost object.
906 qsort(sel.list, sel.count, sizeof(ABObj *), east_compare);
908 /* Set the paned window object's EAST attachments */
909 attach_type = obj_get_attach_type(sel.list[sel.count-1], AB_CP_EAST);
910 attach_val = obj_get_attach_value(sel.list[sel.count-1], AB_CP_EAST);
911 attach_offset = obj_get_attach_offset(sel.list[sel.count-1], AB_CP_EAST);
912 obj_set_attachment(pw_obj,
918 /* Sort the selected object list from leftmost object
919 * to rightmost object. Have to do this because it is
920 * possible that the leftmost and rightmost objects are
921 * in fact one and the same (if it spans the entire window,
922 * for example and the other pane does not).
924 qsort(sel.list, sel.count, sizeof(ABObj *), west_compare);
926 /* Set the paned window object's WEST attachment */
927 attach_type = obj_get_attach_type(sel.list[0],AB_CP_WEST);
928 attach_val = obj_get_attach_value(sel.list[0],AB_CP_WEST);
929 attach_offset = obj_get_attach_offset(sel.list[0],AB_CP_WEST);
930 obj_set_attachment(pw_obj,
936 /* Check whether or not the paned window's children's
937 * EAST/WEST attachment types are equal. If not, then post
938 * a message saying that the attachments may not be correct
939 * and that the user should use the Attachments Editor
942 AttachTypesEqual = TRUE;
943 attach_type = obj_get_attach_type(sel.list[0], AB_CP_EAST);
944 for (i = 1; ((i < sel.count) && AttachTypesEqual); i++)
946 next_attach_type = obj_get_attach_type(sel.list[i], AB_CP_EAST);
947 if (attach_type != next_attach_type)
949 AttachTypesEqual = FALSE;
951 dtb_panedwin_ed_pw_east_attach_msg_initialize(
952 &dtb_panedwin_ed_pw_east_attach_msg);
953 dtb_show_message((Widget)obj_parent->ui_handle,
954 &dtb_panedwin_ed_pw_east_attach_msg, NULL,NULL);
957 /* If all of the paned window's children EAST attachment
958 * types are equal, then check the EAST attachment values.
960 if (AttachTypesEqual)
962 attach_val = obj_get_attach_value(sel.list[0], AB_CP_EAST);
963 for (i = 1; i < sel.count; i++)
965 next_attach_val = obj_get_attach_value(sel.list[i], AB_CP_EAST);
966 if (attach_val != next_attach_val)
969 dtb_panedwin_ed_pw_east_attach_msg_initialize(
970 &dtb_panedwin_ed_pw_east_attach_msg);
971 dtb_show_message((Widget)obj_parent->ui_handle,
972 &dtb_panedwin_ed_pw_east_attach_msg, NULL,NULL);
978 AttachTypesEqual = TRUE;
979 attach_type = obj_get_attach_type(sel.list[0], AB_CP_WEST);
980 for (i = 1; ((i < sel.count) && AttachTypesEqual); i++)
982 next_attach_type = obj_get_attach_type(sel.list[i], AB_CP_WEST);
983 if (attach_type != next_attach_type)
985 AttachTypesEqual = FALSE;
987 dtb_panedwin_ed_pw_west_attach_msg_initialize(
988 &dtb_panedwin_ed_pw_west_attach_msg);
989 dtb_show_message((Widget)obj_parent->ui_handle,
990 &dtb_panedwin_ed_pw_west_attach_msg, NULL,NULL);
993 /* If all of the paned window's children WEST attachment
994 * types are equal, then check the WEST attachment values.
996 if (AttachTypesEqual)
998 attach_val = obj_get_attach_value(sel.list[0], AB_CP_WEST);
999 for (i = 1; i < sel.count; i++)
1001 next_attach_val = obj_get_attach_value(sel.list[i], AB_CP_WEST);
1002 if (attach_val != next_attach_val)
1005 dtb_panedwin_ed_pw_west_attach_msg_initialize(
1006 &dtb_panedwin_ed_pw_west_attach_msg);
1007 dtb_show_message((Widget)obj_parent->ui_handle,
1008 &dtb_panedwin_ed_pw_west_attach_msg, NULL,NULL);
1014 obj_tree_clear_flag(pw_obj, InstantiatedFlag);
1015 abobj_show_tree(pw_obj, True);
1017 /* Make the new obj selected */
1018 abobj_select(pw_obj);
1020 ab_set_busy_cursor(False);
1025 const void *leftEntry,
1026 const void *rightEntry
1029 ABObj *left_obj = (ABObj *)leftEntry;
1030 ABObj *right_obj = (ABObj *)rightEntry;
1032 int left_xpos = obj_get_x(*left_obj);
1033 int left_ypos = obj_get_y(*left_obj);
1034 int right_xpos = obj_get_x(*right_obj);
1035 int right_ypos = obj_get_y(*right_obj);
1037 if (left_ypos - right_ypos != 0)
1038 return (left_ypos - right_ypos);
1040 return (left_xpos - right_xpos);
1045 const void *leftEntry,
1046 const void *rightEntry
1049 ABObj *left_obj = (ABObj *)leftEntry;
1050 ABObj *right_obj = (ABObj *)rightEntry;
1052 int left_xpos = obj_get_x(*left_obj) +
1053 abobj_get_actual_width(*left_obj);
1054 int right_xpos = obj_get_x(*right_obj) +
1055 abobj_get_actual_width(*right_obj);
1056 return (left_xpos - right_xpos);
1061 const void *leftEntry,
1062 const void *rightEntry
1065 ABObj *left_obj = (ABObj *)leftEntry;
1066 ABObj *right_obj = (ABObj *)rightEntry;
1068 int left_xpos = obj_get_x(*left_obj);
1069 int right_xpos = obj_get_x(*right_obj);
1071 return (left_xpos - right_xpos);
1075 * Take the selected group of objects out of the
1076 * paned window and delete the paned window object.
1079 abobj_unmake_panedwin(
1082 ABObj project = proj_get_project();
1083 ABObj pw_obj = NULL;
1084 ABObj obj_parent = NULL;
1088 int i, x_orig = 0, y_orig = 0, ypos = 0;
1089 int j, numChildren = 0, tree_pos = 0;
1091 Boolean parent_exists = True;
1093 /* Undo may take awhile, so set busy cursor */
1094 ab_set_busy_cursor(True);
1096 /* Set the SaveNeeded flag */
1097 abobj_set_save_needed(project, TRUE);
1099 /* Get handle to the paned window objects */
1100 abobj_get_selected(project, False, False, &sel);
1102 /* Go through each paned window object and move
1103 * its children to the paned window's parent.
1105 for (i = 0; i < sel.count; i++)
1107 pw_obj = sel.list[i];
1109 /* Deselect the paned window */
1110 abobj_deselect(pw_obj);
1112 /* Get the parent for all the selected objects */
1113 obj_parent = obj_get_parent(pw_obj);
1115 /* Set the SaveNeeded flag on the module */
1116 abobj_set_save_needed(obj_get_module(pw_obj), TRUE);
1118 /* Get the child position of the paned window
1119 * object in its parent hierarchy.
1121 tree_pos = obj_get_child_num(pw_obj);
1123 /* Get the x,y position of the paned window */
1124 x_orig = obj_get_x(pw_obj);
1125 y_orig = obj_get_y(pw_obj);
1128 numChildren = obj_get_num_salient_children(pw_obj);
1129 for (j = 0; j < numChildren; j++, tree_pos++)
1131 /* The first child really is the next
1132 * child because the previous child has
1133 * been reparented to the paned window's
1136 obj = obj_get_salient_child(pw_obj, 0);
1138 obj_insert_child(obj_parent, obj, tree_pos);
1140 abobj_set_xy(obj, x_orig, ypos);
1141 ypos = ypos + abobj_get_actual_height(obj);
1143 objxm_tree_uninstantiate(obj, True);
1144 abobj_instantiate_changes(obj);
1147 /* Destroy the paned window object */
1148 obj_destroy(pw_obj);
1150 /* REMIND: Not sure if we need this code.
1151 * Paned windows should all have the
1152 * same parent, given the constraint
1153 * that multiple paned windows cannot
1154 * be selected across different modules.
1157 * Keep a list of parents that need to be
1158 * updated after all paned windows are unpaned.
1162 list = (ABObj*)XtMalloc(sizeof(ABObj));
1163 list[0] = obj_parent;
1167 for (j = 0; j < list_items; j++)
1169 if (list[j] == obj_parent)
1171 parent_exists = True;
1175 if (parent_exists == False)
1177 XtRealloc((char*)list, sizeof(ABObj));
1178 list[list_items++] = obj_parent;
1180 parent_exists = False;
1183 ab_set_busy_cursor(False);