CDE has relied upon catgets() implementations following a relaxed interpretation of the XPG internationalization standard that ignored -1, the standard error value returned by catopen, as the catalog argument. However, this same behavior causes segmentation faults with the musl C library. This patch: - Centralizes (with the exception of ToolTalk) all calls to catopen(), catgets(), and catclose() through MsgCat within the DtSvc library. - Prevents calls to catgets() and catclose() that rely upon undefined behavior. - Eliminates a number of bespoke catgets() wrappers, including multiple redundant caching implementations designed to work around a design peculiarity in HP/UX. - Eases building CDE without XPG internationalization support by providing the appropriate macros.
1337 lines
35 KiB
C
1337 lines
35 KiB
C
/*** 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 <stdint.h>
|
|
#include <stdio.h>
|
|
#include <Xm/Xm.h>
|
|
#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 <Xm/List.h>
|
|
#include <Xm/RowColumn.h>
|
|
|
|
#include <ab_private/ui_util.h>
|
|
#include "dtbuilder.h"
|
|
#include "dnd_ed_ui.h"
|
|
#include "abobj_set.h"
|
|
#include "conn.h"
|
|
|
|
#include <ab_private/ab.h>
|
|
#include <ab_private/trav.h>
|
|
#include <ab_private/prop.h>
|
|
#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
|
|
***
|
|
**************************************************************************/
|
|
|
|
|