/*------------------------------------------------------------------------------*
 * File Name: OriginEvents.c													*
 * Creation: RVD																*
 * Purpose: OriginC Source C file for Origin Events								*
 * Copyright (c) Originlab Corp.	2003										*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	ML 4/19/2004 SIMPLIFIED_TRY													*
 *	CPY 7/23/04 ADD_SHEET_TO_BOOK												*
 *	CPY 8/5/04 WKBOOK_CONTEXT_MENU_STANDARD_HANDLING							*
 *	ML 9/15/2004 QA70-5770 QA70-6878 ANALYSIS_MENUS_OC_HANDLING					*
 *	CPY 9/21/04 THEME_FILE_USER_PATH_SYSTEM_PATH								*
 *	YuI 10/20/04 QA70-7072 v7.5153 CORNER_OBJECT_FOR_NEW_WORKBOOK				*
 *	CPY 11/3/04	QA70-7122 ADD_BOX_CHART_TO_DESC_STATS							*
 *	YuI 12/07/04 v7.5172 PICTURE_IN_REPORT_IMPROVEMENT							*
 *	RVD 1/19/2005 QA70-7289 v8.0185 WKS_THEME_SUPPORT							*
 *	Frank 1/21/05 v8.0185 ANALYSIS_GUI_SUBMENU_MAX_ITEM							*
 *	ML 2/17/2005 CUSTOMIZING_TABLE												*
 *	CPY ML 2/25/2005 CELL_NAMED_RANGE_STYLE										*
 *	DSC 3/14/05 v8.0204 QA70-7500 EVENT_ORGANIZER_DLG							*
 *  DG 3/30/05 v8.0212 CLEAN_DUPLICATE_MORE										*
 *	DSC 4/1/05 QA70-7500 v8.215 GET_XF_FROM_ACCELERATOR							*
 *	EJP 2005-04-06 v8.0218 QA70-7588 GRAPHOBJ_SUPPORT_XFUNC						*
 *  Iris 4/13/05 RENAME_NEW_REPORT_NOTES										*
 *	YuI 04/22/05 QA70-6857 OBJECT_CONNECTION_IMPLEMENTATION						*
 *	ML 5/6/2005 QA70-7686 X_FUNCTIONS_DRIVEN_MENU_CUSTOMIZATION					*
 *	DSC 5//23/05 MOVE_GET_CLASS_SETTINGS_TO_VC									*
 *	CPY 5/24/05 QA70-7756 GRAPH_XF_OPEN_DIALOG_BY_POST_MSG						*
 *	EJP 2005-05-25 v8.0241 QA70-7218 NEW_MATRIX_WORKBOOK						*
 *  SY 05/27/2005 v8.0244 QA70-7575 SHEET_DUPLICATE_CONTEXT_MENU				*
 *	ML 6/28/2005 ADDING_GUI_CMD_UPDATE_FOR_XFUNCTIONS							*
 *	EJP 2005-07-05 v8.0261 QA70-7769 MAT_FRAME_BUTTON_OC						*
 *	DSC 8/24/05 MORE_FILTERS_FOR_XF												*
 *	DSC 8/31/05 FIND_GRAPHIC_OBJECT_X_FUNCTIONS									*
 *	ML 9/12/2005 CLEANING_UP_FACTORS_MAP_IN_DATARANGE							*
 *	ML 9/19/2005 QA70-8118 REMOVING_RESULTS_LOG_AS_GRID_AND_RESTORING_THE_OLD_LOG
 *	CPY 9/22/05 QA70-8015-P15 USE_SET_REPORT_TREE_TO_INTERNALLY_PUT_TREE_INTO_FLAT_SHEET
 *	CPY 10/5/05 STATS_ON_ROWS_JUST_NEED_ONE_INSERT_BACK_TO_SRC_SHEET			*
 *	ML 10/13/2005 QA70-8157 SPECIAL_NAMES_STYLES_IN_FLAT_SHEETS					*
 *	CPY 10/31/05 FIT_CUREVES_USE_SRC_DATA_COL_LONG_NAME_AS_SHEET_NAME			*
 *	ML 11/1/2005 QA70-8254 INVOKING_OPERATION_FROM_XFUNCTION					*
 *  Iris 11/08/05 FIX_INCORRECT_CURVE_BOOK_NAME_FOR_NON_FIT_TOOL				*
 *  Iris 1/13/06 REPLACE_TOTALNUM_WITH_PICNUM									*
 *	CPY 1/26/06 REMOVE_QUERY_TOOL_FOR_LATER										*
 *	RVD 2/15/2006 FIX_TABLE_CONTEXT_MENU										*
 *	RVD 2/17/2006 QA70-8359 TABLE_FOOTNOTE										*
 *	RVD 4/7/2006 QA70-8609 v8.0387 TABLE_GRID_BORDERS							*
 *	ML 5/11/2006 COPY_TABLE_ONLY_IF_NO_CHILD_GRIDS								*
 *	TD 5-18-06 QA70-8664 DATASET_OBJECT_CLASS_IN_OC_MORE_WORK					*
 *	ML 6/7/2006 QA70-4434 CUSTOM_TABLES_FOR_FIND_XY								*
 *	RVD 6/13/2006 QA70-8615 TABLE_HEADER										*
 *	ML 6/30/2006 QA70-8768 BUTTONS_IN_PLACE_OF_GRAPHS_IN_REPORTS				*
 *	CPY 7/8/06 XF_FROM_MENU_SHOULD_DUMP_RESULTS_LOG								*
 *	CPY 7/11/2006 USER_COMMENTS_ON_GRID_TABLE									*
 *	ML 7/20/2006 MOVING_GRAPH_BUTTONS_ADDING_TO_BEFORE_FILTERING_OF_REPORT		*
 *	ML 7/21/2006 QA70-4434 CUSTOM_TABLES_FOR_FIND_XY_HOOKING_IMPLEMENTING_COLUMN_FORMULA
 *	ML 7/25/2006 NEW_TABLE_ON_AUTOUPDATE_BUG									*
 *	CPY 8/3/06 REMOVE_VIEW_MENU_FROM_TABLE_IN_GRAPH								*
 *	ML 8/4/2006 REMOVING_CUSTOM_TABLE											*
 *	ML 8/15/2006 ATTACHING_GRAPHS_TO_CELLS_IN_OPERATION							*
 *	CPY 8/18/06 REPORT_SHEET_SHOULD_HAVE_DIFF_THEME								*
 *	DSC 8/20/06 REMOVE_ATTACH_XFUNCTION_CONTEXT_MENU							*
 *	Jasmine 09/28/06 GET_FITCURVE_OUTPUT_BOOK_NAME								*
 *	Cheney 2006-10-8 FIX_BUG_OF_CREATE_MORE_THAN_ONE_RESULT_SHEET_IF_NOT_ONE_DATASET
 * 	Arvin 10/13/06 FITTING_RESIDUALS_HISTOGRAM_PLOT								*
 *	CPY 11/10/06 NLFIT_NEW_CODE_RUNTIME_ERR_ON_CANCEL_BUTTON					*
 *  Iris 11/13/06 DO_TWO_TIMES_SEP_REPORT_IN_NLFIT_AND_OPBASE					*
 *	Cheney 2006-11-14 FIX_RUNTIME_ERROR_WHEN_CHOOSE_THEM_FROM_MENU				*
 *	ML 11/14/2006 MUST_NOT_REUSE_DATARANGE										*
 *  Iris 12/02/2006 v8.0518 KEEP_REAL_PARAM_NAME_FOR_MULTI_DATASET_SEP_REPORT	*
 *	CPY 12/09/2006 MFLIP_XF_NEED_OPTION_INDEX_BUT_ALSO_NEED_OPEN_DIALOG			*
 *	RVD 1/18/2007 QA70-9222 v8.0544 FOOTNOTE_COPY_LINK							*
 *	ML 1/22/2007 QA70-9189 MAKING_A_FLAT_SHEET_WITH_LINKS_ONLY_AND_IN_DATA_AS_WELL_AS_LABELS_AREA_OUT_OF_A_WHOLE_SOURCE_TABLE
 *	CPY 2/19/2007 TABLE_COPY_FOOTNOTE_MENU_SHOULD_CHECK_IF_HAS					*
 *	RVD 2/19/2007 QA70-9371 v8.0566 WKS_SELECTION_FILL							*
 *	CPY 2/21/2007 DATA_INFO_WIN_NOT_SHOWING										*
 *	ML 3/5/3007 QA70-9189 COPY_TO_NEW_SHEET_ETC_ONLY_IF_NO_CHILDREN				*
 *	ML 3/7/2007 QA70-9451 SET_LINKS_TRANSPOSED_ETC								*
 *	ML 3/13/2007 QA70-9477 PROPER_OCOPERATION_CLEANUP_AFTER_EXEC				*
 *	YuI 03/19/07 QA70-9503 MERGE_SELFCREATING_RANGE_INTO_COKPOLYRANGE			*
 *  SY 2007-04-04 QA70-9575 v8.0597 PRINT_OPTIONS_FOR_WKS_PRINT					*
 *  Folger 04/12/07 QA70-9575 v8.0599 PRINT_OPTIONS_FOR_WKS_PRINT				*
 *	RVD 4/4/2007 QA70-9574 GRID_PRINT_SETTINGS									*
 *	YuI 04/10/07 REVERTING_DATA_SELECTOR_TO_EXPANDED_OLD						*
 *	ML 5/7/2007 COPY_CONTEXT_MENU_ITEM_ON_GRAPH_TABLE_CELLS						*
 *	Jasmine 05/08/07 QA80-9654 OPEN_COLUMN_BROWSER								*
 *	Folger 04/09/07 MODIFY_ON_WKS_PRINT_OPTION									*
 *	CPY 5/11/2007 QA70-9760 XFBAR_CONTEXT_MENU_ON_TITLE							*
 *	Folger 05/14/07 MODIFICATION_OF_WKS_PRINT_OPTIONS							*
 *	CPY 5/18/2007 QA70-9795 MENU_FROM_THEME_TO_OPEN_DIALOG						*
 *	Jasmine 05/31/07 ADD_OPTION_TO_EXCLUDE_SPECIFIED_PAGE						*
 *	CPY 6/5/2007 QA70-9803 SHIFT_SELECT_SHOULD_FORCE_DIALOG_TO_OPEN				*
 *	Folger 06/25/07 SET_AUTO_COMPILE_DEPENDENT_FILE_TO_OPEN_WKSPROPERTIESDLG	*
 *	Folger 07/13/07 EXCLUDE_RESULT_SHEET_IN_COLUMN_BROWSER_IS_NEEDED			*
 *	CPY 7/11/2007 QA70-10010 LAST_USED_THEME_WHEN_RUN_FROM_MOST_RECENT_COMMAND	*
 *	Jasmine 07/17/07 SUPPORT_XY_RANGE											*
 *	Jasmine 07/20/07 USE_THE_SAME_RANGE_BROWSER									*
 *	Folger 07/31/07 RENAME_XYRANGE_BROWSER_TO_DATASET_BROWSER					*
 *	ML 8/3/2007 UNNECESSARILY_UNDOABLY_APPLYING_THEME_ON_IMPORT_SPARKLINES_ETC	*
 *	YuI 08/16/07 QA70-10234 MATRIX_PROPERTIES_DIALOG_PROBLEM					*
 *	Jasmine 08/24/07 QA80-10305 OPEN_MATRIX_BROWSER								*
 *	Jasmine 09/28/07 QA70-10305 FILTER_OUT_NON_IMAGE_MATRIX						*
 *	TD 10-03-2007 QA80-10447  CONFUSING_BIT_NAMES_CLEANUP						*
 *	Folger 10/26/07 CORRECT_NAME_SHOWN_IN_RANGE_BROWSER							*
 *	ML 11/7/2007 LOCALIZATION_STUFF												*
 *	Folger 12/17/07 FIX_RUNTIME_ERROR_WHEN_COMMAND_ID_LESS_EQUAL_THAN_ZERO		*
 *	Folger 02/15/08 QA80-11007 MOVE_EXPORT_GRAPH_MAKE_TREE_TO_VC				*
 *	Folger 03/14/08 QA80-11192 FIX_THEME_DEFAULT_MECHANISM_EXECUTE_FROM_MENU	*
 *	CPY 7/23/08 QA70-11849 SHOULD_COMPLETELY_REMOVE_ATTACH_XFUNCTION_CONTEXT_MENU
 *	Hong 09/19/08 QA80-12042 FIX_SEP_REPORT_PARAMS_WRONG_WHEN_CHANGE_PARAMETER	*
 *	EJP 2008-09-22 v8.0945 QA80-12020 SHOW_CMD_WINDOW_ONLY_WHEN_MAIN_VISIBLE	*
 *  Iris 11/10/2008 QA80-12519 v8.0968 REPORT_TABLE_SET_NEMERIC_FORMAT			*
 *	Folger 11/18/08 QA80-12574 v8.0974 SUPPORT_RESET_ALL_GRAPHS_IN_ERPORT_SHEET	*
 *	CPY 12/29/08 CHK_ELAPSED_TIME_FOR_OC_DIALOG_TO_OPEN_TOO_SLOWLY				*
 *	CPY 1/16/09 QA70-12954 OPEN_XYZ2MAT_DIALOG_FROM_LT							*
 *	Kyle 03/05/2009 FIX_THEME_SEPARATE_CLASS_OPTION_ERROR						*
 *	Folger 03/11/09 QA80-13258 OPEN_DIALOG_FROM_MRU_WITHOUT_THEME_NAME_SHOULD_USE_DEFAULT_SETTINGS
 *	Folger 03/12/09 QA80-13258 SUPPORT_OPEN_DIALOG_WITH_LAST_USED_FROM_MRU		*
 *  Iris 03/25/2009 QA80-13295-P3 GOTO_DLG_SUPPORT_COL_BROWSER					*
 *	Sophy 3/26/2009 QA80-13351 SUPPORT_ARRANGE_SAME_TYPE_PLOTS_IN_ONE_GRAPH_CONTEXT_MENU
 *	Folger 03/27/09 ERPLOT_GRAPH_IS_NOT_SUPPORTED_FOR_PA_REPORT_SHEET			*
 *	Sophy 4/1/2009 MORE_WORK_ON_SUPPORT_ARRANGE_SAME_TYPE_PLOTS_IN_ONE_GRAPH_CONTEXT_MENU
 *	ML 4/7/2009 QA70-13404 ALLOW_COPY_TABLE_IF_CLICKED_INSIDE_TABLE				*
 *	CPY 5/15/09 QA70-12602-S3 WKS_AUTOFILL_SHOULD_BE_ON_BY_DEFAULT				*
 *	YuI 05/22/09 QA70-13659 NO_AUTOFILL_IF_EMBEDDINGS_IN_BEGIN_RANGE			*
 *	TD 5-26-2009 QA80-9603 COMMAND_WINDOW_RESTORE_ON_START_BROKEN				*
 *	Folger 06/29/09 QA80-12954-P2 PEAK_FITTING_DIALOG_OF_NLFIT_FAILS_TO_BE_BROUGHT_UP_BY_LABTALK
 *	Sophy 7/13/2009 v8.1063 QA80-13880 MORE_CHECK_ON_SET_COLUMN_SHORT_NAME_FROM_CELL_VALUES
 *	Kenny 09/11/2009 QA81-14241 DEFINE_VARIABLE_NEED_MORE_IMPROVEMENTS			*
 *	Folger 09/17/09 QA80-10305 MATRIX_BROWSER_NEEDED_IN_BOTH_XF_AND_MATRIX_FIT_DIALOG
 *	CPY EJP 2009-10-27 QA81-14534 USE_OC_GETN_FROM_LT							*
 *	Kenny 11/02/2009 QA81-14534 FIX_LT_OPEN_OC_GETNBOX_COMBO_INIT_ISSUE			*
 *	Folger 11/10/09 QA81-14534-P4 BETTER_TITLE_AND_NUMERIC_DISLPLAY_FOR_USING_OC_GETN_FROM_LT
 *	Hong 11/16/09 QA80-14534-P5 FIX_CTRL_IN_LOWER_CASE_FAIL_TO_WORK_WITH_OC_GETN*
 *	Hong 11/16/09 QA80-14534-P5 FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX
 *	EJP 2009-11-17 QA81-14534 LTGETN_SUPPORT_BROWSE_FOR_FILE					*
 *	EJP 2009-11-17 QA81-14534 LTGETN_SUPPORT_NUM_FORMAT							*
 *	EJP 2009-11-23 QA81-14534 INIT_CHECKBOX_HIDESHOW_SIBLINGS					*
 *	EJP 2009-11-23 QA81-14534 USE_CRLF_FOR_DELIMITER							*
 *	CPY 11/26/09 QA81-14759 GETN_COMBO_LIST_NEED_PROPER_TOKENIZING				*
 *	Sim 12-07-2009 QA81-14641 LT_GETN_SUPPORT_DATE_TIME_PICKER					*
 *	Hong 12/24/09 QA80-14832 NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
 *	Sophy 1/11/2010 SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU				*
 *	Folger 04/20/10 QA81-15332 LT_USE_OC_GETN_FAILED_TO_HANDLE_STRING_COMBO		*
 *	Folger 05/18/10 ORG-143 LT_GETN_HINT_TEXT_SUPPORT							*
 *	Folger 06/01/10 ORG-120 DATA_DISPLAY_DIALOG_IMPROVEMENT						*
 *	EJP 2010-09-21 ORG-789 GETN_CHKBOX_SHOWHIDE_ALL_WHEN_COUNT_NOT_SPECIFIED	*
 *	RVD 10/14/2010 org-1266 SYSTEM_THEME_OVERRIDE_BROKEN_81						*
 *------------------------------------------------------------------------------*/
 
#include <origin.h>
#include <Control.h>

//------ Folger 11/18/08 QA80-12574 v8.0974 SUPPORT_RESET_ALL_GRAPHS_IN_ERPORT_SHEET
#include <Operation.h>
//------
#include <GetNBox.h>
#include <..\originlab\theme_utils.h>

/// ML 3/24/2005 CONTEXT_MENU_X_FUNCS
//#include "FunctionGroup.h"
/// end CONTEXT_MENU_X_FUNCS

#pragma labtalk(0) //--- CPY 7/26/05 hide all functions in this file from LT access, as XF should be used instead

#include <OC_res.h>
#include "oEvents.h"
#include "OriginEvents.h"
#include "wkbook.h"

#ifdef _RESULTS_QUERY //CPY 1/26/06 REMOVE_QUERY_TOOL_FOR_LATER
#include "GridQuery.h"
#endif

#include "OneColHeaderHandler.h"
#include <ocMenuId.h>
#include "WksEvents.h"
#include "XFunctionEx.h"
#include "okThemeID.h"
//------CPY 8/28/08 QA70-12878 NLFIT_TOO_SLOW_TO_OPEN
#ifdef _DEBUG
#include <Profiler.h>
#endif
//------

#define _DBMGS(_STR)		//out_str(_STR);

/// EJP 2005-07-08 v8.0266 QA70-7769 MAT_FRAME_BUTTON_OC
typedef int (*PFNMOREMATOBJ)(MatrixLayer& ml);
#define GET_MOREMATOBJ_FUNC(_pfn) PFNMOREMATOBJ _pfn = Project.FindFunction("DoMoreMatrixObjectDialog", "OriginLab\\MoreMatObjDlg.c", TRUE)
/// end MAT_FRAME_BUTTON_OC


#define SN_OC_OFFSET		200
//---- CPY 6/27/2006 GRID_TABLE_FORMATTING
//BOOL EditGridTheme(Grid& gg)
typedef BOOL (*BOOL_GRID)(Grid& gg);
//----
//#define _MEASUER_GRID_RESIZE_TIME

#define STR_DESCSTATS "DescStats"  ///Joseph 11/04/06  LOAD_DESCSTATS_ON_COL_AND_ROW_BY_OPTION  

BEGIN_OK_EVENT_MAP
	ON_OK_EVENT(OE_CREATE_NEW_GRAPH_PAGE_ADD_DATA, OnCreateNewGraphPageAddData)
	ON_OK_EVENT(OE_AFTER_LOAD_FROM_TEMPLATE, OnAfterLoadFromTemplate)
	/// RVD 2/16/2005 QA70-7289 v8.0185 WKS_THEME_SUPPORT
	ON_OK_EVENT(OE_NEW_GRID, OnNewGrid)
	/// end WKS_THEME_SUPPORT
	/// RVD 4/7/2006 QA70-8609 v8.0387 TABLE_GRID_BORDERS
	ON_OK_EVENT(OE_ON_TABLE_CREATE, OnTableCreate)
	/// end TABLE_GRID_BORDERS
	ON_OK_EVENT(OE_ON_SET_REPORT, OnSetReportSheet)//--- CPY 8/18/06 REPORT_SHEET_SHOULD_HAVE_DIFF_THEME
	ON_OK_EVENT(OE_ON_TABLE_PROPS_DIALOG, OnTableEdit) //------------ CPY 6/19/2006 DBL_CLICK_TABLE_TO_OPEN_LINKED_WKS
	ON_OK_EVENT(OE_AUTOFILL, OnAutoFill)/// RVD 2/19/2007 QA70-9371 v8.0566 WKS_SELECTION_FILL

	/// TD 11-12-04 QA70-7027 EVENT_HANDLING_ETC_FOR_OK 
	//msgMap.AddOriginMsg(OE_ONCONTEXTMENU_WKSLAYER, 	OnWksLayerContextMenu, VTS_RORIGINOBJ VTS_I4 VTS_I4);
	//msgMap.AddOriginMsg(OE_ONCONTEXTMENU_WKSPAGE,  	OnWksPageContextMenu, VTS_RORIGINOBJ VTS_I4 VTS_I4);
	//msgMap.AddOriginMsg(OE_ONCONTEXTMENU_WKS_GRIDCHILD, OnResultsSheetGrid,  VTS_RORIGINOBJ VTS_I4 VTS_I4);
	//msgMap.AddOriginMsg(OE_ONCONTEXTMENU_RESULT_LOG_GRIDCHILD, OnResultsLogGrid,  VTS_RORIGINOBJ VTS_I4 VTS_I4);
	msgMap.AddOriginMsg(OE_CONTEXTMENU, OnContext,  VTS_RORIGINOBJ VTS_I4 VTS_I4 VTS_I4);
	
	msgMap.AddOriginMsg(OE_ON_OBJ_DBL_CLICK, OnObjEdit,  VTS_RORIGINOBJ VTS_I4 VTS_I4 VTS_I4);//----- CPY 7/13/07 QA70-9062 SCALE_OBJ_EDIT_FROM_OC

	/// end EVENT_HANDLING_ETC_FOR_OK 
	/// TD 9-13-04 QA70-6376 WORKSHEET_CONTEXT_MORE_WORK
	msgMap.AddOriginMsg(OE_ONCONTEXTMENU_WIN_TITLE_BAR, 	OnWksFrameContextMenu, VTS_RORIGINOBJ VTS_I4 VTS_I4);
	/// end WORKSHEET_CONTEXT_MORE_WORK
	
	msgMap.AddOriginMsg(OE_ONCONTEXTMENU_SHEET_TAB,	OnWksTabContextMenu,  VTS_RORIGINOBJ VTS_I4 VTS_I4 VTS_ORIGINOBJ);
	msgMap.AddOriginMsg(OE_ONCONTEXTMENU_VERT_TAB,	OnSheetVertTabContextMenu,  VTS_RORIGINOBJ VTS_I4 VTS_I4 VTS_ORIGINOBJ); ////CPY 6/30/2005 QA70-7769 v8.0261 MAT_FRAME_BUTTON_OC

	msgMap.AddOriginMsg(OE_ON_DBL_CLICK_VERT_TAB,	OnSheetVertTabDblClick,  VTS_RORIGINOBJ VTS_I4 VTS_I4 VTS_ORIGINOBJ); //--- CPY 12/1/05 QA70-8292 MAT_OBJ_PROP_DIALOG_WHEN_DBL_CLICK

	/// ML 9/15/2004 QA70-5770 QA70-6878 ANALYSIS_MENUS_OC_HANDLING
	msgMap.AddOriginMsg(OE_ON_CLASS_AWARE_UI_UPDATE, OnClassAwareGUIUpdate, VTS_RORIGINOBJ VTS_I4 VTS_I4 VTS_PI4 VTS_PI4);
	msgMap.AddOriginMsg(OE_ON_CLASS_AWARE_COMMAND, OnClassAwareCommand, VTS_RORIGINOBJ VTS_I4);
	/// end ANALYSIS_MENUS_OC_HANDLING
	/// ML 5/6/2005 QA70-7686 X_FUNCTIONS_DRIVEN_MENU_CUSTOMIZATION
	//msgMap.AddOriginMsg(OE_ON_XF_MENUS_UPDATE, OnXFMenusGUIUpdate, VTS_RORIGINOBJ VTS_I4 VTS_I4 VTS_PI4);
	/// ML 6/28/2005 ADDING_GUI_CMD_UPDATE_FOR_XFUNCTIONS
	//msgMap.AddOriginMsg(OE_ON_XF_MENUS_EXEC, OnXFMenusCommand, VTS_RORIGINOBJ VTS_PI4 VTS_PI4 VTS_PI4 VTS_I4 VTS_I4 VTS_I4);
	//------- CPY 9/20/06 BETTER_OPEN_DIALOG_FROM_MENU
	///// YuI 07/29/05 QA70-7953 XF_THEME_SUPPORT
	////	msgMap.AddOriginMsg(OE_ON_XF_MENUS_EXEC, OnXFMenusCommand, 	VTS_RORIGINOBJ VTS_PI4 VTS_PI4 VTS_PI4 VTS_I4 VTS_I4 VTS_I4 VTS_PI4);
	//msgMap.AddOriginMsg(OE_ON_XF_MENUS_EXEC, OnXFMenusCommand, 		VTS_RORIGINOBJ VTS_PI4 VTS_PI4 VTS_PI4 VTS_I4 VTS_I4 VTS_I4 VTS_I4 VTS_PI4);
	msgMap.AddOriginMsg(OE_ON_XF_MENUS_EXEC, OnXFMenusCommand, 			VTS_RORIGINOBJ VTS_PI4 VTS_PI4 VTS_PI4 VTS_I4 VTS_I4 VTS_I4 VTS_PI4);
	//-------
	/// end XF_THEME_SUPPORT
	/// end ADDING_GUI_CMD_UPDATE_FOR_XFUNCTIONS
	/// end X_FUNCTIONS_DRIVEN_MENU_CUSTOMIZATION
	/// TD 10-8-04 GETNDIALOG_TO_EDIT_WORKSHEET_PROPERTIES
	msgMap.AddOriginMsg(OE_WORKSHEET_PROPS_DIALOG, OnWksPropsDialog, VTS_RORIGINOBJ VTS_I4 VTS_I4);
	/// end GETNDIALOG_TO_EDIT_WORKSHEET_PROPERTIES
	
	/// YuI 10/20/04 QA70-7072 v7.5153 CORNER_OBJECT_FOR_NEW_WORKBOOK
	msgMap.AddOriginMsg(OE_ON_OBJECT_HOT_SPOT_CLICK, OnObjectHotSpotClick, VTS_RORIGINOBJ VTS_I4 VTS_I4);
	/// end CORNER_OBJECT_FOR_NEW_WORKBOOK
	/// TD 2-11-05 QA70-7393 ON_SEL_CHANGE_OC_GLOBAL
	msgMap.AddOriginMsg(SN_ACTIVE_SELECTION, OnSelectionChange, VTS_RORIGINOBJ VTS_I4 VTS_I4);
	msgMap.AddOriginMsg(SN_ACTIVE_SELECTION_TRACK, OnSelectionTrackChange,  VTS_RORIGINOBJ VTS_I4 VTS_I4);
	/// end ON_SEL_CHANGE_OC_GLOBAL
	
	///DSC 4/1/05 QA70-7500 v8.0215 GET_XF_FROM_ACCELERATOR
	msgMap.AddOriginMsg(OE_XF_ACCEL, OnXFAccel, VTS_RORIGINOBJ VTS_I4 VTS_I4);
	///end GET_XF_FROM_ACCELERATOR
	
	/// YuI 04/22/05 QA70-6857 OBJECT_CONNECTION_IMPLEMENTATION
	msgMap.AddOriginMsg(OE_DATA_READER_EVENT, OnDataReaderEvent, VTS_RORIGINOBJ VTS_I4 VTS_I4);
	/// end OBJECT_CONNECTION_IMPLEMENTATION
	
	msgMap.AddOriginMsg(OE_ON_ATTACHED_XF_MSG, OnAttachedXFmsg, VTS_RORIGINOBJ VTS_I4 VTS_I4);//--- CPY 5/24/05 QA70-7756 GRAPH_XF_OPEN_DIALOG_BY_POST_MSG

	//msgMap.AddOriginMsg(SN_LOOSE_DATASET_CHANGE, OnLooseDatasetChange, VTS_RORIGINOBJ VTS_I4 VTS_I4); //---- CPY QA70-7860 7/6/05 LOOSE_DATASET_EDIT_UPDATE
	/// TD 4-12-07 QA70-9603 OC_CONTROLLED_DIALOGBARS_AUTOLAUNCH_ON_ORIGIN_BEGIN
	msgMap.AddOriginMsg(OE_AFTER_STARTUP_BUILD, OnAftreStartupBuild, VTS_I4);
	/// end OC_CONTROLLED_DIALOGBARS_AUTOLAUNCH_ON_ORIGIN_BEGIN


END_OK_EVENT_MAP


///--- CPY 2/26/2005 CELL_NAMED_RANGE_STYLE
int	get_cell_wks_selection_named_styles(vector<string> &vstrStyles, Grid &grd, int nSel, int r1, int c1, int c2, int r2)
{
	if(((WKS_SEL_EDIT | WKS_SEL_RANGE | WKS_SEL_LABEL) & nSel) && !(WKS_SEL_DISCONTIGUOUS & nSel))
	{
		if ( grd.Styles(r1, c1, r2, c2, vstrStyles, TRUE) )
			return vstrStyles.GetSize();
	}
	return -1;
}
///--- end CELL_NAMED_RANGE_STYLE

/// ML 9/19/2005 QA70-8118 REMOVING_RESULTS_LOG_AS_GRID_AND_RESTORING_THE_OLD_LOG
#ifdef		__OC_GRID_RLOG
/// end REMOVING_RESULTS_LOG_AS_GRID_AND_RESTORING_THE_OLD_LOG

void log_test()
{
	ResultsLog	rlog;					 
	Grid gg;
	rlog.GetGrid(gg);
	
	Tree		treeQuery, treeResult, trOtherItems;
	if(gg.BuildQueryTree(treeQuery) != 0)
		return;
	
		trOtherItems.Table.ID = IDST_REPORT_NOTES;
		trOtherItems.Table.Value1.ID = IDE_NOTES_USERNAME;
		trOtherItems.Table.Value2.ID = IDE_NOTES_CREATION_TIME;
		
		// Input:		
		trOtherItems.Table1.ID = IDST_REPORT_INPUT_TABLE;
		trOtherItems.Table1.FirstDim.ID = make_one_set_ID(IDST_REPORT_INPUT_ONE_SET, 0);
		//---- CPY 10/25/04 v8.0155 USE_EXCEL_NOTATION_FOR_EXTRACTION
		//trOtherItems.Table1.FirstDim.Value1.ID = IDE_INPUT_X;
		//trOtherItems.Table1.FirstDim.Value2.ID = IDE_INPUT_Y;
		trOtherItems.Table1.FirstDim.Value1.ID = IDE_INPUT_X_EXCEL;
		/// ML 11/8/2005 QA70-8135 Z_IN_REPORT_TABELS
		//trOtherItems.Table1.FirstDim.Value2.ID = IDE_INPUT_Y_EXCEL;
		trOtherItems.Table1.FirstDim.Value2.ID = IDE_INPUT_MAIN_EXCEL;
		/// end Z_IN_REPORT_TABELS
		//-----
		trOtherItems.Table1.FirstDim.Value1.SetAttribute(STR_EVENTS_ATTRIB, EVENTHANDLER_INSERTRELATEDCOLS);
		trOtherItems.Table1.FirstDim.Value2.SetAttribute(STR_EVENTS_ATTRIB, EVENTHANDLER_INSERTRELATEDCOLS);

	int	nFound = gg.Find(treeQuery, treeResult, trOtherItems);
	if(nFound == 0)
	{
		QueryResultsWks		wks;
		wks.Create(treeQuery, treeResult, "Results Log");
	}
}

/// ML 9/19/2005 QA70-8118 REMOVING_RESULTS_LOG_AS_GRID_AND_RESTORING_THE_OLD_LOG
#endif		// __OC_GRID_RLOG
/// end REMOVING_RESULTS_LOG_AS_GRID_AND_RESTORING_THE_OLD_LOG




/// YuI 12/08/06 QA70-9150 EXTENDED_GUI_FOR_INTERCATIVE_CONTROL
typedef bool (*FUNC_TREENODE_EVENT) (TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer);
static BOOL	_call_range_bulder_event(LPCTSTR lpcszEvent, TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	FUNC_TREENODE_EVENT pfn;
	pfn = Project.FindFunction(lpcszEvent, "OriginLab\\RangeBuilderEvents.c");
	if( pfn )
	{
		return pfn(tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
	}
	
	return false;
}

static bool _range_string_builder_object_root_event(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	return _call_range_bulder_event("_range_string_builder_object_root_event_ex", tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
}

static bool _range_string_builder_page_root_event(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	return _call_range_bulder_event("_range_string_builder_page_root_event_ex", tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
}

static bool _range_string_builder_layer_root_event(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	return _call_range_bulder_event("_range_string_builder_layer_root_event_ex", tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
}

static bool _range_string_builder_object_name_event(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	return _call_range_bulder_event("_range_string_builder_object_name_event_ex", tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
}

static bool _range_string_builder_page_name_event(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	return _call_range_bulder_event("_range_string_builder_page_name_event_ex", tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
}

static bool _range_string_builder_layer_name_event(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	return _call_range_bulder_event("_range_string_builder_layer_name_event_ex", tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
}

static bool _range_string_builder_page_template_event(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	return _call_range_bulder_event("_range_string_builder_page_template_event_ex", tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
}

static bool _range_string_builder_layer_template_event(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	return _call_range_bulder_event("_range_string_builder_layer_template_event_ex", tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
}
/// end EXTENDED_GUI_FOR_INTERCATIVE_CONTROL

//------ Folger 02/15/08 QA80-11007 MOVE_EXPORT_GRAPH_MAKE_TREE_TO_VC
static	bool	_call_export_graph_event(bool bImageUtils, LPCTSTR lpcszEvent, TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	FUNC_TREENODE_EVENT pfn;
	pfn = Project.FindFunction(lpcszEvent, bImageUtils ? "OriginLab\\image_utils.c" : "OriginLab\\GraphicalExport.c");
	if( pfn )
	{
		return pfn(tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
	}
	
	return false;
}

static	bool	_export_graph_gui_advanced_event(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	return _call_export_graph_event(false, "_gui_advanced_event", tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
}

static	bool	_export_graph_gui_unit_event(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	return _call_export_graph_event(false, "_gui_unit_event", tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
}

static	bool	_export_graph_gui_rescaling_event(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	return _call_export_graph_event(false, "_gui_rescaling_event", tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
}

static	bool	_export_graph_gui_export_options_eps_event(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	return _call_export_graph_event(true, "_gui_export_options_eps_event", tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
}

static	bool	_export_graph_gui_tif_event(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	return _call_export_graph_event(true, "_gui_tif_event", tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
}

static	bool	_export_graph_gui_ai_event(TreeNode& tr, int nRow, int nCol, TreeNode& trNode, DWORD nEventInfo, int nType, WndContainer& getNContainer)
{
	return _call_export_graph_event(true, "_gui_ai_event", tr, nRow, nCol, trNode, nEventInfo, nType, getNContainer);
}
//------ End MOVE_EXPORT_GRAPH_MAKE_TREE_TO_VC

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
////
////   GridPropsMenu
////
////
class GridPropsMenu :public MenuTree
{
public:
	GridPropsMenu(Grid &grid)
	{
		Grid		&gridacc = m_gridacc;
		gridacc = grid;
		
		GETN_TREE(tr)
		m_gridacc.GetTree(tr);
		m_trMenu = tr.View;
		//-----
		
		createMenuFromTree();
	}
	
	BOOL IsHandled()
	{
		return m_gridacc.IsHandled();
	}

	virtual void Handler(uint nCmd)
	{
		m_gridacc.TogglePropertyValue(nCmd);
	}

	
private:
	GridAccess	m_gridacc;

};

bool WkBookEventsBase::processThemeCommands(int nCmd)
{
	if(nCmd < IDM_CM_THEME_FIRST || nCmd > IDM_CM_THEME_LAST)
		return false;
	
	Datasheet wks;
	if(!GetWksheet(wks))
		return false;

	Grid grd;
	/// TD 8-3-06 QA70-8843 DOWNCAST_BUG
	//grd.Attach(wks);
	Worksheet worksheet = wks;
	grd.Attach(worksheet);
	/// end DOWNCAST_BUG
	Tree tr;
	if(IDM_CM_THEME_PASTE_FORMAT == nCmd)
	{
		if(theme_get_from_clipboard(tr))
		{
			//out_tree(tr);
			//grd.ApplyFormat(tr, TRUE, TRUE);
			LT_execute(";run.section(File,PasteFormats)");
		}
		return true;
	}
	else if(IDM_CM_THEME_SAVE_FORMAT == nCmd)
	{
		// need to use LT delayed execution so we finish with this event first and
		// queue the run.section code for subsequent execution
		//---- CPY 4/7/06 WKS_THEME_CHANGE_FROM_SAVE_TO_EDIT_FORMAT
		//LT_execute(";run.section(File,FmtsSaveAsTheme)");
		LT_execute(";run.section(File,WksEditTheme)");
		//----
		return true;
	}
	DWORD dwProperty = FPB_ALL;
	switch(nCmd)
	{
	case IDM_CM_THEME_COPY_COLORS:
		dwProperty = FPB_STYLE_COLOR_MASK;
		break;
	case IDM_CM_THEME_COPY_FONTS:
		dwProperty = FPB_STYLE_FONT|FPB_STYLE_SIZE;
		break;
	}		
	tr = grd.GetFormat(dwProperty, FOB_ALL & ~FOB_LINK_STYLE, TRUE, TRUE);
	theme_copy_to_clipboard(tr);
	return true;
}
//---
//------------ CPY 6/19/2006 DBL_CLICK_TABLE_TO_OPEN_LINKED_WKS
static void _open_linked_wks(Grid& gg)
{
	Worksheet wksSrc;
	gg.GetOwner(wksSrc);
	if(wksSrc)
	{
		string strBookName = wksSrc.GetPage().GetName();
		string strLT;
		strLT.Format(";win -a %s", strBookName);
		LT_execute(strLT);
	}
}
//-----------

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
////
////   GridMenu
////
////

class GridMenu :public Menu
{
public:
	GridMenu(Grid &grid, point &ptScreen, DWORD dwCntrl = 0, bool bAppendSeparator = false)
	{
		m_grid = grid;
		m_ptScreen	= ptScreen;
		m_dwCntrl = dwCntrl;
		
		bool bIsGoodSelectionForValue = checkGridValueSelection(grid);  /// Iris 9/09/05 CHECK_SELECTION_FOR_VALUE
		//m_bDelayedDoFind = false;
		if( IsFromWks() )
		{
#ifdef _RESULTS_QUERY //CPY 1/26/06 REMOVE_QUERY_TOOL_FOR_LATER
			if( bIsGoodSelectionForValue )  /// Iris 9/09/05 CHECK_SELECTION_FOR_VALUE
			{
				Add(_L("Extract Values of Same Type from &Book"), FindBook);
				Add(_L("Extract Values of Same Type from &Project"), FindOPJ);
			}
#endif //#ifdef _RESULTS_QUERY //CPY 1/26/06 REMOVE_QUERY_TOOL_FOR_LATER

			/// ML 5/11/2006 COPY_TABLE_ONLY_IF_NO_CHILD_GRIDS
			///// ML 12/16/2004 UNIFIED_GRID_CONTEXT_MENU_HANDLING
			//Add(_L("Copy &Table"), CopyTable);
			///// end UNIFIED_GRID_CONTEXT_MENU_HANDLING
			//Add(NULL, EmptySepFunc, MF_SEPARATOR);
			//
			BOOL		bDelete = grid.CanDelete();			
			BOOL		bInsert = grid.CanInsert();	
			BOOL		bInTitleArea = false;
			BOOL		bNeedSeparator = false;
			/// ML 3/5/3007 QA70-9189 COPY_TO_NEW_SHEET_ETC_ONLY_IF_NO_CHILDREN
			int			nNumChildGrids = grid.GetNumChildGrids();
			/// end COPY_TO_NEW_SHEET_ETC_ONLY_IF_NO_CHILDREN
			if (IsTableTitleArea())// || (!bDelete && !bInsert))//(grid.GetNumChildGrids() == 0)//-------- CPY 6/27/2006 GRID_TABLE_FORMATTING
			{
				//-------- CPY 6/27/2006 GRID_TABLE_FORMATTING
				Add(_L("User Comments..."), EditTableHeader);
				//--------
				//Add(NULL, EmptySepFunc, MF_SEPARATOR);
				bInTitleArea = true;
				bNeedSeparator = true;
			}
			/// ML 5/7/2007 COPY_CONTEXT_MENU_ITEM_ON_GRAPH_TABLE_CELLS
			else
			{
				Add(_L("&Copy\tCtrl+C"), Copy);
			}
			/// end COPY_CONTEXT_MENU_ITEM_ON_GRAPH_TABLE_CELLS
			//printf("dwCntrl=%X, %d %d\n", m_dwCntrl, bDelete, bInsert);
			/// ML 4/7/2009 QA70-13404 ALLOW_COPY_TABLE_IF_CLICKED_INSIDE_TABLE
			///// ML 3/5/3007 QA70-9189 COPY_TO_NEW_SHEET_ETC_ONLY_IF_NO_CHILDREN
			////if(bInTitleArea || bDelete || bInsert)
			//if(nNumChildGrids <= 0 && (bInTitleArea || bDelete || bInsert))
			///// end COPY_TO_NEW_SHEET_ETC_ONLY_IF_NO_CHILDREN
			if(nNumChildGrids <= 0)
			/// end ALLOW_COPY_TABLE_IF_CLICKED_INSIDE_TABLE
			{
				Add(_L("Copy &Table"), CopyTable);
				/// RVD 1/18/2007 QA70-9222 v8.0544 FOOTNOTE_COPY_LINK
				//------ CPY 2/19/2007 TABLE_COPY_FOOTNOTE_MENU_SHOULD_CHECK_IF_HAS
				/// ML 4/7/2009 QA70-13404 ALLOW_COPY_TABLE_IF_CLICKED_INSIDE_TABLE
				//if(grid_has_footnote(grid))
				if((bInTitleArea || bDelete || bInsert) && grid_has_footnote(grid))
				/// end ALLOW_COPY_TABLE_IF_CLICKED_INSIDE_TABLE
				//------
					Add(_L("Copy Footnote"), CopyFootnote);
				/// end FOOTNOTE_COPY_LINK
				/// ML 1/22/2007 QA70-9189 MAKING_A_FLAT_SHEET_WITH_LINKS_ONLY_AND_IN_DATA_AS_WELL_AS_LABELS_AREA_OUT_OF_A_WHOLE_SOURCE_TABLE
				Add(_L("Create Copy As New Sheet"), MakeCopyAsFlatSheet);
				/// end MAKING_A_FLAT_SHEET_WITH_LINKS_ONLY_AND_IN_DATA_AS_WELL_AS_LABELS_AREA_OUT_OF_A_WHOLE_SOURCE_TABLE
				/// ML 3/7/2007 QA70-9451 SET_LINKS_TRANSPOSED_ETC
				Add(_L("Create Transposed Copy As New Sheet"), MakeCopyAsFlatSheetTransposed);
				/// end QA70-9451 SET_LINKS_TRANSPOSED_ETC
				bNeedSeparator = true;
			}
			if(bNeedSeparator)
				Add(NULL, EmptySepFunc, MF_SEPARATOR);
			/// end COPY_TABLE_ONLY_IF_NO_CHILD_GRIDS
	
			Add(_L("&Expand"), Expand);
			Add(_L("&Collapse"), Collapse);
			
			//------ Folger 11/18/08 QA80-12574 v8.0974 SUPPORT_RESET_ALL_GRAPHS_IN_ERPORT_SHEET
			Add(NULL, EmptySepFunc, MF_SEPARATOR);
			Add(_L("&Reset All Graphs"), Replot, IsResetGraphsSupported() ? MF_STRING : MF_GRAYED);
			//------
			///Sophy 3/26/2009 QA80-13351 SUPPORT_ARRANGE_SAME_TYPE_PLOTS_IN_ONE_GRAPH_CONTEXT_MENU
			UINT nFlag = checkRearrangePlotsState();
			Add(_L("&Arrange Plots of Same Type in One Graph"), RearrangeSameTypePlots, nFlag);
			///end SUPPORT_ARRANGE_SAME_TYPE_PLOTS_IN_ONE_GRAPH_CONTEXT_MENU
			if (IsTableTitleArea())
			{
				Add(NULL, EmptySepFunc, MF_SEPARATOR);
		
				/// RVD 1/19/2005 QA70-7289 v8.0185 WKS_THEME_SUPPORT
				Add(_L("Copy &Format"), CopyFormat);
	//			Add(_L("Save Format as Theme..."), SetAsTheme);		/// ML 2/17/2005 CUSTOMIZING_TABLE
				Add(_L("&Paste Format"), PasteFormat);
				/// end WKS_THEME_SUPPORT
				if(isShowEditFormatDlg())//---- CPY 2/17/10 QA81-15124 HIDE_EDIT_FORMATTING_DLG
				Add(_L("Edit Formatting..."), EditTheme);  //-- CPY 6/27/2006 GRID_TABLE_FORMATTING				
				//Add(_L("Set Numeric Format(Doing)..."), SetNumericFormat);  /// Iris 11/10/2008 QA80-12519 v8.0968 REPORT_TABLE_SET_NEMERIC_FORMAT				
			}
			if (bDelete || bInsert)
			{
				Add(NULL, EmptySepFunc, MF_SEPARATOR);
				if (bDelete)
					Add(_L("&Delete"), Delete);
				if (bInsert)
					Add(_L("&Insert"), Insert);
			}
	
			if ( bAppendSeparator )
				Add(NULL, EmptySepFunc, MF_SEPARATOR);
		}
		/// RVD 2/15/2006 FIX_TABLE_CONTEXT_MENU
		else if( IsFromTableObj() )
		{
			if( grid.IsLabelsShown(FALSE, RCLT_CHECK_LINK) )
			{
				if( grid.IsLabelsShown(FALSE, RCLT_INVALID) )
					Add(_L("Hide &Row Labels"), HideRowLabels);
				else
					Add(_L("Show &Row Labels"), ShowRowLabels);
			}
			
			if( grid.IsLabelsShown(TRUE, RCLT_CHECK_LINK) )
			{
				if( grid.IsLabelsShown(TRUE, RCLT_INVALID) )
					Add(_L("Hide &Column Labels"), HideColLabels);
				else
					Add(_L("Show &Column Labels"), ShowColLabels);
			}
			
			//---- CPY 6/14/2006 GOTO_WKS_FROM_TABLE
			Add(_L("Go to worksheet"), TableGotoWks);
			Add(_L("Apply Worksheet Format"), ApplyLinkWksTheme);
			//----
				
		}
		//--- TEMP code CPY 7/18/06 TABLE_IN_GRAPH_COL_WIDTH_PROBLEM
		else
		{
			if(isShowEditFormatDlg())//---- CPY 2/17/10 QA81-15124 HIDE_EDIT_FORMATTING_DLG
			Add(_L("Edit Formatting..."), EditTheme);  //-- CPY 6/27/2006 GRID_TABLE_FORMATTING
		}
		//----
		/// end FIX_TABLE_CONTEXT_MENU
#ifdef _RESULTS_QUERY //CPY 1/26/06 REMOVE_QUERY_TOOL_FOR_LATER
		else
		{
			Add(_L("&Extract Values of Same Type"), FindResultsLog);
	
			if ( bAppendSeparator )
				Add(NULL, EmptySepFunc, MF_SEPARATOR);
		}
#endif //#ifdef _RESULTS_QUERY //CPY 1/26/06 REMOVE_QUERY_TOOL_FOR_LATER
	}
	bool	IsFromWks()
	{
		//printf("IsFromWks dwCntrl = %X\n", m_dwCntrl);
		return ((m_dwCntrl & HGE_MASK_TYPE) == HGE_RESULTS_SHEET)? true:false;
	}
	//---- CPY 8/3/06 REMOVE_VIEW_MENU_FROM_TABLE_IN_GRAPH
	bool	IsFromGraphTable()
	{
		if(IsFromWks() || IsFromTableObj())
			return false;
		
		return true;
	}
	//---
	bool	IsFromTableObj()
	{
		return (m_dwCntrl & HGE_MASK_TYPE) == HGE_TABLE_OBJ;
	}
	bool IsTableTitleArea()
	{
		//printf("IsTableTitleArea dwCntrl = %X\n", m_dwCntrl);
		
		if(IsFromWks() && (m_dwCntrl & HGE_TABLE_TITLE))
			return true;
		
		return false;
	}
	void	EmptySepFunc(uint nCmd)
	{
	}
	void Expand(uint nCmd)
	{
		m_grid.Expand(TRUE);
	}
	void Collapse(uint nCmd)
	{
		m_grid.Expand(FALSE);
	}
	
	//------ Folger 11/18/08 QA80-12574 v8.0974 SUPPORT_RESET_ALL_GRAPHS_IN_ERPORT_SHEET
	bool	IsResetGraphsSupported()
	{
		Worksheet wks;
		m_grid.GetOwner(wks);
		
		if ( wks )
		{
			Operation&		op = (Operation&)wks.GetSrcOperation();
			if( !op )
				return false;
			
			///------ Folger 03/27/09 ERPLOT_GRAPH_IS_NOT_SUPPORTED_FOR_PA_REPORT_SHEET
			//LPCSTR	lpcszWizOpration = "WizOperation";
			//return op.GetName().CompareNoCase(lpcszWizOpration) == 0 ? false : true;
			return op.IsReplotGraphsSupported();
			///------ End ERPLOT_GRAPH_IS_NOT_SUPPORTED_FOR_PA_REPORT_SHEET
		}
		
		return false;
	}
	
	void	Replot(uint nCmd)
	{
		Worksheet wks;
		m_grid.GetOwner(wks);
		
		if ( wks )
		{
			Operation&		op = (Operation&)wks.GetSrcOperation();
			if( !op )
				return;
			
			/// Folger, This line is needed for prevent grid keep refreshing.
			/// No idea how it works, just a workaround, need to improve.
			wks.Invalidate(FALSE);
			op.ReplotReportGraphs();
		}
	}
	//------ End SUPPORT_RESET_ALL_GRAPHS_IN_ERPORT_SHEET
	///Sophy 3/26/2009 QA80-13351 SUPPORT_ARRANGE_SAME_TYPE_PLOTS_IN_ONE_GRAPH_CONTEXT_MENU
	void	RearrangeSameTypePlots(uint nCmd)
	{
		Worksheet wks;
		m_grid.GetOwner(wks);
		if ( wks )
		{
			Operation& op = (Operation&)wks.GetSrcOperation();
			if ( !op )
				return;
			op.RearrangeReportPlots(wks);
		}
	}
	///end SUPPORT_ARRANGE_SAME_TYPE_PLOTS_IN_ONE_GRAPH_CONTEXT_MENU
	/// RVD 2/15/2006 FIX_TABLE_CONTEXT_MENU
	void	HideRowLabels(uint nCmd)
	{
		m_grid.ShowLabels(RCLT_INVALID, FALSE, true, false);
	}
	void	ShowRowLabels(uint nCmd)
	{
		m_grid.ShowLabels(RCLT_INVALID, TRUE, true, false);
	}
	void	HideColLabels(uint nCmd)
	{
		m_grid.ShowLabels(RCLT_INVALID, FALSE, true, true);
	}
	void	ShowColLabels(uint nCmd)
	{
		m_grid.ShowLabels(RCLT_INVALID, TRUE, true, true);
	}
	/// end FIX_TABLE_CONTEXT_MENU
	
	//---- CPY 6/14/2006 GOTO_WKS_FROM_TABLE
	void TableGotoWks(uint nCmd)
	{
		_open_linked_wks(m_grid);
	}
	void ApplyLinkWksTheme(uint nCmd)
	{
		Worksheet wksSrc;m_grid.GetOwner(wksSrc);
		Tree trTheme;
		if(theme_get_from_wks_grid(wksSrc, trTheme, FPB_ALL, FOB_ALL, TH_DEL_GRID_COL_HEADING | TH_DEL_GRID_ROW_HEADING))
			m_grid.ApplyFormat(trTheme, true, true);	
	}
	//----
	
#ifdef _RESULTS_QUERY //CPY 1/26/06 REMOVE_QUERY_TOOL_FOR_LATER
	void FindResultsLog(uint nCmd)
	{
		Tree		treeQuery, treeResult, trOtherItems;
		if(!m_grid.BuildQuery(treeQuery, trOtherItems))
			return;

		int	nFound = m_grid.DoQuery(treeQuery, treeResult, trOtherItems);
		if(nFound > 0)
		{
			QueryResultsWks		wks;
			wks.Create(treeQuery, treeResult, "Results Log");
		}
	}
	void FindBook(uint nCmd)
	{
		Tree		treeQuery, treeResult, trOtherItems;
		if(!m_grid.BuildQuery(treeQuery, trOtherItems))
			return;
		WorksheetPage wpg = Project.Pages();
		if(findFromBook(wpg, treeResult, treeQuery, trOtherItems) > 0)
		{
			QueryResultsWks		rwks;
			rwks.Create(treeQuery, treeResult, wpg.GetName());
		}
	}
	void FindOPJ(uint nCmd)
	{
		Tree		treeQuery, treeResult, trOtherItems;
		if(!m_grid.BuildQuery(treeQuery, trOtherItems))
			return;
		int nTotal = 0;
		foreach(WorksheetPage wpg in Project.WorksheetPages)
		{
			nTotal += findFromBook(wpg, treeResult, treeQuery, trOtherItems);
		}
		if(nTotal)
		{
			QueryResultsWks		rwks;
			rwks.Create(treeQuery, treeResult, "Project");
		}			
	}
#endif //#ifdef _RESULTS_QUERY //CPY 1/26/06 REMOVE_QUERY_TOOL_FOR_LATER
	///// ML 12/16/2004 UNIFIED_GRID_CONTEXT_MENU_HANDLING
	void	CopyTable(uint nCmd)
	{
		grid_copy_to_clipboard(m_grid); //--CPY 7/11/06
	}
	/// ML 1/22/2007 QA70-9189 MAKING_A_FLAT_SHEET_WITH_LINKS_ONLY_AND_IN_DATA_AS_WELL_AS_LABELS_AREA_OUT_OF_A_WHOLE_SOURCE_TABLE
	void	MakeCopyAsFlatSheet(uint nCmd)
	{
		grid_make_copy_as_flat_sheet(m_grid);
	}
	/// end MAKING_A_FLAT_SHEET_WITH_LINKS_ONLY_AND_IN_DATA_AS_WELL_AS_LABELS_AREA_OUT_OF_A_WHOLE_SOURCE_TABLE
	/// ML 3/7/2007 QA70-9451 SET_LINKS_TRANSPOSED_ETC
	void	MakeCopyAsFlatSheetTransposed(uint nCmd)
	{
		grid_make_copy_as_flat_sheet(m_grid, TRUE);
	}
	/// end QA70-9451 SET_LINKS_TRANSPOSED_ETC
	
	/// ML 5/7/2007 COPY_CONTEXT_MENU_ITEM_ON_GRAPH_TABLE_CELLS
	void	Copy(uint nCmd)
	{
		m_grid.ProcessCommand(ID_EDIT_COPY);
	}
	/// end COPY_CONTEXT_MENU_ITEM_ON_GRAPH_TABLE_CELLS



	//-------- CPY 7/11/2006 USER_COMMENTS_ON_GRID_TABLE
	void EditTableHeader(uint nCmd)
	{
		grid_edit_user_comments(m_grid);
	}
	//--------
	/// end UNIFIED_GRID_CONTEXT_MENU_HANDLING
	
	/// RVD 1/18/2007 QA70-9222 v8.0544 FOOTNOTE_COPY_LINK
	void	CopyFootnote(uint nCmd)
	{
		m_grid.CopyFootnote();
	}
	/// end FOOTNOTE_COPY_LINK

	/// RVD 1/19/2005 QA70-7289 v8.0185 WKS_THEME_SUPPORT
	void	CopyFormat(uint nCmd)
	{
		DWORD dwProps = FPB_ALL;
		
		if( IsFromTableObj() )
			dwProps &= ~FPB_TEXT;
		
		Tree tr;
		tr = m_grid.GetFormat(dwProps, FOB_ALL & ~FOB_RANGE_STYLE, TRUE, TRUE);
		bool bb = theme_copy_to_clipboard(tr);
	}
	void	PasteFormat(uint nCmd)
	{
		Tree tr;
		if( theme_get_from_clipboard(tr) )
		{
			m_grid.ApplyFormat(tr, TRUE, TRUE);
		}
	}
	/// end WKS_THEME_SUPPORT
		
	void	Delete(uint nCmd)
	{
		m_grid.Delete(true);
	}
	
	void	Insert(uint nCmd)
	{
		m_grid.Insert(true);
	}
//-------------- CPY 6/27/2006 GRID_TABLE_FORMATTING
/*	
	/// ML 2/17/2005 CUSTOMIZING_TABLE
	void	SetAsTheme(uint nCmd)
	{
		Operation	*pop = m_grid.GetOperation();
		if (NULL == pop)
			return;
		
		string			strClassOption = pop->GetThemeFilePrefix();
		Tree			treeTh;
		DWORD			dwProps = FPB_ALL;
		
		if( IsFromTableObj() )
			dwProps &= ~FPB_TEXT;
		
		string			strThemePathName;// = theme_get_theme_file_name(str);
		int				nTableID;
		string			strThemeName = getTableName(&nTableID);
		string			strDescription;
		int 			thtype = THTYPESCOPE_ANALYSIS_CLASS;
		string 			strCategory;
		if(theme_save_as_box(strThemePathName, THTYPE_REPORT_TABLE, strThemeName, strDescription, strClassOption, thtype, strCategory, &nTableID))
		{
			string strPath = GetFilePath(strThemePathName);
			if(CheckMakePath(strPath))
			{
				treeTh = m_grid.GetFormat(dwProps, FOB_ALL & ~FOB_RANGE_STYLE, TRUE, TRUE);
				printf("saving theme to %s\n", strThemePathName);
				treeTh.Save(strThemePathName);
			}
		}
	}
	/// end CUSTOMIZING_TABLE
*/
	void	EditTheme(uint nCmd)
	{
		BOOL_GRID pfn = Project.FindFunction("EditGridTheme", "OriginLab\\ThemeEditor");
		if(pfn)
		{
			pfn(m_grid);
		}
		/*
	GETN_TREE(tr)
    GETN_CHECK(aa,"Path Control", false)    
    GETN_STR_GROUP(states, "PLease picka few US states", "MA", "|MA|CA|RI|VT|NY")
	GETN_BUTTON_GROUP(Button, "Button", 0, "Open Function Browser")
	GETN_OPTION_DISPLAY_FORMAT(DISPLAY_EDITOR_RIGHT)
	if( GetNBox(tr,"Test Check and Button","Test Check...", NULL, NULL) )
		out_tree( tr );
		*/
		
	}
//--------------

	/// Iris 11/10/2008 QA80-12519 v8.0968 REPORT_TABLE_SET_NEMERIC_FORMAT, low level than pa, do later
	/*
	void 	SetNumericFormat(uint nCmd)
	{
		int nTableID;
		getTableName(&nTableID);
		
		// Fail to get operation object in IR968
		OperationBase* pOp = m_grid.GetOperation();
		if( pOp )
		{
			Tree trOp;
			pOp->GetTree(trOp);
		}
		
		Tree tr;
		DWORD dwObjs = FOB_ALL;
		tr = m_grid.GetFormat(FPB_ALL, dwObjs, TRUE, TRUE);
		
		tr.Root.NameStyles.NameStyle2.Style.Format.strVal = "*4";
		tr.Root.NameStyles.NameStyle2.Style.Format.ID = OTID_STYLE_FORMAT;
		
		int iRet = m_grid.UpdateThemeIDs(tr.Root, "Error", "Unknown tag");	
		if(0 == iRet)
			bool bRet = m_grid.ApplyFormat(tr, TRUE, TRUE);
	}
	*/
	///end REPORT_TABLE_SET_NEMERIC_FORMAT
	
	//bool IsDoQuery() {return m_bDelayedDoFind? true:false;}
private:
	string getTableName(int* pnID = NULL)
	{
		if(pnID)
			*pnID = m_grid.GetID();
		
		string	str = m_grid.GetLongName();
		if(!str.IsEmpty()) // check possible name - some longer description, or name (other things) - longer descriptions
		{
			int nPos = str.Find('(');
			if(nPos > 0)
				str = str.Left(nPos);
			else
			{
				nPos = str.Find('-');
				if(nPos > 0)
					str = str.Left(nPos);
			}
		}
		str.TrimRight();
		return str;
	}
	int findFromBook(WorksheetPage& wpg, TreeNode& trResults, const TreeNode& trQuery, const TreeNode& trOtherItems)
	{
		int nFound, nResults = 0;
		int nEntries = trResults.GetNodeCount();
		foreach(Layer wks in wpg.Layers)
		{
			if(!(wks.GetSystemParam(0) & WP_SHEET_HIERARCHY))
				continue;
			
			Grid gg;
			wks.GetGrid(gg);
			if(gg)
			{
				Tree trR;
				int nErr = gg.Find(trQuery, trR, trOtherItems);
				nFound = 0==nErr? trR.GetNodeCount() : 0;
				if(nFound > 0)
				{
					if(0 == nEntries)
					{
						trResults = trR;
						nEntries = nFound;
						if(nEntries == 0)
							out_str("Error, Find result is empty, this is not possible");
					}
					else
						tree_append_children(trResults, trR, "Entry");
					
					nResults+= nFound;
				}
			}
		}
		return nResults;
	}
	
	/// Iris 9/09/05 CHECK_SELECTION_FOR_VALUE
	bool checkGridValueSelection(Grid& grid)
	{
		if( !grid )
			return false;
		
		int r1, c1, r2, c2;
		if( !grid.GetSelectedRange(r1, c1, r2, c2) )
			return false;			
		
		if( r1==0 || r1==1 )//0: column header, 1: column label
			return false;
		
		return true;		
	}
	///End CHECK_SELECTION_FOR_VALUE
	UINT checkRearrangePlotsState()
	{
		Worksheet wks;
		m_grid.GetOwner(wks);
		if ( wks )
		{
			Operation&		op = (Operation&)wks.GetSrcOperation();
			//Sophy 4/1/2009 MORE_WORK_ON_SUPPORT_ARRANGE_SAME_TYPE_PLOTS_IN_ONE_GRAPH_CONTEXT_MENU
			//if ( !op )
				//return MF_UNCHECKED;
			//
			//Tree trOperation;
			//op.GetTree(trOperation);
			//if ( op.GetTotalNumData(trOperation) <= 1 )
				//return MF_GRAYED;
			if ( !op || !op.IsRearrangeGraphSupported() )
				return MF_GRAYED;
			
			Tree trOperation;
			op.GetTree(trOperation);
			///end MORE_WORK_ON_SUPPORT_ARRANGE_SAME_TYPE_PLOTS_IN_ONE_GRAPH_CONTEXT_MENU
			
			/// Iris 10/29/2009 QA81-14546 OP_DLG_NEW_STRUCTURE
			//TreeNode trPlotInOneGraph = trOperation.GUI.Output.PlotSettings.PlotInOneGraph;
			TreeNode trPlotInOneGraph = OP_GUI_GRAPH_ARRANGEMENT_NODE(trOperation.GUI).PlotInOneGraph;
			///end OP_DLG_NEW_STRUCTURE
			if ( trPlotInOneGraph )
			{
				int nCheck = trPlotInOneGraph.nVal;
				if ( nCheck )
					return MF_CHECKED;
				else
					return MF_UNCHECKED;
			}
		}			
		return MF_UNCHECKED;
	}
	
private:		
	//bool		m_bDelayedDoFind;
#ifdef _RESULTS_QUERY //CPY 1/26/06 REMOVE_QUERY_TOOL_FOR_LATER
	GridQuery	m_grid;
#else
	Grid		m_grid;
#endif
	point		m_ptScreen;
	DWORD		m_dwCntrl;
};


bool GridEvents::OnContextMenu(int x, int y, DWORD dwControl)// = 0
{
	//printf("GridEvents::OnContextMenu(x=%d, y=%d, dwControl=%X)\n", x,y, dwControl);

	point pt(x,y);
	GridMenu popup(m_grid, pt, dwControl, true);
	//---- CPY 8/3/06 REMOVE_VIEW_MENU_FROM_TABLE_IN_GRAPH
	// this will hide context menu altogether, to bring back Edit Formatting, need to
	// comment this out
	if(popup.IsFromGraphTable())
		return true;
	//----

	/// RVD 2/15/2006 FIX_TABLE_CONTEXT_MENU
	if( popup.IsFromTableObj() )
	{
		popup.TrackPopupMenu(0,  x, y, GetWindow());
		return TRUE;
	}
	/// end FIX_TABLE_CONTEXT_MENU
	
	GridPropsMenu	propsmenu(m_grid);
	
	// This doesn't work:
	//popup.InsertMenu(-1, MF_BYPOSITION | MF_SEPARATOR);
	//popup.Add(NULL, 0, MF_SEPARATOR);
	popup.InsertPopup(-1, _L("View"), propsmenu, OC_MENURANGE_BEGIN);

	int			nCmdSelected = 0;
	if ( !popup.TrackPopupMenu(0,  x, y, GetWindow(), &nCmdSelected) )
	{
		propsmenu.Handler(nCmdSelected);
	}
	
	return TRUE;
}


static BOOL OnResultsLogGrid(Grid &grid, int x, int y)
{
	point pt(x,y);
	GridMenu popup(grid, pt, HGE_RESULTS_LOG);
	popup.TrackPopupMenu(0,  x, y, GetWindow());
	return TRUE;
}

static BOOL OnResultsSheetGrid(Grid &grid, int x, int y)
{
	point pt(x,y);
	GridMenu popup(grid, pt, HGE_RESULTS_SHEET);
	popup.TrackPopupMenu(0,  x, y, GetWindow());
	return TRUE;
}

class CWksTabMenu :public Menu
{
	
public:
	
	/// EJP 2005-05-25 v8.0241 QA70-7218 NEW_MATRIX_WORKBOOK
	///CWksTabMenu(WorksheetPage &wksPage, Worksheet &wksLayer)
	CWksTabMenu(Page &wksPage, Datasheet &wksLayer)
	/// end NEW_MATRIX_WORKBOOK
	{
		m_wkBook.Init(wksPage, &wksLayer);
		
		Add(_L("&Insert"), InsertSheet);
		Add(_L("&Add"),	AddSheet); //--- CPY 7/23/04 ADD_SHEET_TO_BOOK
		/// SY 05/27/2005 v8.0244 QA70-7575 SHEET_DUPLICATE_CONTEXT_MENU
		Add(_L("Duplicate &Without Data"), DuplicateSheetNoData);
			Add(NULL, EmptySepFunc, MF_SEPARATOR);
		Add(_L("D&uplicate"), DuplicateSheet);
			Add(NULL, EmptySepFunc, MF_SEPARATOR);
		/// end SHEET_DUPLICATE_CONTEXT_MENU
		Add(_L("&Delete"), DeleteSheet);
		Add(_L("&Rename"), RenameSheet);
		Add(_L("&Move"), MoveSheet);
//---- CPY 6/28/06 CHANGE_PARAM_MENU_NO_LONGER_NEEDED		
//		if(m_wkBook.IsChangeParamAvailable())
//			Add(_L("&Change Parameters"), ChangeParams);
//----
	}
	
	void MoveSheet(uint nCmd)
	{
		m_wkBook.MoveSheet();
	}
	//--- CPY 7/23/04 ADD_SHEET_TO_BOOK
	void AddSheet(uint nCmd)
	{
		m_wkBook.AddSheet();
	}
	//---
	void InsertSheet(uint nCmd)
	{
		m_wkBook.InsertSheet();
	}
	void DeleteSheet(uint nCmd)
	{
		m_wkBook.DeleteSheet();
	}
	
	void RenameSheet(uint nCmd)
	{
		m_wkBook.RenameSheet();
	}

	void ChangeParams(uint nCmd)
	{
		m_wkBook.ChangeParam();
	}
	/// SY 05/27/2005 v8.0244 QA70-7575 SHEET_DUPLICATE_CONTEXT_MENU
	void DuplicateSheet(uint nCmd)
	{
		m_wkBook.DuplicateSheet();
	}
	
	void DuplicateSheetNoData(uint nCmd)
	{
		m_wkBook.DuplicateSheetNoData();
	}
	/// end SHEET_DUPLICATE_CONTEXT_MENU
	void	EmptySepFunc(uint nCmd)
	{
	}
	
	
private:
	//--- CPY 8/5/04 WKBOOK_CONTEXT_MENU_STANDARD_HANDLING
	//WorksheetPage 	m_wksPage;
	//Worksheet		m_wksLayer;
	WorkBookActiveSheet	m_wkBook;
	//---
	
};

/// EJP 2005-07-05 v8.0261 QA70-7769 MAT_FRAME_BUTTON_OC
#define VERT_TAB_MENU_FIRST_FRAME_CMD 6
class CMatrixVertTabMenu : public Menu
{
	
public:
	
	CMatrixVertTabMenu(Page &wksPage, Datasheet &wksLayer)
	{
		m_wkBook.Init(wksPage, &wksLayer);
		
		MatrixLayer ml = wksLayer;
		int nObjects = ml.MatrixObjects.Count();//GetObjectCount(ml);
		UINT nFlags = (nObjects > 0 ? MF_STRING : MF_GRAYED);

		Add(_L("&Insert"), Insert, nFlags);
		Add(_L("&Add"),	Add);
		Add(NULL, EmptySepFunc, MF_SEPARATOR);
		Add(_L("&Rename..."), Rename, nFlags);		
		Add(_L("&Delete"), Delete, nFlags);
		Add(NULL, EmptySepFunc, MF_SEPARATOR);

		if( 0 == nObjects )
			Add(_L("No Matrix"), EmptySepFunc, MF_GRAYED);
		else
		{
			bool bMore = false;
			if( nObjects > 9 )
			{
				nObjects = 9;
				bMore = true;
			}

			string str;
			for( int nObj = 0; nObj < nObjects; nObj++ )
			{
				//--- CPY 7/10/05 RENAME_MATRIX_OBJ
				//str.Format(_L("Frame &%d"), nObj, nObj);
				MatrixObject mo = ml.MatrixObjects(nObj);
				if(!mo)
				{
					out_int("error, invalid matrix at index = ", nObj);
					continue;
				}
				string strLongName = mo.GetLongName();
				//if(strLongName.IsEmpty())
				//	strLongName.Format("(Matrix %d)", nObj + 1);
				str.Format("&%d %s", nObj+1, strLongName);
				//---
				if( ml.GetActive() == nObj )
					Add(str, OnSelectMatrix, MF_CHECKED);
				else
					Add(str, OnSelectMatrix);
			}
			if( bMore )
				Add(_L("&More..."), More);
		}
	}
	
	void Add(uint nCmd)
	{
		m_wkBook.AddObject();
	}

	void Insert(uint nCmd)
	{
		m_wkBook.InsertObject();
	}
	void Rename(uint nCmd)
	{
		m_wkBook.RenameObject();
	}
	void Delete(uint nCmd)
	{
		m_wkBook.DeleteObject();
	}

	void EmptySepFunc(uint nCmd)
	{
	}

	void OnSelectMatrix(uint nCmd)
	{
		int nIndex = nCmd - VERT_TAB_MENU_FIRST_FRAME_CMD;
		m_wkBook.SetActiveObject(nIndex);
	}

	void More(uint nCmd)
	{
		MatrixLayer ml = m_wkBook.GetActiveDatasheet();
		if( !ml.IsValid() )
			return;

		GET_MOREMATOBJ_FUNC(pfn);
		if( !pfn )
			return;

		int nActivate = pfn(ml);
		if( nActivate >= 0 )
			m_wkBook.SetActiveObject(nActivate);
	}

protected:
	//--- CPY 7/10/05 RENAME_MATRIX_OBJ
	/*
	int GetObjectCount(MatrixLayer& ml)
	{
		int nIndex = 0;
		while( true )
		{
			MatrixObject mo(ml, nIndex);
			if( !mo )
				break;
			nIndex++
		}
		return nIndex;
	}
	*/

private:
	WorkBookActiveSheet	m_wkBook;
};
/// end MAT_FRAME_BUTTON_OC

//---- CPY 6/30/2005 QA70-7769 v8.0261 MAT_FRAME_BUTTON_OC
static BOOL OnSheetVertTabContextMenu(Page &wksPage, int x, int y, Datasheet wksMatLayer)
{
	/// EJP 2005-07-05 v8.0261 QA70-7769 MAT_FRAME_BUTTON_OC
	/*
	// temp, just call sheet context for now
	MatrixLayer mlay = wksMatLayer;
	if(mlay)
		out_str("from matrix vertical button");
	
	OnWksTabContextMenu(wksPage, x, y, wksMatLayer);
	*/
	CMatrixVertTabMenu wksMenu(wksPage, wksMatLayer);
	wksMenu.TrackPopupMenu(0,  x, y, GetWindow());
	/// end MAT_FRAME_BUTTON_OC

	return TRUE;
}
//---- end MAT_FRAME_BUTTON_OC


//--- CPY 12/1/05 QA70-8292 MAT_OBJ_PROP_DIALOG_WHEN_DBL_CLICK
static BOOL OnSheetVertTabDblClick(Page &wksPage, int x, int y, Datasheet wksMatLayer)
{
	/// YuI 08/16/07 QA70-10234 MATRIX_PROPERTIES_DIALOG_PROBLEM
	//	FUNC_INT_DWORD_LPVOID pfn = Project.FindFunction("ColumnProperties");
	FUNC_INT_DWORD_LPVOID pfn = Project.FindFunction("ColumnProperties", NULL, true);
	/// end MATRIX_PROPERTIES_DIALOG_PROBLEM
	if(pfn)
	{
		pfn(0,0,NULL);
	}

	return TRUE;
}
//---


/// EJP 2005-05-25 v8.0241 QA70-7218 NEW_MATRIX_WORKBOOK
///static BOOL OnWksTabContextMenu(WorksheetPage &wksPage, int x, int y, Worksheet wksLayer)
static BOOL OnWksTabContextMenu(Page &wksPage, int x, int y, Datasheet wksLayer)
/// end NEW_MATRIX_WORKBOOK
{
	// temp
	if(!wksPage && wksLayer)
		wksLayer.GetParent(wksPage);
		
	CWksTabMenu wksMenu(wksPage, wksLayer);
	wksMenu.TrackPopupMenu(0,  x, y, GetWindow());
	return TRUE;
}


/// ML 9/15/2004 QA70-5770 QA70-6878 ANALYSIS_MENUS_OC_HANDLING

#define		OPERATIONID_OFFSET_MASK			0xF
static	UINT	OperationIDToBaseOpID(UINT nID, int *pnOffset)
{
	UINT		nBaseOpID = nID & ~OPERATIONID_OFFSET_MASK;
	if ( pnOffset )
		*pnOffset = nID & OPERATIONID_OFFSET_MASK;
	return nBaseOpID;
}


/// ML 5/17/2005 QA70-7686 X_FUNCTION_DRIVEN_MENUS_WITH_TREE
static string make_class_option_str(LPCTSTR lpcszName, int nOption)
{
	string		strClassName = lpcszName;
	if(nOption > 0)
		strClassName += "_" + nOption;
	return strClassName;
}



static string get_class_option_str(int nBaseOpID, int* lpnOptio = NULL, string* pstrClassName = NULL)
{
	int nOption = 0;
	string		strClassName = GetOperationClassName(nBaseOpID, &nOption);
	if(pstrClassName)
		*pstrClassName = strClassName;
	
	/// ML 5/17/2005 QA70-7686 X_FUNCTION_DRIVEN_MENUS_WITH_TREE
	//if(nOption > 0)
	//	strClassName += "_" + nOption;
	strClassName = make_class_option_str(strClassName, nOption);
	/// end X_FUNCTION_DRIVEN_MENUS_WITH_TREE
	
	if(lpnOptio)
		*lpnOptio = nOption;
	
	return strClassName;
}


/// end X_FUNCTION_DRIVEN_MENUS_WITH_TREE


#define		OPERATIONID_OFFSET_OPENDIALOG	1

// ClassOperationParentMenu is the menu containing analisys-aware item. 
class ClassOperationParentMenu :public Menu
{
public:
	ClassOperationParentMenu(HMENU hMenu)
	: Menu(hMenu)
	{
	}
	
	// For the explanation of hSubMenu, see TN021 in MSDN, under the subtitle "Nested Popup Menus".
	// This function is called for every command menu item of hMenu, in which case nID is the id of the item
	// (or 0 for separator) and hSubMenu is NULL, but it is also called for subpopups of hMenu. In this case
	// hSubMenu is the handle of the subpopup, whereas nID conatins the ID of the first item in the subpopup.
	BOOL	Update(UINT nID, int nIndex, HMENU hSubMenu)
	{
		int			nIDOffset = 0;
		UINT		nBaseOpID = OperationIDToBaseOpID(nID, &nIDOffset);
		string		strClassOptionName = get_class_option_str(nBaseOpID);

		// Get all the themes for this base analysis id:
		vector<string>	vsFilenames, vsDisplayNames;
		
		/// DSC 5//23/05 MOVE_GET_CLASS_SETTINGS_TO_VC
		// int			nCountThemes = theme_get_class_settings(strClassOptionName, vsFilenames, vsDisplayNames, THTYPE_ANALYSIS, false, true);
		
		//------ Folger 03/14/08 QA80-11192 FIX_THEME_DEFAULT_MECHANISM_EXECUTE_FROM_MENU
		//int			nCountThemes = okutil_theme_get_class_settings(strClassOptionName, &vsFilenames, &vsDisplayNames, THTYPE_ANALYSIS, false, true);
		int			nCountThemes = okutil_theme_get_class_settings(strClassOptionName, &vsFilenames, &vsDisplayNames, THTYPE_ANALYSIS, theme_get_default_settings(strClassOptionName), true);
		//------
		
		///end MOVE_GET_CLASS_SETTINGS_TO_VC
		
		///Frank 1/21/05 v8.0185 ANALYSIS_GUI_SUBMENU_MAX_ITEM	
		int			nMaxThemeSubMenus=14;
		if(nCountThemes > nMaxThemeSubMenus)
			nCountThemes = nMaxThemeSubMenus;
		///End ANALYSIS_GUI_SUBMENU_MAX_ITEM	
		
		if ( nIDOffset )		// calling for an offset, i.e. "nonoriginal" command item or for subpopup
								// that contains it
		{
			if (NULL != hSubMenu) // Called for the entire subpopup
			{
				InsertSubpopup(nBaseOpID, nIndex, vsDisplayNames, nCountThemes);
			}
			// else
			// 	Called for an item inside subpopup. Here do nothing because the above case has already
			//	taken care of it.
		}
		else		// called for the original resource menu item
		{
			if (0 < nCountThemes && NULL == hSubMenu)
				InsertSubpopup(nBaseOpID, nIndex, vsDisplayNames, nCountThemes);
			else if ( NULL == hSubMenu )
			{
				// The original resource item. Just check to make sure it has dots:
				string		strItemText;
				GetMenuString(nIndex, strItemText, MF_BYPOSITION);
				if ( strItemText.GetLength() > 3 )
				{
					string		strEnding = strItemText.Right(3);
					string		strDots = "...";
					if (strDots != strEnding)
					{
						DeleteMenu(nIndex, MF_BYPOSITION);
						
						strItemText += strDots;
						InsertMenu(nIndex, MF_BYPOSITION, nID, strItemText);
					}
				}
			}
		}

		return TRUE;
	}
	
	
private:
	BOOL			InsertSubpopup(UINT nBaseOpID, int nIndex, vector<string> &vsDisplayNames, int nCount)
	{
		// Get the existing item string
		string		strItemText;
		GetMenuString(nIndex, strItemText, MF_BYPOSITION);
		
		// Remove the existing menu item:
		DeleteMenu(nIndex, MF_BYPOSITION);

		// Need to build subpopup:
		Menu		subpopup;
		subpopup.Create(TRUE);		// create an empty popup inside
	
		// First all the themes:
		for (int ii = 0; ii < nCount; ii++)
		{
			UINT		nIDNewItem = nBaseOpID + OPERATIONID_OFFSET_OPENDIALOG + ii + 1;	// +OPERATIONID_OFFSET_OPENDIALOG is reserved for  "OpenDialog..."
			string		strText;
			strText.Format("&%d %s", ii + 1, vsDisplayNames[ii]);
			subpopup.InsertMenu(-1, MF_BYPOSITION,  nIDNewItem, strText);
		}
		
		// Separator:
		if (0 < nCount)
			subpopup.InsertMenu(-1, MF_BYPOSITION | MF_SEPARATOR);

		// "Open Dialog..."
		subpopup.InsertMenu(-1, MF_BYPOSITION,  nBaseOpID + OPERATIONID_OFFSET_OPENDIALOG, _L("Open &Dialog..."));
		
		// Detach to get the handle:
		HMENU			hMenuSubPopup = subpopup.Detach();
		ASSERT( hMenuSubPopup );
		
		// Insert the subpopup:
		UINT			nIDNewItem = (UINT)hMenuSubPopup;
		InsertMenu(nIndex, MF_BYPOSITION | MF_POPUP,  nIDNewItem, strItemText);
		
		return TRUE;
	}
};

static BOOL OnClassAwareGUIUpdate(OriginObject &obj, UINT nID, int nIndex, HMENU hMenu, HMENU hSubMenu)
{
	if ( 0 == nID )
		return TRUE;
	
	ClassOperationParentMenu	menu(hMenu);
	
	return menu.Update(nID, nIndex, hSubMenu);
}

/// YuI 07/29/05 QA70-7953 XF_THEME_SUPPORT
static BOOL		_get_theme_name_from_index(LPCSTR lpcszClassOptName, int nThemeIndex, string& strThemeName)
{
	if (0 <= nThemeIndex)
	{
		vector<string>	vsFilenames;
		vector<string>	vsDisplayNames;
		//------ Folger 03/14/08 QA80-11192 FIX_THEME_DEFAULT_MECHANISM_EXECUTE_FROM_MENU
		//int nCountThemes = okutil_theme_get_class_settings(lpcszClassOptName, &vsFilenames, &vsDisplayNames, THTYPE_ANALYSIS, false, true);
		int nCountThemes = okutil_theme_get_class_settings(lpcszClassOptName, &vsFilenames, &vsDisplayNames, THTYPE_ANALYSIS, theme_get_default_settings(lpcszClassOptName), true);
		//------
		if( nThemeIndex < nCountThemes )
		{
			strThemeName = vsDisplayNames[nThemeIndex];
			return true;
		}
	}
		
	return false;
}
/// end XF_THEME_SUPPORT

/// ML 5/6/2005 QA70-7686 X_FUNCTIONS_DRIVEN_MENU_CUSTOMIZATION
/// ML 11/1/2005 QA70-8254 INVOKING_OPERATION_FROM_XFUNCTION
//static	BOOL	DoClassOpCmd(LPCSTR lpcszClassOptName, LPCSTR lpcszClassName, int nThemeIndex, int nOption = 0)
//--CPY 7/11/2007 QA70-10010 LAST_USED_THEME_WHEN_RUN_FROM_MOST_RECENT_COMMAND, added dwExecCntrl
//static	BOOL	DoClassOpCmd(LPCSTR lpcszClassOptName, LPCSTR lpcszClassName, int nThemeIndex, int nOption = 0, LPCSTR lpcszName = NULL)
/// end INVOKING_OPERATION_FROM_XFUNCTION
static	BOOL	DoClassOpCmd(LPCSTR lpcszClassOptName, LPCSTR lpcszClassName, int nThemeIndex, int nOption = 0, LPCSTR lpcszName = NULL, DWORD dwExecCntrl = 0)
{
	//------CPY 8/28/08 QA70-12878 NLFIT_TOO_SLOW_TO_OPEN
#ifdef _DEBUG
//	Profiler __junk(20);
#endif
	//------
	/// Hong 12/24/09 QA80-14832 NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
	/*
	string strThemeName;
	if( _get_theme_name_from_index(lpcszClassOptName, nThemeIndex, strThemeName) )
	{
		/// TD 11-13-2007 QA80-10683  ACCELERATORS_TO_USE_LAST_USED_IF_AVAILABLE
		//bool bOpenDlg = SHIFT_DOWN;   
		bool bOpenDlg = SHIFT_DOWN || (dwExecCntrl & LTXF_SHOW_DIALOG);   
		/// end ACCELERATORS_TO_USE_LAST_USED_IF_AVAILABLE
		/// ML 11/1/2005 QA70-8254 INVOKING_OPERATION_FROM_XFUNCTION
		//do_AU_command(lpcszClassName, bOpenDlg, strThemeName, nOption);
		///------ Folger 03/12/09 QA80-13258 SUPPORT_OPEN_DIALOG_WITH_LAST_USED_FROM_MRU
		//do_AU_command(lpcszClassName, bOpenDlg, strThemeName, nOption, NULL, lpcszName);
		return do_AU_command(lpcszClassName, bOpenDlg, strThemeName, nOption, NULL, lpcszName);
		///------ End SUPPORT_OPEN_DIALOG_WITH_LAST_USED_FROM_MRU
		/// end INVOKING_OPERATION_FROM_XFUNCTION	
	}
	else
	{
		//-------- CPY 7/11/2007 QA70-10010 LAST_USED_THEME_WHEN_RUN_FROM_MOST_RECENT_COMMAND
		if(dwExecCntrl & LTXF_FROM_MRU_MENU)
		{
			///------ Folger 03/11/09 QA80-13258 OPEN_DIALOG_FROM_MRU_WITHOUT_THEME_NAME_SHOULD_USE_DEFAULT_SETTINGS
			//strThemeName = STR_LAST_USED;
			///------ Folger 03/12/09 QA80-13258 SUPPORT_OPEN_DIALOG_WITH_LAST_USED_FROM_MRU
			//strThemeName = STR_DEFAULT;
			strThemeName = dwExecCntrl & LTXF_PREFER_LAST_USED_WITH_DIALOG ? STR_LAST_USED : STR_DEFAULT;
			///------ End SUPPORT_OPEN_DIALOG_WITH_LAST_USED_FROM_MRU
			///------ End OPEN_DIALOG_FROM_MRU_WITHOUT_THEME_NAME_SHOULD_USE_DEFAULT_SETTINGS
			///------ Folger 03/12/09 QA80-13258 SUPPORT_OPEN_DIALOG_WITH_LAST_USED_FROM_MRU
			//do_AU_command(lpcszClassName, true, strThemeName, nOption, NULL, lpcszName);
			//return true;
			return do_AU_command(lpcszClassName, true, strThemeName, nOption, NULL, lpcszName);
			///------ End SUPPORT_OPEN_DIALOG_WITH_LAST_USED_FROM_MRU
		}
		//--------

		/// ML 11/1/2005 QA70-8254 INVOKING_OPERATION_FROM_XFUNCTION
		//do_AU_command(lpcszClassName, true, NULL, nOption);
		///------ Folger 03/12/09 QA80-13258 SUPPORT_OPEN_DIALOG_WITH_LAST_USED_FROM_MRU
		//do_AU_command(lpcszClassName, true, NULL, nOption, NULL, lpcszName);
		return do_AU_command(lpcszClassName, true, NULL, nOption, NULL, lpcszName);
		///------ End SUPPORT_OPEN_DIALOG_WITH_LAST_USED_FROM_MRU
		/// end INVOKING_OPERATION_FROM_XFUNCTION
	}
	/// end XF_THEME_SUPPORT
	
	return TRUE;
	*/
	///Sophy 1/11/2010 SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
	//bool		bFromHotkey = (LTXF_FROM_HOTKEY & dwExecCntrl) ? true : false;
	///end SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
	bool 		bOpenDlg = true;
	LPCSTR		lpcszThemeName = NULL;
	string 		strThemeName;
	if ( _get_theme_name_from_index(lpcszClassOptName, nThemeIndex, strThemeName) )
	{
		lpcszThemeName = strThemeName;
		bOpenDlg = SHIFT_DOWN || (dwExecCntrl & LTXF_SHOW_DIALOG);
	}
	else if ( dwExecCntrl & LTXF_FROM_MRU_MENU )
		lpcszThemeName = dwExecCntrl & LTXF_PREFER_LAST_USED_WITH_DIALOG ? STR_LAST_USED : STR_DEFAULT;
	
	///Sophy 1/11/2010 SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
	//return do_AU_command(lpcszClassName, bOpenDlg, lpcszThemeName, nOption, NULL, lpcszName, bFromHotkey);
	return do_AU_command(lpcszClassName, bOpenDlg, lpcszThemeName, nOption, NULL, lpcszName, dwExecCntrl);
	///end SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
}
/// end X_FUNCTIONS_DRIVEN_MENU_CUSTOMIZATION


#define TIMEGAP_SEL_SAME	300 // 0.03 sec
//---- CPY QA70-7860 7/6/05 LOOSE_DATASET_EDIT_UPDATE, this is no longer used, the dialog will receive this msg
/*
static	BOOL	OnLooseDatasetChange(OriginObject &obj, int wParam, int lParam)
{
	Function fn = Project.FindFunction("LooseDatasetEdit");
	FUNC_INT_DWORD pfn = fn;
	if( pfn )
	{
		DWORD dwCntrl = wParam;
		if(!(OCD_MODIFY & dwCntrl))
			return false;
		
		pfn(OMSG_UPDATE, dwCntrl);
	}
	out_str("OnLooseDatasetChange");
	return true;
}
*/
//----

static	BOOL	OnClassAwareCommand(OriginObject &obj, UINT nID)
{
	int			nIDOffset = 0;
	UINT		nBaseOpID = OperationIDToBaseOpID(nID, &nIDOffset);
	int			nOption; 
	string		strClassName;
	string		strClassOptionName = get_class_option_str(nBaseOpID, &nOption, &strClassName);//GetOperationClassName(nBaseOpID, &nOption);
	
	if(strClassName.IsEmpty())
		return false;
	
	/// ML 5/6/2005 QA70-7686 X_FUNCTIONS_DRIVEN_MENU_CUSTOMIZATION
	/*
	if ( nIDOffset )		// if one of the themes
	{
		vector<string>	vsFilenames, vsDisplayNames;
		int			nCountThemes = theme_get_class_settings(strClassOptionName, vsFilenames, vsDisplayNames, THTYPE_ANALYSIS, false, true);
		int			nThemeIndex = nIDOffset - OPERATIONID_OFFSET_OPENDIALOG - 1;
		
		//---- CPY 9/21/04 THEME_FILE_USER_PATH_SYSTEM_PATH
		if (0 <= nThemeIndex && nThemeIndex < nCountThemes)
		{
			bool bOpenDlg = SHIFT_DOWN? true:false;
			
			string		strThemeName = vsDisplayNames[nThemeIndex];
			//printf("File=%s, Theme=%s\n", strFileName, vsDisplayNames[nThemeIndex]);
			do_AU_command(strClassName, bOpenDlg, NULL, strThemeName, nOption);
		}
		else
			do_AU_command(strClassName, true, NULL, NULL, nOption);// The default (dlg):
		//----
	}
	else
		do_AU_command(strClassName, true, NULL, NULL, nOption);
	*/
	int			nThemeIndex = nIDOffset ? nIDOffset - OPERATIONID_OFFSET_OPENDIALOG - 1 : -1;
	DoClassOpCmd(strClassOptionName, strClassName, nThemeIndex, nOption);	
	/// end X_FUNCTIONS_DRIVEN_MENU_CUSTOMIZATION
		
	return true;
}
/// end ANALYSIS_MENUS_OC_HANDLING

/// ML 5/6/2005 QA70-7686 X_FUNCTIONS_DRIVEN_MENU_CUSTOMIZATION


/// ML 5/17/2005 QA70-7686 X_FUNCTION_DRIVEN_MENUS_WITH_TREE
/*    
class XFMainMenu : public Menu
{
public:
	XFMainMenu(HMENU hMenu)
	: Menu(hMenu)
	{
	}
	
	BOOL	Update(int nCtxt)
	{
		bool			bAddAddAsTool = IDXF_USGCTXT_GRAPH_ANALYSIS == nCtxt;
		StringArray		saNames, saFiles;
		DWORD			dwUsgCtxts = nCtxt;
		IntArray		arrIds;
		int				nn = okutil_find_files(&saNames, &saFiles, SUPPORTFILE_XF, 0, &dwUsgCtxts, 1, &arrIds);
		
		for (int ii = 0; ii < nn; ii++)
		{
			UINT		nId = arrIds[ii];
			ASSERT(0 == (nId & 0xf));		// must be divisible by 16
			
			string		strText = saNames[ii];
			//InsertMenu(-1, MF_BYPOSITION,  nId, strText);
			string		strName = GetFileName(saFiles[ii], TRUE);
			
			// Need to build subpopup:
			Menu		subpopup;
			subpopup.Create(TRUE);		// create an empty popup inside
			
			// Get all the themes for this name:
			vector<string>	vsFilenames, vsDisplayNames;
			int			nCountThemes = theme_get_class_settings(strName, vsFilenames, vsDisplayNames, THTYPE_ANALYSIS, false, true);
	
			///Frank 1/21/05 v8.0185 ANALYSIS_GUI_SUBMENU_MAX_ITEM	
			int			nMaxThemeSubMenus = XFMENU_OFFSET_MAX_NUM_THEMES;			// must leave room for:
																					// 1. Add As Tool
																					// 2. Open Dialog...
			if(nCountThemes > nMaxThemeSubMenus)
				nCountThemes = nMaxThemeSubMenus;
			
			// First all the themes:
			for (int ii = 0; ii < nCountThemes; ii++)
			{
				UINT		nIDNewItem = nId + XFMENU_OFFSET_START_THEMES + ii;
				string		strText;
				strText.Format("&%d %s", ii + 1, vsDisplayNames[ii]);
				subpopup.InsertMenu(-1, MF_BYPOSITION,  nIDNewItem, strText);
			}

			if (0 < nCountThemes)
				subpopup.InsertMenu(-1, MF_BYPOSITION | MF_SEPARATOR);
			
			// "Add As Tool"
			if ( bAddAddAsTool )
				subpopup.InsertMenu(-1, MF_BYPOSITION,  nId + XFMENU_OFFSET_ADD_AS_TOOL, _L("Add As &Tool"));
			
			// "Open Dialog..."
			subpopup.InsertMenu(-1, MF_BYPOSITION,  nId + XFMENU_OFFSET_OPENDIALOG, _L("Open &Dialog..."));
			
			// Detach to get the handle:
			HMENU		hMenuSubPopup = subpopup.Detach();
			ASSERT( hMenuSubPopup );
			
			// Apend the subpopup:
			UINT			nIDNewItem = (UINT)hMenuSubPopup;
			InsertMenu(-1, MF_BYPOSITION | MF_POPUP,  nIDNewItem, strText);

		}
		
		return TRUE;
	}

};


static	BOOL	OnXFMenusGUIUpdate(OriginObject &obj, UINT nType, int nCtxt, HMENU hMenu)
{
	ASSERT(SUPPORTFILE_XF == nType);
	out_int("nCtxt = ", nCtxt);
	XFMainMenu			menu(hMenu);

	return menu.Update(nCtxt);
}
*/
/// end X_FUNCTION_DRIVEN_MENUS_WITH_TREE
static	BOOL	XFAddAsTool(LPCSTR lpcszName, LPCSTR lpszPathName)
{
	GraphLayer	grl = Project.ActiveLayer();
	if (!grl)
	{
		ASSERT(FALSE);
		return FALSE;
	}
	
	GraphObject	gr = create_rect_object(grl);
	
	gr.AttachXFunction(lpcszName);
	
	return TRUE;
}

static	BOOL	OnXFMenusCommand(OriginObject &obj, LPCSTR lpcszPathName, LPCSTR lpcszCompositeName, LPCSTR lpcszName, int nOption, int nOffset, DWORD dwCntrl, int *pnCheckStatus)
{
	DWORD dwExecute = LTXF_EXECUTE;
	if(nOption >= 0)
		dwCntrl &= ~XF_EXEC_PREFER_DIALOG;
	BOOL bClassOp = (dwCntrl & XF_EXEC_OPERATION)?true:false;
	BOOL bXFTheme = (dwCntrl & XF_EXEC_USE_THEME_IN_DIALOG)?true:false;
	if((dwCntrl & XF_EXEC_PREFER_DIALOG) || SHIFT_DOWN)
		dwExecute |= LTXF_SHOW_DIALOG;
	else if(dwCntrl & XF_EXEC_PREFER_XFBAR)
		dwExecute |= LTXF_XFBAR;
	if(dwCntrl & XF_EXEC_FROM_MRUAC)
		dwExecute |= LTXF_FROM_MRU_MENU;
	/// Hong 12/24/09 QA80-14832 NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
	if ( XF_EXEC_FROM_HOTKEY & dwCntrl )
		dwExecute |= LTXF_FROM_HOTKEY;
	/// end NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
#ifdef _DEBUG	
	_CHK_ELAPSED_TIME_START //---- CPY 12/29/08 CHK_ELAPSED_TIME_FOR_OC_DIALOG_TO_OPEN_TOO_SLOWLY
#endif
	
	//printf("OnXFMenusCommand: %s, nOption=%d, nOffsete=%d\n", lpcszName, nOption, nOffset);
	/// ML 6/28/2005 ADDING_GUI_CMD_UPDATE_FOR_XFUNCTIONS
	if (pnCheckStatus)
	{
		*pnCheckStatus = *pnCheckStatus==0?1:0;
		return true;
	}
	else if (XFMENU_OFFSET_ADD_AS_TOOL == nOffset)/// end ADDING_GUI_CMD_UPDATE_FOR_XFUNCTIONS
	{
		return XFAddAsTool(lpcszCompositeName, lpcszPathName);
	}
	else if( bClassOp || bXFTheme )
	{
		if ( XFMENU_OFFSET_OPENDIALOG == nOffset )
		{
			nOffset = -1;
			//----- CPY 8/24/2007 QA70-10231 ALLOW_THEME_TO_BE_REMEMBER_IF_USER_CHANGED_FROM_DIALOG
			dwExecute |= LTXF_FROM_MENU_OPEN_DLG;
			//-----
			///------ Folger 03/12/09 QA80-13258 SUPPORT_OPEN_DIALOG_WITH_LAST_USED_FROM_MRU
			if ( dwCntrl & XF_EXEC_PREFER_LAST_USED_WITH_DIALOG )
				dwExecute |= LTXF_PREFER_LAST_USED_WITH_DIALOG;
			///------ End SUPPORT_OPEN_DIALOG_WITH_LAST_USED_FROM_MRU
		}
		string strClassOptName = make_class_option_str(lpcszName, nOption);
		if( bClassOp )
			/// ML 11/1/2005 QA70-8254 INVOKING_OPERATION_FROM_XFUNCTION
			//return DoClassOpCmd(strClassOptName, lpcszName, nOffset, nOption);	//CPY 7/11/2007 QA70-10010 LAST_USED_THEME_WHEN_RUN_FROM_MOST_RECENT_COMMAND, added dwExecute
			return DoClassOpCmd(strClassOptName, lpcszName, nOffset, nOption, lpcszCompositeName, dwExecute);	
			/// end INVOKING_OPERATION_FROM_XFUNCTION
		else
		{
			///------ Folger 03/12/09 QA80-13258 SUPPORT_OPEN_DIALOG_WITH_LAST_USED_FROM_MRU
			//if( nOffset >= 0 )
			//{
				//string strThemeName;
				//if( _get_theme_name_from_index(strClassOptName, nOffset, strThemeName) )
					//return CallXFunctionEx(lpcszCompositeName, NULL, dwExecute, nOption, NULL, XVT_INT, strThemeName);
			//
				//return false;
			//}
			if ( nOffset >= 0 || dwExecute & LTXF_PREFER_LAST_USED_WITH_DIALOG )
			{
				string strThemeName = dwExecute & LTXF_PREFER_LAST_USED_WITH_DIALOG ? STR_LAST_USED : "";
				if ( !strThemeName.IsEmpty() || _get_theme_name_from_index(strClassOptName, nOffset, strThemeName) )
					return CallXFunctionEx(lpcszCompositeName, NULL, dwExecute, nOption, NULL, XVT_INT, strThemeName);
				
				return false;
			}
			///------ End SUPPORT_OPEN_DIALOG_WITH_LAST_USED_FROM_MRU
			else
				return CallXFunctionEx(lpcszCompositeName, NULL, dwExecute, nOption, NULL, XVT_INT);//, ""); CPY 8/5/05, Yuri had "" here, dont know why, later code only check NULL and no "" for no theme
		}
	}
	/// end XF_THEME_SUPPORT
	
	
	//CPY 5/23/05, else just run it, nOffset = 0,1,2,3 as the value in optargindex (1 offset)
	return CallXFunction(lpcszCompositeName, NULL, dwExecute, nOption);
}
/// end X_FUNCTION_DRIVEN_MENUS_WITH_TREE


/*


// Return FALSE if not handled
static	BOOL	OnHandleWksLayerCtxtMenuCommand(int nCmd, Worksheet &wks, int nSel, int c1, int c2, int r1, int r2)
{
	switch (nCmd)
	{
	case ID_WKSLAYERCTXT_SET_AS_LONG_NAME:
		wks.SetAsLabel(RCLT_LONG_NAME, -1, TRUE);
		break;
		
	case ID_WKSLAYERCTXT_SET_AS_COMMENT:
		wks.SetAsLabel(RCLT_COMMENT, -1, TRUE);
		break;
		
	case ID_WKSLAYERCTXT_APPEND_TO_COMMENT:
		wks.SetAsLabel(RCLT_COMMENT, -1, TRUE, FALSE, TRUE);
		break;
		
	case ID_WKSLAYERCTXT_SET_AS_UNITS:
		wks.SetAsLabel(RCLT_UNIT, -1, TRUE);
		break;
		
	case ID_WKSLAYERCTXT_SET_AS_PARAMETER:
		wks.SetAsLabel(RCLT_PARAM, -1, TRUE);
		break;
		
	case ID_WKSLAYERCTXT_DELETE_SELECTION:
		wks.DeleteSelection(TRUE);
		break;
		
	default:
		return FALSE;
	}
	
	return TRUE;		// handled
}



static bool OneColHeader(Worksheet &wks, int nCol, int x, int y)
{
	if(nCol >= 0 && nCol < wks.GetNumCols())
	{
		Column cc = wks.Columns(nCol);
		//printf("Col(%s) is selected\n", cc.GetName());
		string strClassName = cc.GetEventHandler(true);
		if(!strClassName.IsEmpty())
		{
			OriginEventsBase& co = (OneColHeaderHandler&)Project.FindClass(strClassName, 0);
			if(co)
			{
				//out_str("Found handler");
				return co.DoContextMenu(cc, x, y, GetWindow());
			}
		}
	}
	return false;
}
*/



/// YuI 10/20/04 QA70-7072 v7.5153 CORNER_OBJECT_FOR_NEW_WORKBOOK
// breaking function into two
/*
int load_wks_default_context_menu(Menu* pmenu, Worksheet& wks, int nSel, int nx, int ny, bool bByPos) // = 0,  = false);
{
	HINSTANCE hInstOutil = GetModuleHandle(MODULE_OU);
	if(!wks)
		return 0;
	
	int	nId = nSel;
	int nPos = nx;
	if(bByPos) // id not given, need to get from position
		nId = wks.GetMenuID(nSel, nx, ny, nPos);

	if(nId > 0)
	{
		if(pmenu->Load(hInstOutil, nId, nPos))
		{
			if(nId)
			{
				HWND hMenu = pmenu->GetSafeHmenu();
				if(hMenu)
					wks.AddInternalMenu(hMenu, nId, nPos);
					
			}
			return nId;
		}
	}
	return 0;
}
*/

BOOL load_default_context_menu(Menu* pmenu, OriginObject& wks, int nId, int nPos)
{
	if( !wks )
		return FALSE;
	if( nId <= 0 || nPos < 0 )
		return FALSE;
	
	HINSTANCE hInstOutil = GetModuleHandle(MODULE_OU);
	if( pmenu->Load(hInstOutil, nId, nPos) )
	{
		HWND hMenu = pmenu->GetSafeHmenu();
		if(hMenu)
		{
			wks.AddInternalMenu(hMenu, nId, nPos);
			return TRUE;		
		}
	}
	
	return FALSE;
}
BOOL load_default_context_menu(Menu* pmenu, OriginObject& wks, int nSel, int nx, int ny)
{
	int nPos = -1;
	int nId = wks.GetMenuID(nSel, nx, ny, nPos);
	return load_default_context_menu(pmenu, wks, nId, nPos);
}
/// end CORNER_OBJECT_FOR_NEW_WORKBOOK

/// YuI 11/29/04 V7.5158 QA70-7122 OC_DATA_PLOT_CREATION
/*
enum
{
	CCEHandleContextGeneral = 1,
	CCEHandleContextTitleBar,
	CCEHandleContextHotSpot,
	CCEHandleLaunchPropertyDilaog,
};
*/
/// end OC_DATA_PLOT_CREATION
static BOOL CallClassOnEvent(OriginObject &obj, LPCSTR lpcszDefClassName, int x, int y, DWORD dwCtrl)
{
	/// YuI 11/29/04 V7.5158 QA70-7122 OC_DATA_PLOT_CREATION
	//	return CallClassOnEventEx(obj, lpcszDefClassName, x, y, CCEHandleContextGeneral, dwCtrl);
	return CallClassOnEventEx(obj, lpcszDefClassName, x, y, OE_CONTEXTMENU, dwCtrl);
	/// end OC_DATA_PLOT_CREATION
}

static BOOL CallClassOnEventEx(OriginObject &obj, LPCSTR lpcszDefClassName, int x, int y, int nHandler, DWORD dwCtrl = 0 )
{
	if(!obj)
		return FALSE;
	string strClassName = obj.GetEventHandler(true, true);
	
	if(strClassName.IsEmpty())
	{
		if(lpcszDefClassName)
			strClassName = lpcszDefClassName;
		else
			return FALSE;
	}
	
	OriginEventsBase& wevents = (OriginEventsBase&)Project.FindClass(strClassName);
	if(wevents)
	{
		if( wevents.SetObj(obj) )
		{
			switch(nHandler)
			{
			/// YuI 11/29/04 V7.5158 QA70-7122 OC_DATA_PLOT_CREATION
			/*
			case CCEHandleContextGeneral:
				return wevents.OnContextMenu(x, y, dwCtrl);
			case CCEHandleContextTitleBar:
				return wevents.OnFrameContext(x, y);
			case CCEHandleContextHotSpot:
				return wevents.OnObjectHotSpotClick(x, y);
			case CCEHandleLaunchPropertyDilaog:
				return wevents.OnPropsDiaolog(x, y);
			*/
			
			case OE_CONTEXTMENU:
				return wevents.OnContextMenu(x, y, dwCtrl);
			case OE_ONCONTEXTMENU_WIN_TITLE_BAR:
				return wevents.OnFrameContext(x, y);
			case OE_ON_OBJECT_HOT_SPOT_CLICK:
				return wevents.OnObjectHotSpotClick(x, y);
			case OE_WORKSHEET_PROPS_DIALOG:
				return wevents.OnPropsDiaolog(x, y);
			case SN_ACTIVE_SELECTION:
				return wevents.OnSelectionChange();
			/// end OC_DATA_PLOT_CREATION
			};
		}
	}
	return FALSE;
}

/// TD 11-12-04 QA70-7027 EVENT_HANDLING_ETC_FOR_OK 
//static BOOL OnWksLayerContextMenu(Worksheet &wks, int x, int y)
//{
//	return CallClassOnEvent(wks, "LayerCmdTarget", x, y);
//}
#define		WKSPAGE_EVENT_HANDLER	"OWkBookEvents"
//static BOOL OnWksPageContextMenu(WorksheetPage &wksPage, int x, int y)
//{
//	return CallClassOnEvent(wksPage, WKSPAGE_EVENT_HANDLER, x, y);
//}
// New ID's used
#define IDR_MAINFRAME                   480
#define ID_VIEW_DOCUMENT_LINK			0X8549

static BOOL OnMDIClientContextMenu(int x, int y, DWORD dwCtrl)
{
	Menu menuFile, menuWindow, MDIClientMenu;
	HINSTANCE hInstOrigin = GetModuleHandle(MODULE_ORIGIN);
	menuFile.Load(hInstOrigin, IDR_MAINFRAME, 0);
	menuWindow.Load(hInstOrigin, IDR_WORKSHEETTYPE_V8, 10);
	for(int ii = 10; ii >= 9; ii--)
		menuFile.RemoveMenu(ii, MF_BYPOSITION);
	for(ii = 5; ii >= 2; ii--)
		menuFile.RemoveMenu(ii, MF_BYPOSITION);
	for(ii = 13; ii >= 6; ii--)
		menuWindow.RemoveMenu(ii, MF_BYPOSITION);
	menuWindow.Add("", 0, MF_SEPARATOR);
	/// ML 11/7/2007 LOCALIZATION_STUFF
	//menuWindow.Add("&Quick Help\tAlt+5", ID_VIEW_DOCUMENT_LINK, MF_STRING);
	string			strQuickHelp = _L("&Quick Help\tAlt+5");
	menuWindow.Add(strQuickHelp, ID_VIEW_DOCUMENT_LINK, MF_STRING);
	/// end LOCALIZATION_STUFF
	MDIClientMenu.AddPopup(_L("File"), menuFile);
	MDIClientMenu.AddPopup(_L("Window"), menuWindow);
	int			nCmdSelected = 0;
	if ( !MDIClientMenu.TrackPopupMenu(TPM_NOTIFY,  x, y, GetWindow(), &nCmdSelected) )	 /// TD 08-21-2008 QA80-11882 MDI_CLIENT_POPUP_MENU_HAVE_UNRESOLVED_UNUPDATED_ENTRIES (Changed Flag)
	{
		OriginObject oo;
		oo.ProcessCommand(nCmdSelected);
	}
	return TRUE;
}
static BOOL OnContext(OriginObject &oo, int x, int y, DWORD dwCtrl)
{
	//printf("OnContext(x=%d, y=%d, dwControl=%X)\n", x,y, dwCtrl);
	if(!oo)//MDI Client
	{
		return OnMDIClientContextMenu(x, y, dwCtrl);
	}
	return CallClassOnEvent(oo, NULL, x, y, dwCtrl);
}
/// end EVENT_HANDLING_ETC_FOR_OK 

static BOOL OnObjEdit(OriginObject &oo, int x, int y, DWORD dwCtrl)
{
	// should call CallClassOnEventEx, but
	// for now, just temp solution
	GraphObject go;
	go = oo;
	if(go)
	{
		int nType;
		string str = go.GetObjectType(&nType);
		int nn = go.GetIndex();
		//printf("to edit[%d]-> %s: %s(%d)\n",nn+1,  go.GetName(), str, nType);
		if(nType == GROBJ_TN_SCALER)
		{
			BOOL_FUNC_INT pfn = Project.FindFunction("ScalerPropertyEdit", NULL, true);
			if(pfn)
				pfn(nn);
		}
	}
	return true;
}

/// TD 2-11-05 QA70-7393 ON_SEL_CHANGE_OC_GLOBAL

///DSC 3/14/05 v8.0204 QA70-7500 EVENT_ORGANIZER_DLG
/*
typedef bool (*FUNC_OCEVENTS)(DataRange &dr, int nWinType); 
static void  OnWksSelectionChange(DataRange &dr)
{	
	Function fn = Project.FindFunction("OnSelChange", "OriginLab\\GlobalEvents", false, true);
	FUNC_OCEVENTS pfn = fn;
	if(pfn)
		pfn(dr, EXIST_WKS);
	
}
*/

#define STR_GLOBAL_HANDLER_FILE "OriginLab\\GlobalEvents"
///end EVENT_ORGANIZER_DLG


/// ML 3/24/2005 CONTEXT_MENU_X_FUNCS
// If nCmdId <= 0, then building the menu, otherwise executing one X-function.
bool OWksEvents::doXFuncs(Menu &menu, int nCmdId, int nSel, int r1, int c1, int r2, int c2)
{
/// EJP 2005-04-06 v8.0218 QA70-7588 GRAPHOBJ_SUPPORT_XFUNC
	return DoXFuncMenuItem(nCmdId, IDM_CM_WKS_X_FUNCS_BEGIN, IDM_CM_WKS_X_FUNCS_END, IDXF_USGCTXT_WKS_SEL, "XF_RunWksSelection");
/// end GRAPHOBJ_SUPPORT_XFUNC
}
/// end CONTEXT_MENU_X_FUNCS
/// TD 1-25-2008 QA80-10413  SET_AS_SHORT_NAMES_FOR_ROCHE_PHARMA
///Sophy 7/13/2009 v8.1063 QA80-13880 MORE_CHECK_ON_SET_COLUMN_SHORT_NAME_FROM_CELL_VALUES
enum {
	CN_SET_SN_SUCCESS = 0,
	CN_SET_ILLEGAL_SN = 0x0001,
	CN_SET_DUPLICATE_SN = 0x0002,
};
///end MORE_CHECK_ON_SET_COLUMN_SHORT_NAME_FROM_CELL_VALUES
void OWksEvents::SetSelectedAsShortName()
{
	int c1 = 0, c2 = 0, r1 = 0, r2 = 0;
	Worksheet wks = m_wks;
	wks.GetSelection(c1, c2, r1, r2);
	int numCols = wks.GetNumCols();
	string strNewName;
	
#ifndef	__CHECK_ERROR_ON_SET_SHORTNAMES__	///Sophy 7/13/2009 v8.1063 QA80-13880 MORE_CHECK_ON_SET_COLUMN_SHORT_NAME_FROM_CELL_VALUES
	UndoBlock block;
	BOOL bSuccess = TRUE;
	for(int ii = 0; ii < numCols; ii++)
	{
		if(wks.GetCell(r1, ii, strNewName))
		{
			Column col = wks.Columns(ii);
			if(col)
			bSuccess = col.SetName(strNewName, OCD_UNDO) && bSuccess;
		}
	}
	if(!bSuccess)
 		okutil_MessageBox( GetWindow(), _L("One Or More illegal Strings Found") ,_L("Warning!"), MB_OK );
	else
		wks.DeleteSelection(TRUE);
///Sophy 7/13/2009 v8.1063 QA80-13880 MORE_CHECK_ON_SET_COLUMN_SHORT_NAME_FROM_CELL_VALUES
#else	
	int	nResult = CN_SET_SN_SUCCESS;
	vector<string>	vsShortNames(numCols);
	
	//undoable block
	{
		UndoBlock	udBlock;
		for ( int iCol = 0; iCol < numCols; iCol++ )
		{
			Column col(wks, iCol);
			if ( wks.GetCell(r1, iCol, strNewName) && !col.SetName(strNewName, OCD_UNDO) )
				nResult |= CN_SET_ILLEGAL_SN;
				
			vsShortNames[iCol] = col.GetName();
		}
	}
	
	vector<int>	vnIndices;
	if ( count_list(vsShortNames, vnIndices) ) //check if exist duplicated shortnames
		nResult |= CN_SET_DUPLICATE_SN;
	
	if ( nResult & CN_SET_DUPLICATE_SN ) //error CN_SET_DUPLICATE_SN has higher priority than warning CN_SET_ILLEGAL_SN
	{
		Project.Undo(); //undo last block
		okutil_MessageBox(GetWindow(), _L("Column shortname can not be updated because there are duplicated names!"), _L("Error!"), MB_OK);
	}
	else if ( nResult & CN_SET_ILLEGAL_SN ) //warning
	{
		okutil_MessageBox(GetWindow(), _L("Some column's shortname can not be updated because it only contains one or more of following characters:\r\n%@|#^&$()_\\+-*/,<>=?`~!"), _L("Warning!"), MB_OK);
	}
	else	//success
	{
		wks.DeleteSelection(TRUE);
	}
#endif	//__CHECK_ERROR_ON_SET_SHORTNAMES__
	///end MORE_CHECK_ON_SET_COLUMN_SHORT_NAME_FROM_CELL_VALUES
	wks.Invalidate();
}
/// end SET_AS_SHORT_NAMES_FOR_ROCHE_PHARMA


//------ CPY 5/11/2007 QA70-9760 XFBAR_CONTEXT_MENU_ON_TITLE
BOOL OriginEventsBase::defaultMenu(Menu& menu, int nId, int nPos)
{
	OriginObject& obj = GetObj();
	if(obj)
		return load_default_context_menu(&menu, obj, nId, nPos);
	
	return FALSE;
}
BOOL OriginEventsBase::defaultMenu(Menu& menu, int nSelectionType, int nx, int ny)
{
	OriginObject& obj = GetObj();
	if(obj)
		return load_default_context_menu(&menu, obj, nSelectionType, nx, ny);
	
	return FALSE;
}
bool OriginEventsBase::OnFrameContext(int x, int y)
{
	Menu menu;
	HINSTANCE hInstOutil = GetModuleHandle(MODULE_OU);
	if(menu.Load(hInstOutil, IDR_CM_COMMON, ID_COMMON_TITLE))
	{
		int nCmd = 0;
		if(!ProcessMenu(menu, x, y, nCmd) && nCmd)
		{
			OriginObject& obj = GetObj();
			if(obj)
				obj.ProcessCommand(nCmd);
		}
		
		return true;
	}
	return false;
}

//------ end XFBAR_CONTEXT_MENU_ON_TITLE
	
	
	
/// EJP 2005-04-06 v8.0218 QA70-7588 GRAPHOBJ_SUPPORT_XFUNC
bool OriginEventsBase::InsertXFuncMenu(Menu& menu, int nPos, LPCSTR lpcszMenuName, int nCmdIdStart, int nCmdIdEnd, int nEvent)
{
	DWORD* pdw = NULL;
	int nNumTypes = 0;
	if( nEvent >= 0 )
	{
		pdw = &nEvent;
		nNumTypes = 1;
	}
	///DSC 8/31/05 FIND_GRAPHIC_OBJECT_X_FUNCTIONS
	/*
	// Get X-Function file names and function names
	vector<string> vsFiles, vsNames;
	int nNumFiles = okutil_find_files(&vsNames, &vsFiles, SUPPORTFILE_XF, 0, pdw, nNumTypes);
	
	if( nNumFiles <= 0 )
		return true; // No X-Functions, but not an error so return true

	// Create X-Function menu
	Menu menuSubPopup;
	int nMenuItemCount = 0;

	for( int ii = 0; ii < vsNames.GetSize(); ii++ )
	{		
		int nCmdIdAdd = nCmdIdStart + ii;
		if( nCmdIdEnd < nCmdIdAdd )
			break; // no more
		menuSubPopup.Add(vsNames[ii], nCmdIdAdd);
		nMenuItemCount++;
	}

	// If sub-menu contains items then add it to caller's menu
	if( nMenuItemCount )
	{
		menu.InsertMenu(nPos++, MF_BYPOSITION | MF_SEPARATOR);
		menu.InsertPopup(nPos++, lpcszMenuName, menuSubPopup, OC_MENURANGE_BEGIN);
	}
	return true;
	*/
	return InsertXFuncMenu(menu, nPos, lpcszMenuName, nCmdIdStart, nCmdIdEnd, pdw, nNumTypes);
	///end FIND_GRAPHIC_OBJECT_X_FUNCTIONS
	
}

///DSC 8/31/05 FIND_GRAPHIC_OBJECT_X_FUNCTIONS
bool OriginEventsBase::InsertXFuncMenuFromNames(Menu& menu, int nPos, LPCSTR lpcszMenuName, int nCmdIdStart, int nCmdIdEnd,  const StringArray& vsNames)
{	
	// Create X-Function menu
	Menu menuSubPopup;
	int nMenuItemCount = 0;
	
	for( int ii = 0; ii < vsNames.GetSize(); ii++ )
	{		
		int nCmdIdAdd = nCmdIdStart + ii;
		if( nCmdIdEnd < nCmdIdAdd )
			break; // no more
		menuSubPopup.Add(vsNames[ii], nCmdIdAdd);
		nMenuItemCount++;
	}

	// If sub-menu contains items then add it to caller's menu
	if( nMenuItemCount )
	{
		menu.InsertMenu(nPos++, MF_BYPOSITION | MF_SEPARATOR);
		menu.InsertPopup(nPos++, lpcszMenuName, menuSubPopup, OC_MENURANGE_BEGIN);
	}
	return true;
}

bool OriginEventsBase::InsertXFuncMenu(Menu& menu, int nPos, LPCSTR lpcszMenuName, int nCmdIdStart, int nCmdIdEnd, DWORD* pdw, int nNumTypes)
{
	// Get X-Function file names and function names
	vector<string> vsFiles, vsNames;
	int nNumFiles = okutil_find_files_from_map(&vsNames, &vsFiles, SUPPORTFILE_XF, 0, pdw, nNumTypes);
	
	if( nNumFiles <= 0 )
		return true; // No X-Functions, but not an error so return true

	// Create X-Function menu
	///DSC 8/31/05 FIND_GRAPHIC_OBJECT_X_FUNCTIONS
	/*
	Menu menuSubPopup;
	int nMenuItemCount = 0;

	for( int ii = 0; ii < vsNames.GetSize(); ii++ )
	{		
		int nCmdIdAdd = nCmdIdStart + ii;
		if( nCmdIdEnd < nCmdIdAdd )
			break; // no more
		menuSubPopup.Add(vsNames[ii], nCmdIdAdd);
		nMenuItemCount++;
	}

	// If sub-menu contains items then add it to caller's menu
	if( nMenuItemCount )
	{
		menu.InsertMenu(nPos++, MF_BYPOSITION | MF_SEPARATOR);
		menu.InsertPopup(nPos++, lpcszMenuName, menuSubPopup, OC_MENURANGE_BEGIN);
	}
	return true;
	*/
	return InsertXFuncMenuFromNames(menu, nPos, lpcszMenuName, nCmdIdStart, nCmdIdEnd, vsNames);
	///end FIND_GRAPHIC_OBJECT_X_FUNCTIONS
}
///end FIND_GRAPHIC_OBJECT_X_FUNCTIONS



bool OriginEventsBase::GetXFuncMenuItemName(string& strName, int nCmdId, int nCmdIdStart, int nCmdIdEnd, int nEvent)
{
	if( 0 < nCmdId && (nCmdId < nCmdIdStart || nCmdIdEnd < nCmdId) )
		return false; // nCmdId is not an X-Function

	DWORD* pdw = NULL;
	int nNumTypes = 0;
	if( nEvent >= 0 )
	{
		pdw = &nEvent;
		nNumTypes = 1;
	}
	///DSC 8/31/05 FIND_GRAPHIC_OBJECT_X_FUNCTIONS
	/*
	// Get X-Function file names and function names
	vector<string> vsFiles, vsNames;
	int nNumFiles = okutil_find_files(&vsNames, &vsFiles, SUPPORTFILE_XF, 0, pdw, nNumTypes);
	if( nNumFiles <= 0 )
		return true; // No X-Functions, but not an error so return true

	int nIndex = nCmdId - nCmdIdStart;
	if( vsFiles.GetSize() <= nIndex )
		strName.Empty();
	else
		strName = vsNames[nIndex];
	return true;
	*/
	return GetXFuncMenuItemName(strName, nCmdId, nCmdIdStart, nCmdIdEnd, pdw, nNumTypes);
	///end FIND_GRAPHIC_OBJECT_X_FUNCTIONS
}


///DSC 8/31/05 FIND_GRAPHIC_OBJECT_X_FUNCTIONS
bool OriginEventsBase::GetXFuncMenuItemNameFromCmdID(string& strName, int nCmdId, int nCmdIdStart, int nCmdIdEnd, const StringArray& vsNames)
{
	//------ Folger 12/17/07 FIX_RUNTIME_ERROR_WHEN_COMMAND_ID_LESS_EQUAL_THAN_ZERO
	if ( 0 >= nCmdId )
		return false;
	//------
	if( 0 < nCmdId && (nCmdId < nCmdIdStart || nCmdIdEnd < nCmdId) )
		return false; // nCmdId is not an X-Function
	
	int nIndex = nCmdId - nCmdIdStart;
	if( vsNames.GetSize() <= nIndex )
		strName.Empty();
	else
		strName = vsNames[nIndex];
	
	return true;

}

bool OriginEventsBase::GetXFuncMenuItemName(string& strName, int nCmdId, int nCmdIdStart, int nCmdIdEnd, DWORD* pdw, int nNumTypes)
{
	if( 0 < nCmdId && (nCmdId < nCmdIdStart || nCmdIdEnd < nCmdId) )
		return false; // nCmdId is not an X-Function

	// Get X-Function file names and function names
	vector<string> vsFiles, vsNames;
	int nNumFiles = okutil_find_files_from_map(&vsNames, &vsFiles, SUPPORTFILE_XF, 0, pdw, nNumTypes);
	if( nNumFiles <= 0 )
		return true; // No X-Functions, but not an error so return true

	return GetXFuncMenuItemNameFromCmdID(strName, nCmdId, nCmdIdStart, nCmdIdEnd, vsNames);
}
///end FIND_GRAPHIC_OBJECT_X_FUNCTIONS

bool OriginEventsBase::DoXFuncMenuItem(int nCmdId, int nCmdIdStart, int nCmdIdEnd, int nEvent, LPCSTR lpcszOCFuncName)
{
	string strName;
	if( !GetXFuncMenuItemName(strName, nCmdId, nCmdIdStart, nCmdIdEnd, nEvent) )
		return false; // nCmdId is not an X-Function menu item.
	if( strName.IsEmpty() )
		return true; // No function name, but ID is valid so return true.

	Function fn = Project.FindFunction(lpcszOCFuncName, STR_GLOBAL_HANDLER_FILE, false, true);
	FUNC_STR pfn = fn;
	if( pfn )
	{
		pfn(strName);
	}
	return true;
}

/// end GRAPHOBJ_SUPPORT_XFUNC

// return true if not likely that we must use this event for realtime calculation
static bool _is_skip_event(int nSel)
{
	static int s_nLastSel = 0;
	if(nSel < 0) // tracking, always use event
	{	//return false;
		// still subject to time diff checking, but not checking sel type change
	}
	else if(s_nLastSel != nSel)
	{
		s_nLastSel = nSel;
		return false; // change sel combination, also cannot ignore
	}
		
	static DWORD s_dwLast = 0;
	DWORD dw = GetTickCount();
	if(dw - s_dwLast < TIMEGAP_SEL_SAME)
	{
		//out_int("skip sel = ", nSel);
		return true;
	}
	/*
	
	static int s_nn = 1;
	string str1;str1.Format("%d:  not skip(%d), dt = %f sec",  s_nn++, nSel, (double)(dw - s_dwLast)/1000.0);
	SetDataDisplayText(str1);
	
	*/
	s_dwLast = dw;
	return false;
}

static BOOL OnSelectionTrackChange(OriginObject &oo, int wParam, int lParam)
{
	if(! CallClassOnEventEx(oo, NULL, wParam, lParam, SN_ACTIVE_SELECTION_TRACK))
	{
		if(_is_skip_event(-1))
			return true;
		
		Worksheet wks;
		wks = oo;
		if(wks)
		{
			DataRange dr;
			if( EXIST_WKS == Project.GetSelection(dr) )
			{
				///DSC 3/14/05 v8.0204 QA70-7500 EVENT_ORGANIZER_DLG
				// OnWksSelectionChange(dr);
				OnWksSelectionChange(dr, IDXF_USGCTXT_WKS_SEL_TRACKING);
				///end EVENT_ORGANIZER_DLG					
			}
		}
	}
	return TRUE;
}
static BOOL OnSelectionChange(OriginObject &oo, int wParam, int lParam)
{
	/*
	if(! CallClassOnEventEx(oo, NULL, wParam, lParam, SN_ACTIVE_SELECTION))
	{
		if(_is_skip_event(wParam))
			return true;
		
		Worksheet wks;
		wks = oo;
		if(wks)
		{
			DataRange dr;
			if( EXIST_WKS == Project.GetSelection(dr) )
			{
				///DSC 3/14/05 v8.0204 QA70-7500 EVENT_ORGANIZER_DLG
				// OnWksSelectionChange(dr);
				OnWksSelectionChange(dr, "OnWksSelectionChange");
				///end EVENT_ORGANIZER_DLG
			}
		}
	}
	*/

	if(_is_skip_event(wParam))
		return true;
	
	Worksheet wks;
	wks = oo;
	if(wks)
	{
		DataRange dr;
		if( EXIST_WKS == Project.GetSelection(dr) )
		{
			///DSC 3/14/05 v8.0204 QA70-7500 EVENT_ORGANIZER_DLG
			// OnWksSelectionChange(dr);
			OnWksSelectionChange(dr, IDXF_USGCTXT_WKS_SEL_CHANGE);
			///end EVENT_ORGANIZER_DLG
		}
	}

	return TRUE;
}
/// end ON_SEL_CHANGE_OC_GLOBAL


//static BOOL OnWksFrameContextMenu(WorksheetPage &wksPage, int x, int y)
static BOOL OnWksFrameContextMenu(Page &wksPage, int x, int y)
{
	/// YuI 11/29/04 V7.5158 QA70-7122 OC_DATA_PLOT_CREATION
	//	return CallClassOnEventEx(wksPage, WKSPAGE_EVENT_HANDLER, x, y, CCEHandleContextTitleBar);
	return CallClassOnEventEx(wksPage, WKSPAGE_EVENT_HANDLER, x, y, OE_ONCONTEXTMENU_WIN_TITLE_BAR);
	/// end OC_DATA_PLOT_CREATION
}
/*
static BOOL OnWksFrameContextMenu(WorksheetPage &wksPage, int x, int y)
{
	if(!wksPage)
		return FALSE;
	string strClassName = wksPage.GetEventHandler(true);
	
	if(strClassName.IsEmpty())
			strClassName = WKSPAGE_EVENT_HANDLER;
	
	OWkBookEvents& wevents = (OWkBookEvents&)Project.FindClass(strClassName);
	if(wevents)
	{
		return wevents.SetObj(wksPage) &&
				wevents.OnFrameContext(x, y);
	}
	return FALSE;
	/// YuI 10/20/04 QA70-7072 v7.5153 CORNER_OBJECT_FOR_NEW_WORKBOOK
	// CPY 10/25/04 the code above still need to be cleaned, as it is calling OnFrameContext while the rest are calling OnContext
	//return CallClassOnEvent(wksPage, WKSPAGE_EVENT_HANDLER, x, y);
	/// end CORNER_OBJECT_FOR_NEW_WORKBOOK
}
*/

//--------- CPY 9/3/04 WKBOOK_ORGANIZER
/*
static BOOL OnWksPageContextMenu(WorksheetPage &wksPage, int x, int y)
{
	HINSTANCE hInstOutil = GetModuleHandle(MODULE_OU);
	Worksheet wksLayer = wksPage.Layers();
	
	if(hInstOutil && wksPage)
	{
		int nPos = 0;
		int nId = wksPage.GetMenuID(0, x, y, nPos);//CPY 5/26/04, cannot link so fix later
		if(nId)
		{
			CWksHeaderMenu SubMenu(wksLayer);
			Menu menu(hInstOutil, nId, nPos);
			menu.AddPopup(_L("Show/Hide..."), SubMenu, OC_MENURANGE_BEGIN);
			int nCmd =	menu.TrackPopupResMenu(0,  x, y, GetWindow());
			if(SubMenu.IsHandled())
				return TRUE;
			wksPage.ProcessCommand(nCmd);//CPY 5/26/04, cannot link so fix later
			return TRUE;
		}
	}
	return FALSE;
}
*/
// other context menu without explicit ID already assume OC_MENURANGE_BEGIN, 
// so we need to start from a larger number
/*
#define IDM_CM_SHOW_WKBOOK_ORGANIZER (OC_MENURANGE_BEGIN+20)
#define IDM_CM_HIDE_WKBOOK_ORGANIZER (OC_MENURANGE_BEGIN+21)

static BOOL OnWksPageContextMenu(WorksheetPage &wksPage, int x, int y)
{
	Menu menu;
	Worksheet wks = wksPage.Layers();
	if(!wks)
		return false;

	if(!load_wks_default_context_menu(&menu, wks, IDR_CM_WKS, ID_WKS_OUTSIDE))
		return false;
			
	menu.InsertMenu(0, MF_BYPOSITION | MF_SEPARATOR);
	menu.InsertMenu(0, MF_BYPOSITION, IDM_CM_HIDE_WKBOOK_ORGANIZER, _L("Hide Organizer"));
	menu.InsertMenu(0, MF_BYPOSITION, IDM_CM_SHOW_WKBOOK_ORGANIZER, _L("Show Organizer"));

	CWksHeaderMenu SubMenu(wks);
	menu.AddPopup(_L("Show/Hide..."), SubMenu, OC_MENURANGE_BEGIN);
	int nCmd =	menu.TrackPopupResMenu(0,  x, y, GetWindow());
	if(SubMenu.IsHandled())
		return TRUE;
	if(IDM_CM_SHOW_WKBOOK_ORGANIZER == nCmd)
	{
		LT_execute("page -sps rr[WkbookSplitter]"); 
		return true;
	}
	if(IDM_CM_HIDE_WKBOOK_ORGANIZER == nCmd)
	{
		LT_execute("page -sps"); 
		return true;
	}
	wksPage.ProcessCommand(nCmd);//CPY 5/26/04, cannot link so fix later
	return true;
}
*/




/// TD 10-8-04 GETNDIALOG_TO_EDIT_WORKSHEET_PROPERTIES
static BOOL  OnWksPropsDialog(WorksheetPage &wksPage, int x, int y)
{
	///------------ CPY Jasmine 1/2/2007 QA70-9236 OC_WKS_PROP_DLG
	//	/// YuI 11/29/04 V7.5158 QA70-7122 OC_DATA_PLOT_CREATION
	//	//	return CallClassOnEventEx(wksPage, WKSPAGE_EVENT_HANDLER, x, y, CCEHandleLaunchPropertyDilaog);
	//	return CallClassOnEventEx(wksPage, WKSPAGE_EVENT_HANDLER, x, y, OE_WORKSHEET_PROPS_DIALOG);
	//	/// end OC_DATA_PLOT_CREATION
	///Folger 06/25/07 SET_AUTO_COMPILE_DEPENDENT_FILE_TO_OPEN_WKSPROPERTIESDLG
	//FUNC_INT_DWORD_LPVOID pfn = Project.FindFunction("WksPropertiesDlg");
	FUNC_INT_DWORD_LPVOID pfn = Project.FindFunction("WksPropertiesDlg", NULL, true);
	///End SET_AUTO_COMPILE_DEPENDENT_FILE_TO_OPEN_WKSPROPERTIESDLG
	if(pfn)
	{
		pfn(0, 0, NULL);
	}
	return true;
	///------------End OC_WKS_PROP_DLG

}
/*
{
	if(!wksPage)
		return FALSE;
	string strClassName = wksPage.GetEventHandler(true);
	
	if(strClassName.IsEmpty())
			strClassName = WKSPAGE_EVENT_HANDLER;
	
	OWkBookEvents& wevents = (OWkBookEvents&)Project.FindClass(strClassName);
	if(wevents)
	{
		return wevents.SetObj(wksPage) &&
				wevents.OnPropsDiaolog(x, y);
	}
	return FALSE;
}
*/
/// end GETNDIALOG_TO_EDIT_WORKSHEET_PROPERTIES

//---------

static void	ApplySystemThemeToPage(OriginObject& obj)
{
	GraphPage page;
	page = (GraphPage) obj;

	if( page )
	{
		/// RVD 10/14/2010 org-1266 SYSTEM_THEME_OVERRIDE_BROKEN_81
		//DWORD dwCntrl = LabTalk.page.cntrl;	//temporary solution
		DWORD dwCntrl = page.Cntrl;
		/// end SYSTEM_THEME_OVERRIDE_BROKEN_81
		
		if( !(dwCntrl & PPDWCNTRL_IGNORE_SYSTEM_THEME) )
		{
			string str = okutil_theme_get_system_theme_file_name(THTYPE_GRAPH);
			if( !str.IsEmpty() )
			/// ML 8/3/2007 UNNECESSARILY_UNDOABLY_APPLYING_THEME_ON_IMPORT_SPARKLINES_ETC
			//	obj.ApplyFormat(str);
			{
				// CP agrees that there is no reason to apply system theme undably.
				// And this is called, among other things, for every sparkline creation
				// (for every graoh, really).
				//obj.ApplyFormat(str, TRUE, FALSE, FALSE);
				obj.ApplyFormat(str); //CPY 8/3/07, should just call with default as before
			}
			/// end UNNECESSARILY_UNDOABLY_APPLYING_THEME_ON_IMPORT_SPARKLINES_ETC
		}
	}
}

/// YuI 10/20/04 QA70-7072 v7.5153 CORNER_OBJECT_FOR_NEW_WORKBOOK
static BOOL OnObjectHotSpotClick(OriginObject& obj, int wParam, int lParam)
/// TD 11-12-04 QA70-7027 EVENT_HANDLING_ETC_FOR_OK 
{
	/// YuI 11/29/04 V7.5158 QA70-7122 OC_DATA_PLOT_CREATION
	//	return CallClassOnEventEx(obj, "OriginEventsBase", wParam, lParam, CCEHandleContextHotSpot);
	return CallClassOnEventEx(obj, "OriginEventsBase", wParam, lParam, OE_ON_OBJECT_HOT_SPOT_CLICK);
	/// end OC_DATA_PLOT_CREATION
}
/*
{
	if( !obj )
		return FALSE;
	
	string strClassName = obj.GetEventHandler(true);
	
	if( strClassName.IsEmpty() )
		strClassName = "OriginEventsBase";
	
	OriginEventsBase& events = (OriginEventsBase&)Project.FindClass(strClassName);
	if( events )
	{
		return events.SetObj(obj) && events.OnObjectHotSpotClick(wParam, lParam);
	}
	
	return FALSE;
}
*/
/// end EVENT_HANDLING_ETC_FOR_OK 
/// end CORNER_OBJECT_FOR_NEW_WORKBOOK



///DSC 4/1/05 QA70-7500 v8.0215 GET_XF_FROM_ACCELERATOR
typedef BOOL (*PXF_FROM_ACCEL)(OriginObject &oo, int wParam, int lParam);
static BOOL OnXFAccel(OriginObject &oo, int wParam, int lParam)
{

	Function fn = Project.FindFunction("DoXFAccel", STR_GLOBAL_HANDLER_FILE, false, true);
	PXF_FROM_ACCEL pfn = fn;
	if(pfn)
		pfn(oo, wParam, lParam);

	
	return TRUE;	
	
}
///end GET_XF_FROM_ACCELERATOR
/// YuI 04/22/05 QA70-6857 OBJECT_CONNECTION_IMPLEMENTATION
typedef BOOL (*PFX_DATA_READER_EVENT)(OriginObject &oo, int wParam, int lParam);
static BOOL OnDataReaderEvent(OriginObject &oo, int wParam, int lParam)
{
	Function fn = Project.FindFunction("OnDataReaderToolEvent", STR_GLOBAL_HANDLER_FILE, false, true);
	PFX_DATA_READER_EVENT pfn = fn;
	if(pfn)
		return pfn(oo, wParam, lParam);

	return TRUE;
}
/// end OBJECT_CONNECTION_IMPLEMENTATION

//--- CPY 5/24/05 QA70-7756 GRAPH_XF_OPEN_DIALOG_BY_POST_MSG
static BOOL OnAttachedXFmsg(OriginObject &oo, int wParam, int lParam)
{
	printf("on attached XF, name = %s\n", oo.GetName());
	oo.ProcessCommand(OE_ON_ATTACHED_XF_MSG, 0, wParam, lParam);
	return true;
}
//---

static BOOL OnCreateNewGraphPageAddData(OriginObject& obj)
{
	//MessageBox(NULL, "OnCreateNewGraphPageAddData", "Event");
	ApplySystemThemeToPage(obj);
	
	//----- reminder message box to help user to use Theme
	string strTemp = okutil_theme_get_system_theme(THTYPE_GRAPH);///DSC 2/28/05
	string strMsgKey;
	if(strTemp.IsEmpty())
		strMsgKey = "ThemeNewGraph";
	else
		strMsgKey = "SystemThemeInUse";
	
	strTemp.Format("queue {type -M %s}", strMsgKey);
	LT_execute(strTemp);
	//-----
	return TRUE;
}

/// RVD 2/19/2007 QA70-9371 v8.0566 WKS_SELECTION_FILL
static BOOL	_get_subrange_by_name(DataRange& drDest, DataRange& drSource, LPCSTR lpcszName)
{
	int r1;
	int r2;
	int c1;
	int c2;
	Datasheet wks;
	if( 0 > drSource.GetRange(lpcszName, r1, c1, r2, c2, wks) )
		return FALSE;
	
	drDest.Create();
	return drDest.Add(lpcszName, wks, r1,c1,r2,c2) > 0;
}

static BOOL	OnAutoFill(OriginObject& obj)
{
	DataRange dr;
	dr = obj;

	if( dr )
	{
		//0=repeat, 1 = enumerate
		int nAction;
		if(CNTRL_DOWN)
			nAction = 0;
		else if(ALTER_DOWN)
			nAction = 1;
		else
		//---- CPY 5/22/09 QA70-12602-S3 WKS_AUTOFILL_SHOULD_BE_ON_BY_DEFAULT
		//	return true;// no not fill if user didnt hold any of these keys
			nAction = -1;// will need to convert to 1 later if drBefore is not link-embed
		//----

		/// YuI 03/19/07 QA70-9503 MERGE_SELFCREATING_RANGE_INTO_COKPOLYRANGE
		//	SelfCreatingRange drBefore;
		//	SelfCreatingRange drAfter;
		DataRange drBefore;
		DataRange drAfter;
		/// end MERGE_SELFCREATING_RANGE_INTO_COKPOLYRANGE
		
		if( _get_subrange_by_name(drBefore, dr, BEFORE_AUTOFILL) &&	_get_subrange_by_name(drAfter, dr, AFTER_AUTOFILL) )
		{
			/// YuI 05/22/09 QA70-13659 NO_AUTOFILL_IF_EMBEDDINGS_IN_BEGIN_RANGE
			if(nAction < 0)//added check, otherwise become fill random, CPY 05/22/09 QA70-13659 NO_AUTOFILL_IF_EMBEDDINGS_IN_BEGIN_RANGE
			{
				DWORD dwEbeddingLinking = okutil_check_datarange_for_embedding_linking(&drBefore);
				//----- CPY 05/22/09 QA70-13659 NO_AUTOFILL_IF_EMBEDDINGS_IN_BEGIN_RANGE
				//if(GEMSK_EMBED & dwEbeddingLinking)
				//	return FALSE;
				// need to change nAction to 1 and also check if click outside any data
				if( (GEMSK_OUTSIDE | GEMSK_EMBED) & dwEbeddingLinking )
				{
					return FALSE;
				}
				nAction = 1; // same as ALTER_DOWN
				//-----
			}
			/// end NO_AUTOFILL_IF_EMBEDDINGS_IN_BEGIN_RANGE

			XFunction xf;
			TreeNode trXF;
			bool bSkipHelpNodes = true;
			if(!xf.Load(&trXF, "wautofill", 0, true, bSkipHelpNodes, true))
				return false;

			if( !xf.SetArg("irng", drBefore) )
				return FALSE;
		
			if( !xf.SetArg("orng", drAfter) )
				return FALSE;
			
			if( !xf.SetArg("action", nAction) )
				return FALSE;
			
			return xf.Evaluate();
		}
	}

	return FALSE;
}
/// end WKS_SELECTION_FILL


/// YuI 9/19/03 v7.5700 SYSTEM_THEME_IS_NOT_APPLIED_TO_SOME_PLOTS
BOOL	ApplySystemThemeToActivePage()
{
	Page pg = Project.Pages();
	ApplySystemThemeToPage(pg);
	return TRUE;
}
/// end SYSTEM_THEME_IS_NOT_APPLIED_TO_SOME_PLOTS

static BOOL OnAfterLoadFromTemplate(OriginObject& obj)
{
	//MessageBox(NULL, "OnAfterLoadFromTemplate", "Event");
	ApplySystemThemeToPage(obj);
	return TRUE;
}

/// RVD 2/16/2005 QA70-7289 v8.0185 WKS_THEME_SUPPORT
static BOOL OnNewGrid(OriginObject& obj)
{
	/// TD 8-3-06 QA70-8843 DOWNCAST_BUG
	//Grid grid = obj;
	Grid grid;
	grid = obj;
	/// end DOWNCAST_BUG
	if(grid)
	{
		apply_system_theme(grid, THTYPE_WORKSHEET);
	}
	return TRUE;
}
/// end WKS_THEME_SUPPORT

/// RVD 4/7/2006 QA70-8609 v8.0387 TABLE_GRID_BORDERS
static BOOL	OnTableCreate(OriginObject& obj)
{
	//---- CPY 7/26/06 COPY_PASTE_TO_GRAPH_NO_NEED_FOR_THEME
	//return OnNewGrid(obj);
	return true;
	//----
}
/// end TABLE_GRID_BORDERS
//--- CPY 8/18/06 REPORT_SHEET_SHOULD_HAVE_DIFF_THEME
static BOOL	OnSetReportSheet(OriginObject& obj)
{
	Grid grid;
	grid = obj;
	if(grid)
	{
		apply_system_theme(grid, THTYPE_REPORT_TABLE);
	}
	return true;
	//----
}
//---
static BOOL OnTableEdit(OriginObject& obj)
{
	/// TD 8-3-06 QA70-8843 DOWNCAST_BUG
	//Grid grid = obj;
	Grid grid;
	grid = obj;
	/// end DOWNCAST_BUG
	if(grid)
	{
		_open_linked_wks(grid);
	}
	return true;
}
//------------
//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
//----------------------------- CPY 10/14/06 SEPARATE_OUT_OPERATION_BASE_INTO_SEPARATE_HEADER
//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////
// Called (for now) from modeless dialogs on hitting "Apply", "Compute"
// and alike.
////////////////////////////////////////////////////////////////////////////
bool	do_new_operation(const TreeNode& trNode, LPCSTR lpcszName, BOOL bTry)
{
	/// temp
	//out_str("Inside do_new_operation()");
	//return TRUE;
	///
	
	string			strPathName = "OriginLab\\";
	strPathName += lpcszName;
	strPathName += ".cpp";
	OperationBase	*op = Project.NewOperation(lpcszName, strPathName, TRUE);
	//if( NULL == op ) // If unable to create operation object...
	//{
		//out_str("No operation object created!");
		//return false;
	//}
	if(NULL == op)
		return false;

	if(FALSE == op->Init(trNode))	// it should set all inputs and outputs
	{
		Project.DeleteOperation(op, TRUE);
		return false;
	}
	
//	if (bTry)
//		op->SetShowPageInfoHeader(DBAR_NONE);

	// Exectute operation
	//BOOL			bOK = op->Execute();
	BOOL			bOK = op->Run();
	
	BOOL			bDestroy = bTry || !bOK;
//	if (FALSE == bDestroy)
//		op->UpdateHeaderInfo();
	
	Project.DeleteOperation(op, bDestroy);
	
	return bOK;
}


/// YuI 9/16/04 QA70-5770_2 OPERATION_CREATION_CLEANUP
/// ML 10/7/2004 MULTIPLE_DATASET_OPER_TREATMENT
static	BOOL	_execute_oper(OperationBase &op, int nAutoUpdate, int nExeMode)
{
	if( !op.Execute(nExeMode) )
	{
		op_destroy_on_cancel(op);
		return false;
	}

	if( AU_NONE == nAutoUpdate )
		op_destroy_on_cancel(op, false);
	else
	{
		// following not needed, trOperation.Operation.AutoUpdate.nVal = trGUI.AutoUpdate.nVal;
		//is good enough
		//op.SetAutoUpdateMode(nAutoUpdate);//---- CPY 07/24/06 QA70-8847 COLUMN_FORMULA_FROM_ORIGIN_C_REVAMP
		op.OnKeepOpAfterExecute();	//----CPY 11/10/06 NLFIT_NEW_CODE_RUNTIME_ERR_ON_CANCEL_BUTTON
		// need to clean dirtiness and untask
	}
	
	return TRUE;
}
/// end MULTIPLE_DATASET_OPER_TREATMENT



/// ML 11/1/2005 QA70-8254 INVOKING_OPERATION_FROM_XFUNCTION
//bool	do_AU_command(LPCSTR lpcszClassname, BOOL bOpenGUI, LPCSTR lpcszThemeName, int nOption, DataRange& drInput)
/// Hong 12/24/09 QA80-14832 NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
//bool	do_AU_command(LPCSTR lpcszClassname, BOOL bOpenGUI, LPCSTR lpcszThemeName, int nOption, DataRange& drInput, LPCSTR lpcszName)
///Sophy 1/11/2010 SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
//bool	do_AU_command(LPCSTR lpcszClassname, BOOL bOpenGUI, LPCSTR lpcszThemeName, int nOption, DataRange& drInput, LPCSTR lpcszName, bool bFromHotKey/* = false*/)
bool	do_AU_command(LPCSTR lpcszClassname, BOOL bOpenGUI, LPCSTR lpcszThemeName, int nOption, DataRange& drInput, LPCSTR lpcszName, DWORD dwExeCtrl/* = 0*/, DWORD dwParam /*= 0*/)
///end SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
/// end NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
/// end INVOKING_OPERATION_FROM_XFUNCTION
{
	/// ML 11/1/2005 QA70-8254 INVOKING_OPERATION_FROM_XFUNCTION
	int			nOptDef = 0;
	StringArray	saOptions, saNames;
	string		strClassName, str2;
	bool		bXFtoOpInfo = false;
	string		strSetInfoFromXF = lpcszClassname;
	if (lpcszName)
	{
		bXFtoOpInfo = okutil_xft_get_op_init_info(lpcszName, &nOptDef, &strClassName, &saOptions, &saNames, &str2);
		if (bXFtoOpInfo)
		{
			lpcszClassname = strClassName;
			/// Iris 4/24/2008 HIDE_INNER_OUTER_LIMITS_FOR_XYFIT_AND_PA
			/*
			//---- CPY 5/31/2007 QA70-9672 OP_NO_OPTION_INDEX_SHOULD_DEFAULT_TO_0
			if(nOption < 0)
				nOption = 0;
			//----
			*/
			///end HIDE_INNER_OUTER_LIMITS_FOR_XYFIT_AND_PA
		}
	}
	/// end INVOKING_OPERATION_FROM_XFUNCTION
	
	/// Iris 4/24/2008 HIDE_INNER_OUTER_LIMITS_FOR_XYFIT_AND_PA
	// if not do this, will pass -1 into op_create, but want the default is 0 for normal xy fit for NLSF.
	if(nOption < 0)
		nOption = 0;
	
	// pass fit type to nOption since want know fit type in FitNL::Construct, but fit type info added by FitNL::SetInfoFromXF below after op_create
	if (bXFtoOpInfo)
		nOption = get_fit_type(strSetInfoFromXF);
	////end HIDE_INNER_OUTER_LIMITS_FOR_XYFIT_AND_PA
	
	bool bOK;
	OperationBase& op = op_create(lpcszClassname, bOK, nOption); 
	///Iris 4/06/05 
	if(!op)
		return false;
	
	/// ML 11/1/2005 QA70-8254 INVOKING_OPERATION_FROM_XFUNCTION
	if (bXFtoOpInfo)
		op.SetInfoFromXF(nOption, strSetInfoFromXF, saOptions, saNames, str2);
	/// end INVOKING_OPERATION_FROM_XFUNCTION

	
	//---- CPY 5/19/05 XF_RUN_OP
	bool bInitInputFromDefault = true;
	if(drInput)
	{
		Tree trOp;
		op.GetTree(trOp);
		// first setup input data
		if(!drInput.GetTree(trOp.GUI.InputData, false))
			return error_report("failed to get tree from dr for Op");
		
		//prepare_input_data_for_operation(trOp.GUI.InputData);
		
		op.SetTree(trOp);
		bInitInputFromDefault = false;
	}
	//---- CPY 07/24/06 QA70-8847 COLUMN_FORMULA_FROM_ORIGIN_C_REVAMP
	//bool bAutoUpdate = false;
	int nAutoUpdate = AU_NONE;
	//----
	
	int		nExeMode;	/// Iris 02/27/2007 v8.0571 CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY
	if( bOpenGUI || !bOK )
	{
		/// Hong 12/24/09 QA80-14832 NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
		//bOK = op.Edit(FALSE, nAutoUpdate, lpcszThemeName, bInitInputFromDefault);
		///Sophy 1/11/2010 SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
		//bOK = op.Edit(FALSE, nAutoUpdate, lpcszThemeName, bInitInputFromDefault, bFromHotKey);
		bOK = op.Edit(FALSE, nAutoUpdate, lpcszThemeName, bInitInputFromDefault, dwExeCtrl, dwParam);
		///end SUPPORT_OPEN_NLFIT_FROM_QUICKFIT_CONTEXT_MENU
		/// end NLFIT_OPEN_BY_HOTKEY_SOPPORT_APPLY_SETTING_FROM_QUICKFIT_WITHOUT_ANY_THEME
		//-------- CPY 5/18/2007 QA70-9795 MENU_FROM_THEME_TO_OPEN_DIALOG
		// moved outside to share with OnNoEdit
		//if( !bOK )
		//{
		//	op_destroy_on_cancel(op);
		//	return FALSE;
		//}
		//--------
		nExeMode = OEXEM_ON_CREATE_OPEN_GUI; /// Iris 02/27/2007 v8.0571 CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY
	}
	else 
	{
		//-------- CPY 5/18/2007 QA70-9795 MENU_FROM_THEME_TO_OPEN_DIALOG
		//op.OnNoEdit(nOption, nAutoUpdate, lpcszThemeName, bInitInputFromDefault);
		bOK = op.OnNoEdit(nOption, nAutoUpdate, lpcszThemeName, bInitInputFromDefault);
		//--------
		nExeMode = OEXEM_ON_CREATE; /// Iris 02/27/2007 v8.0571 CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY
	}
	//-------- CPY 5/18/2007 QA70-9795 MENU_FROM_THEME_TO_OPEN_DIALOG
	if( !bOK )
	{
		op_destroy_on_cancel(op);
		return FALSE;
	}
	//--------
	
	///Cheney 2006-11-14 FIX_RUNTIME_ERROR_WHEN_CHOOSE_THEM_FROM_MENU
	Tree	trOp;
	op.GetTree(trOp);
	int		nOutMode = MDOUT_DEFAULT;
	int		nInMode = tree_get_oper_multidata_modes(trOp.GUI, &nOutMode);
	if (MDINPUT_INDEPENDENT_SEPARATE == nInMode)
		if(separate_report_for_multi_dataset(op, trOp, lpcszClassname, bOK, nAutoUpdate))
			return true;
	///end FIX_RUNTIME_ERROR_WHEN_CHOOSE_THEM_FROM_MENU
	
	/// ML 10/7/2004 MULTIPLE_DATASET_OPER_TREATMENT
	//if( !op.Execute() )
	//{
	//	op_destroy_on_cancel(op);
	//	return false;
	//}
	//
	//if( !bAutoUpdate )
	//	op_destroy_on_cancel(op, false);
	//else
	//{
	//	// need to clean dirtiness and untask
	//}
	//return true;
	
	/// ML 3/13/2007 QA70-9477 PROPER_OCOPERATION_CLEANUP_AFTER_EXEC
	///// Iris 02/27/2007 v8.0571 CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY
	////return _execute_oper(op, nAutoUpdate, OEXEM_ON_CREATE);
	//return _execute_oper(op, nAutoUpdate, nExeMode);
	/////end CHANGE_PARAM_TO_OPEN_DLG_FIT_BUTTON_IS_GRAY
	///// end MULTIPLE_DATASET_OPER_TREATMENT
	bool	bRet = _execute_oper(op, nAutoUpdate, nExeMode);
		
	op.Detach();	
	return bRet;
	/// end PROPER_OCOPERATION_CLEANUP_AFTER_EXEC
}

///Cheney 2006-11-14 FIX_RUNTIME_ERROR_WHEN_CHOOSE_THEM_FROM_MENU
bool	separate_report_for_multi_dataset(OperationBase& op, Tree& trOp, LPCSTR lpcszClassname, bool bOK, int nAutoUpdate)
{
	DWORD		dwRules = op.GetDataRules(trOp);
	int			nCountRanges = op_get_input_data_number(trOp.GUI, dwRules);
	if (1 < nCountRanges)		// otherwise nothing to do
	{
		op_destroy_on_cancel(op);
	
		/// Iris 03/14/2007 v8.0581 FIX_ONLY_ONE_REPORT_FOR_SEP_REPORT_SELECTED_LAST_USED_FROM_MENU
		Layer 	layInput = Project.ActiveLayer();
		Page	gpInput = layInput.GetPage();
		///end FIX_ONLY_ONE_REPORT_FOR_SEP_REPORT_SELECTED_LAST_USED_FROM_MENU
		for (int ii = 0; ii < nCountRanges; ii++)
		{
			TreeNode	trSeparate = trOp.Clone();
			TreeNode	trInputSeparate = trSeparate.GUI.InputData;
			// Need to remove all the children except the ii'th one:
			
			/// YuI 03/14/07 we actually need not to remove all except the ii'th
			// but instead copy values from ii'th to the first node only then remove 2nd and consecutive
			/*
			TreeNode	trChild = trInputSeparate.FirstNode;
			int			jj = 0;
			while( trChild.IsValid() )
			{
				if (jj == ii)
					trChild = trChild.NextNode;	// skip
				else
				{
					TreeNode	trDestroy = trChild;
					trChild = trChild.NextNode;
					trInputSeparate.RemoveChild(trDestroy);
				}
				
				jj++;
			}
			*/
			
			TreeNode trFirstChild = trInputSeparate.FirstNode;
			TreeNode trRelevantChild = trFirstChild;
			if( ii != 0 )
			{
				int jj = 0;
				while( trRelevantChild.IsValid() )
				{
					if( jj == ii )
						break;
					jj++;
					trRelevantChild = trRelevantChild.NextNode;
				}
			}
			
			if( trRelevantChild.IsValid() && ii != 0 )
			{
				trFirstChild.Replace(trRelevantChild, TRUE, TRUE);	
			}
			// now we have to remove all nodes after first child
			TreeNode trDestroy = trFirstChild.NextNode;
			while( trDestroy.IsValid() )
			{
				TreeNode trTemp = trDestroy;
				trDestroy = trDestroy.NextNode;
				trInputSeparate.RemoveChild(trTemp);
			}
			/// end YuI
			
			/// ML 11/14/2006 MUST_NOT_REUSE_DATARANGE
			if (0 < ii)
				trInputSeparate.RemoveAttribute(STR_DATARANGE_UID_ATTRIB);	// otherwise multiple operations share the same input DataRange.
			/// end MUST_NOT_REUSE_DATARANGE
			
			OperationBase		&opSeparate = op_create(lpcszClassname, bOK);
			
			//to create data range object and save its UID to trInputData's Attribute DATA_RANGE_UID
			//no need to call this function for LR, but must call it for NLFit since GetInput fail to get all input range except the first xy data
			prepare_input_data_for_operation(trSeparate.GUI.InputData, true); 
			
			//to get the related parameter values for each data set
			separate_multi_parameters_for_nlfit_operation(trSeparate, nCountRanges, ii);				
			
			opSeparate.Init(trSeparate);					
			
			_execute_oper(opSeparate, nAutoUpdate, OEXEM_ON_CREATE);
			
			/// Iris 03/14/2007 v8.0581 FIX_ONLY_ONE_REPORT_FOR_SEP_REPORT_SELECTED_LAST_USED_FROM_MENU
			// after do one report on one dataset, will active this report sheet, will result in fail to get input data in NLFitSession::UpdateInputBranch since it get data from range selection
			if(ii < nCountRanges - 1)
				page_set_active_layer(gpInput, layInput.GetIndex());
			///end FIX_ONLY_ONE_REPORT_FOR_SEP_REPORT_SELECTED_LAST_USED_FROM_MENU
			
		}
		return true;
	}
	
	return false;
}
///end FIX_RUNTIME_ERROR_WHEN_CHOOSE_THEM_FROM_MENU

/// Hong 09/19/08 QA80-12042 FIX_SEP_REPORT_PARAMS_WRONG_WHEN_CHANGE_PARAMETER
static int _remove_subnodes(TreeNode& trNode, bool bRemove, int nStartIndex, int nNum)
{
	int		nIndex = 0;
	foreach ( TreeNode trSub in trNode.Children )
	{		
		if ( nIndex < nStartIndex )
		{
			++nIndex;
			if ( !bRemove )
				trSub.Remove();
			
			continue;
		}
		if ( nNum > 0 )
		{
			--nNum;
			if ( bRemove )
				trSub.Remove();
			
			continue;
		}
		if ( bRemove )
			break;
		
		trSub.Remove();
	}
	
	return trNode.GetNodeCount();
}
/// end FIX_SEP_REPORT_PARAMS_WRONG_WHEN_CHANGE_PARAMETER

/// Iris 11/13/06 DO_TWO_TIMES_SEP_REPORT_IN_NLFIT_AND_OPBASE
bool 	separate_multi_parameters_for_nlfit_operation(TreeNode &trOp, int nCountRanges, int index)
{
	TreeNode trParams = trOp.FitWorkArea.Parameters;
	if( !trParams )
		return false;
	
	int 			nSubStart, nSubEnd = 0;
	vector<string> 	vsNames;
	vsNames = trParams.Names.strVals;	
	int nParaNum = vsNames.GetSize()/nCountRanges;
	nSubStart = index * nParaNum;
	nSubEnd = nSubStart + nParaNum -1;
	
	foreach(TreeNode trN in trParams.Children)
	{
		/// Iris 12/02/2006 v8.0518 KEEP_REAL_PARAM_NAME_FOR_MULTI_DATASET_SEP_REPORT
		//From Easwar, if don't do convert below, will use y0_2, w_2 etc as parameter names for 2nd and later datasets. 
		if(0 == lstrcmp("Names", trN.tagName))
		{
			nSubStart = 0 * nParaNum;
			nSubEnd = nSubStart + nParaNum -1;
		}
		///end KEEP_REAL_PARAM_NAME_FOR_MULTI_DATASET_SEP_REPORT
		
		switch(trN.TypeID)
		{
		case TNVAL_TYPE_CSTRING_VECTOR:
			vector<string> vs, vsTemp;
			vs = trN.strVals;
			get_sub_string_vector(vs, vsTemp, nSubStart, nSubEnd);
			trN.strVals = vsTemp;
			break;
		case TNVAL_TYPE_DOUBLE_VECTOR:
			vector vd, vdTemp;
			vd = trN.dVals;
			vd.GetSubVector(vdTemp, nSubStart, nSubEnd);
			trN.dVals = vdTemp;
			break;
		case TNVAL_TYPE_INT_VECTOR:
			vector<int> vn, vnTemp;
			vn = trN.nVals;			
			vn.GetSubVector(vnTemp, nSubStart, nSubEnd);
			trN.nVals = vnTemp;
		default:
			break;
		}
		/// Iris 3/12/2007 v8.0579 KEEP_REAL_PARAM_NAME_FOR_MULTI_DATASET_SEP_REPORT
		// Must computer back the correct start & end index 
		if(0 == lstrcmp("Names", trN.tagName))
		{
			nSubStart = index * nParaNum;
			nSubEnd = nSubStart + nParaNum -1;
		}
		///end KEEP_REAL_PARAM_NAME_FOR_MULTI_DATASET_SEP_REPORT
	}
	
	/// Hong 09/19/08 QA80-12042 FIX_SEP_REPORT_PARAMS_WRONG_WHEN_CHANGE_PARAMETER
	nSubStart = index * nParaNum;	
	ASSERT(trOp.GUI.Parameters);
	TreeNode		trGUIParams = trOp.GUI.Parameters;
	foreach ( TreeNode trSub in trGUIParams.Children )
	{
		if ( !trSub.FirstNode )
			continue;
		
		int		nNumRemained = _remove_subnodes(trSub, false, nSubStart, nParaNum);
		ASSERT( nNumRemained == nParaNum );
	}
	/// end FIX_SEP_REPORT_PARAMS_WRONG_WHEN_CHANGE_PARAMETER
	
	return true;
}
//end DO_TWO_TIMES_SEP_REPORT_IN_NLFIT_AND_OPBASE

//------- CPY 9/28/04
void op_destroy_on_cancel(OperationBase& op, bool bRestoreInputDataRange)
{
	/// YuI 05/09/07 SEPARATING_OUT_DATA_LOCK_FROM_POLYRANGES
	// code below that I comment out is the old one when when analysis markers and data
	// markers were polyranges
	// now data markers do not involve polyrange, so it will get created for the purpose of operation
	// and must always be destroyed
	/*
	if(bRestoreInputDataRange)
	{
		DataRange dr;
		op.GetInput(dr);
		if(dr)
		{
			op.RemoveInput(dr); // destructor of operation destroys range. This will prevent it
			dr.BreakUp();
		}
	}
	*/
	/// end SEPARATING_OUT_DATA_LOCK_FROM_POLYRANGES
	op.DestroyInternal();
}

bool do_operation_dlg_cancel(const TreeNode& pTree)
{
	OperationBase opb;
	opb = Project.GetObject(pTree.Operation.UID.nVal);
	if( opb )
	{
		opb.Run();
		return true;
	}
	else
	{
		ASSERT(FALSE);
		return false;
	}
}
OperationBase& op_create(LPCSTR lpcszClassName, bool& bInitOK, int nOption, LPCSTR lpcszFilename)
{
	bInitOK = false;
	string strFilename = lpcszFilename;
	if(strFilename.IsEmpty())
		strFilename.Format("Originlab\\%s.cpp", lpcszClassName);
 	OperationBase& op = (OperationBase&) Project.CreateClass(lpcszClassName, strFilename);
	if( NULL == op)
		return NULL;
	
	op.CreateInternal();
	bInitOK = op.Init(nOption);
	return op;
}

/// Iris 1/26/06 QA70-8388 INDEP_DATA_CONSOLID_OR_SEP_REPORT
int		op_get_input_data_number(TreeNode& trGUI, DWORD dwRules)
{
	TreeNode	trInputData = trGUI.InputData;
	DataRange	dr;
	dr.Create(trInputData, false);
	
	return dr.GetNumData(dwRules);
}

//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------
//----------------------------- end			 SEPARATE_OUT_OPERATION_BASE_INTO_SEPARATE_HEADER
//-------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------

bool is_dlg_ShiftShow_checked(LPCSTR lpcszDlgName, bool bDefault) // = false
{
	INIFile iniOrigin;
	string strItem = iniOrigin.ReadString("DBWINPOS", lpcszDlgName);
	if(strItem.IsEmpty())
		return bDefault;
	
	vector<string> vsVals;
	int nTokens = strItem.GetTokens(vsVals);
	int nShiftShowPos = 6;// 1 offset
	if(nTokens < nShiftShowPos)
		return bDefault;

	string strShiftShow = vsVals[nShiftShowPos-1];
	if(strShiftShow.IsEmpty() || strShiftShow.GetLength() < 1)
		return bDefault;// we had bugs that used to put junk into that last position
	
	return strShiftShow[0] == '1'? true:false;
}
//-----




bool GetNBox_on_try_operation(TreeNode& trGUI)
{
	TreeNode trOperation = trGUI.Parent();
	if(!trOperation.IsValid())
	{
		return false;
	}
	
	_DBMGS("Inside GetNBox_on_try_operation()");
	
	//Operation opObj;// = Project.GetObject(tr.Operation.UID.nVal);
	//opObj = Project.GetObject(trOperation.Operation.UID.nVal);
	//if(opObj.IsValid())
	//	opObj.GUItoOperation(trOperation, GUI_OP_TRY);
	OperationBase &operation = Project.GetOperationObject(trOperation.Operation.UID.nVal);
	if(operation.IsValid())
		operation.GUItoOperation(trOperation, GUI_OP_TRY);
	//do_run_operation(&trOperation, trOperation.Operation.AutoUpdate.nVal);
	/// ML 4/19/2004 SIMPLIFIED_TRY
	//do_run_operation(&trOperation, TRUE); //ML said should be always TRUE
	do_run_operation(&trOperation, FALSE);
	/// end SIMPLIFIED_TRY

	/// ML 4/19/2004 SIMPLIFIED_TRY
	//++trOperation.Operation.TryCount.nVal;
	/// end SIMPLIFIED_TRY
		
	return true;
}

class OC_REGISTERED GraphObjEvents : public OriginEventsBase
{
public:
	virtual bool OnContextMenu(int x, int y, DWORD dwControl = 0)
	{
		if(m_grObject)
		{
			int nPos = 0;
			int nId = m_grObject.GetMenuID(0, x, y, nPos);
			Menu menu;
			HINSTANCE hInstOutil = GetModuleHandle(MODULE_OU);
			menu.Load(hInstOutil, nId, nPos);
			m_grObject.AddInternalMenu(menu.GetSafeHmenu(), nId, nPos);
			
			///DSC 8/31/05 FIND_GRAPHIC_OBJECT_X_FUNCTIONS
			// ///DSC 8/24/05 MORE_FILTERS_FOR_XF
			// /// /// EJP 2005-04-11 v8.0220 QA70-7588 GRAPHOBJ_SUPPORT_XFUNC
			// // InsertXFuncMenu(menu, 3, _L("Attach X-Function"), IDM_CM_GROBJ_X_FUNCS_BEGIN, IDM_CM_GROBJ_X_FUNCS_END, IDXF_USGCTXT_GO);
			// // /// end GRAPHOBJ_SUPPORT_XFUNC
			Worksheet		wks = Project.ActiveLayer();
			GraphLayer		grl = Project.ActiveLayer();
			MatrixLayer		ml = Project.ActiveLayer();
						
			//"LT, Menu, AND, winType"
			// DWORD dwIDFX[4];
			// dwIDFX[0] = IDXF_USGCTXT_LABTALK;
			// dwIDFX[1] = IDXF_USGCTXT_MAIN_MENUS;
			// dwIDFX[2] = IDXF_USGCTXT_LOGICAL_AND;
			
			int nWindowType=0;
			if(wks)
				nWindowType = EXIST_WKS;
			else if(grl)
				nWindowType = EXIST_PLOT;		
			else if(ml)
				nWindowType = EXIST_MATRIX;
			else
				return false;
					
			// InsertXFuncMenu(menu, 3, _L("Attach X-Function"), IDM_CM_GROBJ_X_FUNCS_BEGIN, IDM_CM_GROBJ_X_FUNCS_END, dwIDFX, 4);
			//------CPY 7/23/08 QA70-11849 SHOULD_COMPLETELY_REMOVE_ATTACH_XFUNCTION_CONTEXT_MENU
			/*
			vector<string> vsNames;
			vector<string> vsFiles;
			okutil_find_graphic_object_xf_files(&vsNames, &vsFiles, nWindowType);
			///DSC 8/20/06 REMOVE_ATTACH_XFUNCTION_CONTEXT_MENU
			// InsertXFuncMenuFromNames(menu, 3, _L("Attach X-Function"), IDM_CM_GROBJ_X_FUNCS_BEGIN, IDM_CM_GROBJ_X_FUNCS_END, vsNames);
			///end REMOVE_ATTACH_XFUNCTION_CONTEXT_MENU
			*/
			//------end SHOULD_COMPLETELY_REMOVE_ATTACH_XFUNCTION_CONTEXT_MENU
			
			///end MORE_FILTERS_FOR_XF
			/// end FIND_GRAPHIC_OBJECT_X_FUNCTIONS

			
			int nCmd = 	menu.TrackPopupResMenu(0,  x, y, GetWindow());
			
			/// EJP 2005-04-11 v8.0220 QA70-7588 GRAPHOBJ_SUPPORT_XFUNC
			// If XFunction menu item then attach XFunction to object.
			string strName;
			vector<string> vsNames;
			///DSC 8/31/05 MORE_FILTERS_FOR_XF
			// if( GetXFuncMenuItemName(strName, nCmd, IDM_CM_GROBJ_X_FUNCS_BEGIN, IDM_CM_GROBJ_X_FUNCS_END, IDXF_USGCTXT_GO) )
			//if( GetXFuncMenuItemName(strName, nCmd, IDM_CM_GROBJ_X_FUNCS_BEGIN, IDM_CM_GROBJ_X_FUNCS_END, dwIDFX, 4) )
			if( GetXFuncMenuItemNameFromCmdID(strName, nCmd, IDM_CM_GROBJ_X_FUNCS_BEGIN, IDM_CM_GROBJ_X_FUNCS_END, vsNames) )
			///end MORE_FILTERS_FOR_XF
			{
				if( !strName.IsEmpty() )
					m_grObject.AttachXFunction(strName);
				return true;
			}
			/// end GRAPHOBJ_SUPPORT_XFUNC
			
			m_grObject.ProcessCommand(nCmd);

			return true;
		}
		return false;	
	}
	
	virtual	bool SetObj(OriginObject &obj)
	{
		m_grObject = obj;
		if(m_grObject)
			return TRUE;
		return FALSE;
	}
	
private:	
	GraphObject m_grObject; 
};

class OC_REGISTERED DataPlotEvents : public OriginEventsBase
{
public:
	virtual bool OnContextMenu(int x, int y, DWORD dwControl = 0)
	{
		//--- CPY 7/29/05 this is no longer needed as we have place holder based XF
		/*
		if(m_dpObject)
		{
			int nPos = 0;
			int nId = m_dpObject.GetMenuID(0, x, y, nPos);
			Menu menu;
			HINSTANCE hInstOutil = GetModuleHandle(MODULE_OU);
			menu.Load(hInstOutil, nId, nPos);
			m_dpObject.AddInternalMenu(menu.GetSafeHmenu(), nId, nPos);

			//Add Xfunction to Menu
			InsertXFuncMenu(menu, 1, _L("Attach X-Function"), IDM_CM_GROBJ_X_FUNCS_BEGIN, IDM_CM_GROBJ_X_FUNCS_END, IDXF_USGCTXT_GO);
			int nCmd = 	menu.TrackPopupResMenu(0,  x, y, GetWindow());
			
			string strName;
			if( GetXFuncMenuItemName(strName, nCmd, IDM_CM_GROBJ_X_FUNCS_BEGIN, IDM_CM_GROBJ_X_FUNCS_END, IDXF_USGCTXT_GO) )
			{
				if( !strName.IsEmpty() )
					MessageBox(GetWindow(), strName + " :Could not attach X-Function to DataPlot");

				return true;
			}
			m_dpObject.ProcessCommand(nCmd);
			return true;
		}
		*/
		return false;	
	}
	
	virtual	bool SetObj(OriginObject &obj)
	{
		m_dpObject = obj;
		if(m_dpObject)
			return TRUE;
		return FALSE;
	}
private:
	
	DataPlot m_dpObject; 

};

bool	get_operation_GUI_tree(LPCSTR lpcszClassName, Tree& trOpGUI, bool bLoadCurrentTheme, int nOption, bool bInitData) //=false, = 0. = false
{
	string  strClassName = lpcszClassName;
	if( strClassName.IsEmpty() )
		return	false;
	///Kyle 03/05/2009 FIX_THEME_SEPARATE_CLASS_OPTION_ERROR
	// no need to do this since okutil_theme_separate_class_option can return the option
	/////Joseph 11/04/06  LOAD_DESCSTATS_ON_COL_AND_ROW_BY_OPTION  
	//if(strClassName.Find(STR_DESCSTATS) >= 0)
	//{
		//if(strClassName.Find("_1") >= 0)
			//nOption = 1;
		//else
			//nOption = 0;
		//strClassName = STR_DESCSTATS;
	//}
	/////End LOAD_DESCSTATS_ON_COL_AND_ROW_BY_OPTION
	///End FIX_THEME_SEPARATE_CLASS_OPTION_ERROR
	string	strPath = "OriginLab\\" + strClassName;//CPY 10/25/04, no file ext will allow internal search for .cpp then .c files

	OperationBase& op = (OperationBase&) Project.CreateClass(strClassName, strPath);
	if( op != NULL )
	{
		op.CreateInternal();
		op.Init(nOption);
		TreeNode trOp;
		op.GetTree(trOp);
		if(bLoadCurrentTheme)
		{
			string strThemeName;
			/// Iris 7/27/06 CLEANUP_INIT_INPUT_SEL_CODES 
			//op.OperationtoGUI(trOp, true, &strThemeName, false);// pass in ThemeName will load internal default theme
			op.OperationtoGUI(trOp, true, &strThemeName, bInitData);// pass in ThemeName will load internal default theme
			///end CLEANUP_INIT_INPUT_SEL_CODES
		}
		else
			op.OperationtoGUI(trOp, true);
		trOpGUI = trOp.GUI;
		op.DestroyInternal();
		
		return	true;
	}
	
	error_report("get_operation_GUI_tree failed");
	return false;
}
///End SETTINGS_THEME_FILE_SAVE_LOAD

#ifdef _LAYER_CMD_TARGET //---- CPY 10/14/06 MOVE_OPERATION_OUT_OF_SYS_FOLDER	

////////////////////////////////////////////////////////////////////////////////////
/// TD 9-13-04 QA70-6376 WORKSHEET_CONTEXT_MORE_WORK
//class	LayerCmdTarget	:	public	ObjectCmdTarget
class	OC_REGISTERED LayerCmdTarget	:	public	OWksEvents
/// end WORKSHEET_CONTEXT_MORE_WORK
{
	
public:
	LayerCmdTarget()		
	{
		InitMsgMap();
	}
	
	~LayerCmdTarget()		{}

public:
	BOOL	OnButtonClick(int nRow, int nCol)
	{
		Worksheet wks;
		if( GetSender(wks) )
		{
			
			UINT uidOperation = wks.GetIncomingOperation(nRow, nCol);
			if( uidOperation )
			{
				OperationBase& op = Project.GetOperationObject(uidOperation);
				if( op )
					op.ChangeParam();
			}
		}
		
		return TRUE;
	}
protected:	
	
	BOOL InitMsgMap()
	{
		Msgmap msgMap;
		msgMap.AddOriginMsg(OE_BUTTONCLICK, OnButtonClick, VTS_I4 VTS_I4);
		m_msgmap = msgMap; 
		return TRUE;
	}
};

void instantiateCmdTarget()
{
	LayerCmdTarget clJunk;
}

#endif //#ifdef _LAYER_CMD_TARGET //---- CPY 10/14/06 MOVE_OPERATION_OUT_OF_SYS_FOLDER	


///DG CLEAN_DUPLICATE_MORE
#ifdef XF_ORGANIZER //---- CPY 12/17/05 we don't use this anymore
int		XFunctionOrganizer::OnShowMenu(TreeNode &trRow, TreeNode &trFunction, int nx, int ny, HWND hWndParent, int nRow, bool bXFDlg, bool bAdvanView)
{
	///Frank 4/4/05	Not need check here.
	//if(!IsFunction(trFunction))
		//return false;
	if(!IsPopUpMenu(trRow, bAdvanView))
		return -1;
	
	TreeNode trVars=GetVarsNode(trFunction);
	string strTemp;
	//bool bAllowDelete= trVars.GetNodeCount() > 1 && trRow && trRow.GetAttribute(STR_XF_VARIABLE_NODE_ATTRIB, strTemp);
	bool bAllowDelete = false;
	if(trVars)
		bAllowDelete = trVars.GetNodeCount() > 1 && trRow && trRow.GetAttribute(STR_XF_VARIABLE_NODE_ATTRIB, strTemp);
	
	XFControlMenu myMenu(bAllowDelete, bXFDlg);
	
	int nCmd = myMenu.DoTrackPopup(nx, ny, hWndParent, bAllowDelete);
	switch(nCmd)
	{
	case XF_MENU_ADD:
		if(!trVars)
		{
			vector<string> vsTypes = {"vector"};
			ConstructXFunction(trFunction, "", vsTypes);
			trVars=GetVarsNode(trFunction);
			trVars.V1.name.strVal = "";
		}
		else
			AddNewVar(trVars);
		//AddNewVar(trVars);
		break;
	case XF_MENU_DEL:
		trRow.Remove();
		break;
	case XF_MENU_INSERT:
		//InsertNewVar(trVars, nRow);
		InsertNewVar(trVars, trRow);
		break;
	default:
		break;
	}
	return nCmd;
}
///end CLEAN_DUPLICATE_MORE
#endif //#ifdef XF_ORGANIZER //---- CPY 12/17/05 we don't use this anymore

///Folger 04/09/07 MODIFY_ON_WKS_PRINT_OPTION
typedef BOOL (*FUNC_TRNODE_HWND) (TreeNode &trSettings, HWND hWndParent);
/// SY 2007-04-04 QA70-9575 v8.0597 PRINT_OPTIONS_FOR_WKS_PRINT
/// SY 2007-05-22 QA70-9575 v8.0624 PRINT_OPTIONS_FOR_WKS_PRINT
/*
BOOL OnWksPrintOptions(TreeNode &trSettings, HWND hWndParent)
{
	string strPath = "Originlab\\commonDlgs.c";
	FUNC_TRNODE_HWND pfn = Project.FindFunction("Wks_Print_Option", strPath);
	if (pfn)
	{
		/// SY 2007-05-21 QA70-9575 v8.0623 PRINT_OPTIONS_FOR_WKS_PRINT
		///	///Folger 05/14/07 MODIFICATION_OF_WKS_PRINT_OPTIONS
		///	Worksheet wks = Project.ActiveLayer();
		///	Tree tr;
		///	if (!wks.GetBinaryStorage("OpenFirstTime", tr))
		///	{
		///		wks.PutBinaryStorage("OpenFirstTime", tr);
		///		trSettings.Root.Print.Cntrl.nVal |= GPC_HORZ_GRIDS;
		///		trSettings.Root.Print.Cntrl.nVal |= GPC_VERT_GRIDS;
		///		trSettings.Root.Print.Cntrl.nVal |= GPC_ROW_HEADER;
		///		trSettings.Root.Print.Cntrl.nVal |= GPC_COL_HEADER;
		///		trSettings.Root.Print.Cntrl.nVal |= GPC_BACKGROUND;			
		///	}
		///	///End MODIFICATION_OF_WKS_PRINT_OPTIONS
		/// end PRINT_OPTIONS_FOR_WKS_PRINT
		return pfn(trSettings, hWndParent, FALSE);
	}
	return FALSE;
}

BOOL InitWksPrintOptions(TreeNode &trSettings)
{
	string strPath = "Originlab\\commonDlgs.c";
	FUNC_TRNODE_HWND pfn = Project.FindFunction("Wks_Print_Option", strPath);
	if( pfn )
		return pfn(trSettings, NULL, TRUE);

	return FALSE;
}
*/
BOOL OnWksPrintOptions(Datasheet& wks, HWND hWndParent)
{
	Tree trPrintOptions;
	BOOL bRet = FALSE;

	if( wks.GetPrintOptions(trPrintOptions) )
	{
		string strPath = "Originlab\\commonDlgs.c";
		FUNC_TRNODE_HWND pfn = Project.FindFunction("wks_print_option", strPath);
		if (pfn)
		{
			bRet = pfn(trPrintOptions, hWndParent);
			if( bRet )
				wks.SetPrintOptions(trPrintOptions);
		}
	}
	return bRet;
}
/// end PRINT_OPTIONS_FOR_WKS_PRINT
/// end PRINT_OPTIONS_FOR_WKS_PRINT
///End MODIFY_ON_WKS_PRINT_OPTION

/// EJP 2008-09-22 v8.0945 QA80-12020 SHOW_CMD_WINDOW_ONLY_WHEN_MAIN_VISIBLE
static BOOL IsMainWindowVisible()
{
	HWND hWndMain = GetWindow(OGW_MAIN);
	if( hWndMain )
		return IsWindowVisible(hWndMain);
	return FALSE;
}
/// end SHOW_CMD_WINDOW_ONLY_WHEN_MAIN_VISIBLE

/// TD 4-12-07 QA70-9603 OC_CONTROLLED_DIALOGBARS_AUTOLAUNCH_ON_ORIGIN_BEGIN
#define SHOW_VAL "Show"
#define SHOW_FUNCTION  "Function"
BOOL RegisterDlgBarState(LPCSTR lpcszBarFile, LPCSTR lpcszFn, BOOL bShow)
{
	/// EJP 2008-09-22 v8.0945 QA80-12020 SHOW_CMD_WINDOW_ONLY_WHEN_MAIN_VISIBLE
	if( !IsMainWindowVisible() )
		return FALSE;
	/// end SHOW_CMD_WINDOW_ONLY_WHEN_MAIN_VISIBLE

	if(!lpcszBarFile || !lpcszFn)
		return FALSE;

	Registry reg(HKEY_CURRENT_USER);
	string strKey = GetRegKey() + "\\" + KEY_OCDLGBAR + "\\" + lpcszBarFile + "\\";
	reg.SetValue(strKey, SHOW_FUNCTION, lpcszFn);
	reg.SetValue(strKey, SHOW_VAL, bShow);
	return TRUE;
}
static int LoadRegisteredBars()
{
	/// EJP 2008-09-22 v8.0945 QA80-12020 SHOW_CMD_WINDOW_ONLY_WHEN_MAIN_VISIBLE
	if( !IsMainWindowVisible() )
		return FALSE;
	/// end SHOW_CMD_WINDOW_ONLY_WHEN_MAIN_VISIBLE

	Registry reg(HKEY_CURRENT_USER);
	string strKey = GetRegKey() + "\\" + KEY_OCDLGBAR + "\\";
	StringArray saKeys;
	int nCount = reg.EnumKey(saKeys, strKey);
	DWORD dwShow = 0;
	string strFunction;
	int numLaunched = 0;
	for(int ii = 0; ii < nCount; ii++)
	{
 		/// TD 5-26-2009 QA80-9603 COMMAND_WINDOW_RESTORE_ON_START_BROKEN
		//string strSubKey = strKey + "\\" + saKeys[ii] + "\\";
		string strSubKey = strKey + saKeys[ii] + "\\";
		/// end COMMAND_WINDOW_RESTORE_ON_START_BROKEN
		if(reg.GetValue(strSubKey, SHOW_VAL, dwShow) && dwShow &&
				reg.GetValue(strSubKey, SHOW_FUNCTION, strFunction)
			) 
		{
			string strFile = "OriginLab\\" + saKeys[ii] + ".c";
			BOOL_FUNC pfnLaunch = Project.FindFunction(strFunction, strFile, true);
			if(pfnLaunch)
				pfnLaunch();
		   numLaunched++;
		}
	}
	return numLaunched;

}


static BOOL OnAftreStartupBuild(BOOL bSuccess)
{
	if(bSuccess)
		LoadRegisteredBars();
	return TRUE;
}
/// end OC_CONTROLLED_DIALOGBARS_AUTOLAUNCH_ON_ORIGIN_BEGIN
/// TD YuI 5-2-07 QA70-9576 COLUMNS_IN_MENU_WITH_NEW_DISPLAY_FORMAT
// this function is called on clicking the "Cols Dlg" entry in some interactive controls
// e.g input of Statistics On Columns, and Stats (X-Function)
///Jasmine 05/31/07 ADD_OPTION_TO_EXCLUDE_SPECIFIED_PAGE
//typedef BOOL (*FUNC_VECTOR_STR_DWORD_HWND_BOOL) (vector<string>& vsResult, DWORD dwHwnd, HWND hWnd, bool bMultipleSelect);//CPY 5/8/07
//---------Folger 07/13/07 EXCLUDE_RESULT_SHEET_IN_COLUMN_BROWSER_IS_NEEDED
//typedef BOOL (*FUNC_VECTOR_STR_DWORD_HWND_BOOL_STR) (vector<string>& vsResult, DWORD dwHwnd, HWND hWnd, bool bMultipleSelect, LPCSTR lpcszExcludeGraph);
typedef BOOL (*FUNC_VECTOR_STR_DWORD_HWND_BOOL_STR_BOOL) (vector<string>& vsResult, DWORD dwHwnd, HWND hWnd, bool bMultipleSelect, LPCSTR lpcszExcludeGraph, bool bResultSheet = false);
///Jasmine 07/17/07 SUPPORT_XY_RANGE
///Jasmine 07/20/07 USE_THE_SAME_RANGE_BROWSER
//typedef BOOL (*FUNC_VECTOR_STR_HWND_BOOL) (vector<string>& vsResult, HWND hParent, bool bMultipleSelect);
/// Kenny 09/11/2009 QA81-14241 DEFINE_VARIABLE_NEED_MORE_IMPROVEMENTS
//typedef BOOL (*FUNC_VECTOR_STR_HWND_INT_BOOL_BOOL_DWORD_STR) (vector<string>& vsResult, HWND hParent, int nPageType, bool bXYRange = false, bool bMultipleSelect = true, DWORD dwFilter = 0, LPCSTR lpcszDlg = NULL);	///Jasmine 09/28/07 FILTER_OUT_NON_IMAGE_MATRIX
typedef BOOL (*FUNC_VECTOR_STR_HWND_INT_BOOL_BOOL_DWORD_STR) (vector<string>& vsResult, HWND hParent, int nPageType, bool bXYRange = false, bool bMultipleSelect = true, DWORD dwFilter = 0, LPCSTR lpcszDlg = NULL, UINT nSelectedColUID = 0);
/// End QA81-14241 DEFINE_VARIABLE_NEED_MORE_IMPROVEMENTS
//---------Folger 07/13/07 EXCLUDE_RESULT_SHEET_IN_COLUMN_BROWSER_IS_NEEDED
// TD 5-18-07 dwCtrl may be one of the following bits defined in OC_Const.h {SCD_SINGLE_SELECTION}
/*
int  OnShowColumnsDialog(StringArray &saSelecions, HWND hWnd, DWORD dwCtrl)
{
	//BOOL ProjectBrowseColumns(vector<string>& vsResult, DWORD dwHwnd, HWND hWnd, bool bMultipleSelect = true)
	
	///Jasmine 05/08/07 QA80-9654 OPEN_COLUMN_BROWSER
	/// TD 5-23-07 UPDATE_OC_FOR_MULTISELETC
	//BOOL bMultipleSelect = true;
	bool bMultipleSelect = !(dwCtrl & SCD_SINGLE_SELECTION);
	/// end UPDATE_OC_FOR_MULTISELETC
	string strPath;
	//if((dwCtrl & SCD_SINGLE_XYRANGE) || (dwCtrl & SCD_MULTIPLE_XYRANGE))
	//{
		bMultipleSelect = bMultipleSelect || (dwCtrl & SCD_MULTIPLE_XYRANGE);
		bool bXYRange = (dwCtrl & SCD_SINGLE_XYRANGE) || (dwCtrl & SCD_MULTIPLE_XYRANGE);
		string strDlgName = bXYRange? _L("Dataset Browser") : _L("Column Browser");
		strPath = "Originlab\\RangeBrowser.c";
		//FUNC_VECTOR_STR_HWND_BOOL pfn = Project.FindFunction("RangeBrowser", strPath);
		FUNC_VECTOR_STR_HWND_INT_BOOL_BOOL_DWORD_STR pfn = Project.FindFunction("RangeBrowser", strPath);
		//if(!pfn || !pfn(saSelecions, hWnd, EXIST_WKS, bMultipleSelect))
		//------ Folger 07/31/07 RENAME_XYRANGE_BROWSER_TO_DATASET_BROWSER
		//if(!pfn || !pfn(saSelecions, hWnd, EXIST_WKS, bXYRange, bMultipleSelect, false, bXYRange? _L("XYRange Browser") : _L("Column Browser")))
		if(!pfn || !pfn(saSelecions, hWnd, EXIST_WKS, bXYRange, bMultipleSelect, SCD_NO_RESULT_SHEET, strDlgName))	///Jasmine 09/28/07 FILTER_OUT_NON_IMAGE_MATRIX
		//------ End RENAME_XYRANGE_BROWSER_TO_DATASET_BROWSER
			return 0;
		return 1;
	//}
///End SUPPORT_XY_RANGE
/*
	string strExcludePage;	
	strPath = "Originlab\\ProjectBrowser.c";
	//---------Folger 07/13/07 EXCLUDE_RESULT_SHEET_IN_COLUMN_BROWSER_IS_NEEDED
	//FUNC_VECTOR_STR_DWORD_HWND_BOOL_STR pfn = Project.FindFunction("ProjectBrowseColumns", strPath);
	FUNC_VECTOR_STR_DWORD_HWND_BOOL_STR_BOOL pfn = Project.FindFunction("ProjectBrowseColumns", strPath);
	//---------End EXCLUDE_RESULT_SHEET_IN_COLUMN_BROWSER_IS_NEEDED
	if(!pfn || !pfn(saSelecions, 0, hWnd, bMultipleSelect, strExcludePage))
///End ADD_OPTION_TO_EXCLUDE_SPECIFIED_PAGE
		return 0;
	///End OPEN_COLUMN_BROWSER
	return 1;
	*/
//}
///------ Folger 06/01/10 ORG-120 DATA_DISPLAY_DIALOG_IMPROVEMENT
//int  OnShowColumnsDialog(StringArray &saSelecions, HWND hWnd, DWORD dwCtrl)
int  OnShowColumnsDialog(StringArray &saSelecions, HWND hWnd, DWORD dwCtrl, LPCSTR lpcszBookSheetSpecified = NULL)
///------ End DATA_DISPLAY_DIALOG_IMPROVEMENT
{
	bool bMultipleSelect = !(dwCtrl & SCD_SINGLE_SELECTION);
	bool bXYRange = (dwCtrl & SCD_XYRANGE);

	///Iris 03/25/2009 QA80-13295-P3 GOTO_DLG_SUPPORT_COL_BROWSER
	/*
	string strDlgName = bXYRange? _L("Dataset Browser") : _L("Column Browser");
	string strPath = "Originlab\\RangeBrowser.c";

	FUNC_VECTOR_STR_HWND_INT_BOOL_BOOL_DWORD_STR pfn = Project.FindFunction("RangeBrowser", strPath);

	///Sophy 6/17/2008 QA80-10415 SHOULD_HIDE_BOOK_AND_SHEET_ITEM_IN_COMBOLIST_WHEN_PLOT_DATA_TYPE_IS_VECTOR
	//if(!pfn || !pfn(saSelecions, hWnd, EXIST_WKS, bXYRange, bMultipleSelect, SCD_NO_RESULT_SHEET, strDlgName))	///Jasmine 09/28/07 FILTER_OUT_NON_IMAGE_MATRIX
	if(!pfn || !pfn(saSelecions, hWnd, EXIST_WKS, bXYRange, bMultipleSelect, SCD_NO_RESULT_SHEET | (SCD_VECTOR_TYPE & dwCtrl), strDlgName))	///Jasmine 09/28/07 FILTER_OUT_NON_IMAGE_MATRIX
	///end SHOULD_HIDE_BOOK_AND_SHEET_ITEM_IN_COMBOLIST_WHEN_PLOT_DATA_TYPE_IS_VECTOR
		return 0;
	return 1;
	*/
	///------ Folger 06/01/10 ORG-120 DATA_DISPLAY_DIALOG_IMPROVEMENT
	//return open_column_browser(hWnd, saSelecions, bMultipleSelect, bXYRange);
	return open_column_browser(hWnd, saSelecions, bMultipleSelect, bXYRange, false, lpcszBookSheetSpecified);
	///------ End DATA_DISPLAY_DIALOG_IMPROVEMENT
	///end GOTO_DLG_SUPPORT_COL_BROWSER
}

///End USE_THE_SAME_RANGE_BROWSER
/// end COLUMNS_IN_MENU_WITH_NEW_DISPLAY_FORMAT
///Jasmine 08/24/07 QA80-10305 OPEN_MATRIX_BROWSER
int  OnShowMatrixBrowser(StringArray &saSelecions, HWND hWnd, DWORD dwCtrl)
{
	bool bMultipleSelect = !(dwCtrl & SCD_SINGLE_SELECTION);
	bool bXYRange = false;	
	DWORD dwFilter = (dwCtrl & SCD_IMAGE_MATRIX_ONLY)? SCD_IMAGE_MATRIX_ONLY : 0;	///Jasmine 09/28/07 FILTER_OUT_NON_IMAGE_MATRIX
	//------ Folger 10/26/07 CORRECT_NAME_SHOWN_IN_RANGE_BROWSER
	//string strDlgName = _L("Matrix Browser");
	string strDlgName = dwFilter == 0 ? _L("Matrix Browser") : _L("Image Browser");
	//------ End CORRECT_NAME_SHOWN_IN_RANGE_BROWSER
	string strPath = "Originlab\\RangeBrowser.c";
	FUNC_RANGE_BROWSER	pfn = Project.FindFunction("RangeBrowser", strPath);
	if(!pfn || !pfn(saSelecions, hWnd, EXIST_MATRIX, bXYRange, bMultipleSelect, dwFilter, strDlgName))
		return 0;
	return 1;
}
///End OPEN_MATRIX_BROWSER

///------ Folger 09/17/09 QA80-10305 MATRIX_BROWSER_NEEDED_IN_BOTH_XF_AND_MATRIX_FIT_DIALOG
int  OnShowMatrixBrowser(string &strMatrix, HWND hWndParent, DWORD dwCtrl)
{
	StringArray saSelecions; 
	saSelecions.Add(strMatrix);
	dwCtrl |= SCD_SINGLE_SELECTION;
	int nRet = OnShowMatrixBrowser(saSelecions, hWndParent, dwCtrl);
	if(saSelecions.GetSize() > 0)
		strMatrix = saSelecions[0];

	return nRet;
}
///------ End MATRIX_BROWSER_NEEDED_IN_BOTH_XF_AND_MATRIX_FIT_DIALOG

/// TD 09-04-2007 QA80-10305 IMAGE_BROWSER
int  OnShowImageBrowser(string &strImage, HWND hWndParent, DWORD dwCtrl)
{
	// For now I am hooking this up to OnShowMatrixBrowser, so user have some choice, but a subset of Images is a subset of All matrix objects
	StringArray saSelecions; 
	saSelecions.Add(strImage);
	dwCtrl |= SCD_SINGLE_SELECTION | SCD_IMAGE_MATRIX_ONLY;	///Jasmine 09/28/07 FILTER_OUT_NON_IMAGE_MATRIX
	int nRet = OnShowMatrixBrowser(saSelecions, hWndParent, dwCtrl);
	if(saSelecions.GetSize() > 0)
		strImage = saSelecions[0];

	return nRet;
}
/// end IMAGE_BROWSER


/// TD 09-17-2007 QA80-10392  UPDATE_PATH_FOR_PROJECT_FOLDER_ENTRIES
#define NODE_ROOT			"RootFolder"
#define RELATIVE_PATH		"RelativeFolder"
enum
{
	FOLDER_NONE,
	FOLDER_USER,
	FOLDER_GROUP,
	FOLDER_SYSTEM,
	FOLDER_ABSOLUTE
};
/*
static bool _isSubPath(string strRoot, string strPath)
{
	if(strPath.IsEmpty())
		return false;
	strRoot.MakeUpper();
	strPath.MakeUpper();
	
	return 0 == strPath.Find(strRoot);
}
*/
static void _updateNodeWithRootId(int nRootId, TreeNode node, BOOL bResetPath = FALSE)
{
	string strRootFolder;
	switch(nRootId)
	{
	case FOLDER_NONE:
			node.Enable = DISABLE;
			break;
	case FOLDER_USER:
	case FOLDER_GROUP:
	case FOLDER_SYSTEM:
			strRootFolder = okutil_get_origin_path(nRootId + ORIGIN_PATH_USER - FOLDER_USER);
	case FOLDER_ABSOLUTE:
			node.SetAttribute(STR_ATTRIB_ROOT_FOLDER, strRootFolder);
			node.Enable = ENABLE;
			if(bResetPath)
				node.strVal = strRootFolder;
			break;
	}
}

static bool _onOptionChange(TreeNode& tr, int nRow, int nCntrlType, Dialog& getNDlg)
{
	if(ONODETYPE_RADIOS_BY_INDEX != nCntrlType || nRow < 0)
		return false;
	 int nRootId = tr.RootFolder.nVal;
	 TreeNode tnPath = tr.RelativeFolder;
	 _updateNodeWithRootId(nRootId, tnPath, nRow >= 0);
	 return true;
}

BOOL OnOCFileInfo(TreeNode &nodeInfo, DWORD dwCtrl)
{
	int nRoot = FOLDER_NONE;
	string strRelative;
	TreeNode tnRoot = nodeInfo.GetNode(NODE_ROOT);
	TreeNode tnRelative = nodeInfo.GetNode(RELATIVE_PATH);
	if(tnRoot)
	{
		nRoot = tnRoot.nVal;
		nRoot -= ORIGIN_PATH_USER- FOLDER_USER;
		if(nRoot < FOLDER_USER || nRoot > FOLDER_SYSTEM)
			nRoot = FOLDER_ABSOLUTE;
	}
	if(tnRelative)
		strRelative = tnRelative.strVal;


 	GETN_TREE(trGetN);
	GETN_RADIO_INDEX(RootFolder, nRoot, _L("None|Relative to User Folder|Relative to Group Folder|Relative to Sytem Folder|Absolute Path"))	TREE_ADD_LABEL(_L("Root Folder")); 
	GETN_BUTTON(RelativeFolder, _L("Folder Path"), strRelative)
		GETN_STR_COMBO("...PATH"); _updateNodeWithRootId(nRoot, _tmpSubNode);

   if(GetNBox(trGetN, _L("Choose Update Path"), NULL, NULL, _onOptionChange))
   {
   		nRoot = trGetN.RootFolder.nVal;
		if(FOLDER_NONE == nRoot)
		{
			if(tnRoot || tnRelative)
			{
				nodeInfo.RemoveChild(NODE_ROOT);
				nodeInfo.RemoveChild(RELATIVE_PATH);
				return TRUE;
			}
			return FALSE;

		}
   		else if(nRoot < FOLDER_ABSOLUTE)
   			nRoot += ORIGIN_PATH_USER - FOLDER_USER;
   		else
   			nRoot = ORIGIN_PATH_UNDEF;
   		nodeInfo.RootFolder.nVal = nRoot;
   		nodeInfo.RelativeFolder.strVal = trGetN.RelativeFolder.strVal;
   		return TRUE;
   }

   return FALSE;
}
/// end UPDATE_PATH_FOR_PROJECT_FOLDER_ENTRIES

///------ Folger 06/29/09 QA80-12954-P2 PEAK_FITTING_DIALOG_OF_NLFIT_FAILS_TO_BE_BROUGHT_UP_BY_LABTALK
static	BOOL	_is_op_invoked_by_xf(LPCSTR lpcszClassName)
{
	return okutil_xft_get_op_init_info(lpcszClassName, NULL, NULL, NULL, NULL) ? TRUE : FALSE;
}
///------ End PEAK_FITTING_DIALOG_OF_NLFIT_FAILS_TO_BE_BROUGHT_UP_BY_LABTALK

//---- CPY EJP 2009-10-27 QA81-14534 USE_OC_GETN_FROM_LT
enum {
	LTGetNCtrl_Unknown,
	LTGetNCtrl_Edit, LTGetNCtrl_Combo, LTGetNCtrl_Check,
	LTGetNCtrl_BranchBegin, LTGetNCtrl_BranchEnd,
	LTGetNCtrl_BasicColorList,
	LTGetNCtrl_FontList, LTGetNCtrl_FontSizeList,
	LTGetNCtrl_SymbolList, LTGetNCtrl_SymbolSizeList,
	LTGetNCtrl_BrowseButton,
};
enum {LTGetNVar_Numeric, LTGetNVar_String, LTGetNVar_StringSub,};

static char STR_LTGETN_VARTYPE[] = "LTGetNVarType";
static char STR_LTGETN_CHECK_HIDESHOW[] = "LTGetNHideShow";
static char STR_LTGETN_CHECK_HIDESHOW_COUNT[] = "LTGetNHideShowCount";

#define SGETN_CHECK(_STR_NAME, _NODE_LABEL, _DEFAULT_VAL, _VARTYPE) \
	_tmpSubNode = _tmpNode.AddNumericNode((int)_DEFAULT_VAL, _STR_NAME, TRGP_CHECK);TREE_ADD_LABEL(_NODE_LABEL); \
	_tmpSubNode.SetAttribute(STR_LTGETN_VARTYPE, _VARTYPE)
#define SGETN_CHECK_HIDESHOW(_OPTION1, _OPTION2) \
	if(_OPTION1) _tmpSubNode.SetAttribute(STR_LTGETN_CHECK_HIDESHOW, _OPTION1); \
	if(_OPTION2) _tmpSubNode.SetAttribute(STR_LTGETN_CHECK_HIDESHOW_COUNT, _OPTION2)
#define IS_SHOW_CONTROLS_ON_CHECKED(_HIDESHOW) ('s'==(_HIDESHOW))

#define SGETN_STR(_STR_NAME, _NODE_LABEL, _DEFAULT_VAL, _VARTYPE) \
	_tmpSubNode = _tmpNode.AddTextNode(_DEFAULT_VAL, _STR_NAME, TRGP_STR);TREE_ADD_LABEL(_NODE_LABEL); \
	_tmpSubNode.SetAttribute(STR_LTGETN_VARTYPE, _VARTYPE)

///------ Folger 11/10/09 QA81-14534-P4 BETTER_TITLE_AND_NUMERIC_DISLPLAY_FOR_USING_OC_GETN_FROM_LT
#define SGETN_NUM(_STR_NAME, _NODE_LABEL, _DEFAULT_VAL, _VARTYPE) \
		GETN_CURRENT_SUBNODE = GETN_CURRENT_NODE.AddNumericNode(_DEFAULT_VAL, _STR_NAME, TRGP_DOUBLE); \
		TREE_ADD_LABEL(_NODE_LABEL); \
		GETN_CURRENT_SUBNODE.SetAttribute(STR_LTGETN_VARTYPE, _VARTYPE) \
		
///------ End BETTER_TITLE_AND_NUMERIC_DISLPLAY_FOR_USING_OC_GETN_FROM_LT

/// Kenny 11/02/2009 QA81-14534 FIX_LT_OPEN_OC_GETNBOX_COMBO_INIT_ISSUE
// #define SGETN_COMBO(_STR_NAME, _NODE_LABEL, _DEFAULT_VAL, _COMBO_STR, _VARTYPE) \
// 	_tmpSubNode = _tmpNode.AddTextNode(_DEFAULT_VAL, _STR_NAME, TRGP_NUMERIC_LIST); \
// 	TREE_ADD_LABEL(_NODE_LABEL); \
// 	_tmpSubNode.SetAttribute(STR_COMBO_ATTRIB, _COMBO_STR); \
// 	_tmpSubNode.SetAttribute(STR_LTGETN_VARTYPE, _VARTYPE)
#define SGETN_COMBO(_STR_NAME, _NODE_LABEL, _DEFAULT_VAL, _COMBO_STR, _VARTYPE) \
	_tmpSubNode = _tmpNode.AddNumericNode((int)_DEFAULT_VAL, _STR_NAME, TRGP_ENUM_LIST); \
	TREE_ADD_LABEL(_NODE_LABEL); \
	_tmpSubNode.SetAttribute(STR_COMBO_ATTRIB, _COMBO_STR); \
	_tmpSubNode.SetAttribute(STR_LTGETN_VARTYPE, _VARTYPE)
/// End QA81-14534 FIX_LT_OPEN_OC_GETNBOX_COMBO_INIT_ISSUE

#define LTGetNMaxBranches	10
#define LTGetNTempStrLen	300

#define SGETN_INIT_BRANCH \
	int nBranches = 0

#define SGETN_BEGIN_BRANCH(_STR_NAME, _NODE_LABEL, _SHOW_OPEN) \
	if( nBranches < LTGetNMaxBranches ) \
	{ \
		_tmpSubNode = _tmpNode.AddNode(_STR_NAME, TRGP_BRANCH); \
		TREE_ADD_LABEL(_NODE_LABEL); \
		_tmpNode = _tmpSubNode; \
		if( _SHOW_OPEN ) {GETN_OPTION_BRANCH(GETNBRANCH_OPEN);} \
	} \
	nBranches++

#define SGETN_END_BRANCH(_STR_NAME) \
	nBranches--; \
	if( nBranches < LTGetNMaxBranches ) \
		_tmpNode = _tmpNode.Parent()

#define SGETN_COLOR(_STR_NAME, _NODE_LABEL, _DEFAULT_VAL, _VARTYPE) \
	_tmpSubNode = _tmpNode.AddNumericNode(_DEFAULT_VAL, _STR_NAME, TRGP_COLOR); \
	TREE_ADD_LABEL(_NODE_LABEL); _tmpSubNode.SetAttribute(STR_LTGETN_VARTYPE, _VARTYPE)

#define SGETN_FONT(_STR_NAME, _NODE_LABEL, _DEFAULT_VAL, _VARTYPE) \
	_tmpSubNode = _tmpNode.AddNumericNode(_DEFAULT_VAL, _STR_NAME, ONODETYPE_DROPLIST_FONTS); \
	TREE_ADD_LABEL(_NODE_LABEL); _tmpSubNode.SetAttribute(STR_LTGETN_VARTYPE, _VARTYPE)

#define SGETN_SYMBOL(_STR_NAME, _NODE_LABEL, _DEFAULT_VAL, _VARTYPE) \
	_tmpSubNode = _tmpNode.AddNumericNode((int)_DEFAULT_VAL, _STR_NAME, TRGP_SYMBOL); \
	TREE_ADD_LABEL(_NODE_LABEL); _tmpSubNode.SetAttribute(STR_LTGETN_VARTYPE, _VARTYPE)

/// EJP 2009-11-17 QA81-14534 LTGETN_SUPPORT_BROWSE_FOR_FILE
#define SGETN_BUTTON_EX(_STR_NAME, _NODE_LABEL, _DEFAULT_VAL, _STR_COMBO, _VARTYPE) \
	_tmpSubNode = _tmpNode.AddTextNode(_DEFAULT_VAL, _STR_NAME, TRGP_STR_BUTTON); \
	TREE_ADD_LABEL(_NODE_LABEL); \
	_tmpSubNode.SetAttribute(STR_COMBO_ATTRIB, _STR_COMBO); \
	_tmpSubNode.SetAttribute(STR_LTGETN_VARTYPE, _VARTYPE)
/// end LTGETN_SUPPORT_BROWSE_FOR_FILE

///---Sim 12-07-2009 QA81-14641 LT_GETN_SUPPORT_DATE_TIME_PICKER
//#ifdef __SUPPORT_DATE_TIME_DYNA_CTRL__ 
#define SGETN_DATE(_STR_NAME, _NODE_LABEL, _DEFAULT_VAL, _STRFMT, _VARTYPE) \
		GETN_CURRENT_SUBNODE = GETN_CURRENT_NODE.AddNumericNode(_DEFAULT_VAL, _STR_NAME, TRGP_DATE); \
		TREE_ADD_LABEL(_NODE_LABEL); \
		GETN_CURRENT_SUBNODE.SetAttribute(STR_ATTRIB_DATE_TIME_CUSTOM_FORMAT, _STRFMT); \
		GETN_CURRENT_SUBNODE.SetAttribute(STR_LTGETN_VARTYPE, _VARTYPE)
#define SGETN_TIME(_STR_NAME, _NODE_LABEL, _DEFAULT_VAL, _STRFMT, _VARTYPE) \
		GETN_CURRENT_SUBNODE = GETN_CURRENT_NODE.AddNumericNode(_DEFAULT_VAL, _STR_NAME, TRGP_TIME); \
		TREE_ADD_LABEL(_NODE_LABEL); \
		GETN_CURRENT_SUBNODE.SetAttribute(STR_ATTRIB_DATE_TIME_CUSTOM_FORMAT, _STRFMT); \
		GETN_CURRENT_SUBNODE.SetAttribute(STR_LTGETN_VARTYPE, _VARTYPE)
//#endif // __SUPPORT_DATE_TIME_DYNA_CTRL__
///---END QA81-14641 LT_GETN_SUPPORT_DATE_TIME_PICKER

/// EJP 2009-11-23 QA81-14534 INIT_CHECKBOX_HIDESHOW_SIBLINGS
static void lt_getn_update_checkbox_hideshow(TreeNode& tnCheckBox)
{
	int nHideShowCount = 0; // 0 == hide/show all
	/// EJP 2010-09-21 ORG-789 GETN_CHKBOX_SHOWHIDE_ALL_WHEN_COUNT_NOT_SPECIFIED, ok if count not specified
	///if( !tnCheckBox.GetAttribute(STR_LTGETN_CHECK_HIDESHOW_COUNT, nHideShowCount) || 0 == nHideShowCount )
	///	return;
	tnCheckBox.GetAttribute(STR_LTGETN_CHECK_HIDESHOW_COUNT, nHideShowCount);
	/// end GETN_CHKBOX_SHOWHIDE_ALL_WHEN_COUNT_NOT_SPECIFIED

	int nHideShow;
	if( !tnCheckBox.GetAttribute(STR_LTGETN_CHECK_HIDESHOW, nHideShow) )
		return;

	bool bShow;
	if( IS_SHOW_CONTROLS_ON_CHECKED(nHideShow) )
		bShow = (tnCheckBox.nVal ? true : false);
	else // hide controls on checked
		bShow = (tnCheckBox.nVal ? false : true);

	TreeNode tn = tnCheckBox.NextNode;
	if( nHideShowCount )
	{
		while( tn && nHideShowCount-- )
		{
			tn.Show = bShow;
			tn = tn.NextNode;
		}
	}
	else // hide/show all
	{
		while( tn )
		{
			tn.Show = bShow;
			tn = tn.NextNode;
		}
	}
}

static void lt_getn_init_checkbox_hideshow(TreeNode& trLTGetN)
{
	TreeNode tn = trLTGetN;
	while( tn.IsValid() )
	{
		if( TRGP_CHECK == tn.ID )
			lt_getn_update_checkbox_hideshow(tn);
		if( tn.Children.Count() )
			tn = tn.Children.Item(0);
		else if( tn.NextNode )
			tn = tn.NextNode;
		else
		{
			tn = tn.Parent();
			tn = tn.NextNode;
		}
	}
}
/// end INIT_CHECKBOX_HIDESHOW_SIBLINGS

static int lt_getn_event1(TreeNode& tr, int nRow, int nEvent, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& getNCountainer, string& strAux, string& strErrMsg)
{
	switch( nEvent )
	{
	case ONODETYPE_CHECKBOX:
		{
			TreeNode tn;
			tn = tr.GetNode(lpcszNodeName);
			if( tn )
			{
				/// EJP 2009-11-23 QA81-14534 INIT_CHECKBOX_HIDESHOW_SIBLINGS
				/*
				int nHideShow;
				if( tn.GetAttribute(STR_LTGETN_CHECK_HIDESHOW, nHideShow) && nHideShow )
				{
					bool bShow;
					if( IS_SHOW_CONTROLS_ON_CHECKED(nHideShow) )
						bShow = (tn.nVal ? true : false);
					else // hide controls on checked
						bShow = (tn.nVal ? false : true);
						
					int nHideShowCount = 0;
					tn.GetAttribute(STR_LTGETN_CHECK_HIDESHOW_COUNT, nHideShowCount);
					tn = tn.NextNode;
					if( nHideShowCount )
					{
						while( tn && nHideShowCount-- )
						{
							tn.Show = bShow;
							tn = tn.NextNode;
						}
					}
					else // hide/show all
					{
						while( tn )
						{
							tn.Show = bShow;
							tn = tn.NextNode;
						}
					}
				}
				*/
				lt_getn_update_checkbox_hideshow(tn);
				/// end INIT_CHECKBOX_HIDESHOW_SIBLINGS
			}
		}
		break;
	}
	return 0;
}

/// Hong 11/16/09 QA80-14534-P5 FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX
#define			INDEX_LT_TO_OC(_idx)			(_idx -= 1)
#define			INDEX_OC_TO_LT(_idx)			(_idx += 1)

bool _is_LT_GetN_numeric_value_index(int nLTCtrlType)
{
	vector<int>		vnLTGetNIndexCtrlType = {
		LTGetNCtrl_Combo,
		LTGetNCtrl_BasicColorList,
		LTGetNCtrl_FontList,
		LTGetNCtrl_SymbolList
	};
	return (-1 != find_in_list(nLTCtrlType, vnLTGetNIndexCtrlType, false));
}

bool _is_GetN_numeric_value_index(int nNodeID)
{
	vector<int>		vnGetNIndexNodeID = {
		TRGP_ENUM_LIST,
		TRGP_COLOR,
		ONODETYPE_DROPLIST_FONTS,
		TRGP_SYMBOL
	};
	return (-1 != find_in_list(nNodeID, vnGetNIndexNodeID, false));
}
/// end FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX

int internal_open_GetNBox(LPSTR* pargs, int nArgs, LPCSTR lpcszTitle, LPCSTR lpcszOptns)
{
	/* for testing purposes
	printf("title:%s\n", lpcszTitle);
	for(int ii = 0; ii < nArgs; ii++)
	{
		printf("%d: %s\n", ii+1, pargs[ii]);
	}
	*/

	string strLabel, strVar, strCtrl, strDefVal, strParam1, strComboVals;
	int nVarType, nCtrlType, nDefVal, nParam1, nParam2;
	double dDefVal;
	char sz[LTGetNTempStrLen+1];

	SGETN_INIT_BRANCH;
	GETN_BOX(trLTGetN);

	for( int nArg = 0; nArg < nArgs; nArg++ )
	{
		//-------------------------------------------------
		// Init optional control params
		//-------------------------------------------------
		nParam1 = nParam2 = 0;
		strParam1.Empty(); /// EJP 2009-11-17 QA81-14534 LTGETN_SUPPORT_NUM_FORMAT

		//-------------------------------------------------
		// Get the Label
		//-------------------------------------------------
		strLabel = (LPCSTR)pargs[nArg];
		nArg++;

		//-------------------------------------------------
		// Get the Variable and optional Control
		//-------------------------------------------------
		strVar = (LPCSTR)pargs[nArg];
		int nFind = strVar.Find(':');
		if( -1 == nFind )
		{
			strCtrl.Empty();
		}
		else
		{
			strCtrl = strVar.Mid(nFind + 1);
			strVar = strVar.Left(nFind);
		}

		//-------------------------------------------------
		// Get the Variable Type
		//-------------------------------------------------
		if( '%' == strVar[0] )
			nVarType = LTGetNVar_StringSub;
		else if( '$' == strVar[strVar.GetLength() - 1] )
			nVarType = LTGetNVar_String;
		else
			nVarType = LTGetNVar_Numeric;

		//-------------------------------------------------
		// Get the Default Value
		//-------------------------------------------------
		if( LTGetNVar_Numeric == nVarType )
		{
			if( !LT_get_var(strVar, &dDefVal) )
				dDefVal = 0.0;

			// Also get as integer and string
			nDefVal = (int)dDefVal;
			///------ Folger 11/10/09 QA81-14534-P4 BETTER_TITLE_AND_NUMERIC_DISLPLAY_FOR_USING_OC_GETN_FROM_LT
			//strDefVal.Format("%f", dDefVal);
			///------ End BETTER_TITLE_AND_NUMERIC_DISLPLAY_FOR_USING_OC_GETN_FROM_LT
		}
		else // get default value from string variable
		{
			if( LT_get_str(strVar, sz, LTGetNTempStrLen) )
				strDefVal = sz;
			else
				strDefVal.Empty();

			/// EJP 2009-11-17 QA81-14534 LTGETN_SUPPORT_BROWSE_FOR_FILE
			// Remove the prefix or suffix from the string var name so
			// it can be used as the node name.
			if( LTGetNVar_StringSub == nVarType )
				strVar.Delete(0); // delete '%' prefix
			else if( LTGetNVar_String == nVarType )
				strVar.Delete(strVar.GetLength() - 1); // delete '$' suffix
			/// end LTGETN_SUPPORT_BROWSE_FOR_FILE
		}

		//-------------------------------------------------
		// Get control type
		//-------------------------------------------------
		nCtrlType = LTGetNCtrl_Unknown; // init to unknown
		if( strCtrl.IsEmpty() )
		{
			nCtrlType = LTGetNCtrl_Edit;

			/// EJP 2009-11-17 QA81-14534 LTGETN_SUPPORT_BROWSE_FOR_FILE, move to where we get the default value
			///if( LTGetNVar_StringSub == nVarType )
			///	strVar.Delete(0); // delete '%' prefix
			///else if( LTGetNVar_String == nVarType )
			///	strVar.Delete(strVar.GetLength() - 1); // delete '$' suffix
			/// end LTGETN_SUPPORT_BROWSE_FOR_FILE
		}
		else if( '2' == strCtrl[0] ) // 2 for CheckBox
		{
			nCtrlType = LTGetNCtrl_Check;

			// Check for optional 'h' or 's'
			if( strCtrl.GetLength() > 1 )
			{
				strCtrl.MakeLower();
				if( 'h' == strCtrl[1] || 's' == strCtrl[1] )
				{
					nParam1 = strCtrl[1];

					// Check for optional count, Ex: 2s5
					if( strCtrl.GetLength() > 2 )
						nParam2 = atoi(strCtrl.Mid(2));
				}
			}
		}
		else if( 1 == strCtrl.GetLength() && IsCharAlpha(strCtrl[0]) )
		{
			// Get list values from string substitution variable
			strCtrl.Insert(0, '%');
			if( LT_get_str(strCtrl, sz, LTGetNTempStrLen) )
			{
				nCtrlType = LTGetNCtrl_Combo;
				strComboVals = sz;
				//---- CPY 11/26/09 QA81-14759 GETN_COMBO_LIST_NEED_PROPER_TOKENIZING
				//strComboVals.Replace(' ', '|');
				vector<string> vsTemp;
				okutil_get_tokens(strComboVals, &vsTemp, 0, NULL, GT_TRIM_QUOTES);

				strComboVals.SetTokens(vsTemp,'|');
				//---- end GETN_COMBO_LIST_NEED_PROPER_TOKENIZING
				/// Hong 11/16/09 QA80-14534-P5 FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX
				/*
				nDefVal--; // LT is 1 based, OC is 0 based
				if( nDefVal < 0 || strComboVals.GetNumTokens('|') <= nDefVal )
					nDefVal = 0;
				strDefVal = strComboVals.GetToken(nDefVal, '|');
				*/
				/// end FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX
			}
		}
		else if( '@' == strCtrl[0] ) // If special '@' option
		{
			/// Hong 11/16/09 QA80-14534-P5 FIX_CTRL_IN_LOWER_CASE_FAIL_TO_WORK_WITH_OC_GETN
			strCtrl.MakeUpper();
			/// end FIX_CTRL_IN_LOWER_CASE_FAIL_TO_WORK_WITH_OC_GETN
			switch( strCtrl[1] )
			{
			/// EJP 2009-11-17 QA81-14534 LTGETN_SUPPORT_BROWSE_FOR_FILE
			case 'B':
				if( 'B' == strCtrl[2] ) // :@BB
				{
					nCtrlType = LTGetNCtrl_BrowseButton;
					strParam1.Format("...%s", strCtrl.Mid(3));
				}
				break;
			/// end LTGETN_SUPPORT_BROWSE_FOR_FILE
			case 'C': // Basic Color List
				nCtrlType = LTGetNCtrl_BasicColorList;
				break;
			/// EJP 2009-11-17 QA81-14534 LTGETN_SUPPORT_NUM_FORMAT
			case 'F':
				if( LTGetNVar_Numeric == nVarType )
				{
					nCtrlType = LTGetNCtrl_Edit;
					strParam1 = strCtrl.Mid(2);
				}
				break;
			/// end LTGETN_SUPPORT_NUM_FORMAT
			case 'G': // Branch option
				if( 0 == strLabel.Compare("-") ) // If ending a branch
					nCtrlType = LTGetNCtrl_BranchEnd;
				else // beginning a branch
				{
					nCtrlType = LTGetNCtrl_BranchBegin;
					if( 2 == strCtrl.GetLength() )
						nParam1 = 1; // Branch is open by default
					else
						nParam1 = strCtrl[2] - '0';
				}
				break;
			case 'S': // Font Size List
				strComboVals = "8|9|10|11|12|14|16|18|20|22|24|26|28|36|48|72";
				nCtrlType = LTGetNCtrl_Combo;
				break;
			case 'T': // Font List
				nCtrlType = LTGetNCtrl_FontList;
				break;
			case 'W': // Line Width List
				strComboVals = "0.2|0.5|1|1.5|2|3|4|5";
				nCtrlType = LTGetNCtrl_Combo;
				break;
			case 'Z': // @Z == Symbol Size List, @ZZ == Symbol List
				if( strCtrl.GetLength() > 2 && 'Z' == strCtrl[2] )
					nCtrlType = LTGetNCtrl_SymbolList;
				else
				{
					strComboVals = "0|1|3|5|8|12|15|18|24|30";
					nCtrlType = LTGetNCtrl_Combo;
				}
				break;
			///------ Folger 05/18/10 ORG-143 LT_GETN_HINT_TEXT_SUPPORT
			case 'H':
				nParam1 = strCtrl.GetLength() > 2 && strCtrl[2] == 'L' ? 2 : 1;		/// for Hint
				nCtrlType = LTGetNCtrl_Edit;
				break;
			///------ End LT_GETN_HINT_TEXT_SUPPORT
			}
		}
		///------ Folger 04/20/10 QA81-15332 LT_USE_OC_GETN_FAILED_TO_HANDLE_STRING_COMBO
		else
		{
			double	rr;
			string	strTemp;
			if ( LT_get_var(strVar, &rr) && check_cvt_str(strCtrl, &strTemp) >= CCS_NO_CHANGE )
			{
				vector<string>	vsCombos;
				okutil_get_tokens(strTemp, &vsCombos, 0, NULL, GT_TRIM_QUOTES); 
				nDefVal = rr;
				strComboVals.SetTokens(vsCombos, '|');
				nCtrlType = LTGetNCtrl_Combo;
			}
		}
		///------ End LT_USE_OC_GETN_FAILED_TO_HANDLE_STRING_COMBO
		
		/// Hong 11/16/09 QA80-14534-P5 FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX
		if ( _is_LT_GetN_numeric_value_index(nCtrlType) )
			INDEX_LT_TO_OC(nDefVal);
		/// end FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX

		//-------------------------------------------------
		// Add node to tree
		//-------------------------------------------------
		switch( nCtrlType )
		{
		case LTGetNCtrl_Edit:
		///------ Folger 11/10/09 QA81-14534-P4 BETTER_TITLE_AND_NUMERIC_DISLPLAY_FOR_USING_OC_GETN_FROM_LT
			//SGETN_STR(strVar, strLabel, strDefVal, nVarType);
			if ( LTGetNVar_Numeric == nVarType )
			{
				///---Sim 12-07-2009 QA81-14641 LT_GETN_SUPPORT_DATE_TIME_PICKER
				//if ( !strParam1.IsEmpty() && 'D' == strParam1[0] )
				bool bDatePickerCtrl = false, bTimePickerCtrl = false;
				LPCSTR lpcstrFmt = NULL;
				if ( !strParam1.IsEmpty() && 'D' == strParam1[0] )
				{
					int nType = atoi(strParam1.Mid(1));
					lpcstrFmt = get_date_format_str(nType);
					bDatePickerCtrl = true;
				}				
				if ( !strParam1.IsEmpty() && 'T' == strParam1[0] )
				{
					int nType = atoi(strParam1.Mid(1));
					lpcstrFmt = get_time_format_str(nType);
					bTimePickerCtrl = true;
				}				
				
				if ( bDatePickerCtrl && lpcstrFmt )
				{
					SGETN_DATE(strVar, strLabel, dDefVal, lpcstrFmt, nVarType);
				}
				else
				if ( bTimePickerCtrl && lpcstrFmt )
				{
					SGETN_TIME(strVar, strLabel, dDefVal, lpcstrFmt, nVarType);
				}
				else
				{
				///---END QA81-14641 LT_GETN_SUPPORT_DATE_TIME_PICKER
					SGETN_NUM(strVar, strLabel, dDefVal, nVarType);
					/// EJP 2009-11-17 QA81-14534 LTGETN_SUPPORT_NUM_FORMAT
					if( !strParam1.IsEmpty() )
						GETN_OPTION_NUM_FORMAT(strParam1)
					/// end LTGETN_SUPPORT_NUM_FORMAT
				}///---Sim 12-07-2009 QA81-14641 LT_GETN_SUPPORT_DATE_TIME_PICKER
			}
			else
			{
				SGETN_STR(strVar, strLabel, strDefVal, nVarType);
				///------ Folger 05/18/10 ORG-143 LT_GETN_HINT_TEXT_SUPPORT
				if ( 1 == nParam1 )
				{
					GETN_HINT_EX(TRUE, FALSE);
				}
				else if ( 2 == nParam1 )
				{
					GETN_HINT_EX(FALSE, FALSE);
				}
				///------ End ORG-143 LT_GETN_HINT_TEXT_SUPPORT
			}
			///------ End BETTER_TITLE_AND_NUMERIC_DISLPLAY_FOR_USING_OC_GETN_FROM_LT
			break;
		case LTGetNCtrl_Check:
			SGETN_CHECK(strVar, strLabel, nDefVal, nVarType);
			SGETN_CHECK_HIDESHOW(nParam1, nParam2);
			break;
		case LTGetNCtrl_Combo:
			/// Hong 11/16/09 QA80-14534-P5 FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX
			if( nDefVal < 0 || strComboVals.GetNumTokens('|') <= nDefVal )
				nDefVal = 0;
			/// end FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX
			/// Kenny 11/02/2009 QA81-14534 FIX_LT_OPEN_OC_GETNBOX_COMBO_INIT_ISSUE
			//SGETN_COMBO(strVar, strLabel, strDefVal, strComboVals, nVarType);
			SGETN_COMBO(strVar, strLabel, nDefVal, strComboVals, nVarType);
			/// End QA81-14534 FIX_LT_OPEN_OC_GETNBOX_COMBO_INIT_ISSUE
			break;
		case LTGetNCtrl_BasicColorList:
			/// Hong 11/16/09 QA80-14534-P5 FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX
			//SGETN_COLOR(strVar, strLabel, nDefVal - 1, nVarType);
			SGETN_COLOR(strVar, strLabel, nDefVal, nVarType);
			/// end FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX
			break;
		case LTGetNCtrl_FontList:
			/// Hong 11/16/09 QA80-14534-P5 FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX
			//SGETN_FONT(strVar, strLabel, nDefVal - 1, nVarType);
			SGETN_FONT(strVar, strLabel, nDefVal, nVarType);
			/// end FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX
			break;
		case LTGetNCtrl_SymbolList:
			SGETN_SYMBOL(strVar, strLabel, nDefVal, nVarType);
			break;
		case LTGetNCtrl_BranchBegin:
			strVar = strLabel;
			strVar.MakeValidCName('B');
			SGETN_BEGIN_BRANCH(strVar, strLabel, nParam1);
			break;
		case LTGetNCtrl_BranchEnd:
			SGETN_END_BRANCH(strVar);
			break;
		/// EJP 2009-11-17 QA81-14534 LTGETN_SUPPORT_BROWSE_FOR_FILE
		case LTGetNCtrl_BrowseButton:
			SGETN_BUTTON_EX(strVar, strLabel, strDefVal, strParam1, nVarType);
			break;
		/// end LTGETN_SUPPORT_BROWSE_FOR_FILE
		}
	}

	/// EJP 2009-11-23 QA81-14534 INIT_CHECKBOX_HIDESHOW_SIBLINGS
	TreeNode tn = trLTGetN;
	lt_getn_init_checkbox_hideshow(tn);
	/// end INIT_CHECKBOX_HIDESHOW_SIBLINGS

	///------ Folger 11/10/09 QA81-14534-P4 BETTER_TITLE_AND_NUMERIC_DISLPLAY_FOR_USING_OC_GETN_FROM_LT
	//if( GetNBox(trLTGetN, lpcszTitle) )
	if( GetNBox(trLTGetN, lt_getn_event1, NULL, lpcszTitle) )
	///------ End BETTER_TITLE_AND_NUMERIC_DISLPLAY_FOR_USING_OC_GETN_FROM_LT
	{
		/// EJP 2009-11-23 QA81-14534 INIT_CHECKBOX_HIDESHOW_SIBLINGS
		///TreeNode tn = trLTGetN;
		tn = trLTGetN;
		/// end INIT_CHECKBOX_HIDESHOW_SIBLINGS
		while( tn.IsValid() )
		{
			if( tn.GetAttribute(STR_LTGETN_VARTYPE, nVarType) )
			{
				strVar = tn.tagName;
				switch( nVarType )
				{
				case LTGetNVar_Numeric:
					/// EJP 2009-11-02 QA81-14534 USE_OC_GETN_FROM_LT
					///LT_set_var(strVar, tn.dVal);
					///------ Folger 11/10/09 QA81-14534-P4 BETTER_TITLE_AND_NUMERIC_DISLPLAY_FOR_USING_OC_GETN_FROM_LT
					//LT_set_var(strVar, atof(tn.strVal));
					/// Hong 11/16/09 QA80-14534-P5 FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX
					//LT_set_var(strVar, tn.dVal);
					double		dVal = tn.dVal;
					if ( _is_GetN_numeric_value_index(tn.ID) )
						INDEX_OC_TO_LT(dVal);
					LT_set_var(strVar, dVal);
					/// end FIX_LT_GETN_CMD_FAIL_FOR_INDEX_CTRL_IF_USE_OC_GETNBOX
					///------ End BETTER_TITLE_AND_NUMERIC_DISLPLAY_FOR_USING_OC_GETN_FROM_LT
					/// end USE_OC_GETN_FROM_LT
					break;
				case LTGetNVar_String:
					strVar = strVar + "$";
					/// EJP 2009-11-23 QA81-14534 USE_CRLF_FOR_DELIMITER
					if( TRGP_STR_BUTTON == tn.ID )
						tn.strVal.Replace("\n", "\r\n");
					/// end USE_CRLF_FOR_DELIMITER
					LT_set_str(strVar, tn.strVal);
					break;
				case LTGetNVar_StringSub:
					strVar.Insert(0, '%');
					LT_set_str(strVar, tn.strVal);
					break;
				}
			}
			if( tn.Children.Count() )
				tn = tn.Children.Item(0);
			else if( tn.NextNode )
				tn = tn.NextNode;
			else
			{
				tn = tn.Parent();
				tn = tn.NextNode;
			}
		}
		
		return 1; // IDOK
	}
	return 2; // IDCANCEL;
}
//---- end USE_OC_GETN_FROM_LT

//----- CPY 1/16/09 QA70-12954 OPEN_XYZ2MAT_DIALOG_FROM_LT
#pragma labtalk(2)
// strClassName is case sensitive, like
// run -oc run_classop XYZ2Mat
void run_classop(string strClassName, BOOL bUseLastUsedTheme = true)
{
	string strThemeName = bUseLastUsedTheme? STR_LAST_USED : "";
	/*string strFile;
	if(okutil_find_file_from_map(&strFile, SUPPORTFILE_XF, ORIGIN_PATH_UNDEF, strName) == ORIGIN_PATH_UNDEF)
	{
		printf("Cannot Find X-Function: %s\n",strName);
		return;
	}
	string strCompositeName = okutil_composite_name_from_file_path(strFile, "X-Functions");

	do_AU_command(NULL, true, strThemeName, -1, NULL, strCompositeName);
	*/
	///------ Folger 06/29/09 QA80-12954-P2 PEAK_FITTING_DIALOG_OF_NLFIT_FAILS_TO_BE_BROUGHT_UP_BY_LABTALK
	//do_AU_command(strClassName, true, strThemeName, -1, NULL, NULL);
	LPCSTR lpcszName = NULL;
	if ( _is_op_invoked_by_xf(strClassName) )
		lpcszName = strClassName;
	do_AU_command(strClassName, true, strThemeName, -1, NULL, lpcszName);
	///------ End PEAK_FITTING_DIALOG_OF_NLFIT_FAILS_TO_BE_BROUGHT_UP_BY_LABTALK
}
//----- end OPEN_XYZ2MAT_DIALOG_FROM_LT

/// Fisher 6/9/2009 QA80-1863 ADD_EXTRACTING_CONTOUR_LINES_MENU_ITEM
#ifdef __EXTRACTING_CONTOUR_LINES__
/// YuI 06/22/09 QA70-13595 SUPPORT_FOR_DATA_PLOT_ELEMENTS_ACCESS
/*
BOOL	ExtractContourLinesFromDataPlot( DataPlot &dp, int nContourIndex = -1, BOOL bAllAtCurrentLevel = FALSE )
{
	
	if(!dp)
		return FALSE;
	
	WorksheetPage wp;
 	wp.Create("Origin");
	Worksheet wks(wp.GetName());
	wks.SetSize(-1, 2);
			
	Column colX(wks, 0), colY(wks, 1);
	int nRet = dp.ExtractContourData(colX, colY, nContourIndex, bAllAtCurrentLevel);

	if( nRet < 0 )
		wks.Destroy();
	
	return nRet;
	
	
	return TRUE;
	
}
*/

BOOL	ExtractContourLines(OriginObject& obj)
{
	vector vX;
	vector vY;
	vector vLevels;
	vector<int> vCounts;	
		
	DataPlot dp;
	PlotElement pe;
	dp = obj;
	if( !dp )
		pe = obj;
	
	BOOL bSuccessfulExtraction = FALSE;
	if( dp )
		bSuccessfulExtraction = (dp.ExtractContourData(vX, vY, vCounts, vLevels) > 0);
	else if( pe )
		bSuccessfulExtraction = (pe.ExtractContourData(vX, vY, vCounts, vLevels) > 0);
	
	if( bSuccessfulExtraction )
	{
		WorksheetPage wp;
		wp.Create("Origin");
	
		/// Fisher 2009/08/26 TERNARY_CONTOUR_PLOT
		/// Fisher 09/01/09	QA80-14237	FAIL_TO_EXTRACT_TERNARY_CONTOUR_DATA
		//int nPlotType = dp.GetPlotType();
		//int nPlotType = dp ? dp.GetPlotType() : pe.GetPlotType();
		int nPlotType = 0;
		if ( dp )
			nPlotType = dp.GetPlotType();
		else
			nPlotType = pe.GetPlotType();
		/// End	FAIL_TO_EXTRACT_TERNARY_CONTOUR_DATA
		int numDataCols = IDM_PLOT_TERNARY_CONTOUR == nPlotType ? 3 : 2;
		/// --------
		
		Worksheet wks(wp.GetName());
		
		/// Fisher 09/01/09	QA80-14237-P15	Z_LEVEL_LABEL_SHOULD_GO_TO_USER_DEFINED_HEADER
        vector<string> vsNames, vsValues;
		vsNames.SetSize(1);
		vsNames[0] = numDataCols == 3 ? "Zh-Level" : "Z-Level";
		vsValues.SetSize(1);
		/// End Z_LEVEL_LABEL_SHOULD_GO_TO_USER_DEFINED_HEADER

		wks.SetSize(-1, numDataCols * vLevels.GetSize());
		int nBeginOfLevel = 0;
		for( int ii = 0; ii < vLevels.GetSize(); ii++ )
		{
			Column colX(wks, ii * numDataCols);
			Column colY(wks, ii * numDataCols + 1);
			colX.SetType(OKDATAOBJ_DESIGNATION_X);
			colY.SetType(OKDATAOBJ_DESIGNATION_Y);
			
			/// Fisher 09/01/09	QA80-14237-P15	Z_LEVEL_LABEL_SHOULD_GO_TO_USER_DEFINED_HEADER
			vsValues[0] = vLevels[ii];
			set_user_parameters(colX, vsNames, vsValues);
			set_user_parameters(colY, vsNames, vsValues);
			/// End Z_LEVEL_LABEL_SHOULD_GO_TO_USER_DEFINED_HEADER
			
			Dataset dsX(colX);
			Dataset dsY(colY);
			vector vLevelX;
			vector vLevelY;
			vLevelX.SetSize(vCounts[ii]);
			vLevelY.SetSize(vCounts[ii]);
			vX.GetSubVector(vLevelX, nBeginOfLevel, nBeginOfLevel + vCounts[ii] -1);
			vY.GetSubVector(vLevelY, nBeginOfLevel, nBeginOfLevel + vCounts[ii] -1);

			/// Fisher 2009/08/26 TERNARY_CONTOUR_PLOT
			if(IDM_PLOT_TERNARY_CONTOUR == nPlotType)
			{
				Column colZ(wks, ii * numDataCols + 2);
				colZ.SetType(OKDATAOBJ_DESIGNATION_Z);
				/// Fisher 09/01/09	QA80-14237-P15	Z_LEVEL_LABEL_SHOULD_GO_TO_USER_DEFINED_HEADER
				set_user_parameters(colZ, vsNames, vsValues);
				/// End Z_LEVEL_LABEL_SHOULD_GO_TO_USER_DEFINED_HEADER
				
				Dataset dsZ(colZ);
				vector vLevelZ;	
				vLevelZ.SetSize(vCounts[ii]);
				ocmath_get_ternary_data_from_xy(vCounts[ii], vLevelX, vLevelY, vLevelZ);
				dsZ = vLevelZ;
			}
			/// --------
			
			dsX = vLevelX;
			dsY = vLevelY;			
			nBeginOfLevel += vCounts[ii];
		}
	}
	return TRUE;
}

/// end SUPPORT_FOR_DATA_PLOT_ELEMENTS_ACCESS
#endif		// __EXTRACTING_CONTOUR_LINES__
/// End ADD_EXTRACTING_CONTOUR_LINES_MENU_ITEM

