/*** DTB_USER_CODE_START vvv Add file header below vvv ***/ /* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these libraries and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /*** DTB_USER_CODE_END ^^^ Add file header above ^^^ ***/ /* * File: dnd_ed_stubs.c * Contains: Module callbacks and connection functions * * This file was generated by dtcodegen, from module dnd_ed * * Any text may be added between the DTB_USER_CODE_START and * DTB_USER_CODE_END comments (even non-C code). Descriptive comments * are provided only as an aid. * * ** EDIT ONLY WITHIN SECTIONS MARKED WITH DTB_USER_CODE COMMENTS. ** * ** ALL OTHER MODIFICATIONS WILL BE OVERWRITTEN. DO NOT MODIFY OR ** * ** DELETE THE GENERATED COMMENTS! ** */ #include #include #include #include "dtb_utils.h" #include "dtbuilder.h" #include "dnd_ed_ui.h" /************************************************************************** *** DTB_USER_CODE_START *** *** All necessary header files have been included. *** *** Add include files, types, macros, externs, and user functions here. ***/ #include #include #include #include "dtbuilder.h" #include "dnd_ed_ui.h" #include "abobj_set.h" #include "conn.h" #include #include #include #include "abobj_list.h" /* REMIND: nuke this! */ #include "help_ed_ui.h" #define NO_DISMISS 0 #define DISMISS 1 #include "dtb_utils.h" /* * Drag and Drop Editor Settings */ typedef struct DND_EDITOR_SETTINGS { ABObj curObj; AB_OBJECT_TYPE objType; int objSubtype; Widget propSheet; Widget objTypeMenu; Widget objList; PropCheckboxSettingRec drag_ops_checkbox; PropFieldSettingRec drag_icon_text; PropFieldSettingRec drag_icon_mask_text; PropRadioSettingRec drag_types_radiobox; PropCheckboxSettingRec drop_ops_checkbox; PropCheckboxSettingRec drop_types_checkbox; PropCheckboxSettingRec drop_child_checkbox; } DndEditorSettingsRec, *DndEditorSettings; static void dnd_change_objecttype_palCB( Widget widget, XtPointer client_data, XtPointer call_data ); static void change_objtype( Widget widget, AB_OBJECT_TYPE newtype, int newsubtype ); static void update_objecttype_menu_from_obj( Widget menu, ABObj obj ); static Widget dnd_ed_editor_init( DtbDndEdDialogInfo dnd_ed, Widget parent ); static DTB_MODAL_ANSWER do_auto_apply( Widget list, ABObj old_obj, ABObj new_obj ); static void clear_editor_fields(void); static BOOL dnd_editable_obj_test( PalEditableObjInfo *ed_obj_info ); static int dnd_ed_editor_load( ABObj project ); static int dnd_ed_editor_apply(void); static void dnd_turnoff_changebars(void); static int check_active(void); static int dnd_ed_update_objecttype_menu( Widget menu_pane ); static BOOL dnd_list_test( ABObj test_obj ); static int dnd_store_attrs( ABObj obj ); static void dnd_fetch_attrs( ABObj obj ); static BOOL dnd_obj_is_target_type( ABObj obj ); static int dnd_obj_was_deleted( ObjEvDestroyInfo info ); static int dnd_obj_was_renamed( ObjEvAttChangeInfo info ); static int dnd_obj_was_updated( ObjEvUpdateInfo info ); static void dnd_select_instanceCB( Widget widget, XtPointer client_data, XmListCallbackStruct *listdata ); static void dnd_prevent_closeCB( Widget widget, XtPointer client_data, XtPointer call_data ); /* * Declarations of global widgets used by callbacks. */ static DndEditorSettingsRec dndEdInfo; /* * End declarations of global widgets */ void dnd_ed_show_dialog(void) { /* If there is no DragAndDrop Editor, create it */ if (AB_dnd_dialog == (Widget)NULL) { AB_dnd_dialog = dnd_ed_editor_init(&dtb_dnd_ed_dialog, AB_toplevel); } if (AB_dnd_dialog != NULL) ab_show_window(AB_dnd_dialog); } /* * Returns the topmost form widget */ static Widget dnd_ed_editor_init( DtbDndEdDialogInfo dnd_ed, Widget parent ) { DndEditorSettings dds = &dndEdInfo; Widget item[10]; int item_val[10]; int n = 0; /* * Create Dialog widgets... */ if (dnd_ed->dialog_shellform != NULL) { return dnd_ed->dialog_shellform; } if (dtb_dnd_ed_dialog_initialize(dnd_ed, parent) != 0) { #ifdef DEBUG util_dprintf(1, "dnd_ed_show_dialog: could not initialize Drag and Drop Editor\n"); return NULL; #endif /* DEBUG */ } /* * Hook widgets up to DragAndDrop Editor */ dds->curObj = NULL; dds->objType = AB_TYPE_UNDEF; dds->objSubtype = 0; dds->propSheet = dnd_ed->attrs_ctrlpanel; dds->objList = dnd_ed->objlist; dds->objTypeMenu = dnd_ed->objtype_opmenu; /* * Initialization of Editor Settings... */ /* drag operation checkbox */ n = 0; item[n] = dnd_ed->drag_op_checkbox_items.Copy_item; item_val[n++] = (int)ABDndOpCopy; item[n] = dnd_ed->drag_op_checkbox_items.Move_item; item_val[n++] = (int)ABDndOpMove; item[n] = dnd_ed->drag_op_checkbox_items.Link_item; item_val[n++] = (int)ABDndOpLink; prop_checkbox_init(&(dds->drag_ops_checkbox), dnd_ed->drag_op_checkbox_label, dnd_ed->drag_op_checkbox, n, item, item_val, dnd_ed->drag_op_cb); /* drag icon text */ prop_field_init(&(dds->drag_icon_text), dnd_ed->drag_icon_field_label, dnd_ed->drag_icon_field, dnd_ed->drag_icon_cb); prop_field_init(&(dds->drag_icon_mask_text), dnd_ed->drag_icon_mask_field_label, dnd_ed->drag_icon_mask_field, dnd_ed->drag_icon_mask_cb); /* drag data types checkbox */ n = 0; item[n] = dnd_ed->drag_data_checkbox_items.Text_item; item_val[n++] = (int)ABDndTypeText; item[n] = dnd_ed->drag_data_checkbox_items.Filename_item; item_val[n++] = (int)ABDndTypeFilename; item[n] = dnd_ed->drag_data_checkbox_items.Buffer_item; item_val[n++] = (int)ABDndTypeUserDef; prop_radiobox_init(&(dds->drag_types_radiobox), dnd_ed->drag_data_checkbox_label, dnd_ed->drag_data_checkbox, n, item, (XtPointer*)item_val, dnd_ed->drag_data_cb); /* drop ops checkbox */ n = 0; item[n] = dnd_ed->drop_op_checkbox_items.Copy_item; item_val[n++] = (int)ABDndOpCopy; item[n] = dnd_ed->drop_op_checkbox_items.Move_item; item_val[n++] = (int)ABDndOpMove; item[n] = dnd_ed->drop_op_checkbox_items.Link_item; item_val[n++] = (int)ABDndOpLink; prop_checkbox_init(&(dds->drop_ops_checkbox), dnd_ed->drop_op_checkbox_label, dnd_ed->drop_op_checkbox, n, item, item_val, dnd_ed->drop_op_cb); /* drop data types checkbox */ n = 0; item[n] = dnd_ed->drop_data_checkbox_items.Text_item; item_val[n++] = (int)ABDndTypeText; item[n] = dnd_ed->drop_data_checkbox_items.Filename_item; item_val[n++] = (int)ABDndTypeFilename; item[n] = dnd_ed->drop_data_checkbox_items.Buffer_item; item_val[n++] = (int)ABDndTypeUserDef; prop_checkbox_init(&(dds->drop_types_checkbox), dnd_ed->drop_data_checkbox_label, dnd_ed->drop_data_checkbox, n, item, item_val, dnd_ed->drop_data_cb); /* allow drops on children checkbox */ n = 0; item[n] = dnd_ed->drop_child_checkbox_items.nolabel_item; item_val[n++] = 0; prop_checkbox_init(&(dds->drop_child_checkbox), dnd_ed->drop_child_checkbox_label, dnd_ed->drop_child_checkbox, n, item, item_val, dnd_ed->drop_child_cb); /* * Build object type menu and select the first item (but first must * destroy dummy option item) */ dndEdInfo.objType = AB_TYPE_UNDEF; dndEdInfo.objSubtype = 0; XtDestroyWidget(dnd_ed->objtype_opmenu_items.object_type_item); pal_add_editable_obj_menu_items(dnd_ed->objtype_opmenu_menu, dnd_change_objecttype_palCB, dnd_editable_obj_test); XtVaGetValues(dds->objList, XmNitemCount,&n, NULL); if(n > 0) { XmListSelectPos(dds->objList,1,True); /* invokes callbacks */ } /* Register Dnd Editor callbacks */ XtAddCallback(dds->objList, XmNsingleSelectionCallback, (XtCallbackProc)dnd_select_instanceCB, (XtPointer)NULL); /* * Setup dialog to participate in dtbuilder window protocol */ ab_register_window(dnd_ed->dialog_shellform, AB_WIN_DIALOG, WindowHidden, AB_toplevel, AB_WPOS_TILE_HORIZONTAL, dnd_prevent_closeCB, NULL); dnd_turnoff_changebars(); /* * Make necessary fields active */ check_active(); /* ** Hook up callbacks so we're notified when an object is modified. ** an update callback occurs when the object has been completely ** modified (e.g., when an object is loaded from a file). ** ** The second parameter is our "name" for debugging messages. We'll Just ** use the file name. ** ** We don't use the create_callback() to detect the creation of objects ** because at the time they are created their name is "(nil)". However, ** a later part of the creation process is to change their name from ** "(nil)" to their proper name, and at that time the rename callback is ** called. We therefore use the rename callback to handle both object ** creation and renaming. */ obj_add_destroy_callback(dnd_obj_was_deleted, __FILE__); obj_add_rename_callback(dnd_obj_was_renamed, __FILE__); obj_add_update_callback(dnd_obj_was_updated, __FILE__); return dnd_ed->dialog_shellform; } static int dnd_ed_update_objecttype_menu( Widget menu_pane ) { return 0; } static void dnd_change_objecttype_palCB( Widget widget, XtPointer client_data, XtPointer call_data ) { PalEditableObjInfo *item = (PalEditableObjInfo*)client_data; change_objtype(widget,item->type,item->subtype); } static void change_objtype( Widget widget, AB_OBJECT_TYPE newtype, int newsubtype ) { DTB_MODAL_ANSWER answer; int i; DndEditorSettings dds = &dndEdInfo; /* ** If there are pending changes, process the requested ** load in a special way that allows the user to abort it ** if they so choose. */ if((dds->curObj != NULL) && prop_changebars_pending(dds->propSheet)) { answer = do_auto_apply(widget, dds->curObj, (ABObj)NULL); if (answer == DTB_ANSWER_CANCEL) { update_objecttype_menu_from_obj(dds->objTypeMenu, dds->curObj); return; } } /* ** Either nothing to auto-apply, or the user said "Sure, go ahead". ** Because the do_auto_apply() function didn't have a new object to ** change to (automatically) we have to do it manually */ /* First, clear out fields in Dnd Editor */ clear_editor_fields(); /* Update current-objecttype (from menu selection) & clear current object */ dds->curObj = (ABObj)NULL; dds->objType = newtype; dds->objSubtype = newsubtype; /* Load object list with new type */ (void) abobj_list_load(dds->objList,proj_get_project(),dnd_list_test); /* Select 1st item in the list (if there is one) and load its attributes */ XtVaGetValues(dds->objList, XmNitemCount,&i, NULL); if(i > 0) { /* ** This will call the item_selected callback for the list, ** which will update the Dnd Editor's fields. */ XmListSelectPos(dds->objList,1,True); } else { check_active(); /* gray out fields */ } return; } /* Update the object type menu to match the type of a given object */ static void update_objecttype_menu_from_obj( Widget menu, ABObj obj ) { PalItemInfo* palitem = (PalItemInfo*)NULL; XmString xmlabel = NULL; Widget menu_selection = NULL; if(obj == (ABObj)NULL) return; /* Get palette item info for target object */ if( (palitem = pal_get_item_info(obj)) == (PalItemInfo*)NULL) return; /* Get selection button gadget for specified option menu */ if((menu_selection = XmOptionButtonGadget(menu)) == NULL) return; xmlabel = XmStringCreateLocalized(palitem->name); XtVaSetValues(menu_selection, XmNlabelString, xmlabel, NULL); XmStringFree(xmlabel); } static BOOL dnd_editable_obj_test( PalEditableObjInfo *ed_obj_info ) { BOOL needed = FALSE; switch(ed_obj_info->type) { case AB_TYPE_BASE_WINDOW: case AB_TYPE_DIALOG: case AB_TYPE_DRAWING_AREA: case AB_TYPE_LABEL: needed = TRUE; break; case AB_TYPE_CONTAINER: needed = (ed_obj_info->subtype == (int)AB_CONT_RELATIVE); break; } return needed; } static int dnd_ed_editor_load( ABObj obj ) { DndEditorSettings dds = &dndEdInfo; if (obj == NULL) { if (dds->curObj != NULL) obj = dds->curObj; else return ERROR; } else dds->curObj = obj; /* REMIND: LOAD ALL EDITOR SETTINGS WITH OBJ VALUES HERE */ dnd_turnoff_changebars(); return OK; } static int dnd_ed_editor_apply(void) { return dnd_store_attrs(dndEdInfo.curObj); } static void dnd_turnoff_changebars(void) { DndEditorSettings dds = &dndEdInfo; prop_set_changebar(dds->drag_ops_checkbox.changebar,PROP_CB_OFF); prop_set_changebar(dds->drag_icon_text.changebar,PROP_CB_OFF); prop_set_changebar(dds->drag_icon_mask_text.changebar,PROP_CB_OFF); prop_set_changebar(dds->drag_types_radiobox.changebar,PROP_CB_OFF); prop_set_changebar(dds->drop_ops_checkbox.changebar,PROP_CB_OFF); prop_set_changebar(dds->drop_types_checkbox.changebar,PROP_CB_OFF); prop_set_changebar(dds->drop_child_checkbox.changebar,PROP_CB_OFF); prop_changebars_cleared(dds->propSheet); } /* ** Callback: object has been selected from list of objects */ static void dnd_select_instanceCB( Widget widget, XtPointer client_data, XmListCallbackStruct *listdata ) { ABObj module = NULL; ABObj selected_obj = NULL; STRING name = NULL; DndEditorSettings dds = &dndEdInfo; name = objxm_xmstr_to_str(listdata->item); if ( (listdata->selected_item_count == 0) || (name == NULL) ) { dndEdInfo.curObj = NULL; check_active(); return; } if (name != NULL) { util_dprintf(2,"You selected <%s>\n",name); abobj_moduled_name_extract(name, &module, &selected_obj); XtFree(name); if (selected_obj) { /* ** If there are pending changes, process the requested ** load in a special way that allows the user to abort it ** if they so choose. */ if((dds->curObj != NULL) && prop_changebars_pending(dds->propSheet) == True) { (void) do_auto_apply(widget, dds->curObj, selected_obj); } /* No pending changes, so just load the new object */ else { dds->curObj = selected_obj; dds->objType = obj_get_type(dds->curObj); dds->objSubtype = obj_get_subtype(dds->curObj); dnd_fetch_attrs(dds->curObj); } return; } } if (util_get_verbosity() > 0) fprintf(stderr,"Dnd Editor::dnd_select_instanceCB: could not get object in list\n"); } /* ** Handle auto apply. This condition can occur in any of the following ways: ** - The user selects another object to be edited and hasn't yet saved changes ** made to the current object (old_obj = current object, new_obj = new ** object they've chosen from the list) ** - The user selects "Close" from the Motif window menu and hasn't yet saved ** changes made to the current object (old_obj and new_obj are both = ** current object) ** - The user selects another object type from the object type menu and hasn't ** yet saved changes made to the current object (old_obj = current object, ** new_obj = NULL) ** The assumption here is that the user wants to be given the opportunity ** to save the changes or discard them, and a modal dialog is an o.k. ** way to handle the situation. */ static DTB_MODAL_ANSWER do_auto_apply( Widget list, ABObj old_obj, ABObj new_obj ) { DTB_MODAL_ANSWER answer; char buffer[256]; char *old_name, *new_name; BOOL changing_objects = FALSE; XmString xm_buf = (XmString) NULL; if(old_obj == (ABObj) NULL) return(DTB_ANSWER_CANCEL); else old_name = abobj_get_moduled_name(old_obj); if (new_obj == (ABObj) NULL) new_name = ""; else new_name = abobj_get_moduled_name(new_obj); /* Check for object change auto-apply vs. same object auto-apply */ if( (new_obj != (ABObj) NULL) && (new_obj != old_obj) ) changing_objects = TRUE; if (dtb_app_resource_rec.implied_apply == True) answer = DTB_ANSWER_ACTION1; else { if (changing_objects) { sprintf(buffer, CATGETS(Dtb_project_catd, 100, 31, "Drag and drop properties for \"%s\"\n\ have been modified but not Applied.\n\n\ You can Apply the Changes or Cancel the\n\ Load operation for \"%s\"."),old_name, new_name); } else { if(new_obj != (ABObj) NULL) { sprintf(buffer, CATGETS(Dtb_project_catd, 100, 32, "Drag and drop properties for \"%s\"\n\ have been modified but not Applied.\n\n\ You can Apply the Changes or Cancel the\n\ Close operation."), old_name); } else { sprintf(buffer,CATGETS(Dtb_project_catd, 100, 33, "Drag and drop properties for \"%s\"\n\ have been modified but not Applied.\n\n\ You can Apply the Changes or Cancel the\n\ 'Change Object-Type' operation."), old_name); } } /* Popup modal message and wait for answer */ /* REMIND: make new dnd_ed_warn_msg.. */ xm_buf = XmStringCreateLocalized(buffer); dtb_help_ed_wrn_msg_initialize(&dtb_help_ed_wrn_msg); answer = dtb_show_modal_message(list, &dtb_help_ed_wrn_msg, xm_buf, NULL, NULL); XmStringFree(xm_buf); } /* Process answer */ switch(answer) { case DTB_ANSWER_ACTION1: /* Apply Changes */ dnd_store_attrs(old_obj); if (changing_objects) dnd_fetch_attrs(new_obj); break; case DTB_ANSWER_CANCEL: /* Cancel */ if(changing_objects) { util_dprintf(2,"Resetting <%s> as the current item\n", old_name); ui_list_select_item(list,old_name,FALSE); } break; } if (old_obj != (ABObj)NULL) XtFree(old_name); if (new_obj != (ABObj)NULL) XtFree(new_name); /* Pass along the answer in case the caller needs it */ return (answer); } static void clear_editor_fields(void) { DndEditorSettingsRec *dds = &dndEdInfo; prop_checkbox_set_value(&(dds->drag_ops_checkbox), ABDndOpCopy, False, False); prop_checkbox_set_value(&(dds->drag_ops_checkbox), ABDndOpLink, False, False); prop_checkbox_set_value(&(dds->drag_ops_checkbox), ABDndOpMove, False, False); prop_field_set_value(&(dds->drag_icon_text), Util_empty_string, False); prop_field_set_value(&(dds->drag_icon_mask_text), Util_empty_string, False); prop_radiobox_set_value(&(dds->drag_types_radiobox), (XtPointer)ABDndTypeText, False); prop_checkbox_set_value(&(dds->drop_ops_checkbox), ABDndOpCopy, False, False); prop_checkbox_set_value(&(dds->drop_ops_checkbox), ABDndOpLink, False, False); prop_checkbox_set_value(&(dds->drop_ops_checkbox), ABDndOpMove, False, False); prop_checkbox_set_value(&(dds->drop_types_checkbox), ABDndTypeText, False, False); prop_checkbox_set_value(&(dds->drop_types_checkbox), ABDndTypeFilename, False, False); prop_checkbox_set_value(&(dds->drop_types_checkbox), ABDndTypeUserDef, False, False); prop_checkbox_set_value(&(dds->drop_child_checkbox), 0, False, False); /* Reset changebars */ dnd_turnoff_changebars(); } /* ** Test function to determine whether an object should appear in the Dnd ** Editor's list. */ static BOOL dnd_list_test( ABObj test_obj ) { /* Is this an object we'd want to display? */ if (obj_is_salient_ui(test_obj) && obj_is_defined(test_obj) && (!obj_is_list_item(test_obj)) && /* no List Items */ /* (!obj_is_popup_win(test_obj)) && no CustomDialogs */ (obj_get_module(test_obj) != NULL) && (obj_has_flag(test_obj, MappedFlag) || (obj_is_message(test_obj))) ) { /* Yes it is. If we're looking for a current type, do they match ? */ return(dnd_obj_is_target_type(test_obj)); } return(False); } /* ** Get the dnd attributes from an object and update the Dnd Editor's ** fields accordingly. */ static void dnd_fetch_attrs( ABObj obj ) { DndEditorSettingsRec *dds = &dndEdInfo; ABDndOpFlags dragOps = 0; ABDndTypeFlags dragType = 0; ABDndOpFlags dropOps = 0; ABDndTypeFlags dropTypes = 0; BOOL dropOnChildren = FALSE; util_dprintf(2,"Load object dnd attributes into editor display fields\n"); if (obj == NULL) { clear_editor_fields(); dds->curObj = NULL; return; } /* get some data */ dragOps = obj_get_drag_ops(obj); dragType = obj_get_drag_types(obj); dropOps = obj_get_drop_ops(obj); dropTypes = obj_get_drop_types(obj); dropOnChildren = obj_drop_on_children_is_allowed(obj); if ((dragOps != 0) && (dragType == 0)) { dragType = ABDndTypeText; } if ((dropOps != 0) && (dropTypes == 0)) { dropTypes |= ABDndTypeText; } /* Fill the editor's fields with the object's data */ prop_checkbox_set_value(&(dds->drag_ops_checkbox), ABDndOpCopy, ((dragOps & ABDndOpCopy) != 0), False); prop_checkbox_set_value(&(dds->drag_ops_checkbox), ABDndOpLink, ((dragOps & ABDndOpLink) !=0), False); prop_checkbox_set_value(&(dds->drag_ops_checkbox), ABDndOpMove, ((dragOps & ABDndOpMove) != 0), False); prop_field_set_value(&(dds->drag_icon_text), obj_get_drag_cursor(obj), False); prop_field_set_value(&(dds->drag_icon_mask_text), obj_get_drag_cursor_mask(obj), False); if (dragOps != 0) prop_radiobox_set_value(&(dds->drag_types_radiobox), (XtPointer)(uintptr_t) dragType, False); prop_checkbox_set_value(&(dds->drop_ops_checkbox), ABDndOpCopy, ((dropOps & ABDndOpCopy) != 0), False); prop_checkbox_set_value(&(dds->drop_ops_checkbox), ABDndOpLink, ((dropOps & ABDndOpLink) != 0), False); prop_checkbox_set_value(&(dds->drop_ops_checkbox), ABDndOpMove, ((dropOps & ABDndOpMove) != 0), False); prop_checkbox_set_value(&(dds->drop_types_checkbox), ABDndTypeText, ((dropTypes & ABDndTypeText) != 0), False); prop_checkbox_set_value(&(dds->drop_types_checkbox), ABDndTypeFilename, ((dropTypes & ABDndTypeFilename) != 0), False); prop_checkbox_set_value(&(dds->drop_types_checkbox), ABDndTypeUserDef, ((dropTypes & ABDndTypeUserDef) != 0), False); prop_checkbox_set_value(&(dds->drop_child_checkbox), 0, dropOnChildren, False); /* Reset changebars */ dnd_turnoff_changebars(); /* Update current object */ dds->curObj = obj; dds->objType = obj_get_type(dds->curObj); dds->objSubtype = obj_get_subtype(dds->curObj); check_active(); } /* ** Get the new dnd info out of the Dnd Editor and update the ** object's dnd attributes accordingly. */ static int dnd_store_attrs( ABObj obj ) { DndEditorSettings dds = &dndEdInfo; BOOL changesPending = FALSE; STRING dragIcon = NULL; STRING dragIconMask = NULL; ABDndOpFlags dragOps = 0; ABDndTypeFlags dragType = 0; ABDndOpFlags dropOps = 0; ABDndTypeFlags dropTypes = 0; BOOL dropOnChildren = FALSE; if (obj == NULL) { return ERR; } util_dprintf(2,"Store prop dnd attributes into obj fields\n"); changesPending = prop_changebars_pending(dds->propSheet); /* * Get data from fields */ if (prop_checkbox_get_value(&(dds->drag_ops_checkbox), ABDndOpCopy)) { dragOps |= ABDndOpCopy; } if (prop_checkbox_get_value(&(dds->drag_ops_checkbox), ABDndOpLink)) { dragOps |= ABDndOpLink; } if (prop_checkbox_get_value(&(dds->drag_ops_checkbox), ABDndOpMove)) { dragOps |= ABDndOpMove; } dragIcon = prop_field_get_value(&(dds->drag_icon_text)); dragIconMask = prop_field_get_value(&(dds->drag_icon_mask_text)); dragType = prop_radiobox_get_value(&(dds->drag_types_radiobox)); if (prop_checkbox_get_value(&(dds->drop_ops_checkbox), ABDndOpCopy)) { dropOps |= ABDndOpCopy; } if (prop_checkbox_get_value(&(dds->drop_ops_checkbox), ABDndOpLink)) { dropOps |= ABDndOpLink; } if (prop_checkbox_get_value(&(dds->drop_ops_checkbox), ABDndOpMove)) { dropOps |= ABDndOpMove; } if (prop_checkbox_get_value(&(dds->drop_types_checkbox), ABDndTypeText)) { dropTypes |= ABDndTypeText; } if (prop_checkbox_get_value(&(dds->drop_types_checkbox), ABDndTypeFilename)) { dropTypes |= ABDndTypeFilename; } if (prop_checkbox_get_value(&(dds->drop_types_checkbox), ABDndTypeUserDef)) { dropTypes |= ABDndTypeUserDef; } dropOnChildren = prop_checkbox_get_value(&(dds->drop_child_checkbox), 0); /* * Fiddle with the data a little bit */ if ((dragOps != 0) && (dragType == 0)) { dragType = ABDndTypeText; } if ((dropOps != 0) && (dropTypes == 0)) { dropTypes |= ABDndTypeText; } /* * Put the data into the object */ obj_set_drag_initially_enabled(obj, (dragOps != 0)); obj_set_drag_cursor(obj, dragIcon); obj_set_drag_cursor_mask(obj, dragIconMask); obj_set_drag_ops(obj, dragOps); obj_set_drag_types(obj, dragType); obj_set_drop_initially_enabled(obj, (dropOps != 0)); obj_set_drop_ops(obj, dropOps); obj_set_drop_types(obj, dropTypes); obj_set_drop_on_children_is_allowed(obj, dropOnChildren); /* Reset changebars */ dnd_turnoff_changebars(); /* Update current object */ dds->curObj = obj; dds->objType = obj_get_type(dds->curObj); dds->objSubtype = obj_get_subtype(dds->curObj); /* * Redisplay any modified data. */ dnd_fetch_attrs(obj); if (changesPending) { abobj_set_save_needed(obj, True); } check_active(); return 0; } /* ** Called when the user attempts to dismiss the Dnd Editor via the Motif ** window menu. */ static void dnd_prevent_closeCB( Widget widget, XtPointer client_data, XtPointer call_data ) { DTB_MODAL_ANSWER answer; DndEditorSettingsRec *dds = &dndEdInfo; /* ** If there are pending changes for the current object, handle the ** implied auto-apply. */ if((dds->curObj != NULL) && prop_changebars_pending(dds->propSheet)) { answer = do_auto_apply(widget, dds->curObj, dds->curObj); if (answer == DTB_ANSWER_ACTION1) ui_win_show(AB_dnd_dialog, False, XtGrabNone); } else { /* Nope, no pending changes, so just dismiss the Dnd Editor */ ui_win_show(AB_dnd_dialog, False, XtGrabNone); } } /* * Activates or greys out fields, as necessary. */ static int check_active(void) { DndEditorSettings dds = &dndEdInfo; DtbDndEdDialogInfo dnd_ed = &dtb_dnd_ed_dialog; BOOL sensitive = False; if (dds->curObj != NULL) { XtSetSensitive(dnd_ed->drag_op_checkbox_rowcolumn, True); sensitive = False; if ( prop_checkbox_get_value(&(dds->drag_ops_checkbox), ABDndOpCopy) || prop_checkbox_get_value(&(dds->drag_ops_checkbox), ABDndOpLink) || prop_checkbox_get_value(&(dds->drag_ops_checkbox), ABDndOpMove) ) { /* at least one operation is valid - enable fields */ sensitive = True; } XtSetSensitive(dnd_ed->drag_icon_field_rowcolumn, sensitive); XtSetSensitive(dnd_ed->drag_icon_mask_field_rowcolumn, sensitive); XtSetSensitive(dnd_ed->drag_data_checkbox_rowcolumn, sensitive); XtSetSensitive(dnd_ed->drag_conn_button, sensitive); XtSetSensitive(dnd_ed->drop_op_checkbox_rowcolumn, True); sensitive = False; if ( prop_checkbox_get_value(&(dds->drop_ops_checkbox), ABDndOpCopy) || prop_checkbox_get_value(&(dds->drop_ops_checkbox), ABDndOpLink) || prop_checkbox_get_value(&(dds->drop_ops_checkbox), ABDndOpMove) ) { sensitive = True; } XtSetSensitive(dnd_ed->drop_data_checkbox_rowcolumn, sensitive); XtSetSensitive(dnd_ed->drop_child_checkbox_rowcolumn, sensitive); XtSetSensitive(dnd_ed->drop_conn_button, sensitive); } else { XtSetSensitive(dnd_ed->drag_op_checkbox_rowcolumn, False); XtSetSensitive(dnd_ed->drag_icon_field_rowcolumn, False); XtSetSensitive(dnd_ed->drag_icon_mask_field_rowcolumn, False); XtSetSensitive(dnd_ed->drag_data_checkbox_rowcolumn, False); XtSetSensitive(dnd_ed->drag_conn_button, False); XtSetSensitive(dnd_ed->drop_op_checkbox_rowcolumn, False); XtSetSensitive(dnd_ed->drop_data_checkbox_rowcolumn, False); XtSetSensitive(dnd_ed->drop_child_checkbox_rowcolumn, False); XtSetSensitive(dnd_ed->drop_conn_button, False); } return 0; } static BOOL dnd_obj_is_target_type( ABObj obj ) { DndEditorSettingsRec *dds = &dndEdInfo; AB_OBJECT_TYPE type = obj_get_type(obj); int subtype = obj_get_subtype(obj); /* In some cases we care about both type & subtype and must check both */ if( (dds->objType == AB_TYPE_ITEM) || (dds->objType == AB_TYPE_CONTAINER) ) { if((type == dds->objType) && (subtype == dds->objSubtype) ) { return(True); } else return(False); } /* ** Otherwise we only need to check object type, and in fact don't want to ** check subtype because it might confuse things (e.g. we're looking for ** any Button palette item, which includes several subtypes of type ** AB_TYPE_BUTTON). */ else { if(type == dds->objType) return(True); else return(False); } /* Should never get here - every test above returns True or False */ } static int dnd_obj_was_deleted( ObjEvDestroyInfo info ) { DndEditorSettings dds = &dndEdInfo; /* ** If this happens to be the object currently being displayed, ** clear out the editor's fields, remove it from the object list ** and leave the list & editor without a selected object. Don't change ** the current object type, though. ** ** Otherwise, just delete it from the list. */ if((dds->curObj != NULL) && (info->obj == dds->curObj)) { clear_editor_fields(); dds->curObj = (ABObj) NULL; } abobj_list_obj_destroyed(dds->objList, info->obj, dnd_list_test); return 0; } static int dnd_obj_was_renamed( ObjEvAttChangeInfo info ) { return abobj_list_obj_renamed( dndEdInfo.objList, info->obj, istr_string(info->old_name), dnd_list_test); } static int dnd_obj_was_updated( ObjEvUpdateInfo info ) { return abobj_list_obj_updated(dndEdInfo.objList, info, dnd_list_test); } /*** DTB_USER_CODE_END *** *** End of user code section *** **************************************************************************/ void dnd_okCB( Widget widget, XtPointer clientData, XtPointer callData ) { /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/ /*** DTB_USER_CODE_END ^^^ Add C variables and code above ^^^ ***/ /*** DTB_USER_CODE_START vvv Add C code below vvv ***/ dnd_applyCB(widget, clientData, callData); ui_win_show(dtb_dnd_ed_dialog.dialog, False, XtGrabNone); /*** DTB_USER_CODE_END ^^^ Add C code above ^^^ ***/ } void dnd_applyCB( Widget widget, XtPointer clientData, XtPointer callData ) { /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/ /*** DTB_USER_CODE_END ^^^ Add C variables and code above ^^^ ***/ /*** DTB_USER_CODE_START vvv Add C code below vvv ***/ dnd_ed_editor_apply(); /*** DTB_USER_CODE_END ^^^ Add C code above ^^^ ***/ } void dnd_resetCB( Widget widget, XtPointer clientData, XtPointer callData ) { /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/ /*** DTB_USER_CODE_END ^^^ Add C variables and code above ^^^ ***/ /*** DTB_USER_CODE_START vvv Add C code below vvv ***/ if (dndEdInfo.curObj != NULL) { dnd_fetch_attrs(dndEdInfo.curObj); } /*** DTB_USER_CODE_END ^^^ Add C code above ^^^ ***/ } void dnd_cancelCB( Widget widget, XtPointer clientData, XtPointer callData ) { /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/ /*** DTB_USER_CODE_END ^^^ Add C variables and code above ^^^ ***/ /*** DTB_USER_CODE_START vvv Add C code below vvv ***/ dnd_resetCB(widget, clientData, callData); ui_win_show(dtb_dnd_ed_dialog.dialog, False, XtGrabNone); /*** DTB_USER_CODE_END ^^^ Add C code above ^^^ ***/ } void dnd_drag_connCB( Widget widget, XtPointer clientData, XtPointer callData ) { /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/ /*** DTB_USER_CODE_END ^^^ Add C variables and code above ^^^ ***/ /*** DTB_USER_CODE_START vvv Add C code below vvv ***/ if (dndEdInfo.curObj != NULL) { conn_set_source(dndEdInfo.curObj); conn_set_target(NULL); conn_override_default_when(AB_WHEN_DRAGGED_FROM); conn_override_default_action_type(AB_FUNC_USER_DEF); conn_popup_dialog(dtb_get_toplevel_widget(), (XtPointer)0, NULL); conn_reset_default_when(); conn_reset_default_action_type(); } /*** DTB_USER_CODE_END ^^^ Add C code above ^^^ ***/ } void dnd_drop_connCB( Widget widget, XtPointer clientData, XtPointer callData ) { /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/ /*** DTB_USER_CODE_END ^^^ Add C variables and code above ^^^ ***/ /*** DTB_USER_CODE_START vvv Add C code below vvv ***/ if (dndEdInfo.curObj != NULL) { conn_set_source(dndEdInfo.curObj); conn_set_target(NULL); conn_override_default_when(AB_WHEN_DROPPED_ON); conn_override_default_action_type(AB_FUNC_USER_DEF); conn_popup_dialog(dtb_get_toplevel_widget(), (XtPointer)0, NULL); conn_reset_default_when(); conn_reset_default_action_type(); } /*** DTB_USER_CODE_END ^^^ Add C code above ^^^ ***/ } void drag_op_CB( Widget widget, XtPointer clientData, XtPointer callData ) { /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/ /*** DTB_USER_CODE_END ^^^ Add C variables and code above ^^^ ***/ /*** DTB_USER_CODE_START vvv Add C code below vvv ***/ check_active(); /*** DTB_USER_CODE_END ^^^ Add C code above ^^^ ***/ } void drop_op_CB( Widget widget, XtPointer clientData, XtPointer callData ) { /*** DTB_USER_CODE_START vvv Add C variables and code below vvv ***/ /*** DTB_USER_CODE_END ^^^ Add C variables and code above ^^^ ***/ /*** DTB_USER_CODE_START vvv Add C code below vvv ***/ check_active(); /*** DTB_USER_CODE_END ^^^ Add C code above ^^^ ***/ } /************************************************************************** *** DTB_USER_CODE_START *** *** All automatically-generated data and functions have been defined. *** *** Add new functions here, or at the top of the file. ***/ /*** DTB_USER_CODE_END *** *** End of user code section *** **************************************************************************/