/*
	Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved.
*/

/*--------------------------------------------------------------------*\
Pro/TOOLKIT includes
\*--------------------------------------------------------------------*/
#include "ProToolkit.h"
#include "ProMdl.h"
#include "ProObjects.h"
#include "ProFeature.h"
#include "ProSizeConst.h"
#include "ProNotify.h"
#include "ProParamval.h"
#include "ProMenu.h"
#include "ProClCmd.h"
#include "ProUtil.h"
#include "ProWorkspace.h"
#include "PTApplsUnicodeUtils.h"
/*--------------------------------------------------------------------*\
    C System includes
\*--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*\
    Application includes
\*--------------------------------------------------------------------*/
#include "TestError.h"
#include "UtilString.h"
#include "UtilMenu.h"
#include "UtilNames.h"
/*--------------------------------------------------------------------*\
    Application types
\*--------------------------------------------------------------------*/
typedef struct notifyinfo
{
    ProNotifyType	type;			/* The type of this notify */
    char		status;			/* The current status	   */
    char		name[PRO_NAME_SIZE];	/* The name (also the menu button) */
    ProFunction		func;			/* The function to be called */
} NotifyInfo;

/*--------------------------------------------------------------------*\
	Static variables
NOTE:   The defenition of NotifyStatus array moved after notification 
	functions
\*--------------------------------------------------------------------*/

static FILE *notify_fp;

static int  user_notify_cancel = 1;/* 0 - cancel, 1 - agree*/

/*--------------------------------------------------------------------*\
    Notification functions
\*--------------------------------------------------------------------*/

/*====================================================================*\
FUNCTION : ProTestNotifyReport
PURPOSE  : write the log file
\*====================================================================*/
void ProTestNotifyReport(
    char *func,
    char *args)
{
    ProTKPrintf("ProTestNotifyReport() - %s() : %s\n", func, args);
    ProTKFprintf(notify_fp, "ProTestNotifyReport() - %s() - %s\n", func, args);
    fflush (notify_fp);
}

/*====================================================================*\
FUNCTION : ProUtilModelToStr
PURPOSE  : Convert ProModel* to str
\*====================================================================*/
char *ProUtilModelToStr(
    ProModel *p_mdldata,
    char *buff)
{
    ProCharName  name;
    char type[10];
    
    ProTKSprintf(buff, "model=%s.%s", ProWstringToString(name, p_mdldata->name),
	    ProWstringToString(type, p_mdldata->type));
    return(buff);
}

/*====================================================================*\
FUNCTION : ProUtilModelFromToStr
PURPOSE  : Convert ProModel* to str
\*====================================================================*/
char *ProUtilModelFromToStr(
    ProModel *p_from,
    ProModel *p_to,
    char *buff)
{
    ProUtilstrcpy(buff, "from ");
    ProUtilModelToStr(p_from, buff + strlen(buff));
    ProUtilstrcat(buff, " to ");
    ProUtilModelToStr(p_to, buff + strlen(buff));
    return(buff);
}

/*====================================================================*\
FUNCTION : ProUserMdlSavePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlSavePre(
    ProPath r_model_path)
{
static unsigned char    cancel = 1;
    ProError            ret = PRO_TK_NO_ERROR;

    if (user_notify_cancel == 0)
    {

        if (cancel == 1)
        {
            cancel = 0;
            ret = PRO_TK_GENERAL_ERROR;
        }
        else
            cancel = 1;
    }
    
    TEST_CALL_REPORT( "ProModelSavePreAction", "ProUserMdlSavePre", PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport((char*)"ProUserMdlSavePre",
        (char*)((ret==PRO_TK_NO_ERROR)?"Agree.":
            "Cancel."));
    
    return (ret);
}

/*====================================================================*\
FUNCTION : ProUserMdlSavePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlSavePost(
    ProPath model_path, ProMdlfileType model_file_type)
{
    ProError status = PRO_TK_NO_ERROR;
    ProName wksp_wstr;
    ProCharName wksp_name;
    char fTypeSrt[PRO_LINE_SIZE] = "";
    char buff[PRO_PATH_SIZE*2] = "";

    TEST_CALL_REPORT( "ProModelSavePostAction", "ProUserMdlSavePost", PRO_TK_NO_ERROR, 0 );
 
    ProWstringToString(buff, model_path);
    ProUtilObjtypeStr(model_file_type, fTypeSrt);
    ProUtilstrcat(buff, " Type: ");
    ProUtilstrcat(buff, fTypeSrt);

    if (model_path == NULL_WCHAR)
    {
        status = ProCurrentWorkspaceGet(wksp_wstr);
        TEST_CALL_REPORT("ProCurrentWorkspaceGet()", "ProUserMdlSavePost()",
                         status, status != PRO_TK_NO_ERROR &&
                         status != PRO_TK_E_NOT_FOUND);
        if (status == PRO_TK_NO_ERROR)
        {
            ProUtilstrcat(buff, " in workspace ");
            ProWstringToString(wksp_name, wksp_wstr);
            ProUtilstrcat(buff, (const char*)wksp_name);
        }
    }
    ProTestNotifyReport((char*)"ProUserMdlSavePost", buff);
    if (model_path != NULL_WCHAR)
    {
        ProTKFprintf(notify_fp, "! path=%s\n", 
	    ProWstringToString(buff, model_path));
        ProTKPrintf("! path=%s\n",  buff);
    }
    return (PRO_TK_NO_ERROR);
}


/*====================================================================*\
FUNCTION : ProUserMdlSavePostAll
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlSavePostAll(
    ProPath model_path, ProMdlfileType model_file_type)
{
    ProError status = PRO_TK_NO_ERROR;
    ProName wksp_wstr;
    ProCharName wksp_name;
    char fTypeSrt[PRO_LINE_SIZE] = "";
    char buff[PRO_PATH_SIZE * 2] = "";
 
    TEST_CALL_REPORT( "ProModelSavePostAllAction", "ProUserMdlSavePostAll", 
       PRO_TK_NO_ERROR, 0 );

    ProWstringToString(buff, model_path);
    ProUtilObjtypeStr(model_file_type, fTypeSrt);
    ProUtilstrcat(buff, " Type: ");
    ProUtilstrcat(buff, fTypeSrt);

    if (model_path == NULL_WCHAR)
    {
        status = ProCurrentWorkspaceGet(wksp_wstr);
        TEST_CALL_REPORT("ProCurrentWorkspaceGet()", "ProUserMdlSavePost()",
                         status, status != PRO_TK_NO_ERROR &&
                         status != PRO_TK_E_NOT_FOUND);
        if (status == PRO_TK_NO_ERROR)
        {
            ProWstringToString(wksp_name, wksp_wstr);
	    ProTKSprintf(buff + strlen(buff), " in workspace %s", 
	        ProWstringToString(wksp_name, wksp_wstr));
        }
    }
    ProTestNotifyReport((char*)"ProUserMdlSavePostAll", buff);
    if (model_path != NULL_WCHAR)
    {
        ProTKFprintf(notify_fp, "! path=%s\n", 
	    ProWstringToString(buff, model_path));
        ProTKPrintf("! path=%s\n",  buff);
    }
    return (PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlCopyPre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlCopyPre(
    ProMdl* r_from, ProPath r_to)
{
    char buff[PRO_PATH_SIZE];

    ProError            ret = (user_notify_cancel==1)?
                            (PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR);
    
    TEST_CALL_REPORT( "ProModelCopyPreAction", "ProUserMdlCopyPre", PRO_TK_NO_ERROR, 0 )

    ProUtilstrcpy (buff, ret==PRO_TK_NO_ERROR?"Agree. ":"Cancel. ");

    ProTestNotifyReport((char*)"ProUserMdlCopyPre", buff);
    return ret;
}

/*====================================================================*\
FUNCTION : ProUserMdlCopyPost
PURPOSE  : Notification user_notify_cancel
\*====================================================================*/
ProError ProUserMdlCopyPost(
    ProMdl r_from, ProPath toMdlPath, ProMdlfileType toMdlType)
{
    ProError status = PRO_TK_NO_ERROR;
    char buff[PRO_PATH_SIZE * 2];
    ProMdlName name1;
    ProMdlExtension ext1;
    char cName[PRO_MDLNAME_SIZE];
    char cPath[PRO_PATH_SIZE];
    char cExt[PRO_MDLEXTENSION_SIZE];
    char fTypeSrt[PRO_LINE_SIZE];

    TEST_CALL_REPORT( "ProModelCopyPostAction", "ProUserMdlCopyPost", PRO_TK_NO_ERROR, 0 );

    status = ProMdlMdlnameGet(r_from, name1);
    TEST_CALL_REPORT("ProMdlMdlnameGet", "ProUserMdlCopyPre",
        status, status != PRO_TK_NO_ERROR);

    status = ProMdlExtensionGet(r_from, ext1);
    TEST_CALL_REPORT("ProMdlMdlnameGet", "ProUserMdlCopyPre",
        status, status != PRO_TK_NO_ERROR);

    ProWstringToString(cName, name1);
    ProWstringToString(cExt, ext1);

    ProUtilstrcpy(buff, " From: ");
    ProUtilstrcat(buff, cName);
    ProUtilstrcat(buff, ".");
    ProUtilstrcat(buff, cExt);

    ProUtilstrcat(buff, " To: ");

    ProWstringToString(cPath, toMdlPath);
    ProUtilstrcat(buff, cPath);
    ProUtilstrcat(buff, " Type ");
    ProUtilObjtypeStr(toMdlType, fTypeSrt);
    ProUtilstrcat(buff, fTypeSrt);

    ProTestNotifyReport((char*)"ProUserMdlCopyPost",buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlCopyPostAll
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlCopyPostAll(
    ProMdl r_from, ProPath toMdlPath, ProMdlfileType toMdlType)
{
    ProError status = PRO_TK_NO_ERROR;
    char buff[PRO_PATH_SIZE * 2];
    ProMdlName name1;
    ProMdlExtension ext1;
    char cName[PRO_MDLNAME_SIZE];
    char cPath[PRO_PATH_SIZE];
    char cExt[PRO_MDLEXTENSION_SIZE];
    char fTypeSrt[PRO_LINE_SIZE];

    TEST_CALL_REPORT( "ProModelCopyPostAllAction", "ProUserMdlCopyPostAll", 
       PRO_TK_NO_ERROR, 0 );

    status = ProMdlMdlnameGet(r_from, name1);
    TEST_CALL_REPORT("ProMdlMdlnameGet", "ProUserMdlCopyPre",
        status, status != PRO_TK_NO_ERROR);

    status = ProMdlExtensionGet(r_from, ext1);
    TEST_CALL_REPORT("ProMdlMdlnameGet", "ProUserMdlCopyPre",
        status, status != PRO_TK_NO_ERROR);

    ProWstringToString(cName, name1);
    ProWstringToString(cExt, ext1);

    ProUtilstrcpy(buff, " From: ");
    ProUtilstrcat(buff, cName);
    ProUtilstrcat(buff, ".");
    ProUtilstrcat(buff, cExt);

    ProUtilstrcat(buff, " To: ");

    ProWstringToString(cPath, toMdlPath);
    ProUtilstrcat(buff, cPath);
    ProUtilstrcat(buff, " Type ");
    ProUtilObjtypeStr(toMdlType, fTypeSrt);
    ProUtilstrcat(buff, fTypeSrt);

    ProTestNotifyReport((char*)"ProUserMdlCopyPostAll", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlRenamePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlRenamePre(
    ProMdl* r_from, ProMdlFileName r_to)
{
    ProError status = PRO_TK_NO_ERROR;
    char buff[PRO_PATH_SIZE * 2];
    ProMdlName name1;
    ProMdlExtension ext1;
    char cName[PRO_MDLNAME_SIZE];
    char cPath[PRO_PATH_SIZE];
    char cExt[PRO_MDLEXTENSION_SIZE];

    ProError            ret = (user_notify_cancel==1)?
                            (PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR);

    TEST_CALL_REPORT( "ProModelRenamePreAction", "ProUserMdlRenamePre", PRO_TK_NO_ERROR, 0 );
    ProUtilstrcpy (buff, ret==PRO_TK_NO_ERROR?"Agree. ":"Cancel. ");

    ProTestNotifyReport((char*)"ProUserMdlRenamePre", buff);
    return ret;
}

/*====================================================================*\
FUNCTION : ProUserMdlRenamePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlRenamePost(
    ProMdl model, ProMdlFileName old_name)
{
    ProError status = PRO_TK_NO_ERROR;
    char buff[PRO_PATH_SIZE * 2];
    ProMdlName name1;
    ProMdlExtension ext1;
    char cName[PRO_MDLNAME_SIZE];
    char cPath[PRO_PATH_SIZE];
    char cExt[PRO_MDLEXTENSION_SIZE];

    TEST_CALL_REPORT( "ProModelRenamePostAction", "ProUserMdlRenamePost", PRO_TK_NO_ERROR, 0 );

    ProUtilstrcpy(buff, " From: ");

    ProWstringToString(cPath, old_name);
    ProUtilstrcat(buff, cPath);

    status = ProMdlMdlnameGet(model, name1);
    TEST_CALL_REPORT("ProMdlMdlnameGet", "ProUserMdlCopyPre",
        status, status != PRO_TK_NO_ERROR);

    status = ProMdlExtensionGet(model, ext1);
    TEST_CALL_REPORT("ProMdlMdlnameGet", "ProUserMdlCopyPre",
        status, status != PRO_TK_NO_ERROR);

    ProWstringToString(cName, name1);
    ProWstringToString(cExt, ext1);

    ProUtilstrcat(buff, " To: ");
    ProUtilstrcat(buff, cName);
    ProUtilstrcat(buff, ".");
    ProUtilstrcat(buff, cExt);

    ProTestNotifyReport((char*)"ProUserMdlRenamePost", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlErasePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlErasePre()
{
    ProError            ret = PRO_TK_NO_ERROR;
static unsigned char cancel = 1;
    
    if (user_notify_cancel==0)
    {
ProTKPrintf ("\tProUserMdlErasePre return %s\n",
    cancel==1?"PRO_TK_GENERAL_ERROR":"PRO_TK_NO_ERROR");
        if (cancel == 1)
        {
            cancel = 0;
            ret=PRO_TK_GENERAL_ERROR;
        }
        else
            cancel = 1;
    }
    
    TEST_CALL_REPORT( "ProMdlErasePreAction", "ProUserMdlErasePre", PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport((char*)"ProUserMdlErasePre", 
        (char*)(ret==PRO_TK_NO_ERROR?"Agree.":"Cancel."));
    
    return (ret);
}

/*====================================================================*\
FUNCTION : ProUserMdlErasePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlErasePost(
    ProMdl p_erased_mdl)
{
    ProError status = PRO_TK_NO_ERROR;
    char buff[PRO_PATH_SIZE * 2];
    ProMdlName name1;
    ProMdlExtension ext1;
    char cName[PRO_MDLNAME_SIZE];
    char cPath[PRO_PATH_SIZE];
    char cExt[PRO_MDLEXTENSION_SIZE];

    TEST_CALL_REPORT( "ProModelErasePostAction", "ProUserMdlErasePost", PRO_TK_NO_ERROR, 0 );

    status = ProMdlMdlnameGet(p_erased_mdl, name1);
    TEST_CALL_REPORT("ProMdlMdlnameGet", "ProUserMdlCopyPre",
        status, status != PRO_TK_NO_ERROR);

    status = ProMdlExtensionGet(p_erased_mdl, ext1);
    TEST_CALL_REPORT("ProMdlMdlnameGet", "ProUserMdlCopyPre",
        status, status != PRO_TK_NO_ERROR);

    ProWstringToString(cName, name1);
    ProWstringToString(cExt, ext1);

    ProUtilstrcpy(buff, cName);
    ProUtilstrcat(buff, ".");
    ProUtilstrcat(buff, cExt);

    ProTestNotifyReport((char*)"ProUserMdlErasePost", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlErasePostAll
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlErasePostAll(
    ProMdl p_erased_mdl)
{
    ProError status = PRO_TK_NO_ERROR;
    char buff[PRO_PATH_SIZE * 2];
    ProMdlName name1;
    ProMdlExtension ext1;
    char cName[PRO_MDLNAME_SIZE];
    char cPath[PRO_PATH_SIZE];
    char cExt[PRO_MDLEXTENSION_SIZE];

    TEST_CALL_REPORT( "ProModelErasePostAllAction", "ProUserMdlErasePostAll",
       PRO_TK_NO_ERROR, 0 );

    status = ProMdlMdlnameGet(p_erased_mdl, name1);
    TEST_CALL_REPORT("ProMdlMdlnameGet", "ProUserMdlCopyPre",
        status, status != PRO_TK_NO_ERROR);

    status = ProMdlExtensionGet(p_erased_mdl, ext1);
    TEST_CALL_REPORT("ProMdlMdlnameGet", "ProUserMdlCopyPre",
        status, status != PRO_TK_NO_ERROR);

    ProWstringToString(cName, name1);
    ProWstringToString(cExt, ext1);

    ProUtilstrcpy(buff, cName);
    ProUtilstrcat(buff, ".");
    ProUtilstrcat(buff, cExt);

    ProTestNotifyReport((char*)"ProUserMdlErasePostAll", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlPurgePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlPurgePre(
    ProModel *p_mdldata)
{
    char        buff[124];
    ProError    ret = (user_notify_cancel==1)?
                    (PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR);
                            
    TEST_CALL_REPORT( "ProMdlPurgePreAction", "ProUserMdlPurgePre", PRO_TK_NO_ERROR, 0 );
    ProUtilstrcpy (buff, ret==PRO_TK_NO_ERROR?"Agree. ":"Cancel. ");
    ProUtilModelToStr(p_mdldata, buff+strlen(buff));    
    ProTestNotifyReport((char*)"ProUserMdlPurgePre", buff);
    return ret;
}

/*====================================================================*\
FUNCTION : ProUserMdlPurgePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlPurgePost(
    ProModel *p_mdldata)
{
    char buff[100];

    TEST_CALL_REPORT( "ProMdlPurgePostAction", "ProUserMdlPurgePost", PRO_TK_NO_ERROR, 0 );

    ProUtilModelToStr(p_mdldata, buff);    
    ProTestNotifyReport((char*)"ProUserMdlPurgePost", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlDeletePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlDeletePre()
{
    ProError    ret = (user_notify_cancel==1)?
                    (PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR);    
    TEST_CALL_REPORT( "ProMdlDeletePreAction", "ProUserMdlDeletePre", PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport((char*)"ProUserMdlDeletePre", 
        (char*)(ret==PRO_TK_NO_ERROR?"Agree. ":"Cancel. "));

     return ret;
}

/*====================================================================*\
FUNCTION : ProUserMdlDeletePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlDeletePost(
    ProModel *p_mdldata)
{
    char buff[100];

    TEST_CALL_REPORT( "ProMdlDeletePostAction", "ProUserMdlDeletePost", PRO_TK_NO_ERROR, 0 );

    ProUtilModelToStr(p_mdldata, buff);    
    ProTestNotifyReport((char*)"ProUserMdlDeletePost", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlDeletePostAll
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlDeletePostAll(
    ProMdldata *p_mdldata)
{
    char buff[100];

    TEST_CALL_REPORT( "ProMdlDeletePostAllAction", "ProUserMdlDeletePostAll",
        PRO_TK_NO_ERROR, 0 );
    ProUtilModelToStr((ProModel*)p_mdldata, buff);    
    ProTestNotifyReport((char*)"ProUserMdlDeletePostAll", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlRetrievePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlRetrievePre(
    ProPath         path,
    ProFileRetrieveOpt **p_retr_options_arr)
{
    static ProFileRetrieveOpt arr[]= {PRO_RETRIEVE_OP_NORMAL};
    TEST_CALL_REPORT( "ProModelRetrievePreAction", "ProUserMdlRetrievePre",
       PRO_TK_NO_ERROR, 0 );
    ProStringToWstring(path, (char*)"p1.prt.1");

    (*p_retr_options_arr) = arr;

    ProTestNotifyReport ((char*)"ProUserMdlRetrievePre", (char*)"");
    return (PRO_TK_NO_ERROR);
}


/*====================================================================*\
FUNCTION : ProUserMdlRetrievePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlRetrievePost(
    ProMdl p_retrieved_mdl)
{
    ProError status = PRO_TK_NO_ERROR;
    char buff[PRO_PATH_SIZE * 2];
    ProMdlName name1;
    ProMdlExtension ext1;
    char cName[PRO_MDLNAME_SIZE];
    char cPath[PRO_PATH_SIZE];
    char cExt[PRO_MDLEXTENSION_SIZE];

    TEST_CALL_REPORT( "ProModelRetrievePostAction", "ProUserMdlRetrievePost",
       PRO_TK_NO_ERROR, 0 );
    
    status = ProMdlMdlnameGet(p_retrieved_mdl, name1);
    TEST_CALL_REPORT("ProMdlMdlnameGet", "ProUserMdlCopyPre",
        status, status != PRO_TK_NO_ERROR);

    status = ProMdlExtensionGet(p_retrieved_mdl, ext1);
    TEST_CALL_REPORT("ProMdlMdlnameGet", "ProUserMdlCopyPre",
        status, status != PRO_TK_NO_ERROR);

    ProWstringToString(cName, name1);
    ProWstringToString(cExt, ext1);

    ProUtilstrcpy(buff, cName);
    ProUtilstrcat(buff, ".");
    ProUtilstrcat(buff, cExt);

    ProTestNotifyReport((char*)"ProUserMdlRetrievePost", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlRetrievePostAll
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlRetrievePostAll(
    ProMdl p_retrieved_mdl)
{
    ProError status = PRO_TK_NO_ERROR;
    char buff[PRO_PATH_SIZE * 2];
    ProMdlName name1;
    ProMdlExtension ext1;
    char cName[PRO_MDLNAME_SIZE];
    char cPath[PRO_PATH_SIZE];
    char cExt[PRO_MDLEXTENSION_SIZE];

    TEST_CALL_REPORT( "ProModelRetrievePostAllAction", 
	"ProUserMdlRetrievePostAll", PRO_TK_NO_ERROR, 0 );

    status = ProMdlMdlnameGet(p_retrieved_mdl, name1);
    TEST_CALL_REPORT("ProMdlMdlnameGet", "ProUserMdlCopyPre",
        status, status != PRO_TK_NO_ERROR);

    status = ProMdlExtensionGet(p_retrieved_mdl, ext1);
    TEST_CALL_REPORT("ProMdlMdlnameGet", "ProUserMdlCopyPre",
        status, status != PRO_TK_NO_ERROR);

    ProWstringToString(cName, name1);
    ProWstringToString(cExt, ext1);

    ProUtilstrcpy(buff, cName);
    ProUtilstrcat(buff, ".");
    ProUtilstrcat(buff, cExt);

    ProTestNotifyReport((char*)"ProUserMdlRetrievePostAll", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlCreatePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlCreatePre(
    ProMdlType  mdl_type,
    int         sub_type,
    ProName     r_model_name,
    ProBoolean *r_allow_override)
{
    char        buff[124];
    ProError    ret = (user_notify_cancel==1)?
                    (PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR);
    
    TEST_CALL_REPORT( "ProMdlCreatePreAction", "ProUserMdlCreatePre", PRO_TK_NO_ERROR, 0 );
    *r_allow_override = PRO_B_TRUE;
    ProStringToWstring(r_model_name, (char*)"create_pre");
    ProTKSprintf (buff, "%s. mdl_type=%d, sub_type=%d", 
        ret==PRO_TK_NO_ERROR?"Agree":"Cancel",
        mdl_type, sub_type);
    ProTestNotifyReport ((char*)"ProUserMdlCreatePre", buff);

    return ret;
}

/*====================================================================*\
FUNCTION : ProUserMdlCreatePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlCreatePost(
    ProModel *p_mdldata)
{
    char buff[100];
    
    TEST_CALL_REPORT( "ProMdlCreatePostAction", "ProUserMdlCreatePost", PRO_TK_NO_ERROR, 0 );
    ProUtilModelToStr(p_mdldata, buff);    
    ProTestNotifyReport ((char*)"ProUserMdlCreatePost", buff);
    return (PRO_TK_NO_ERROR);
}


/*====================================================================*\
FUNCTION : ProUserMdlDbmsFailure
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlDbmsFailure(
    char *dbms_action_string,
    ProPath        mdl1_path,
    ProMdlfileType mdl1_file_type,
    ProPath        mdl2_path,
    ProMdlfileType mdl2_file_type,
    ProError status)
{
    char buff[PRO_PATH_SIZE*2] = "";
    char path1[PRO_PATH_SIZE] = "";
    char fTypeSrt[PRO_LINE_SIZE] = "";

    TEST_CALL_REPORT( "ProModelDbmsFailureAction ", "ProUserMdlDbmsFailure", 
       PRO_TK_NO_ERROR, 0 );

    ProUtilstrcpy(buff, (const char*)dbms_action_string);

    ProWstringToString(path1, mdl1_path);
    ProUtilstrcat(buff, path1);

    ProUtilstrcat(buff, " model=.");

    ProTestNotifyReport((char*)"ProUserMdlDbmsFailure", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlDisplayPre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlDisplayPre(
    ProMdl p_model)
{
    TEST_CALL_REPORT( "ProMdlDisplayPreAction", "ProUserMdlDisplayPre", PRO_TK_NO_ERROR, 0 );
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlDisplayPost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlDisplayPost()
{
    TEST_CALL_REPORT( "ProMdlDisplayPostAction", "ProUserMdlDisplayPost",
       PRO_TK_NO_ERROR, 0 );
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlBackupPre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlBackupPre(
    ProModel *r_from,
    ProMdldata *r_to)
{
    char        buff[124];
    char        path[PRO_PATH_SIZE];    
    ProError    ret = (user_notify_cancel==1)?
                    (PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR);
    
    TEST_CALL_REPORT( "ProMdlBackupPreAction", "ProUserMdlBackupPre", PRO_TK_NO_ERROR, 0);
    ProUtilstrcpy (buff, ret==PRO_TK_NO_ERROR?"Agree. ":"Cancel. ");
    ProUtilModelToStr(r_from, buff+strlen(buff));    
    ProUtilstrcpy(path, "  Path :%s");
    ProWstringToString(path+strlen(path), r_to->path);
    ProUtilstrncpy(buff+strlen(buff), (const char*)path, sizeof(buff)/sizeof(buff[0]) - 1 -
	    strlen(buff));
    buff[sizeof(buff)/sizeof(buff[0]) - 1] = '\0';
    
    ProTestNotifyReport ((char*)"ProUserMdlBackupPre", buff);
    return ret;
}


/*====================================================================*\
FUNCTION : ProUserMdlBackupPost
PURPOSE  : Notification Func
\*====================================================================*/
ProError  ProUserMdlBackupPost(
    ProModel *model,
    ProMdldata *r_to)
{
    char buff[100];
    char path[PRO_PATH_SIZE];    
    
    TEST_CALL_REPORT( "ProMdlBackupPostAction", "ProUserMdlBackupPost", PRO_TK_NO_ERROR, 0);
    
    ProUtilModelToStr(model, buff);    
    ProUtilstrcpy(path, "  Path :%s");
    ProWstringToString(path+strlen(path), r_to->path);
    ProUtilstrncpy(buff+strlen(buff), (const char*)path, sizeof(buff)/sizeof(buff[0]) - 1 -
	    strlen(buff));
    buff[sizeof(buff)/sizeof(buff[0]) - 1] = '\0';
    
    ProTestNotifyReport ((char*)"ProUserMdlBackupPost", buff);
    return (PRO_TK_NO_ERROR);
}



/*====================================================================*\
FUNCTION : ProUserSolidRegenPre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserSolidRegenPre(
    ProSolid    solid,
    ProFeature *p_feature)
{
    ProCharName name;
    char type[10];
    char buff[100];
    
    TEST_CALL_REPORT( "ProSolidRegeneratePreAction", "ProUserSolidRegenPre",
       PRO_TK_NO_ERROR, 0 );

    ProUtilModelnameGet((ProMdl*)&solid, name, type);
    ProTKSprintf(buff, "model=%s.%s Feat id=%d", name, type, p_feature->id); 
    
    ProTestNotifyReport((char*)"ProUserSolidRegenPre",buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlDeletePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserSolidRegenPost(
    ProSolid   solid,
    ProFeature *p_feature,
    ProError status)
{
    ProCharName name;
    char type[10];
    char buff[100];
    
    TEST_CALL_REPORT( "ProSolidRegeneratePostAction", "ProUserSolidRegenPost",
       PRO_TK_NO_ERROR, 0 );

    ProUtilModelnameGet((ProMdl*)&solid, name, type);
    ProTKSprintf(buff, "model=%s.%s Feat id=%d Status=%d", name, type, p_feature->id,
	status); 
    
    ProTestNotifyReport((char*)"ProUserSolidRegenPost",(char*)"");
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserDirectoryChangePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserDirectoryChangePost(
    ProPath new_path)
{
    char buff[PRO_PATH_SIZE];

    TEST_CALL_REPORT( "ProDirectoryChangePostAction",
	"ProUserDirectoryChangePost", PRO_TK_NO_ERROR, 0 );
    ProWstringToString(buff, new_path);
    ProTestNotifyReport((char*)"ProUserDirectoryChangePost", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserWindowChangePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserWindowChangePost()
{
    TEST_CALL_REPORT( "ProWindowChangePostAction", "ProUserWindowChangePost",
       PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport((char*)"ProUserWindowChangePost",(char*)"");
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserFeatCreatePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatCreatePre(
    ProFeature *p_feature)
{
    char buff[100];
    
    TEST_CALL_REPORT( "ProFeatureCreatePreAction", "ProUserFeatCreatePre",
       PRO_TK_NO_ERROR, 0 );
    ProTKSprintf(buff, "Feat Id=%d", p_feature->id);
    ProTestNotifyReport ((char*)"ProUserFeatCreatePre", buff);
    return (PRO_TK_NO_ERROR);
}


/*====================================================================*\
FUNCTION : ProUserFeatCreatePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatCreatePost(
    ProFeature *new_feature)
{
    char buff[100];

    TEST_CALL_REPORT( "ProFeatureCreatePostAction", "ProUserFeatCreatePost",
       PRO_TK_NO_ERROR, 0 );
    ProTKSprintf(buff, "Feat Id=%d", new_feature->id);
    ProTestNotifyReport((char*)"ProUserFeatCreatePost", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserFeatCopyPost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatCopyPost(
    ProFeature *from_feature,
    ProFeature *to_feature,
    ProFeatcopyType type)
{
    char buff[100];

    TEST_CALL_REPORT( "ProFeatureCopyPostAction", "ProUserFeatCopyPost",
       PRO_TK_NO_ERROR, 0 );
    ProTKSprintf(buff, "from=%d, to=%d", from_feature->id, to_feature->id);
    ProTestNotifyReport((char*)"ProUserFeatCopyPost", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserFeatDeletePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatDeletePre(
    ProFeature *p_feature)
{
    char        buff[124];
    ProError    ret = (user_notify_cancel==1)?
                    (PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR);
                    
    TEST_CALL_REPORT( "ProFeatureDeletePreAction", "ProUserFeatDeletePre",
       PRO_TK_NO_ERROR, 0 );
    ProTKSprintf(buff, "%s. Feat Id=%d", 
        ret==PRO_TK_NO_ERROR?"Agree":"Cancel",
        p_feature->id);
    ProTestNotifyReport((char*)"ProUserFeatDeletePre",buff);
    return ret;
}

/*====================================================================*\
FUNCTION : ProUserFeatDeletePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatDeletePost(
    ProFeature *p_feature)
{
    char buff[100];

    TEST_CALL_REPORT( "ProFeatureDeletePostAction", "ProUserFeatDeletePost",
       PRO_TK_NO_ERROR, 0 );
    ProTKSprintf(buff, "Feat Id=%d", p_feature->id);
    ProTestNotifyReport((char*)"ProUserFeatDeletePost", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserFeatSuppressPre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatSuppressPre(
    ProFeature *p_feature)
{
    char        buff[124];
    ProError    ret = (user_notify_cancel==1)?
                    (PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR);
    TEST_CALL_REPORT( "ProFeatureSuppressPreAction", "ProUserFeatSuppressPre",
       PRO_TK_NO_ERROR, 0 );
    ProTKSprintf(buff, "%s. Feat Id=%d", 
        ret==PRO_TK_NO_ERROR?"Agree":"Cancel",
        p_feature->id);
    ProTestNotifyReport((char*)"ProUserFeatSuppressPre", buff);
    return ret;
}

/*====================================================================*\
FUNCTION : ProUserFeatSuppressPost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatSuppressPost(
    ProFeature *p_feature)
{
    char buff[100];

    TEST_CALL_REPORT( "ProFeatureSuppressPostAction", "ProUserFeatSuppressPost",
       PRO_TK_NO_ERROR, 0 );
    ProTKSprintf(buff, "Feat Id=%d", p_feature->id);
    ProTestNotifyReport((char*)"ProUserFeatSuppressPost", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserFeatregenPre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatRegenPre(
    ProFeature *p_feature)
{
    char        buff[1240];
    ProError    ret = (user_notify_cancel==1)?
                    (PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR);
    TEST_CALL_REPORT( "ProFeatureRegenPreAction", "ProUserFeatRegenPre",
       PRO_TK_NO_ERROR, 0 );
    ProTKSprintf(buff, "%s. Feat Id=%d", 
        ret==PRO_TK_NO_ERROR?"Agree":"Cancel",
        p_feature->id);
    ProTestNotifyReport((char*)"ProUserFeatRegenPre",buff);
    return ret;
}

/*====================================================================*\
FUNCTION : ProUserFeatRegenPost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatRegenPost(
    ProFeature *p_feature)
{
    char buff[100];

    TEST_CALL_REPORT( "ProFeatureRegenPostAction", "ProUserFeatRegenPost",
       PRO_TK_NO_ERROR, 0 );
    ProTKSprintf(buff, "Feat Id=%d", p_feature->id);
    ProTestNotifyReport((char*)"ProUserFeatRegenPost", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserFeatRegenFailure
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatRegenFailure(
    ProFeature *p_feature)
{
    char buff[100];
    
    TEST_CALL_REPORT( "ProFeatureRegenFailureAction", "ProUserFeatRegenFailure",
       PRO_TK_NO_ERROR, 0 );
    ProTKSprintf(buff, "Feat Id=%d", p_feature->id);
    ProTestNotifyReport ((char*)"ProUserFeatRegenFailure", buff);
    return (PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserFeatRedefinePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatRedefinePre(
    ProFeature *p_feature)
{
    char        buff[124];
    ProError    ret = (user_notify_cancel==1)?
                    (PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR);
    TEST_CALL_REPORT( "ProFeatureRedefinePreAction", "ProUserFeatRedefinePre",
       PRO_TK_NO_ERROR, 0 );
    ProTKSprintf(buff, "%s. Feat Id=%d", 
        ret==PRO_TK_NO_ERROR?"Agree":"Cancel",
        p_feature->id);
    ProTestNotifyReport ((char*)"ProUserFeatRedefinePre", buff);
    return ret;
}


/*====================================================================*\
FUNCTION : ProUserParamCreatePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserParamCreatePre(
    ProModelitem *p_mdlitem,
    ProName w_name,
    ProUnititem* units,
    ProParamvalue *p_pvalue)
{
    char        name[PRO_FILE_NAME_SIZE+24];
    ProError    ret = (user_notify_cancel==1)?
                    (PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR);
    TEST_CALL_REPORT( "ProParameterCreateWithUnitsPreAction", "ProUserParamCreatePre",
       PRO_TK_NO_ERROR, 0 );
    ProUtilstrcpy (name, ret==PRO_TK_NO_ERROR?"Agree. ":"Cancel. ");
    ProWstringToString(name+strlen(name), w_name);
    ProTestNotifyReport((char*)"ProUserParamCreatePre", name);
    return ret;
}

/*====================================================================*\
FUNCTION : ProUserParamModifyPre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserParamModifyPre(
    ProParameter *p_param,
    ProParamvalue *p_pvalue,
    ProUnititem* new_units,
    ProParamvalue * old_value,
    ProUnititem * old_units)
{
    ProError    ret = (user_notify_cancel==1)?
                    (PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR);
    TEST_CALL_REPORT( "ProParameterModifyWithUnitsPreAction", "ProUserParamModifyPre",
       PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport((char*)"ProUserParamModifyPre",
        (char*)(ret==PRO_TK_NO_ERROR?"Agree. ":"Cancel. "));
    return ret;

}

/*====================================================================*\
FUNCTION : ProUserParamDeletePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserParamDeletePre(
    ProParameter *p_param)
{
    ProError    ret = (user_notify_cancel==1)?
                    (PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR);
    TEST_CALL_REPORT( "ProParameterDeletePreAction", "ProUserParamDeletePre",
       PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport((char*)"ProUserParamDeletePre",
        (char*)(ret==PRO_TK_NO_ERROR?"Agree. ":"Cancel. "));
    return ret;
}

/*====================================================================*\
FUNCTION : ProUserNCSeqCLPost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserNCSeqCLPost(
    ProMdldata *p_mdldata)
{
    char buff[100];

    TEST_CALL_REPORT( "ProNcseqClPostAction", "ProUserNCSeqCLPost",
       PRO_TK_NO_ERROR, 0 );
    ProUtilModelToStr((ProModel*)p_mdldata, buff);    
    ProTestNotifyReport((char*)"ProUserNCSeqCLPost",buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserMdlDeletePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserOperCLPost(
    ProMdldata *p_mdldata)
{
    char buff[100];

    TEST_CALL_REPORT( "ProMfgoperClPostAction", "ProUserOperCLPost", PRO_TK_NO_ERROR, 0 );
    ProUtilModelToStr((ProModel*)p_mdldata, buff);    
    ProTestNotifyReport((char*)"ProUserOperCLPost", buff);
    return(PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserNClCommandExpand
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserNClCommandExpand(
    ProFeature *p_feature,
    wchar_t	(*command)[512],
    int		num_cmd_lines,
    ProClCmdData **r_output_arr,
    int		*output_num)
{
    char buff[100];
    int i;
    
    TEST_CALL_REPORT( "ProClCommandExpandAction", "ProUserNClCommandExpand",
       PRO_TK_NO_ERROR, 0 );
    ProTKSprintf(buff, "Feat Id=%d", p_feature->id);
    ProTestNotifyReport ((char*)"ProUserNClCommandExpand", buff);
    for (i = 0; i < num_cmd_lines; i++)
    {
        ProTKPrintf ("\t%s\n", command[i]);
    }
    *output_num = 0;
    return (PRO_TK_NO_ERROR);
}
    
/*====================================================================*\
FUNCTION : ProUserMdlDeletePost
PURPOSE  : Notification Func
\*====================================================================*/
ProBoolean ProUserNClGetLocation( 
    ProFeature     *p_feature,
    wchar_t        (*command)[512],
    int            num_cmd_lines,
    ProPoint3d     location )
{
    char buff[100];
    int i;
    
    TEST_CALL_REPORT( "ProClCommandGetLocAction", "ProUserNClGetLocation",
       PRO_TK_NO_ERROR, 0 );
    ProTKSprintf(buff, "Feat Id=%d", p_feature->id);
    ProTestNotifyReport ((char*)"ProUserNClCommandExpand", buff);
    for (i = 0; i < num_cmd_lines; i++)
    {
        ProTKPrintf ("\t%s\n", command[i]);
    }
    return (PRO_B_FALSE);
}

/*====================================================================*\
FUNCTION : ProUserMdlDeletePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFileOpenOK (
    ProMdlType mdl_type,
    int        sub_type,
    ProName    model_name)
{
    char buff[100];
    char name[PRO_NAME_SIZE];
    
    TEST_CALL_REPORT( "ProFileOpenOKAction", "ProUserFileOpenOK",
       PRO_TK_NO_ERROR, 0 );
    ProTKSprintf (buff, "mdl_type=%d, sub_type=%d, model=%s",
        mdl_type, sub_type, ProWstringToString (name, model_name));
    ProTestNotifyReport ((char*)"ProUserFileOpenOK", buff);
    return (PRO_TK_NO_ERROR);
}


/*====================================================================*\
FUNCTION : ProUserSolidUnitConvertPre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserSolidUnitConvertPre(
    ProSolid	solid,
    int         convert_numbers )
{
    char buff[100];
 
    TEST_CALL_REPORT( "ProSolidUnitConvertPreAction", 
	"ProUserSolidUnitConvertPre", PRO_TK_NO_ERROR, 0 );
    ProTKSprintf( buff, "%s", convert_numbers ? "quantities are converted" :
	"quantities are reinterpreted" );
    ProTestNotifyReport( (char*)"ProUserSolidUnitConvertPre", buff );
 
    return (PRO_TK_NO_ERROR);
}


/*====================================================================*\
FUNCTION : ProUserSolidUnitConvertPost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserSolidUnitConvertPost(
    ProSolid	solid,
    int         convert_numbers )
{
    char buff[100];
 
    TEST_CALL_REPORT( "ProSolidUnitConvertPostAction", 
	"ProUserSolidUnitConvertPost", PRO_TK_NO_ERROR, 0 );
    ProTKSprintf( buff, "%s", convert_numbers ? "quantities are converted" :
	"quantities are reinterpreted" );
    ProTestNotifyReport( (char*)"ProUserSolidUnitConvertPost", buff );
 
    return (PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserWeldSympathGet
PURPOSE  : Notification Func
\*====================================================================*/

ProError ProUserWeldSympathGet(
    ProDrawing	drawing,
    ProMdl model,
    int feat_id,
    ProPath sym_def_file_path,
    ProPath ptk_sym_def_path)   
{
    char buff[100];
    ProTKSprintf(buff,"Feat Id=%d", feat_id);
    TEST_CALL_REPORT( "ProDrawingWeldSympathGetAction", 
	"ProUserWeldSympathGet", PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport( (char*)"ProUserWeldSympathGet", buff );
 
    return (PRO_TK_NO_ERROR);

}

/*====================================================================*\
FUNCTION : ProUserWeldGroupsGet
PURPOSE  : Notification Func
\*====================================================================*/

ProError ProUserWeldGroupsGet(
    ProDrawing	drawing,
    ProMdl model,
    int feat_id,
    int sym_def_id,
    ProBoolean left_side,
    ProName* group_names,
    int n_groups,
    ProBoolean* include_groups )
    
{
    char buff[100];
    ProTKSprintf(buff,"Feat Id=%d", feat_id);
    TEST_CALL_REPORT( "ProDrawingWeldGroupsGetAction", 
	"ProUserWeldGroupsGet", PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport( (char*)"ProUserWeldGroupsGet", buff );
 
    return (PRO_TK_NO_ERROR);

}

/*====================================================================*\
FUNCTION : ProUserDrawingWeldSymtexGet
PURPOSE  : Notification Func
\*====================================================================*/

ProError ProUserDrawingWeldSymtexGet(
    ProDrawing	drawing,
    ProMdl model,
    int feat_id,
    int sym_def_id,
    wchar_t sym_prompt_name[],
    int sym_prompt_nm_idx,
    ProParamvalue* p_text,
    ProParamvalue* p_ptk_text )
    
{
    char buff[100];
    ProTKSprintf(buff,"Feat Id=%d", feat_id);
    TEST_CALL_REPORT( "ProDrawingWeldSymtextGetAction", 
	"ProUserDrawingWeldSymtexGet", PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport( (char*)"ProUserDrawingWeldSymtexGet", buff );
 
    return (PRO_TK_NO_ERROR);

}

/*====================================================================*\
FUNCTION : ProUserMdlCreateCancel
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserMdlCreateCancel ()
{

    TEST_CALL_REPORT( "ProMdlCreateCancelAction", 
	"ProUserMdlCreateCancel", PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport((char*)"ProUserMdlCreateCancel", (char*)"");
    return (PRO_TK_NO_ERROR);    
}

/*====================================================================*\
FUNCTION : ProUserDimModifyValuePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserDimModifyValuePre (ProDimension *dimension)
{
    char        buff[124];
    ProError    ret = (user_notify_cancel==1)?
                    (PRO_TK_NO_ERROR):(PRO_TK_GENERAL_ERROR);
    ProTKSprintf(buff,"%s. Dimension Id=%d", 
        ret==PRO_TK_NO_ERROR?"Agree":"Cancel",
        dimension->id);    

    TEST_CALL_REPORT( "ProDimModifyValuePreAction", 
	    "ProUserDimModifyValuePre", PRO_TK_NO_ERROR, 0 );
        
    ProTestNotifyReport((char*)"ProUserDimModifyValuePre", buff);
    return ret;    
}

/*====================================================================*\
FUNCTION : ProUserFeatureRedefinePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatureRedefinePost(ProFeature *p_feat)
{
    char buff[100];
    ProTKSprintf(buff,"Feat Id=%d", p_feat->id);    
    TEST_CALL_REPORT( "ProFeatureRedefinePostAction", 
	"ProUserFeatureRedefinePost", PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport((char*)"ProUserFeatureRedefinePost", buff);
    return (PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserFeatureReroutePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatureReroutePre(ProFeature *p_feat)
{
    char buff[100];
    ProTKSprintf(buff,"Feat Id=%d", p_feat->id);    
    TEST_CALL_REPORT( "ProFeatureReroutePreAction", 
	"ProUserFeatureReroutePre", PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport((char*)"ProUserFeatureReroutePre", buff);
    return (PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserFeatureReroutePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatureReroutePost(ProFeature *p_feat)
{
    char buff[100];
    ProTKSprintf(buff,"Feat Id=%d", p_feat->id);    
    TEST_CALL_REPORT( "ProFeatureReroutePostAction", 
	"ProUserFeatureReroutePost", PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport((char*)"ProUserFeatureReroutePost", buff);
    return (PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserFeatureReplacePre
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatureReplacePre(ProFeature *p_feat)
{
    char buff[100];
    ProTKSprintf(buff,"Feat Id=%d", p_feat->id);    
    TEST_CALL_REPORT( "ProFeatureReplacePreAction", 
	"ProUserFeatureReplacePre", PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport((char*)"ProUserFeatureReplacePre", buff);
    return (PRO_TK_NO_ERROR);
}

/*====================================================================*\
FUNCTION : ProUserFeatureReplacePost
PURPOSE  : Notification Func
\*====================================================================*/
ProError ProUserFeatureReplacePost(ProFeature *p_feat)
{
    char buff[100];
    ProTKSprintf(buff,"Feat Id=%d", p_feat->id);    
    TEST_CALL_REPORT( "ProFeatureReplacePostAction", 
	"ProUserFeatureReplacePost", PRO_TK_NO_ERROR, 0 );
    ProTestNotifyReport((char*)"ProUserFeatureReplacePost", buff);
    return (PRO_TK_NO_ERROR);
}

static NotifyInfo NotifyStatus[] =
{
{ PRO_MODEL_SAVE_PRE,		0,	"Save Pre",		(ProFunction)ProUserMdlSavePre},
{ PRO_MODEL_SAVE_POST,    	0,	"Save Post",		(ProFunction)ProUserMdlSavePost},
{ PRO_MODEL_SAVE_POST_ALL,	0,	"Save Post All",	(ProFunction)ProUserMdlSavePostAll},
{ PRO_MODEL_COPY_PRE,		0,	"Copy Pre",		(ProFunction)ProUserMdlCopyPre},
{ PRO_MODEL_COPY_POST,		0,	"Copy Post",		(ProFunction)ProUserMdlCopyPost},
{ PRO_MODEL_COPY_POST_ALL,	0,	"Copy Post All",	(ProFunction)ProUserMdlCopyPostAll},
{ PRO_MODEL_RENAME_PRE,		0,	"Rename Pre",		(ProFunction)ProUserMdlRenamePre},
{ PRO_MODEL_RENAME_POST,    0,	"Rename Post",		(ProFunction)ProUserMdlRenamePost},
{ PRO_MDL_ERASE_PRE,		0,	"Erase Pre",		(ProFunction)ProUserMdlErasePre},
{ PRO_MODEL_ERASE_POST,     0,	"Erase Post",		(ProFunction)ProUserMdlErasePost},
{ PRO_MODEL_ERASE_POST_ALL,	0,	"Erase Post All",	(ProFunction)ProUserMdlErasePostAll},
{ PRO_MDL_PURGE_PRE,		0,	"Purge Pre",		(ProFunction)ProUserMdlPurgePre},
{ PRO_MDL_PURGE_POST,		0,	"Purge Post",		(ProFunction)ProUserMdlPurgePost},
{ PRO_MDL_DELETE_PRE,		0,	"Del Pre",		(ProFunction)ProUserMdlDeletePre},
{ PRO_MDL_DELETE_POST, 		0,	"Del Post",		(ProFunction)ProUserMdlDeletePost},
{ PRO_MDL_DELETE_POST_ALL,	0,	"Del Post All",		(ProFunction)ProUserMdlDeletePostAll},
{ PRO_MODEL_RETRIEVE_POST,	0,	"Retr Post", 		(ProFunction)ProUserMdlRetrievePost},
{ PRO_MODEL_RETRIEVE_POST_ALL,	0,	"Retr Post All",	(ProFunction)ProUserMdlRetrievePostAll},
{ PRO_MODEL_DBMS_FAILURE,   0,	"DBMS Failure",		(ProFunction)ProUserMdlDbmsFailure},
{ PRO_SOLID_REGEN_PRE,		0,	"Regen Pre",		(ProFunction)ProUserSolidRegenPre},
{ PRO_SOLID_REGEN_POST,		0,	"Regen Post",		(ProFunction)ProUserSolidRegenPost},
{ PRO_DIRECTORY_CHANGE_POST,	0,	"Change Dir",		(ProFunction)ProUserDirectoryChangePost},
{ PRO_WINDOW_CHANGE_POST,	0,	"Change Window",	(ProFunction)ProUserWindowChangePost},
{ PRO_MDL_DISPLAY_PRE,		0,	"Repaint Pre",		(ProFunction)ProUserMdlDisplayPre},
{ PRO_MDL_DISPLAY_POST,		0,	"Repaint Post",		(ProFunction)ProUserMdlDisplayPost},
{ PRO_NCSEQ_CL_POST,		0,	"NCSEQ CL Post",	(ProFunction)ProUserNCSeqCLPost},
{ PRO_MFGOPER_CL_POST,		0,	"OPER CL Post",		(ProFunction)ProUserOperCLPost},
{ PRO_FEATURE_CREATE_POST,	0,	"Feat Create Post",	(ProFunction)ProUserFeatCreatePost},
{ PRO_FEATURE_COPY_POST,	0,	"Feat Copy Post",	(ProFunction)ProUserFeatCopyPost},
{ PRO_FEATURE_DELETE_PRE,	0,	"Feat Delete Pre",	(ProFunction)ProUserFeatDeletePre},
{ PRO_FEATURE_DELETE_POST,	0,	"Feat Delete Post",	(ProFunction)ProUserFeatDeletePost},
{ PRO_FEATURE_SUPPRESS_PRE,	0,	"Feat Supp Pre",	(ProFunction)ProUserFeatSuppressPre},
{ PRO_FEATURE_SUPPRESS_POST,	0,	"Feat Supp Post",	(ProFunction)ProUserFeatSuppressPost},
{ PRO_FEATURE_REGEN_PRE,	0,	"Feat Regen Pre",	(ProFunction)ProUserFeatRegenPre},
{ PRO_FEATURE_REGEN_POST,	0,	"Feat Regen Post",	(ProFunction)ProUserFeatRegenPost},
{ PRO_PARAM_CREATE_W_UNITS_PRE,		0,	"Parm Create Pre",	(ProFunction)ProUserParamCreatePre},
{ PRO_PARAM_MODIFY_W_UNITS_PRE, 	0,	"Parm Modify Pre", 	(ProFunction)ProUserParamModifyPre},
{ PRO_PARAM_DELETE_PRE, 	0,	"Parm Delete Pre",	(ProFunction)ProUserParamDeletePre},
{ PRO_MDL_CREATE_POST,		0,	"Create Post",		(ProFunction)ProUserMdlCreatePost},
{ PRO_FEATURE_REGEN_FAILURE,	0,	"Feat Regen Fail",	(ProFunction)ProUserFeatRegenFailure},
{ PRO_NCL_COMMAND_EXPAND,	0,	"NClCmd Expand",	(ProFunction)ProUserNClCommandExpand},
{ PRO_NCL_COMMAND_GET_LOC,	0,	"NClCmd GetLoc",	(ProFunction)ProUserNClGetLocation},
{ PRO_FEATURE_CREATE_PRE,	0,	"Feat Create Pre",	(ProFunction)ProUserFeatCreatePre},
{ PRO_FEATURE_REDEFINE_PRE,	0,	"Feat Redef Pre",	(ProFunction)ProUserFeatRedefinePre},
{ PRO_FILE_OPEN_OK,		0,	"File open",		(ProFunction)ProUserFileOpenOK},
{ PRO_MDL_CREATE_PRE,		0,	"Create Pre",		(ProFunction)ProUserMdlCreatePre},
{ PRO_MODEL_RETRIEVE_PRE,   0,	"Retr Pre",		(ProFunction)ProUserMdlRetrievePre},
{ PRO_MDL_BACKUP_PRE,		0,	"Backup Pre",		(ProFunction)ProUserMdlBackupPre},
{ PRO_MDL_BACKUP_POST,		0,	"Backup Post",		(ProFunction)ProUserMdlBackupPost}, 
{ PRO_SOLID_UNIT_CONVERT_PRE,	0,	"Unit Convert Pre",	(ProFunction)ProUserSolidUnitConvertPre},
{ PRO_SOLID_UNIT_CONVERT_POST,	0,	"Unit Convert Post",    (ProFunction)ProUserSolidUnitConvertPost},
{ PRO_DRAWING_WELD_SYMPATH_GET, 0,      "Weld Sympath Get",     (ProFunction)ProUserWeldSympathGet},
{ PRO_DRAWING_WELD_GROUPS_GET,  0,      "Weld Groups Get",      (ProFunction)ProUserWeldGroupsGet},
{ PRO_DRAWING_WELD_SYMTEXT_GET, 0,      "Weld Symtext Get",     (ProFunction)ProUserDrawingWeldSymtexGet},
{ PRO_MDL_CREATE_CANCEL,        0,      "Create Cancel",        (ProFunction)ProUserMdlCreateCancel},
{ PRO_DIM_MODIFY_VALUE_PRE,     0,      "Modify Value Pre",     (ProFunction)ProUserDimModifyValuePre},
{ PRO_FEATURE_REDEFINE_POST,    0,      "Feat Redefine Post",   (ProFunction)ProUserFeatureRedefinePost},
{ PRO_FEATURE_REROUTE_PRE,      0,      "Feat Reroute Pre",     (ProFunction)ProUserFeatureReroutePre},
{ PRO_FEATURE_REROUTE_POST,     0,      "Feat Reroute Post",    (ProFunction)ProUserFeatureReroutePost},
{ PRO_FEATURE_REPLACE_PRE,      0,      "Feat Replace Pre",     (ProFunction)ProUserFeatureReplacePre},
{ PRO_FEATURE_REPLACE_POST,     0,      "Feat Replace Post",    (ProFunction)ProUserFeatureReplacePost}

};

#define MAX_NOTIFY_TYPES (sizeof(NotifyStatus)/sizeof(NotifyStatus[0]))

/*====================================================================*\
    FUNCTION :	ProTestNotifyToggle()
    PURPOSE  :	Toggle the status of a specified notification
\*====================================================================*/
int ProTestNotifyToggle(
    char *dummy,
    int type)
{
    ProError status;
    int m;
    
    
    for(m=0; m<MAX_NOTIFY_TYPES; m++)
    {
	if(NotifyStatus[m].type == type)
	{
	    NotifyStatus[m].status = !NotifyStatus[m].status;

	    if(NotifyStatus[m].status)
	    {
		status = ProNotificationSet(NotifyStatus[m].type, NotifyStatus[m].func);
		TEST_CALL_REPORT("ProNotificationSet()", "ProTestNotifyToggle()",
				       status, status != PRO_TK_NO_ERROR);
	    }
	    else
	    {
		status = ProNotificationUnset(NotifyStatus[m].type);
		TEST_CALL_REPORT("ProNotificationUnset()", "ProTestNotifyToggle()",
				       status, status != PRO_TK_NO_ERROR);
	    }
	    break;
	}

    }
    return(0);
}

/*====================================================================*\
    FUNCTION :	ProTestNotifyDone()
    PURPOSE  :	Options for closing the notify status menu
\*====================================================================*/
int ProTestNotifyDone(
    char *dummy,
    int option)
{
#define NOTIFY_SETALL	0
#define NOTIFY_CLEAR	1
#define NOTIFY_ACCEPT	2
#define NOTIFY_QUIT	3
    int m;
    ProError status;

    switch(option)
    {
    case NOTIFY_SETALL :
	for(m=0; m<MAX_NOTIFY_TYPES; m++)
	{
	    status = ProMenubuttonHighlight((char*)"TkNotify",NotifyStatus[m].name);
            TEST_CALL_REPORT( "ProMenubuttonHighlight", "ProTestNotifyDone",
                status, status != PRO_TK_NO_ERROR);
            if(NotifyStatus[m].status==0) {    
	        status = ProNotificationSet(NotifyStatus[m].type, NotifyStatus[m].func);
#if 0                                   
    	        TEST_CALL_REPORT("ProNotificationSet()", "ProTestNotifyDone()",
				   status, 
                                   status != PRO_TK_NO_ERROR);
#else 
/*  ProNotificationSet returns -1 with notify type PRO_FEATURE_REDEFINE_PRE
    (bugminsk1340 )  */
		TEST_CALL_REPORT("ProNotificationSet()", "ProTestNotifyDone()",
				    status,
                                    0);
#endif                                   
                                
                if (status==PRO_TK_NO_ERROR) NotifyStatus[m].status = 1;
            }                                   
	}
	break;
    case NOTIFY_CLEAR :
	for(m=0; m<MAX_NOTIFY_TYPES; m++)
	{
	    status = ProMenubuttonUnhighlight((char*)"TkNotify",NotifyStatus[m].name);
            TEST_CALL_REPORT( "ProMenubuttonUnhighlight", "ProTestNotifyDone",
                status, status != PRO_TK_NO_ERROR);
            if(NotifyStatus[m].status!=0) {    
	        status = ProNotificationUnset(NotifyStatus[m].type);
        	TEST_CALL_REPORT("ProNotificationUnset()", "ProTestNotifyDone()",
				   status, 
                                   status != PRO_TK_NO_ERROR);                                   
                if(status==PRO_TK_NO_ERROR) NotifyStatus[m].status = 0;                                   
            }                                   
            
	}

	fclose(notify_fp);
	notify_fp = NULL;
	break;
    case NOTIFY_ACCEPT :
	status = ProMenuDeleteWithStatus(option);
        TEST_CALL_REPORT( "ProMenuDeleteWithStatus", "ProTestNotifyDone",
                status, status != PRO_TK_NO_ERROR);
	break;
    case NOTIFY_QUIT :
	status = ProMenuDeleteWithStatus(option);
        TEST_CALL_REPORT( "ProMenuDeleteWithStatus", "ProTestNotifyDone",
                status, status != PRO_TK_NO_ERROR);
	break;
    }

    return (0);
}

/*====================================================================*\
    FUNCTION :	ProTestNotify()
    PURPOSE  :	Commands for testing notification in Pro/TOOLKIT
\*====================================================================*/
int ProTestNotify()
{

    int         m, option;
    NotifyInfo  old_status[MAX_NOTIFY_TYPES];
    ProError    status;
    static ProUtilMenuButtons cancel_type[] = { 
        {"-CancelAgree",0,  TEST_CALL_PRO_MENU_DELETE},
        {"Cancel",      0,  0},
        {"Agree",       1,  0},
        {"",            0,  0}
    };
    
    int         id;

    if(notify_fp == NULL)
	notify_fp = PTApplsUnicodeFopen("notify.log","w");

    memcpy(old_status, NotifyStatus, MAX_NOTIFY_TYPES * sizeof(NotifyInfo));

    status = ProMenuFileRegister((char*)"TkNotify",(char*)"tknotify.mnu", &id);
    TEST_CALL_REPORT( "ProMenuFileRegister", "ProTestNotify",
        status, status != PRO_TK_NO_ERROR);
    for(m=0; m<MAX_NOTIFY_TYPES; m++)
    {
	status = ProMenubuttonActionSet((char*)"TkNotify", NotifyStatus[m].name,
	    (ProMenubuttonAction)ProTestNotifyToggle, NULL, 
	    NotifyStatus[m].type);
        TEST_CALL_REPORT( "ProMenubuttonActionSet", "ProTestNotify",
            status, status != PRO_TK_NO_ERROR);
    }
    status = ProMenubuttonActionSet((char*)"TkNotify",(char*)"TkNotify",
	(ProMenubuttonAction)ProMenuDelete, NULL, 0);
    TEST_CALL_REPORT( "ProMenubuttonActionSet", "ProTestNotify",
        status, status != PRO_TK_NO_ERROR);
    status = ProMenuModeSet((char*)"TkNotify",PROMENUMODE_DATA);
    TEST_CALL_REPORT( "ProMenubModeSet", "ProTestNotify",
        status, status != PRO_TK_NO_ERROR);
    status = ProMenuDatamodeSet((char*)"TkNotify",PRO_B_TRUE);
    TEST_CALL_REPORT( "ProMenuDatamodeSet", "ProTestNotify",
        status, status != PRO_TK_NO_ERROR);

    status = ProMenuCreate(PROMENUTYPE_MAIN, (char*)"TkNotify", &id);
    TEST_CALL_REPORT( "ProMenuCreate", "ProTestNotify",
        status, status != PRO_TK_NO_ERROR);
    for(m=0;  m<MAX_NOTIFY_TYPES; m++)
	if(NotifyStatus[m].status)
        {
	    status = ProMenubuttonHighlight((char*)"TkNotify",NotifyStatus[m].name);
            TEST_CALL_REPORT( "ProMenubuttonHighlight", "ProTestNotify",
                status, status != PRO_TK_NO_ERROR);
        }

    status = ProMenuFileRegister((char*)"TkNfyDone",(char*)"tknotdone.mnu", &id);
    TEST_CALL_REPORT( "ProMenuFileRegister", "ProTestNotify",
        status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet((char*)"TkNfyDone",(char*)"Set All",      
	(ProMenubuttonAction)ProTestNotifyDone, NULL, NOTIFY_SETALL);
    TEST_CALL_REPORT( "ProMenubuttonActionSet", "ProTestNotify",
        status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet((char*)"TkNfyDone",(char*)"Unset All",
        (ProMenubuttonAction)ProTestNotifyDone, NULL, NOTIFY_CLEAR);
    TEST_CALL_REPORT( "ProMenubuttonActionSet", "ProTestNotify",
        status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet((char*)"TkNfyDone",(char*)"Accept Status",
	(ProMenubuttonAction)ProTestNotifyDone, NULL, NOTIFY_ACCEPT);
    TEST_CALL_REPORT( "ProMenubuttonActionSet", "ProTestNotify",
        status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet((char*)"TkNfyDone",(char*)"Quit",
	(ProMenubuttonAction)ProTestNotifyDone, NULL, NOTIFY_QUIT);
    TEST_CALL_REPORT( "ProMenubuttonActionSet", "ProTestNotify",
        status, status != PRO_TK_NO_ERROR);
    status = ProMenubuttonActionSet((char*)"TkNfyDone", (char*)"TkNfyDone",
	(ProMenubuttonAction)ProMenuHold, NULL, 0);
    TEST_CALL_REPORT( "ProMenubuttonActionSet", "ProTestNotify",
        status, status != PRO_TK_NO_ERROR);

    status = ProMenuCreate(PROMENUTYPE_SUB, (char*)"TkNfyDone", &id);
    TEST_CALL_REPORT( "ProMenuCreate", "ProTestNotify",
        status, status != PRO_TK_NO_ERROR);
    status = ProMenuProcess((char*)"TkNfyDone", &option);
    TEST_CALL_REPORT( "ProMenuProcess", "ProTestNotify",
        status, status != PRO_TK_NO_ERROR);
    if(option == NOTIFY_QUIT)
	memcpy(NotifyStatus, old_status, MAX_NOTIFY_TYPES * sizeof(NotifyInfo));

    if(option == NOTIFY_ACCEPT || option == NOTIFY_QUIT)
    {
	status = ProMenuDelete();
        TEST_CALL_REPORT( "ProMenuDelete", "ProTestNotify",
            status, status != PRO_TK_NO_ERROR);
    }
    
    /*
    Menu for support cancel functionality
    */
    status = ProUtilMenuIntValueSelect (cancel_type, &id);    
    if (status == PRO_TK_NO_ERROR)
        user_notify_cancel = id;
    return(0);
}