/*------------------------------------------------------------------------------*
 * File Name:TreeEditControl.h													*
 * Creation: CPY 6/21/2003														*
 * Purpose: OriginC Header file for general vsFlexGrid based TreeEditor			*
 * Copyright (c) Originlab Corp. 2003, 2004, 2005, 2006, 						*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	CPY 8/24/03 v7.5674 QA70-5061 ADD_DISPLAY_OPTIONS							*
 *	CPY v7.5723 QA70-5376 	GETNBOX_ADD_SIG_DIGITS_SUPPORT						*
 *	CPY v7.5785 12/18/03 QA70-5738 BUTTON_EVENT_SHOULD_SHARE_SAME_HANDLER_MANAGEMENT
 *	CPY v7.5785 12/19/03 QA70-5738 GETN_BOX_COMBO_CHANGE_NEEDED					*
 *	YuI 1/26/04 v7.5807 QA70-5797 INTERACTIVE_TEXT_PROPERTY_IMPLEMENTATION		*
 *	ML 3/3/2004 RANGE_BASED_REGRESSIONS											*
 *  Danice 3/9/04 v8.0834 	ADD_MORE_MESSAGE									*
 *	YuI 3/24/04 v7.5846 QA70-6118 NEW_DATA_SELECTOR_TOOL						*
 *  Danice 4/30/04 QA70-6222 v8.0865 RIGHT_CLICK_ACCESS							*
 *	Frank 5/11/04 v8.0870 	ADD_MORE_TYPE_SET_COMBO_STRING						*
 *  Danice v8.0870 5/11/04 	QA70-6222 GETNTREE_AUTO_LOAD_DEFAULT				*
 *  Danice v8.0881 5/31/04 	SUPPORT_BRANCH_DISPLAY_OPTIONS						*
 *  Frank  v8.0890 6/15/04 	QA70-6222 GETNTREE_CONTEXT_MENU_MORE_SETTING		*
 *  Danice v8.0890 6/16/04 	QA70-6222 COMBINE_TREEEDIT_SAVE_AND_COPY_SETTING	*
 *	CPY 6/16/04 QA70-6294	OC_INPUT_DATA_NODE_CLEANUP							*
 *	Frank 6/22/04 QA70-6086 v8.0893 REFRESH_GRID_SHOW_NOT_RECONSTRUCT_ALL_GRIL_ROW*
 *  Danice 6/22/04 v8.0893 SUPPORT_RIGHT_CLICK_SELECTION						*
 *  Danice 7/14/04 QA70-6631 v8.0907 TREE_BRANCH_COLLAPSED_DEFAULT				*
 *	CPY 7/16/04 DISABLED_CHECK_BOX_STILL_WORK									*
 *	CPY 7/16/04 BRANCH_NODE_SHOULD_NOT_SHOW_TEXT								*
 *	CPY 7/19/04 GETN_EDIT_ALIGNMENTS											*
 *	CPY SY 07/27/2004 QA70-6719 v8.0105 GETN_AUTO_RESIZE_WIDTH_WITH_LONG_LABEL	*
 *	CPY 8/3/04 GETN_DLG_CALL_NODE_BASED_EVENT_HANDLERS_ON_INIT					*
 *	CPY 8/27/04 QA70-5890 v8.0125 BRANCH_ALLOW_CHECKBOX							*
 *	CPY 9/2/04 GETN_STR_COMBO_NOT_UPDATING_EDIT_CELL							*
 *  Forest 9/12/04 QA70-6682 SETTINGS_THEME_FILE_SAVE_LOAD						*
 *  Danice 9/13/04 QA70-6891 v8.0132b SUPPORT_GRID_VIEW							*
 *  Forest 9/14/04 QA70-6682 REMOVE_THEME_CONTEXT_MENU	                        *
 *  Frank 9/15/04 QA70-6086	SET_UNEDITABLE_AFTER_UPDATE_GRID                    *
 *  CPY 10/1/04 QA70-6752 GET_NODE_NUM_FORMAT_CONTROL							*
 *  SY 10/06/2004 QA70-6582 v8.0145 GETN_LIST_DROP_DOWN							*
 *	Frank 10/16/04 CELL_WIDTH_NEED_UPDATE_LOAD_PICTURE							*
 *  Danice 10/21/04 QA70-5890 V8.0152 BRANCH_CHECKBOX_IMPROVEMENT				*
 *  Danice 11/10/04 v8.0161 SUPPORT_EMPTY_TREENODE_AND_LABEL_CONTROL			*
 *  Danice 11/10/04 v8.0161 ADD_CHECK_SHOW_OPTION								*
 *  Danice 11/15/04 QA70-7169 v8.0163 TREE_ROW_SHOW_ALTERNATE_COLORS			*
 *  Danice 11/16/04 QA70-7169 v8.0162 MARK_EMPTY_GETN_STR						*
 *  Frank 11/17/04 SUPPORT_SIZE_MULTILINE_ROW_HEIGHT							*
 *  Danice 11/29/04 QA70-7169 v8.0167 NEW_WAY_FOR_ALTERNATE_COLORS				*
 *  Danice 11/29/04 QA70-7169 v8.0167 MARK_EMPTY_GETN_STR_CENTRALIZE			*
 *	CPY TD 11-30-04 QA70-6582 ADD_COMBO_IMAGE_TO_RIGHT_OF_EDIT_CELL				*
 *  Danice 12/2/04 v8.0169 DISABLE_ROW_WITHOUT_GRAY_COLOR						*
 *  Danice 12/10/04 v8.0169 DISABLE_ROW_WITHOUT_GRAY_COLOR2						*
 *  Frank 12/14/04 AUTO_SET_MULTILINE_EDIT_SHOW_RANGE							*
 * EJP 12-16-2004 QA70-6721 ASCIMP_OPTIONS_USE_GETNBOX							*
 *  DG 1/20/05 QA70-7331 v8.0185 GRID_VIEW_GET_TREE_NODE						*
 *  DG 3/30/05 v8.0211 VALIDATE_KILL_FOCUS										*
 *  Frank 3/30/05	TREE_EDIT_SUPPORT_MOVE_ROWS									*
 *  DG 4/13/05 v8.0220 UNLIMIT_CONTEXT_MENU_IN_COL_TEXT							*
 *	ML 4/15/2005 XVAR_DATA_CHANGE_ATT											*
 *  DG 4/27/05 QA70-7581 v8.0227 TREE_CTRL_IN_PROPERTYPAGE_NEED_MSG				*
 *	CPY 5/20/05 QA70-7744 NEW_GETN_EVENT										*
 *	Frank 5/26/05	GETN_EVENT_SUPPORT_GRID_VIEW								*
 *  DG 7/12/05 QA70-6631 v8.0265 USE_BRANCH_DEFAULT_CLOSED						*
 *  SY 08/24/2005 v8.0294 SHOW_DROPLIST_ON_ONE_CLICK							*
 *	CPY 8/26/05 ADD_HELP_TO_XF													*
 *	YuI 09/22/05 GETN_BUTTON_BRANCH_OPTION										*
 *	YuI 10/19/05 INTERACTIVE_CONTOROL_NEED_UPDATE_RESIZE_GETN_GRID				*
 *	Frank 11/16/05 QA70-8293 RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC			*
 *	ML 2/10/2006 QA70-8490 NEW_VC_TREE_CONTROL									*
 *	TD 09-19-2007 QA80-10117 GRID_CANT_PASTE									*
 *	Hong 11/11/09 QA80-14625 TREE_EDIT_CTRL_DISPLAY_VECTOR_TREENODE_AS_DEBUG_VARIABLE_TAB
 *------------------------------------------------------------------------------*/

#ifndef _TREE_EDIT_CONTROL_H_
#define _TREE_EDIT_CONTROL_H_
 
#include <Range.h> //CPY 4/22/04 moved here from GetNBox.c
#include "GridControl.h"
#include "MenuBase.h"
#include "TreeEditInputData.h" //CPY 6/14/04
#include "TreeEditSaveSettings.h"	//Danice 6/15/04
 
/// ML 2/10/2006 QA70-8490 NEW_VC_TREE_CONTROL
/////Danice 3/9/04 v8.0834 ADD_MORE_MESSAGE
//#define WM_USER_TREEEDITOR_VALUE_CHANGE	(WM_USER + 1001)
/////END ADD_MORE_MESSAGE
/// end NEW_VC_TREE_CONTROL

//---- CPY 7/19/04 GETN_EDIT_ALIGNMENTS
#define JUSTIFICATION_CHECKBOX	m_nCheckAlignment//flexPicAlignCenterCenter
#define JUSTIFICATION_NUM		m_nNumAlignment//flexPicAlignLeftCenter	//flexPicAlignRightCenter
#define JUSTIFICATION_STR		m_nStrAlignment//flexPicAlignLeftCenter
#define JUSTIFICATION_MULTILINE	flexPicAlignLeftTop

#define MIN_MULTILINE_ROWS		3 //CPY 12/20/04
//----

/// ML 2/10/2006 QA70-8490 NEW_VC_TREE_CONTROL
// Moved to oc_sys.h:
/*
enum {
	GRID_CHANGE_SHOW = 0x0001,
	GRID_CHANGE_ENABLE = 0x0002,
	GRID_CHANGE_VALUE = 0x0004,
	GRID_CHANGE_SIZE = 0x0008,
	GRID_CHANGE_COMBOSTR = 0x0010, //---- CPY v7.5785 12/19/03 QA70-5738 GETN_BOX_COMBO_CHANGE_NEEDED
	GRID_CHANGE_SKIP_HANDLERS_ON_UPDATE = 0x0020, //CPY 8/27/04 QA70-5890 v8.0125 BRANCH_ALLOW_CHECKBOX
	GRID_CHANGE_TREE_STRUCTURE = 0x0040,/// YuI 09/22/05 GETN_BUTTON_BRANCH_OPTION
	GRID_CHANGE_LAST_ENTRY
};
*/
/// end NEW_VC_TREE_CONTROL

//----- CPY 7/29/04 FIT_LR_DLG_NOT_VISIBLE_DUE_TO_NEG_GRID_HEIGHT
#define ROW_HEIGHT_ENLARGER 1.1 
//#define ROW_HEIGHT_ENLARGER_GRID 0.9 // CPY 9/24/04 for grid edit, multiplel cols, no need to have big rows
#define ROW_HEIGHT_ENLARGER_GRID 1.0	//DG 3/22/05 for FB filter, too small to see
#define ROW_HEIGHT_ENLARGER_CHKBOX 0.95
//-----

///Danice TREE_ROW_SHOW_ALTERNATE_COLORS : L1 | L2 | B1
enum { COLOR_BACK_GROUND, COLOR_ALTERNATE_COLOR, COLOR_FIRST_BRANCH_COLOR, TOTAL_BASIC_ALTERNATE_COLORS };
///end
/// ML 2/10/2006 QA70-8490 NEW_VC_TREE_CONTROL
//enum {HANDLER_MSG_NOT_POSTED, HANDLER_MSG_POSTED, HANDLER_NOT_CALLED}; ///Frank 11/16/05 QA70-8293 RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
/// end NEW_VC_TREE_CONTROL
///Danice MARK_EMPTY_GETN_STR
enum {COLOR_EMPTY_INDECATOR_FOREGROUND, COLOR_EMPTY_INDECATOR_BACKGROUND, COLOR_READ_ONLY_FOREGROUND, COLOR_READ_ONLY_BACKGROUND, TOTAL_INDECATOR_COLORS };
///end

//------ CPY 11/19/05 QA70-8339 ROC_CURVE_NEEDS_STATE_VALUES
#define IS_GETN_NODE_HAS_COMBO(_nid) (TRGP_NUMERIC_LIST == _nid || TRGP_ENUM_LIST == _nid || TRGP_STR_GROUP == _nid || TRGP_STR_LIST == _nid)
#define IS_GETN_NODE_MAYBE_COMBO(_nid) (TRGP_NUMERIC_LIST == _nid || TRGP_ENUM_LIST == _nid || TRGP_STR_GROUP == _nid || TRGP_STR == _nid)
//------

//CPY 6/16/04 QA70-6294 OC_INPUT_DATA_NODE_CLEANUP insert class InputDataTreeControl
class TreeEditControl : public TreeEditInputData //public GridTreeControl
{
public:
	///Danice SUPPORT_EMPTY_TREENODE_AND_LABEL_CONTROL && ADD_CHECK_SHOW_OPTION
	TreeEditControl()
	{
		m_bCheckTreeShow=true;
		m_bShowLabelCol=true;
	}
	bool GetSetShowColLabel(bool bShow)
	{
		bool bOldVal=m_bShowLabelCol;
		m_bShowLabelCol=bShow;
		return bOldVal;
	}
	bool GetSetCheckTreeShow(bool bCheck)
	{
		bool bOldVal=m_bCheckTreeShow;
		m_bCheckTreeShow=bCheck;
		return bOldVal;
	}
	///end
	
	///DG GRID_VIEW_GET_TREE_NODE
	TreeNode GetTreeNode(int nRow, int nCol=-1)
	{
		return get_tree_node(nRow, nCol);
	}
	///end GRID_VIEW_GET_TREE_NODE
	
	///---Danice NEW_WAY_FOR_ALTERNATE_COLORS
	/*
	///Danice TREE_ROW_SHOW_ALTERNATE_COLORS : Leaf1 | Leaf2 | Branch1 | Branch2 | Branch3 | ...
	bool SetTreeRowAlternateColors(vector<uint> vnAlternateColors)
	{
		int nColorSize=vnAlternateColors.GetSize();
		if(TOTAL_BASIC_ALTERNATE_COLORS > nColorSize)
			return error_report("Basic Alternate Colors is not enough");
		
		m_vnTreeRowColors.SetSize(nColorSize);
		m_vnTreeRowColors=vnAlternateColors;
		m_flx.BackColor=m_vnTreeRowColors[COLOR_BACK_GROUND];
		SetAlternateRowColors(m_vnTreeRowColors[COLOR_ALTERNATE_COLOR]);
		
		return true;
	}
	///end TREE_ROW_SHOW_ALTERNATE_COLORS
	*/
	///---end NEW_WAY_FOR_ALTERNATE_COLORS
	
	//void Init(int nID, bool bFlatDlgDisplay, bool bSubBranch, PEVENT_FUNC pfn, Dialog& dlg)
	//void Init(int nID, bool bFlatDlgDisplay, bool bSubBranch, PEVENT_FUNC pfn, WndContainer& dlg)	///DG TREE_CTRL_IN_PROPERTYPAGE_NEED_MSG : because now PropertyPage don't support user msg, we must post it to dialog first
	void Init(int nID, bool bFlatDlgDisplay, bool bSubBranch, PEVENT_FUNC pfn, WndContainer& dlg, WndContainer* pParentDlg = NULL)
	{
		m_dwEditor = 0;		
		m_bIsFlatDialogDisplay = bFlatDlgDisplay;
		//GridTreeControl::Init(nID, dlg, bSubBranch);	///DG TREE_CTRL_IN_PROPERTYPAGE_NEED_MSG
		GridTreeControl::Init(nID, dlg, bSubBranch, pParentDlg);
		//m_bDataReady = false;//CPY 9/1/05 SET_READY_FROM_BASE_CLASS_ONLY moved to base class

//WAIT_BUG_FIX
//		m_dlg = dlg;
		m_pdlg = &dlg;
		m_pfnEvent = pfn;
		
		m_strNumFormat = "*"; //CPY v7.5723 QA70-5376 GETNBOX_ADD_SIG_DIGITS_SUPPORT
		//----- CPY 7/19/04 GETN_EDIT_ALIGNMENTS
		m_nCheckAlignment = flexPicAlignCenterCenter;
		m_nNumAlignment = flexPicAlignLeftCenter;
		m_nStrAlignment = flexPicAlignLeftCenter;
		//-----
		
		m_flx.Cols = 2;

		m_flx.Editable = flexEDKbdMouse;
		
		///Frank 3/30/05	TREE_EDIT_SUPPORT_MOVE_ROWS
		m_bMoveRows = false;
		///End	TREE_EDIT_SUPPORT_MOVE_ROWS
		//flx.GridLines = flexGridInsetHorz;
	
		m_flx.OwnerDraw = flexODContent;	//flexODOver;
		//m_flx.ExplorerBar = flexExSortShow;
		m_flx.ExplorerBar = flexExNone; ///Frank 3/30/05 This value default should be None, because others case need code support
		m_flx.AllowUserResizing = flexResizeColumns;
			
		if(m_bIsFlatDialogDisplay)
		{
			m_flx.GridLines = flexGridFlat;
			m_flx.ExtendLastCol = false;
		}
		else if(bSubBranch)
			SetAlternateRowColors();			
			
		m_nEditRow = -1;	///DG VALIDATE_KILL_FOCUS
	}
	
	///Danice SUPPORT_GRID_VIEW
	void CreateTreeView()
	{
		SetTreeView(true);
		ClearAll();
		SetupRowsCols(0, 0, -1, 2);
		//m_flx.OutlineCol = 0;
		m_flx.OutlineBar = flexOutlineBarSimpleLeaf;
		m_flx.MergeCells = flexMergeSpill;
		
		//m_flx.SelectionMode = flexSelectionFree;//flexSelectionByRow;			//Forces selections to span entire rows.
		m_flx.AllowSelection = false;
		m_flx.GridLines = flexGridNone;
		
		m_flx.ExplorerBar = flexExNone;
	}
	void CreateGridView(int nRow=-1, int nCol=1)
	{
		SetTreeView(false);
		ClearAll();
		SetupRowsCols(1, 1, nRow, nCol);
		//m_flx.OutlineCol = 0;
		m_flx.OutlineBar = flexOutlineBarNone;
		m_flx.MergeCells = flexMergeNever;
		
		m_flx.AllowSelection = true;
		m_flx.GridLines=flexGridFlatVert;
		///Frank 3/30/05	TREE_EDIT_SUPPORT_MOVE_ROWS
		//m_flx.ExplorerBar = flexExSortShow;
		m_flx.ExplorerBar = flexExMoveRows;     //If you want to let Grid view can support move column and sort column, you can set this preporty.
		///End	TREE_EDIT_SUPPORT_MOVE_ROWS
		m_flx.AutoSizeMode = flexAutoSizeColWidth;
	}
	///end
	
	/// YuI 5/24/04 v7.5877 QA70-6118 NEW_DATA_SELECTOR_TOOL
	// this function just reinitializes tree control and VS Flexgrid with new updated tree
	bool	ReInit()
	{
		//m_bDataReady = FALSE;
		SetReadyFlag(false);
		RemoveSelection();
		Update(m_trEdit, false, true);
		//m_bDataReady = TRUE;
		SetReadyFlag(true);
		return true;
	}
	/// end NEW_DATA_SELECTOR_TOOL

	//----CPY 8/24/03 v7.5674 QA70-5061 ADD_DISPLAY_OPTIONS
	bool IsResizeOnCollapse(int nRow, int nState)
	{
		if(nRow < 0)
			return true;
		DWORD dwTemp = GetRowData(nRow);
		if(dwTemp)
		{
			if((GETNBRANCH_KEEP_SIZE_ON_COLLAPSE & dwTemp) && flexOutlineCollapsed == nState)
				return false;
			if((GETNBRANCH_KEEP_SIZE_ON_EXPAND & dwTemp) && nState < flexOutlineCollapsed)
				return false;
		}
		return true;// default is to resize
	}
	//----
	void SetGridLines(int nOption)
	{
		m_flx.GridLines = nOption; 
	}
	
	/// YuI 6/16/04 v7.5891 QA70-6556 DATA_RANGE_MARKERS
	/*
	bool UpdateFromDataSelector(DataSelector& ds, int nEditRow, bool bUpdateGridDisplay = true)
	{
		if(TreeEditInputData::UpdateFromDataSelector(ds, nEditRow))
		{
			if(bUpdateGridDisplay)
				UpdateGridValues();
			return true;
		}
		return false;
	}
	*/
	//---- CPY 4/25/05 XY_DATA_RANGE_INTERACTIVE_CONTORL_CHANGE_NOTIFICATION
	// this should not be needed, should just call base class and update of disply should be
	// done inside OnAfterEdit
	/*
	bool UpdateTreeFromDataRange(int nEditRow, bool bUpdateGridDisplay = true)
	{
		if(TreeEditInputData::UpdateTreeFromDataRange(nEditRow))
		{
			if(bUpdateGridDisplay)
				UpdateGridValues();
			return true;
		}
		return false;
	}
	*/
	//---- end XY_DATA_RANGE_INTERACTIVE_CONTORL_CHANGE_NOTIFICATION
	/// end DATA_RANGE_MARKERS
		
	//--- CPY 5/30/03 QA70-4577 EVENT_HANDLER_NEED_DIALOG_AND_VALUE_UPDATE, 1/17/04 CPY moved from private to public and added bChkCellResize
	bool UpdateGridValues(bool bChkCellResize = true, bool bCheckComboChange = false, bool bCheckChanged = true)  // ret true to indicate dialog needs resize to fit, grid size has changed
	{
		bool bRet = false;
		_DBSTR("UpdateGridValues");
		string strComboChanged;
		///Danice 9/17/04 SUPPORT_GRID_VIEW
		for(int ii=m_flx.FixedCols; ii < m_flx.Rows; ii++)
		{
			/*
			TreeNode trNode = get_tree_node(ii);
			if(!bCheckChanged || tree_node_changed(trNode))
			{
				trNode.RemoveAttribute(STR_CHANGED_ATTRIB);
				string strOldVal = m_flx.Cell(flexcpData, ii, EDIT_COL_INDEX);
				setGridCellValue(ii, EDIT_COL_INDEX, trNode);
				if(bChkCellResize && updateGridColWidth(ii, strOldVal))
					bRet = true;
			}
			if(bCheckComboChange && trNode.GetAttribute(STR_COMBO_CHANGED, strComboChanged))
			{
				trNode.RemoveAttribute(STR_COMBO_CHANGED);
				updateComboStr(ii, EDIT_COL_INDEX, trNode);
			}
			*/
			for(int jj = getEditColBegin(); jj<m_flx.Cols; jj++)
			{
				TreeNode trNode = get_tree_node(ii, jj);
				if(!trNode) continue;
				if(!bCheckChanged || tree_node_changed(trNode))
				{
					trNode.RemoveAttribute(STR_CHANGED_ATTRIB);
					string strOldVal = GetCell(flexcpData, ii, jj);
					setGridCellValue(ii, jj, trNode);
					if(bChkCellResize && updateGridColWidth(ii, strOldVal))
						bRet = true;
				}
				if(bCheckComboChange && trNode.GetAttribute(STR_COMBO_CHANGED, strComboChanged))
				{
					trNode.RemoveAttribute(STR_COMBO_CHANGED);
					updateComboStr(ii, jj, trNode);
				}
			}
		}
		///end SUPPORT_GRID_VIEW
		
		// following should not be needed as STR_CHANGED_ATTRIB should already be removed 
		//ASSERT(0==tree_remove_attribute(m_trEdit, STR_CHANGED_ATTRIB));
		///Frank 9/15/04 QA70-6086	SET_UNEDITABLE_AFTER_UPDATE_GRID 
		onAfterUpdateValues() ;
		///End	SET_UNEDITABLE_AFTER_UPDATE_GRID 

		return bRet;
	}
	//--- end CPY 5/30/03 QA70-4577 
	///Frank 6/22/04 QA70-6086         REFRESH_GRID_SHOW_NOT_RECONSTRUCT_ALL_GRIL_ROW
	void RefreashGridShow(TreeNode &tr, int nStartRow = 0, int nStopRow = -1)
	{
		if(tr.IsValid())
			m_trEdit = tr;
		
		int nEndRow = nStopRow;
		if(nStopRow == -1)
			nEndRow = m_flx.Rows;
		
		if(nEndRow < nStartRow|| nStartRow < 0)
			return ;
		
		m_flx.Redraw = flexRDNone;
		double fSizeFactor = 1.00;
		double fRowSizeFactor = fSizeFactor * ROW_HEIGHT_ENLARGER;
		double fTempFactor;
		
		for(int ii = nStartRow; ii < nEndRow ; ii++)
		{
			double fTempFactor = fRowSizeFactor;
			vector<int> vnBranchRowsToExpand;
			if(prepareEditCell(ii, fTempFactor, vnBranchRowsToExpand))
				SetRowHeight(ii, GetBaseRowHeight(fTempFactor));//0.5 + m_nRowHeight * fTempFactor;
			else
				SetRowHeight(ii, 0);
		};
		m_flx.Redraw = flexRDBuffered;
	}
	///End     REFRESH_GRID_SHOW_NOT_RECONSTRUCT_ALL_GRIL_ROW
	
	///DG VALIDATE_KILL_FOCUS
	//return true if change being validate, else change fail
	bool ValidateChanged()
	{
		if(!IsInEditing())
			return true;
		
		OnKillFocus();
		return true;
	}
	///end VALIDATE_KILL_FOCUS
	
	//---- CPY 7/19/04 GETN_EDIT_ALIGNMENTS
private:
	int get_value(LPCSTR lpcsz, int nDefault, int n1, int n2)
	{
		if(!is_numeric(lpcsz, false, false))
			return nDefault;
		return get_value(atoi(lpcsz), nDefault, n1, n2);
	}
	int get_value(int nn, int nDefault, int n1, int n2)
	{
		if(nn < n1 || nn > n2)
			return nDefault;
		return nn;
	}
	int get_alignment(int nn, int nDefault, bool bVerCetner = true)
	{
		return GetVsFlexAlignment(get_value(nn, nDefault, DISPLAY_LEFT, DISPLAY_RIGHT));
	}
	//---- end GETN_EDIT_ALIGNMENTS
private:
	void get_tree_display_settings();
public:	
//--------- CPY 9/1/05 SET_READY_FROM_BASE_CLASS_ONLY
//	bool SetReady(bool bSet) {bool bOld = m_bDataReady; m_bDataReady = bSet; return m_bDataReady;} // CPY 9/11/04 OPERATION_OUTPUT_TREE_IN_SPLITTER
//	bool IsReady() { return m_bDataReady; }	///DG 4/2/05
//---------
	bool Update(TreeNode& tr, bool bResize = true, bool bInit = false, bool bCallNodesHandlers = true);
	///Danice SUPPORT_GRID_VIEW
	bool UpdateGrid(TreeNode &tr, bool bChkCellResize = true, bool bTranspose=false, bool bCallNodesHandlers=true);	///DG 3/9/05 ADD_CALL_NODE_HANDLE : same as TreeView
	
	/// YuI 3/24/04 v7.5846 QA70-6118 NEW_DATA_SELECTOR_TOOL
	void		getTree(TreeNode& tr, BOOL bActiveCell = FALSE)
	{
		if( !m_trEdit.IsValid() )
			return;
		
		if( bActiveCell )
		{
			tr = get_tree_node(m_flx.Row);
		}
		else
		{
			tr = m_trEdit;
		}
	}
	
	void		getActiveRowCol(int& nRow, int& nCol)
	{
		nRow = m_flx.Row;
		nCol = m_flx.Col;
	}
	
	void		addTreeNode(TreeNode& tr)
	{
		m_trEdit.AddNode(tr);
	}
	/// end NEW_DATA_SELECTOR_TOOL
	
//protected:
public:
	void OnDestroy(void)
	{
		Cleanup();
		/// YuI 6/16/04 v7.5891 QA70-6556 DATA_RANGE_MARKERS
		TreeEditInputData::OnDestroy();
		/// end DATA_RANGE_MARKERS
	}
	
	void Cleanup()
	{
		EditorManager	trNodeManager;
		int nCol = EDIT_COL_INDEX;
		DWORD dwTemp;
		
		for(int nRow = 0; nRow < m_flx.Rows; nRow++)
		{
			///Danice 9/23/04 SUPPORT_GRID_VIEW
			/*
			// clean up Row Data
			dwTemp = m_flx.Cell(flexcpData, nRow, nCol);			
			trNodeManager.Delete(dwTemp);
			m_flx.Cell(flexcpData, nRow, nCol) = 0;
			*/
			for(nCol=0; nCol<m_flx.Cols; nCol++)
			{
				dwTemp = GetCell(flexcpData, nRow, nCol);			
				trNodeManager.Delete(dwTemp);
				SetCell(0, flexcpData, nRow, nCol);
			}
			///end SUPPORT_GRID_VIEW
		}
		
		m_bShowLabelCol = true;
		HideCol(-1, false);	///DG 4/12/05 : show all col for row and col setup again
		TreeEditInputData::Cleanup();
	}
	//virtual 
	void ClearAll()
	{
		Cleanup();
		/// YuI 10/26/04 v7.5891 QA70-6556 DATA_RANGE_MARKERS
		//	GridListControl::ClearAll();
		TreeEditInputData::ClearAll();
		/// end DATA_RANGE_MARKERS
	}

	/// YuI 7/22/04 v7.5102 QA70-6404 NEW_FUNCTION_MANAGER
	DWORD GetPropertyEditor(int nRow, int nCol)
	{
		return GetCell(flexcpData, nRow, nCol);
	}
	/// end NEW_FUNCTION_MANAGER
	
	void GetGridSize(int& nx, int& ny)
	{
		GridListControl::GetGridSize(nx, ny);
		if(!m_bIsFlatDialogDisplay)
		{
			ny += 3; // somehow needs spaces for the edge or something
			nx += 25;//CPY 3/28/04 changed from 24 to 25 after seeing Desc Stats GetN dlg not resized properly
		}
		else
		{
			ny += 3;
			nx += 21;
		}
	}
	virtual BOOL OnReconstructGrid(UINT wParam, UINT lParam)
	{
		BOOL bRet = FALSE;// return TRUE to indicate need for resize
		

		
		//m_bDataReady = false;
		SetReadyFlag(false);
		/// YuI 09/22/05 GETN_BUTTON_BRANCH_OPTION
		//	bool bNeedResize = (wParam & GRID_CHANGE_SHOW)? true : false;
		//	if(bNeedResize)
		//	{
			//	int nRow = m_flx.Row;
			//	int nCol = m_flx.Col;
			//	RemoveSelection();
			//	//--------- CPY 8/27/04 QA70-5890 v8.0125 BRANCH_ALLOW_CHECKBOX	
			//	//Update(m_trEdit, false);
			//	Update(m_trEdit, false, false, (wParam & GRID_CHANGE_SKIP_HANDLERS_ON_UPDATE)? false:true);
			//	//---------
			//	bRet = TRUE;
			//	if(nCol > 0 && nRow >= 0)
			//	{
			//		m_flx.Select(nRow,nCol);
			//	}
		//	}
		if( wParam & GRID_CHANGE_TREE_STRUCTURE || wParam & GRID_CHANGE_SHOW )
		{
			int nRow = m_flx.Row;
			int nCol = m_flx.Col;
			RemoveSelection();
			if( wParam & GRID_CHANGE_TREE_STRUCTURE )
				Update(m_trEdit, true, true, (wParam & GRID_CHANGE_SKIP_HANDLERS_ON_UPDATE)? false:true);
			else
				Update(m_trEdit, false, false, (wParam & GRID_CHANGE_SKIP_HANDLERS_ON_UPDATE)? false:true);
			bRet = TRUE;
			if(nCol > 0 && nRow >= 0)
			{
				m_flx.Select(nRow,nCol);
			}
		}
		/// end GETN_BUTTON_BRANCH_OPTION
		else
		{
			if(wParam & GRID_CHANGE_ENABLE)
				updateGridEnableSettings();
			
			if(wParam & GRID_CHANGE_COMBOSTR)//---- CPY v7.5785 12/19/03 QA70-5738 GETN_BOX_COMBO_CHANGE_NEEDED
				updateGridComboStrs();
			
			//----  CPY 5/30/03 QA70-4577 EVENT_HANDLER_NEED_DIALOG_AND_VALUE_UPDATE
			if(wParam & GRID_CHANGE_VALUE)
				bRet = UpdateGridValues();
			if(wParam & GRID_CHANGE_SIZE)
				bRet = true;
			//---- end 
		}

		//m_bDataReady = true;
		SetReadyFlag(true);
		return bRet;
	}
	///// vsFlexGrid events
	BOOL OnSetFocus()
	{
		m_flx.Col=1;
		m_flx.Row=0;
		return true;
	}
	
	/// YuI 01/03/2005 v7.5183 QA70-7253 VECTORIAL_NUMERIC_FUNCTIONS
	// moved to base class
	/*
	BOOL OnEditorKillFocus( uint wParam = 0, uint lParam=0 )
	{
		_DBSTR("")
		_DBINT3("On OnEditorKillFocus,[Edit Row, Col] ", m_nEditRow, m_nEditCol, m_dwEditor)
		
		if(0==m_dwEditor)
		{
			if(lParam)
			{
				_DBSTR("OnEditorKillFocus Error, this should not happen.");
			}
			return TRUE;
		}
		if(lParam && m_dwEditor != lParam)
		{
			// debug
			//printf("m_dwEditor=%X, lParam = %X\n", m_dwEditor, lParam);
		}
		//---- CPY 8/27/04 QA70-5890 v8.0125 BRANCH_ALLOW_CHECKBOX
		if(m_nEditRow < 0)
		{
			_DBSTR("OnEditorKillFocus skip, not in edit mode");
			return TRUE;
		}
		//----
			
		m_flx.Row = m_nEditRow;
		m_flx.Col = m_nEditCol;
		
		/// YuI 3/24/04 v7.5846 QA70-6118 NEW_DATA_SELECTOR_TOOL
		int nTempRow = m_nEditRow;
		int	nTempCol = m_nEditCol;
		/// end NEW_DATA_SELECTOR_TOOL

		///Frank 9/15/04 QA70-6086	SET_UNEDITABLE_AFTER_UPDATE_GRID 
		if(m_bOnAfterEditNeeded)
			OnAfterEdit(m_nEditRow, m_nEditCol);
		///End	SET_UNEDITABLE_AFTER_UPDATE_GRID 
			
		EditorManager	trNodeManager;
		
		DWORD dwTemp = m_dwEditor;
		m_dwEditor = 0;
		trNodeManager.DestroyEditor(dwTemp);
		
		/// YuI 3/24/04 v7.5846 QA70-6118 NEW_DATA_SELECTOR_TOOL
		OnDestroyEditor(nTempRow, nTempCol);
		/// end NEW_DATA_SELECTOR_TOOL
			
		
		return TRUE;
	}
	*/
	/// end VECTORIAL_NUMERIC_FUNCTIONS

	void OnDrawCell(UINT hDC, int nRow, int nCol, int nLeft, int nTop, int nRight, int nBottom, BOOL* pDone)
	{
		DWORD	dwTemp = GetCell(flexcpData, nRow, nCol);
		if(dwTemp)
		{
			EditorManager	trNodeManager;
			BOOL bSelected = nRow == m_flx.RowSel && nCol == m_flx.ColSel? true:false;
			RECT rect;
			SetRect(rect, nLeft, nTop, nRight, nBottom);
			//InflateRect(&rect, -m_nHaldGridLineWidth, -m_nHaldGridLineWidth);
			rect.right -= m_nHaldGridLineWidth;
			rect.bottom -= m_nHaldGridLineWidth;
			//_DBINT("in Drawcell, bSelected=", bSelected)
			*pDone = trNodeManager.DrawCell(dwTemp, hDC, &rect, bSelected); 
			return;
		}
		*pDone = FALSE;// let VSFlex grid to finish drawing cell
	}
	///---- CPY 9/2/04 GETN_STR_COMBO_NOT_UPDATING_EDIT_CELL
	
	
	///Danice 9/15/04 SUPPORT_GRID_VIEW
	//--------- CPY 9/18/04 GETN_TREE_LOST_ALL_BRANCH_LABELS
	int getEditColBegin()
	{
		if(IsTreeView())
			return EDIT_COL_INDEX;
			
		return m_flx.FixedRows;
	}
	//---------
	
	/// YuI 01/03/2005 v7.5183 QA70-7253 VECTORIAL_NUMERIC_FUNCTIONS
	// I am moving this function to the base class
	/*
	TreeNode get_tree_node(int nRow, int nCol=-1)
	{
		int nRowIndex = nRow - m_flx.FixedRows;
		int nColIndex = nCol - m_flx.FixedCols;
		if(IsTreeView())
		{
			///Danice 11/10/04 SUPPORT_EMPTY_TREENODE_AND_LABEL_CONTROL
			//when m_trEdit is only leave, tree_get_node() return junk, so as to support leave shown, return m_trEdit directly
			//return tree_get_node(m_trEdit, nRowIndex);
			if(m_trEdit.GetNodeCount() < 1 && 0 == nRowIndex)
				return m_trEdit;
			else
				return tree_get_node(m_trEdit, nRowIndex);
			///END
		}
		else
		{
			return m_trTable.GetTreeNode(nColIndex, nRowIndex);
		}
	}
	*/
	/// end VECTORIAL_NUMERIC_FUNCTIONS
	///end SUPPORT_GRID_VIEW

private:
	//----- CPY 9/10/05 IRIS_FOUND_BRANCH_COMBO_SINGLE_ITEM_WITH_SPACE_BECOMES_TWO
	bool isVsFlexStrListCombo(const TreeNode& trNode)
	{
		if(!trNode)
			return false;
		int nID = trNode.ID;
		if(TRGP_ENUM_LIST == nID)
			return true;
		if(TRGP_BRANCH == nID)
		{
			string str;
			if(trNode.GetAttribute(STR_ATTRIB_BRANCH_COMBO, str))
				return true;
		}
		return false;
	}
	
	//-----
	

	// there might be other types of combo,
	bool isVsFlexCombo(const TreeNode& trNode, bool& bIsDropDown) // drop down = edit cell, drop list = no edit cell
	{
		if(!trNode)
			return false;
		int nID = trNode.ID;
		bool bOK = IS_GETN_NODE_MAYBE_COMBO(nID)? true:false;
		//----- CPY 10/7/04 COMBO_BRANCH_FOR_MULTIPLE_RANGE_MODE
		if(!bOK)
		{
			string str;
			/// YuI 09/22/05 GETN_BUTTON_BRANCH_OPTION
			//	if(trNode.GetAttribute(STR_ATTRIB_BRANCH_COMBO, str))
			if( trNode.GetAttribute(STR_ATTRIB_BRANCH_COMBO, str) && str != STR_THREE_DOTS )
			/// end GETN_BUTTON_BRANCH_OPTION
				bOK = true;
		}
		//-----
		bIsDropDown = false;
		if(bOK)
		{
			string strCombo = get_node_combo_str(trNode, true);// CPY 9/10/05 IRIS_FOUND_BRANCH_COMBO_SINGLE_ITEM_WITH_SPACE_BECOMES_TWO, add true to get_node_combo_str
	
			if(!strCombo.IsEmpty() && strCombo[0] == '|')
				bIsDropDown = true;
			//----- CPY 12/1/04 QA70-6582 ADD_COMBO_IMAGE_TO_RIGHT_OF_EDIT_CELL
			else if(strCombo.IsEmpty()) 
				bOK = false;
			//-----
		}
		return bOK;
	}
	//-----
public:
	void OnComboCloseUp(int nRow, int nCol, BOOL* pFinishEdit)
	{
		//TreeNode trNode = get_tree_node(nRow);	///Danice 9/15/04 SUPPORT_GRID_VIEW
		TreeNode trNode = get_tree_node(nRow, nCol);
		///---- CPY 9/2/04 GETN_STR_COMBO_NOT_UPDATING_EDIT_CELL
		//if(trNode && (TRGP_NUMERIC_LIST == trNode.ID || TRGP_ENUM_LIST ==trNode.ID) )
		//{
		//	*pFinishEdit = true;
		//}
		//
		// dont know why this is needed, vsFlex should automatically take care of this
		bool bIsDropDown; // otherwise drop list
		if(isVsFlexCombo(trNode, bIsDropDown)) // otherwise some other type should not be possible though
		{
			//string strEdit = m_flx.EditText;
			int nIndex = m_flx.ComboIndex;
			if(-1 < nIndex)	 //Do selection
			{
				string strInCombo = GetComboItem(nIndex);
				//printf("Edit=%s, [%d]=%s\n", strEdit,nIndex, strInCombo);
				//------- CPY 11/19/05 QA70-8339 ROC_CURVE_NEEDS_STATE_VALUES moved here
				check_translate_OnComboCloseUp(trNode, strInCombo, m_flx.EditText);
				//-------
				m_flx.EditText = strInCombo;
			}
		}
		else // to get here the message has to be coming from vsFlex, so not likely to be otherwise
			out_str("OnComboCloseUp: Should never come here");
		//-----
	}
	
	void OnBeforeMouseDown(short nButton, short nShift, float X, float Y, BOOL* pCancel)
	{
		int iRow = m_flx.MouseRow;
		int iCol = m_flx.MouseCol;
		
		//OnEditorKillFocus();	///DG VALIDATE_KILL_FOCUS
		if((MK_RBUTTON != nButton) || (iRow != m_nEditRow) || (iCol != m_nEditCol))/// TD 09-19-2007 QA80-10117 GRID_CANT_PASTE
		OnKillFocus();
		
		//if(iCol == 0 && !IsTreeView()) // label col	///	Frank 3/30/05	TREE_EDIT_SUPPORT_MOVE_ROWS
		if(iCol == 0 && !IsTreeView() && (!getMoveRows() || iRow == 0) ) // label col
		{
			_DBINT("Quite at ", iRow)
			RemoveSelection();
			*pCancel = TRUE;
			return;
		}
		//TreeNode trNode = get_tree_node(iRow);	///Danice 9/15/04 SUPPORT_GRID_VIEW
		TreeNode trNode = get_tree_node(iRow, iCol);
		if(!trNode)
		{
			_DBINT("no tree node at row = ", iRow);
			///Danice 9/15/04 SUPPORT_GRID_VIEW
			//if(IsCancelMouseDown(iRow, iCol) || !getMoveRows())
			if(IsCancelMouseDown(iRow, iCol))
			{
			*pCancel = TRUE;
			return;
			}
			///end
		}
		//--- CPY 7/16/04 DISABLED_CHECK_BOX_STILL_WORK
		else //Danice 9/15/04 SUPPORT_GRID_VIEW: trNode is invald when sort column
		{
			//if(trNode.Enable == 0)		///Danice DISABLE_ROW_WITHOUT_GRAY_COLOR
			if(!isEnableEdit(trNode))
			{
				*pCancel = TRUE;
				return;
			}
			//---
			
			//--------- CPY 8/27/04 QA70-5890 v8.0125 BRANCH_ALLOW_CHECKBOX
			int nCheck = true;
			bool bIsCheckBox = false;
			if(iCol == 0 && isEditableBranch(trNode, &nCheck, &bIsCheckBox) && 0 == nCheck && bIsCheckBox)
			{
				GridListControl::OnBeforeMouseDown(nButton, nShift, X, Y, pCancel);
				*pCancel = TRUE;
				return;
			}
			//--------- end BRANCH_ALLOW_CHECKBOX
			
			/// YuI 3/24/04 v7.5846 QA70-6118 NEW_DATA_SELECTOR_TOOL
			//	if(iCol == 0 && trNode.ID != TRGP_BRANCH)
			if(iCol == 0 
				&& trNode.ID != TRGP_BRANCH 
				&& trNode.ID != TRGP_DATA_RANGE  
				&& trNode.ID != TRGP_XY_DATA_RANGE  /// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
				&& trNode.ID != TRGP_XYZ_DATA_RANGE  /// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
				&& trNode.ID != TRGP_XY_COMPLEX_DATA_RANGE  /// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
			)
			/// end NEW_DATA_SELECTOR_TOOL
			{
				_DBSTR("col = 0, skip OnBeforeMouseDown ")
				RemoveSelection();
				*pCancel = TRUE;
				return;
			}
			
			/// SY 08/24/2005 v8.0294 SHOW_DROPLIST_ON_ONE_CLICK
			if( MK_LBUTTON == nButton && 0 == nShift && IS_GETN_NODE_HAS_COMBO(trNode.ID) )
			{
				*pCancel = TRUE;
				m_flx.Select(iRow, iCol);
				m_flx.EditCell();
				HWND hWnd = (HWND)(long)m_flx.EditWindow;
				Window wnd(hWnd);
				if( wnd )
					wnd.SendMessage(CB_SHOWDROPDOWN, 1L, 0L);
				
				return;
			}
			/// end SHOW_DROPLIST_ON_ONE_CLICK
		}
		GridListControl::OnBeforeMouseDown(nButton, nShift, X, Y, pCancel);
	}
	void OnButtonClick(int nRow, int nCol)
	{
		//TreeNode trNode = get_tree_node(nRow);	///Danice 9/15/04 SUPPORT_GRID_VIEW
		TreeNode trNode = get_tree_node(nRow, nCol);
		//---- CPY v7.5785 12/18/03 QA70-5738 BUTTON_EVENT_SHOULD_SHARE_SAME_HANDLER_MANAGEMENT
		/*
		PEVENT_FUNC pfn = getEventHandler(trNode);
		
		if(pfn && trNode.IsValid())
		{
			if(pfn(m_trEdit, nRow, trNode.ID, *m_pdlg)) //CPY 5/30/03 QA70-4577 EVENT_HANDLER_NEED_DIALOG_AND_VALUE_UPDATE, add *this
			{
				string strOldVal = m_flx.Cell(flexcpText, nRow, nCol);
				m_flx.Cell(flexcpText, nRow, nCol) = trNode.Text;
				if(updateGridColWidth(nRow, strOldVal))
					PostDlgMessage(WM_USER_RECONSTRUCT, GRID_CHANGE_SIZE);
			}
		}
		*/
		invokeEventHandler(trNode, nRow, nCol);
		//---- end 12/18/03 QA70-5738 
				
	}
	void OnRowColChange()
	{
		//---------- CPY 9/1/05 SET_READY_FROM_BASE_CLASS_ONLY
		//if(!m_bDataReady)
		if(!IsReady())
		//----------
			return;
		
		int nRow = m_flx.Row;
		//TreeNode trNode = get_tree_node(nRow);	///Danice 9/15/04 SUPPORT_GRID_VIEW
		int nCol = m_flx.Col;
		TreeNode trNode = get_tree_node(nRow, nCol);
		
		if(trNode)
		{
			int nID = trNode.ID;
			switch(nID)
			{
			case TRGP_CHECK:
			case TRGP_ENUM_LIST:
			case TRGP_COLOR:
			case TRGP_RANGE:
			case TRGP_STR_BUTTON:
			case TRGP_SLIDEREDIT:///----- YuI 01/14/04 v7.5801 QA70-5799 SLIDER_CONTROL_TO_GETNBOX
			case TRGP_SLIDER:///----- YuI 01/14/04 v7.5801 QA70-5799 SLIDER_CONTROL_TO_GETNBOX
			case TRGP_INTERACTIVE:///----- YuI 1/26/04 v7.5807 QA70-5797 INTERACTIVE_TEXT_PROPERTY_IMPLEMENTATION
			case TRGP_MULTILINE_TEXT:/// YuI 7/23/04 v7.5103 QA70-6582 GETN_MULTILINE_TEXT_IMPLEMENTATION
			case TRGP_DOUBLE: //---- CPY 10/1/04 ADD_DATE_DISPLAY_INFO_FOR_WKBOOK_ORGANIZER
			case TRGP_BRANCH:	//---- CPY 12/29/04 QA70-5890 BRANCH_CHECK_BOX_CLICK_OUTSIDE_CHECK_TO_TOGGLE
			case TRGP_XY_DATA_RANGE:/// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
			case TRGP_XYZ_DATA_RANGE:/// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
			case TRGP_XY_COMPLEX_DATA_RANGE:/// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
			case ONODETYPE_CODE_EDITOR: /// TD 2-16-04 QA70-7368 CODE_EDITOR_IN_DIALOG
				break;
				
			default:
				DWORD	dwTemp = GetCell(flexcpData, nRow, EDIT_COL_INDEX);
				if(0 == dwTemp) // if there is a Propty object, then we should pass this along, for now, lets just ignore them
				{
					m_flx.EditCell();
					m_flx.EditSelStart = 0;
					m_flx.EditSelLength = 30000;  // try to select all
				}
				break;
			}
		}
	}
	void OnValidateEdit(int nRow, int nCol, BOOL* pCancel)
	{
		string strEdit = m_flx.EditText;
		DWORD	dwTemp = GetCell(flexcpData, nRow, nCol);
		if(dwTemp)
		{
			EditorManager	trNodeManager;
			if(!trNodeManager.ValidateEdit(dwTemp, strEdit))
				*pCancel = TRUE;
	
			return;
		}
	
		//TreeNode trNode = get_tree_node(nRow);	///Danice 9/15/04 SUPPORT_GRID_VIEW
		TreeNode trNode = get_tree_node(nRow, nCol);
		if(trNode)
		{
			if(is_node_need_numeric_validation(trNode))
			{
				check_translate(trNode, strEdit); /// EJP 12-16-2004 QA70-6721 ASCIMP_OPTIONS_USE_GETNBOX
				if(!is_numeric(strEdit))
					*pCancel = true;
			}
		}
	}
	///Frank 3/30/05	TREE_EDIT_SUPPORT_MOVE_ROWS
	void OnAfterMoveRows(int nRow, int *nPosition)
	{
		if(!m_bTranspose)
		{
			///Can not support transpose now, if want to support, please change m_flx.ExplorerBar to flexExMove
			///And add another two events OnBeforeMoveColumn and OnAfterMoveColumn.....following code are same.
			error_report("Can not support transpose TreeTable now");
		}
		treeMoveRows(nRow, *nPosition);
		ResetTreeTable();
		//out_str("After Move Rows");
	}
	void OnBeforeMoveRows(int nRow, int *nPosition)
	{
		//out_str("Before Move Rows");
	}	
	///End	TREE_EDIT_SUPPORT_MOVE_ROWS
private:
	/// EJP 12-16-2004 QA70-6721 ASCIMP_OPTIONS_USE_GETNBOX
	// check attribute STR_ATTRIB_SPECIALVALS, if present replace strEdit with corresponding mapping value
	// return false if no change
	bool check_translate(const TreeNode& trNode, string& strEdit, bool bValueToItem=false);
	/// end ASCIMP_OPTIONS_USE_GETNBOX
				
	bool check_translate_OnComboCloseUp(const TreeNode& trNode, string& strEdit, string strOldEdit);//------- CPY 11/19/05 QA70-8339 ROC_CURVE_NEEDS_STATE_VALUES moved here
	
	///---- CPY 7/15/04  YuI 3/24/04 v7.5846 QA70-6118 NEW_DATA_SELECTOR_TOOL
private:
	bool isDataRangeInteractiveNode(const TreeNode& trNode)
	{
		int nID = trNode.ID;
		
		if(nID != TRGP_DATA_RANGE && nID != TRGP_INTERACTIVE)
			return false;
		

		PageBase pg = Project.Pages();
		BOOL bNonGraphPage = ( !pg || pg.GetType() != EXIST_GRAPH);
		if( bNonGraphPage && nID == TRGP_DATA_RANGE )
			return true;

		/// YuI 07/22/05 INTERACTIVE_CONTROL_SHOULD_BE_EDITABLE_IN_GRAPH
		//	if( !bNonGraphPage && (nID == TRGP_INTERACTIVE || (nID == TRGP_DATA_RANGE && is_xyz_data_range_node(trNode))) )
		//		return true;
		if( !bNonGraphPage && (nID == TRGP_DATA_RANGE && is_xyz_data_range_node(trNode)) )
			return true;
		/// end INTERACTIVE_CONTROL_SHOULD_BE_EDITABLE_IN_GRAPH
	}		
	///---- end CPY 7/15/04
	
	
	
public:	
	///Danice 9/14/04 SUPPORT_GRID_VIEW
	virtual bool IsEditable(int nRow, int nCol)
	{
		if(IsTreeView())
		{
			if(nCol != EDIT_COL_INDEX)
				return false;
			
			return true;
		}
		// then it is a grid
		return true;
	}
	bool IsCancelMouseDown(int nRow, int nCol)
	{
		///Frank 3/30/05	TREE_EDIT_SUPPORT_MOVE_ROWS
		/*
		if(!IsTreeView() && 0 == nRow)	//click header
			return false;
		*/
		if((!IsTreeView() && 0 == nRow) || ( getMoveRows() && 0< nRow))	//click header
			return false;
		///End	TREE_EDIT_SUPPORT_MOVE_ROWS
		return true;
	}
	///end SUPPORT_GRID_VIEW
	void OnBeforeEdit(long nRow, long nCol, BOOL* pCancel)
	{		
		///Danice 9/14/04 SUPPORT_GRID_VIEW
		/*if(nCol != EDIT_COL_INDEX)
		{
			*pCancel = TRUE;
			return;
		}*/
		if(!IsEditable(nRow, nCol))
		{
			*pCancel = TRUE;
			return;
		}
		///end SUPPORT_GRID_VIEW
		
				
		//TreeNode trNode = get_tree_node(nRow);	///Danice 9/15/04 SUPPORT_GRID_VIEW
		TreeNode trNode = get_tree_node(nRow, nCol);
		if(trNode)
		{
			//-------- CPY 8/27/04 QA70-5890 v8.0125 BRANCH_ALLOW_CHECKBOX
			//if(trNode.Enable == 0 || TRGP_BRANCH == trNode.ID )
			if(!isGeneralEdit(trNode, nCol))
			//--------
			{
				//printf("No Edit, nRow = %d, tr.Enable = %d, tr.ID = %d\n", nRow, trNode.Enable, trNode.ID);
				*pCancel = TRUE;
				return;
			}
			//_DBINT3("OnBeforeEdit, [nRow, tr.Enable] tr.ID =", nRow, trNode.Enable, trNode.ID);
		}
		
		/// end NEW_DATA_SELECTOR_TOOL
		
		DWORD	dwTemp = GetCell(flexcpData, nRow, nCol);
		//_DBINT("OnBeforeEdit cell data = ", dwTemp)
		
		///DG VALIDATE_KILL_FOCUS
		m_nEditRow = nRow;
		m_nEditCol = nCol;
		///end VALIDATE_KILL_FOCUS

		if(dwTemp)
		{
			*pCancel = TRUE;
			if(m_dwEditor) // busy, possible due to come messaging problem
			{
				_DBINT("OnBeforeEdit, should be NULL, but has ", m_dwEditor)
				return;
			}
			if(nRow != m_flx.MouseRow || nCol != m_flx.MouseCol)
			{
				_DBSTR("Custom Editor must be initiated from mouse click only")
				return;
			}

			EditorManager	trNodeManager;
			string strCombo, strEditMask;
			m_flx.ComboSearch = trNodeManager.GetEditInfo(dwTemp, strCombo, strEditMask);
			m_flx.ComboList = strCombo;
			m_flx.EditMask = strEditMask;
			
			
			///---- CPY SY 10/06/2004 QA70-6582 v8.0145 GETN_LIST_DROP_DOWN
			// Block change, the original code removed, please refer source safe if need
			if(OnBeforeCreateEditor(trNode, nRow, nCol))
			{
				RECT rect;
				GetCellRect(nRow, nCol, rect);
				string strFontName = GetCell(flexcpFontName, nRow, nCol);
				int nFontSize = GetCell(flexcpFontSize, nRow, nCol);

				/// YuI 07/22/05 INTERACTIVE_CONTROL_SHOULD_BE_EDITABLE_IN_GRAPH
				//	m_dwEditor = trNodeManager.CreateEditor(dwTemp, &rect, GetDlgSafeHwnd(), EDITOR_ID, strFontName, nFontSize);
				PageBase pg = Project.Pages();
				BOOL bGraphPage = pg ? (pg.GetType() == EXIST_GRAPH) : FALSE;
				m_dwEditor = trNodeManager.CreateEditor(dwTemp, &rect, GetDlgSafeHwnd(), EDITOR_ID, strFontName, nFontSize, bGraphPage);
				/// end INTERACTIVE_CONTROL_SHOULD_BE_EDITABLE_IN_GRAPH
				
				if(m_dwEditor)
				{
					int nOK = trNodeManager.StartEdit(dwTemp, nRow);
					///DG VALIDATE_KILL_FOCUS : make kill focus more general, move out
					/*
					_DBINT("Start Edit returns ", nOK)
					m_nEditRow = nRow;
					m_nEditCol = nCol;
					*/
					///end VALIDATE_KILL_FOCUS
		
					/// YuI 3/24/04 v7.5846 QA70-6118 NEW_DATA_SELECTOR_TOOL
					if( !OnAfterCreateEditor(trNode, nRow, nCol) )
					{
						//OnEditorKillFocus();	///DG VALIDATE_KILL_FOCUS
						OnKillFocus();
						return;
					}
					/// end NEW_DATA_SELECTOR_TOOL
					
					m_bOnAfterEditNeeded = true;///Frank 9/15/04 QA70-6086	SET_UNEDITABLE_AFTER_UPDATE_GRID 
					return;
				}
				_DBSTR("OnBeforeCreateEditor=true, but CreateEditor NULL");
			}
			_DBPRINTF("BeforeEdit has Cell data, but use normal vsFlex edit, combostr = %s\n", strCombo);
			*pCancel = FALSE; // no editor created, allow grid's own editor
			
			///---- end CPY SY 10/06/2004 QA70-6582 v8.0145 GETN_LIST_DROP_DOWN
		}
		else
		{
			string str = m_flx.EditMask;
			if(!str.IsEmpty())
			{
				str.Empty();
				m_flx.EditMask = str;
			}
		}
		
		//if(nCol != EDIT_COL_INDEX || NULL == trNode) // col(0) parameter labels, cannot edit 
		if(!IsEditable(nRow, nCol) || NULL == trNode)	///Danice SUPPORT_GRID_VIEW
		{
			*pCancel = TRUE;
			m_nEditRow = -1;	///DG VALIDATE_KILL_FOCUS
			return;
		}
		if(0==dwTemp) //CPY SY 10/06/2004 QA70-6582 v8.0145 GETN_LIST_DROP_DOWN, already setup in GetEditInfo
			m_flx.ComboList = get_node_combo_str(trNode, true);
	}

	
	//virtual
	void OnAfterEdit(int nRow, int nCol);

#ifdef _INTERACTIVE_CNTRL_IN_FLEX_GRID //---- CPY 10/14/06 MOVE_OPERATION_OUT_OF_SYS_FOLDER	
	
	/// YuI 1/26/04 v7.5807 QA70-5797 INTERACTIVE_TEXT_PROPERTY_IMPLEMENTATION
public:
	BOOL	OnSelectionChange()
	{
		string strText;
		int nType = getActiveWksMatrixSel(strText);
		if( nType == EXIST_WKS || nType == EXIST_MATRIX )
		{
			EditorManager	trNodeManager;
			if( updateActiveWksSel(strText, nType) )
				trNodeManager.SetEditorStr(m_dwEditor, strText);
				
			return trNodeManager.OnSelectionChange(m_dwEditor);
		}
		
		return FALSE;
	}
	
	BOOL	OnSelectionTrack()
	{
		string strText;
		int nType = getActiveWksMatrixSel(strText);
		if( nType == EXIST_WKS || nType == EXIST_MATRIX )
		{
			EditorManager	trNodeManager;
			if( updateActiveWksSel(strText, nType) )
				trNodeManager.SetEditorStr(m_dwEditor, strText);
				
			return trNodeManager.OnSelectionTrack(m_dwEditor);
		}
		
		return FALSE;
	}
protected:
	//---- CPY Yuri 6/18/04 CONTEXT_MENU_CLEANUP
	// add trSelNode arg and create centralized handler doContextMenuPopup
	/// YuI 3/24/04 v7.5846 QA70-6118 NEW_DATA_SELECTOR_TOOL
	bool	DoInputDataContextMenu(TreeNode& trSelNode, int nx, int ny, int nCol, int nRow)
	{
		/// Iris 02/04/06 QA70-8480 UPDATE_DATA_RANGE_MANIPULATION
		//TreeEditInputDataMenu myMenu(trSelNode, nRow, nCol);
		//doContextMenuPopup(myMenu, nx, ny); 
		GraphLayer gl = Project.ActiveLayer();
		if(gl)
		{
			TreeEditInputDataMenu myMenu(trSelNode, nRow, nCol);
			doContextMenuPopup(myMenu, nx, ny); 
		}
		///End UPDATE_DATA_RANGE_MANIPULATION
		return true;
	}
	bool	DoDataRangeContextMenu(TreeNode& trSelNode, int nx, int ny, int nCol, int nRow)
	{
		/// Iris 02/04/06 QA70-8480 UPDATE_DATA_RANGE_MANIPULATION
		TreeNode trInputData = trSelNode.Parent();
		if(!trInputData)
			return false;
		if(trInputData.GetNodeCount() <= 1)
			return false;
		///End UPDATE_DATA_RANGE_MANIPULATION
		
		TreeEditDataRangeMenu myMenu(trSelNode, nRow, nCol);
		doContextMenuPopup(myMenu, nx, ny); 
		return true;
	}
#endif //#ifdef _INTERACTIVE_CNTRL_IN_FLEX_GRID //---- CPY 10/14/06 MOVE_OPERATION_OUT_OF_SYS_FOLDER	

private:	
	void doContextMenuPopup(MenuBase& aMenu, int nx, int ny)
	{
		int nRet = aMenu.DoTrackPopup(nx, ny, m_pdlg->GetSafeHwnd()); // need update if > 0
		if(TREE_STRUCT_CHANGED == nRet)
			ReInit();
		else if(TREE_VAL_CHANGED == nRet)
			UpdateGridValues();
		
		PostDlgMessage(WM_USER_TREEEDITOR_VALUE_CHANGE);///Danice 9/12/04 UPDATE_VALUE_CHANGE
	}
	//---- end CPY Yuri 6/18/04
	
	//---- CPY 7/25/05 ON_AFTER_EDIT_BETTER_CHANGE_DETECTION
	bool isValueChanged(TreeNode& trNode, const string& strNew, const string& strOld)
	{
		if(strNew == strOld)
			return false;
		// check if numeric
		int nNodeType = trNode.ID;
		if(TRGP_CHECK == nNodeType ||
		   TRGP_ENUM_LIST == nNodeType ||
		   TRGP_COLOR == nNodeType)
		{
			int nNew = atoi(strNew);
			int nOld = atoi(strOld);
			return nNew == nOld? false:true;
		}
		return true;
	}
	//---- end CPY 7/25/05
protected:
	//////////////////////////////////////////////////////
	/// end NEW_DATA_SELECTOR_TOOL
	
	///Danice 6/15/04
	bool	DoDefaultContextMenu(TreeNode& trSelNode, int nx, int ny, int nCol, int nRow)
	{
		string strBranch;
		///-----Forest 9/14/04 QA70-6682 REMOVE_THEME_CONTEXT_MENU, remove if
		//if(m_strThemeFilePrefix.GetLength() == 0)	///Forest 9/12/04 QA70-6682 SETTINGS_THEME_FILE_SAVE_LOAD, add if
		//{
		if( !trSelNode || !trSelNode.GetAttribute(STR_ATTRIB_BRANCH, strBranch) || !(GETNBRANCH_SAVE_SETTINGS & atoi(strBranch)) )
			return false;
		//}
		///-----
		
		///Danice v8.0890 6/16/04 QA70-6222 COMBINE_TREEEDIT_SAVE_AND_COPY_SETTING
		///---Frank  v8.0890 6/15/04 QA70-6222 GETNTREE_CONTEXT_MENU_MORE_SETTING	
		//if((GETNBRANCH_SAVE_SETTINGS & atoi(strBranch)))
		//{
		//TreeEditSaveSettingMenu myMenu(trSelNode, nRow, nCol); ///Forest 9/12/04 QA70-6682 SETTINGS_THEME_FILE_SAVE_LOAD, add boolean
		//TreeEditSaveSettingMenu myMenu(trSelNode, nRow, nCol, m_strThemeFilePrefix, m_trEdit); ///Forest 9/14/04 QA70-6682 REMOVE_THEME_CONTEXT_MENU
		TreeEditSaveSettingMenu myMenu(trSelNode, nRow, nCol, m_strThemeFilePrefix);
		
		int nRet = myMenu.DoTrackPopup(nx, ny, m_pdlg->GetSafeHwnd());
		if(TREE_VAL_CHANGED == nRet)
		{
			UpdateGridValues(false, false, false);
			//PostDlgMessage(WM_USER_TREEEDITOR_VALUE_CHANGE, nRow, 1);/////PostMessage back , here lPara = 1 mean will update the section storage
			PostDlgMessage(WM_USER_TREEEDITOR_VALUE_CHANGE, nRow, 0);/////PostMessage back , here lPara = 1 mean will update the section storage
		}
		//}
		/*
		else
			if((GETNBRANCH_COPY_SETTINGS & atoi(strBranch)))
			{
				TreeEditCopySettingMenu myMenu(trSelNode, nRow, nCol);
				bool bNeedUpdateValues;
				myMenu.DoTrackPopup(nx, ny, m_pdlg->GetSafeHwnd(), bNeedUpdateValues);
				if(bNeedUpdateValues)
				{
					UpdateGridValues(false, false, false);
					PostDlgMessage(WM_USER_TREEEDITOR_VALUE_CHANGE, nRow, 1);/////PostMessage back , here lPara = 1 mean will update the section storage
				}
			}
			else
				return false;
		///---End	 GETNTREE_CONTEXT_MENU_MORE_SETTING	
		*/
		///end COMBINE_TREEEDIT_SAVE_AND_COPY_SETTING
		return true;

	}
	///END Danice 6/15/04
	
	//////////////////////////////////////////////////////
public:	
	///Danice QA70-6222 RIGHT_CLICK_ACCESS
	BOOL OnShowMenu(UINT nResIDCtrl, int nx, int ny)
	{
		int nxTemp, nyTemp, nRow, nCol;
		int nClickRow, nClickCol;
		GetSelCell(nxTemp, nyTemp, nRow, nCol);
		FindCell(nx, ny, nClickRow, nClickCol);
		///Danice SUPPORT_RIGHT_CLICK_SELECTION
		/*
		if(nClickRow != nRow || nClickCol != nCol)
			return false;
		*/
		if(nClickRow != nRow)
		{
			nRow = nClickRow;
			SelRow(nRow);
		}
		///end SUPPORT_RIGHT_CLICK_SELECTION
		
		//nCol = nClickCol; ///Forest 9/12/04 QA70-6682 SETTINGS_THEME_FILE_SAVE_LOAD ///Forest 9/14/04 QA70-6682 REMOVE_THEME_CONTEXT_MENU
		
		//TreeNode trSelNode = get_tree_node(nRow);	///Danice 9/15/04 SUPPORT_GRID_VIEW
		TreeNode trSelNode = get_tree_node(nRow, nCol);
#ifdef _INTERACTIVE_CNTRL_IN_FLEX_GRID //---- CPY 10/14/06 MOVE_OPERATION_OUT_OF_SYS_FOLDER	
		//if(0 == nCol && trSelNode.IsValid() && trSelNode.GetNodeCount()>0)	///DG UNLIMIT_CONTEXT_MENU_IN_COL_TEXT : now getnbox col text can not be selected
		if(trSelNode.IsValid() && trSelNode.GetNodeCount()>0)
		{
			switch( trSelNode.ID )
			{
			case TRGP_DATA_RANGE:
				return DoDataRangeContextMenu(trSelNode, nx, ny, nCol, nRow);
			default:
				{
					if( trSelNode.ID == TRGP_BRANCH && trSelNode.FirstNode && trSelNode.FirstNode.ID == TRGP_DATA_RANGE )
						return DoInputDataContextMenu(trSelNode, nx, ny, nCol, nRow);
					
					return DoDefaultContextMenu(trSelNode, nx, ny, nCol, nRow);			
				}
			}
		}
		///----Forest 9/14/04 QA70-6682 REMOVE_THEME_CONTEXT_MENU
		//else if(m_strThemeFilePrefix.GetLength() > 0)	///Forest 9/12/04 QA70-6682 SETTINGS_THEME_FILE_SAVE_LOAD
		//	return	DoDefaultContextMenu(trSelNode, nx, ny, nCol, nRow);
		///----
		return true;
#else
		return	DoDefaultContextMenu(trSelNode, nx, ny, nCol, nRow);
#endif
	}
	///END RIGHT_CLICK_ACCESS
	/// end INTERACTIVE_TEXT_PROPERTY_IMPLEMENTATION
//-- CPY 4/12/04 SLIDER_TRACK_NOTIFICATION
	int GetEditRow() {return m_nEditRow;}
	TreeNode GetEditNode()
	{
		TreeNode tr;
		if(m_nEditRow < 0)
			return tr;
		
		return get_tree_node(m_nEditRow);
	}
//--
	
private:
	/// YuI 03/14/2005 MATRIX_OBJECT_SELECTION
	BOOL updateActiveWksSel(string& strSelection, int nSelectionType);
	/*
	//----- CPY 3/31/04 remove get_active_wks_selection
	BOOL getActiveWksSel(string& strSelection)
	{
		vector<string> vsTemp;
		int nType = Project.GetSelection(vsTemp);
		if(nType == EXIST_WKS)
		{
			strSelection = vsTemp[0];
			return TRUE;
		}
		
		return FALSE;
	}
	//------
	*/
	
	int getActiveWksMatrixSel(string& strSelection)
	{
		vector<string> vsTemp;
		int nType = Project.GetSelection(vsTemp);
		strSelection = vsTemp[0];
		return nType;
	}
	/// end MATRIX_OBJECT_SELECTION
	//------------------------------------------------------------------------- CPY 8/3/04 GETN_DLG_CALL_NODE_BASED_EVENT_HANDLERS_ON_INIT
	// this is called on Init, before Update, so no need to check change etc
	int invokeAllNodesHandlers()
	{
		int nRow = 0;
		int nCalls = 0;
		//---- CPY 5/20/05 QA70-7744 NEW_GETN_EVENT
		//if(IsTreeView())
			nCalls = invokeNodesHandlers(m_trEdit, nRow);
		// it seems that we need to call all the nodes, regardless if they are shown on the grid,so cannot use code below
		/*
		else // grid view
		{
			for(int ii = m_flx.FixedRows; ii < m_flx.Rows; ii++)
			{
				for(int jj = m_flx.FixedRows; jj < m_flx.Cols; jj++)
				{
					TreeNode trNode = get_tree_node(ii, jj);
					PEVENT_NODE_FUNC pfn = getEventHandlerRowCol(trNode);
					if(pfn)
					{
						if(pfn(m_trEdit, ii, jj, trNode, GETNEVENT_VIEW_LIST | GETNEVENT_ON_INIT, trNode.ID, *m_pdlg))
							nCalls++;
					}
				}
			}
		}
		*/
		//---- end NEW_GETN_EVENT
		// also check if tree level handler is present
		/*
		PEVENT_FUNC pfn = m_pfnEvent;
		TreeNode trNode = m_trEdit;

		if(trNode)
		{
			if(pfn(m_trEdit, -1, 0, *m_pdlg))
				nCalls++;
		}
		*/
		return nCalls;
	}
	// recursive call helper
	int invokeNodesHandlers(TreeNode& tr, int& nRow)
	{
		int nCalls = 0;
		
		foreach(TreeNode trNode in tr.Children)
		{
			//---- CPY 5/20/05 QA70-7744 NEW_GETN_EVENT
			/*
			PEVENT_FUNC pfn = getEventHandler(trNode, true);
			//uint wParam = 0;
			if(pfn)
			{
				if(pfn(m_trEdit, nRow, trNode.ID, *m_pdlg))
					nCalls++;
			}
			*/
			DWORD dwfnRC, dwfnR;
			if(getEventHandler(trNode, dwfnRC, dwfnR, true))
			{
				bool bRet = false;
				//printf("calling handler (%s), rc=%X, r=%X, nRow=%d\n", trNode.tagName,dwfnRC, dwfnR);
				if(dwfnRC)
				{
					PEVENT_NODE_FUNC pfn = (PEVENT_NODE_FUNC)dwfnRC; 
					///-----Frank 5/26/05	GETN_EVENT_SUPPORT_GRID_VIEW
					//bRet = pfn(m_trEdit, nRow, -1, trNode, GETNEVENT_ON_INIT | (IsTreeView()?0:GETNEVENT_VIEW_LIST), trNode.ID, *m_pdlg);

					int nGridRow, nGridCol;
					getViewColRow(nRow  , nGridRow, nGridCol);
					
					bRet = pfn(m_trEdit, nGridRow, nGridCol, trNode, GETNEVENT_ON_INIT | (IsTreeView()?0:GETNEVENT_VIEW_LIST), trNode.ID, *m_pdlg);
					///-----End	GETN_EVENT_SUPPORT_GRID_VIEW
				}
				else if(dwfnR)
				{
					PEVENT_FUNC pfn = (PEVENT_FUNC)dwfnR; 
					bRet = pfn(m_trEdit, nRow, trNode.ID, *m_pdlg);
				}
				if(bRet)
					nCalls++;
			}
			//----- end NEW_GETN_EVENT
			nRow++;
			
			if(trNode.GetNodeCount() > 0) // branch node
				nCalls += invokeNodesHandlers(trNode, nRow);
		}
		return nCalls;
	}
	//------------------------------------------------------------------------- end GETN_DLG_CALL_NODE_BASED_EVENT_HANDLERS_ON_INIT
	
	//---- CPY v7.5785 12/18/03 QA70-5738 BUTTON_EVENT_SHOULD_SHARE_SAME_HANDLER_MANAGEMENT
	//CPY 10/26/05 INTERACTIVE_CONTOROL_NEED_UPDATE_RESIZE_GETN_GRID, changed return to bool and return true only if event handler lead to eventual PostMessage 
	///Frank 11/16/05 QA70-8293 RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
	//bool invokeEventHandler(TreeNode trNode, int nRow, int nCol, bool bCheckCellSizeChange = false, string strOldVal = "")
	int invokeEventHandler(TreeNode trNode, int nRow, int nCol, bool bCheckCellSizeChange = false, string strOldVal = "")
	///End RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
	{
		//PEVENT_FUNC pfn = getEventHandler(trNode);
		DWORD dwfnRC, dwfnR;
		if(!getEventHandler(trNode, dwfnRC, dwfnR))
			return false;
		
		uint wParam = 0;
		///-----Frank 11/16/05 QA70-8293 RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
		/*
		// we need to know if event handler has changed any .Show 
		vector<int> vSaveShows; tree_get_shows(m_trEdit, vSaveShows);
		vector<int> vSaveEnables; tree_get_enables(m_trEdit, vSaveEnables);
		vector<string> vSaveValues; tree_get_values(m_trEdit, vSaveValues);//CPY 5/30/03 QA70-4577 EVENT_HANDLER_NEED_DIALOG_AND_VALUE_UPDATE
		vector<string> vsSaveCombos; tree_get_attributes(m_trEdit,vsSaveCombos, STR_COMBO_ATTRIB); //---- CPY v7.5785 12/19/03 QA70-5738 GETN_BOX_COMBO_CHANGE_NEEDED
		/// YuI 09/22/05 GETN_BUTTON_BRANCH_OPTION
		int	nSavedNodeCount = tree_count_items_by_attribute(m_trEdit);
		vector<string> vsSaveLabels; tree_get_attributes(m_trEdit, vsSaveLabels, STR_LABEL_ATTRIB); 
		/// end GETN_BUTTON_BRANCH_OPTION
		*/
		GetNTreeChanges gnMsg(m_trEdit);
		///-----End RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC

		//bool bRet = false;
		int nRet =HANDLER_NOT_CALLED;
		if(dwfnRC)
		{
			PEVENT_NODE_FUNC pfn = (PEVENT_NODE_FUNC)dwfnRC; 
			//bRet = pfn(m_trEdit, nRow, nCol, trNode, IsTreeView()?0:GETNEVENT_VIEW_LIST, trNode.ID, *m_pdlg);
			if(pfn(m_trEdit, nRow, nCol, trNode, IsTreeView()?0:GETNEVENT_VIEW_LIST, trNode.ID, *m_pdlg))
				nRet =HANDLER_MSG_POSTED;
		}
		else if(dwfnR)
		{
			PEVENT_FUNC pfn = (PEVENT_FUNC)dwfnR; 
			///-----Frank 11/15/05 RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
			//bRet = pfn(m_trEdit, nRow, trNode.ID, *m_pdlg);
			if(pfn(m_trEdit, nRow, trNode.ID, *m_pdlg))
				nRet =HANDLER_MSG_POSTED;
			///-----End RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
		}
		///-----Frank 11/15/05 RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
		else
			return HANDLER_NOT_CALLED;
		///-----End RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
			
		//if(bRet)
		if(nRet != HANDLER_NOT_CALLED )
		{
			///-----Frank 11/16/05 QA70-8293 RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
			/*
			//out_str("need to update");
			vector<int> vShows; tree_get_shows(m_trEdit, vShows);
			wParam = is_same(vShows, vSaveShows)? 0 : GRID_CHANGE_SHOW;
			
			vector<int> vEnables; tree_get_enables(m_trEdit, vEnables);
			if(!is_same(vEnables, vSaveEnables))
				wParam |= GRID_CHANGE_ENABLE;
			
			int nChanges = tree_update_changes(m_trEdit, vSaveValues);
			if(nChanges > 0)
				wParam |= GRID_CHANGE_VALUE;
			
			//---- CPY v7.5785 12/19/03 QA70-5738 GETN_BOX_COMBO_CHANGE_NEEDED
			vector<string> vsCombos; tree_get_attributes(m_trEdit, vsCombos, STR_COMBO_ATTRIB);
			int nChanged = get_changed(vsCombos, vsSaveCombos);
			if(nChanged >= 0)
			{
				// save index into tree for faster update later
				string strTemp = nChanged;
				m_trEdit.SetAttribute(STR_COMBO_CHANGED, strTemp);
				wParam |= GRID_CHANGE_COMBOSTR;
			}
			//---- end GETN_BOX_COMBO_CHANGE_NEEDED
			
			/// YuI 09/22/05 GETN_BUTTON_BRANCH_OPTION
			int nNodeCount = tree_count_items_by_attribute(m_trEdit);
			if( nNodeCount != nSavedNodeCount )
				wParam |= GRID_CHANGE_TREE_STRUCTURE;
			
			vector<string> vsLabels; tree_get_attributes(m_trEdit, vsLabels, STR_LABEL_ATTRIB);
			nChanged = get_changed(vsLabels, vsSaveLabels);
			if(nChanged >= 0)
				wParam |= GRID_CHANGE_TREE_STRUCTURE;
			/// end GETN_BUTTON_BRANCH_OPTION
			*/
			wParam = gnMsg.GetMsg();
			///-----End RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
		}
		if(bCheckCellSizeChange && !(wParam & GRID_CHANGE_VALUE) && !(wParam & GRID_CHANGE_SHOW))
		{
			if(updateGridColWidth(nRow, strOldVal))
				wParam |= GRID_CHANGE_SIZE;
		}
		
		///-----Frank 11/16/05 QA70-8293 RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
		//if(wParam)
		if(wParam && nRet == HANDLER_MSG_POSTED)
		///-----End RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
		{
			PostDlgMessage(WM_USER_RECONSTRUCT, wParam | GRID_CHANGE_SKIP_HANDLERS_ON_UPDATE);
			//---- CPY 10/26/05 INTERACTIVE_CONTOROL_NEED_UPDATE_RESIZE_GETN_GRID
			//return (wParam & GRID_CHANGE_SIZE)? true:false;
			return (wParam & GRID_CHANGE_SIZE)? nRet:HANDLER_MSG_POSTED;			///-----Frank 11/16/05 QA70-8293 RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
			//----
		}
		//return false;
		return HANDLER_MSG_POSTED;			///-----Frank 11/16/05 QA70-8293 RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
	}
	//--- end 12/18/03 QA70-5738
	
	//------- CPY 5/20/05 QA70-7744 NEW_GETN_EVENT
	/*
	PEVENT_FUNC getEventHandler(const TreeNode& trNodeRow, bool bNodeHandlerOnly = false)
	{
		//--- CPY 8/24/03 v7.5674 QA70-5061 ADD_DISPLAY_OPTIONS
		if(trNodeRow)
		{
			string strTemp;
			if(trNodeRow.GetAttribute(STR_ATTRIB_HANDLER, strTemp) && !strTemp.IsEmpty())
			{
				DWORD dwTemp = atoi(strTemp);
				PEVENT_FUNC pfn = (PEVENT_FUNC)dwTemp;
				if(pfn)
					return pfn;
				return NULL; // if handler is set but not valid, we can diable generic handler 
			}
		}
		if(bNodeHandlerOnly)
			return NULL;
		
		PEVENT_FUNC temp_pEventFunc = m_pfnEvent;// wait until we can call member function pointer directly
		TreeNode trNode = m_trEdit;

		if(trNode)
			return temp_pEventFunc;
		
		return NULL;
	}
	*/
	bool getEventHandler(const TreeNode& trNode, DWORD& dwRC, DWORD& dwRowOnly, bool bNodeHandlerOnly = false)
	{
		dwRC = dwRowOnly = 0;
		if(!trNode)
			return false;
		string strTemp;
		DWORD dwTemp;
		if(trNode.GetAttribute(STR_ATTRIB_HANDLER_RC, strTemp) && !strTemp.IsEmpty())
		{
			dwTemp = atoi(strTemp);
			PEVENT_NODE_FUNC pfn = (PEVENT_NODE_FUNC)dwTemp;
			if(pfn)
				dwRC = dwTemp;
		}
		if(trNode.GetAttribute(STR_ATTRIB_HANDLER, strTemp) && !strTemp.IsEmpty())
		{
			DWORD dwTemp = atoi(strTemp);
			PEVENT_FUNC pfn = (PEVENT_FUNC)dwTemp;
			if(pfn)
				dwRowOnly = dwTemp;
		}
		if(dwRowOnly || dwRC)
			return true;
		
		if(bNodeHandlerOnly)
			return false;
		
		PEVENT_FUNC temp_pEventFunc = m_pfnEvent;// wait until we can call member function pointer directly
		TreeNode trN = m_trEdit;

		if(trN)
		{
			dwRowOnly = (DWORD)temp_pEventFunc;
			return true;
		}
		
		return false;
	}
	PEVENT_NODE_FUNC getEventHandlerRowCol(const TreeNode& trNode)
	{
		if(trNode)
		{
			string strTemp;
			if(trNode.GetAttribute(STR_ATTRIB_HANDLER_RC, strTemp) && !strTemp.IsEmpty())
			{
				DWORD dwTemp = atoi(strTemp);
				PEVENT_NODE_FUNC pfn = (PEVENT_NODE_FUNC)dwTemp;
				if(pfn)
					return pfn;
				return NULL; // if handler is set but not valid, we can diable generic handler 
			}
		}
		return NULL;
	}		
	//------
	void prepareGridForDisplay(bool bResize = true, bool bInit = false)
	{
//		out_str("enter prepareGridForDisplay");
		// make all font size bigger
		double fSizeFactor = 1.00;
		double fRowSizeFactor = fSizeFactor * (IsTreeView()? ROW_HEIGHT_ENLARGER : ROW_HEIGHT_ENLARGER_GRID);
		double fTempFactor;
		m_flx.Row = 0;
		m_flx.Col = 0;
		int nSize = m_nFontSize;//flx.CellFontSize;
		
		nSize = 0.5 + nSize * fSizeFactor;
		
		vector<int> vnBranchRowsToExpand;//---- CPY 8/24/03 v7.5674 QA70-5061 ADD_DISPLAY_OPTIONS
		//---- CPY 1/16/05
		//for(int ii = m_flx.FixedCols; ii < m_flx.Rows; ii++)
		for(int ii = m_flx.FixedRows; ii < m_flx.Rows; ii++)
		//----
		{
			///Danice SUPPORT_GRID_VIEW
			/*
			fTempFactor = fRowSizeFactor;

			if(prepareEditCell(ii, fTempFactor, vnBranchRowsToExpand))
				m_flx.RowHeight(ii) = 0.5 + m_nRowHeight * fTempFactor;
			else
				m_flx.RowHeight(ii) = 0;
			*/
			fTempFactor = fRowSizeFactor;
			//for(int jj=m_flx.FixedRows; jj<m_flx.Cols; jj++) CPY 9/18/04 GETN_TREE_LOST_ALL_BRANCH_LABELS, replace m_flx.FixedRows with getEditColBegin
			for(int jj = getEditColBegin(); jj < m_flx.Cols; jj++)
			{
				if(prepareEditCell(ii, fTempFactor, vnBranchRowsToExpand, jj))
				/// YuI 10/03/04 QA70-4387 GETN_PICTURE_IMPLEMENTATION
				//	m_flx.RowHeight(ii) = 0.5 + m_nRowHeight * fTempFactor;
				{
					if( fTempFactor > 0 ) // negative to indicate that caller should not worry about row height
						SetRowHeight(ii, GetBaseRowHeight(fTempFactor));
				}
					/// end GETN_PICTURE_IMPLEMENTATION
				else
					SetRowHeight(ii, 0);
			}
			///end SUPPORT_GRID_VIEW
		}
		if(bInit && IsTreeView())
		{
			///Danice 7/14/04 QA70-6631 v8.0907 TREE_BRANCH_COLLAPSED_DEFAULT
			/*
			m_flx.Outline(0);// collaps the tree
			//---- CPY 8/24/03 v7.5674 QA70-5061 ADD_DISPLAY_OPTIONS
			for(int jj = 0; jj < vnBranchRowsToExpand.GetSize(); jj++)
				m_flx.IsCollapsed(vnBranchRowsToExpand[jj]) = flexOutlineExpanded;	
			//----
			*/
			int nRows=m_flx.Rows;
			vector<byte> vb(nRows);
			vb = flexOutlineCollapsed;
			for(int jj=0; jj < vnBranchRowsToExpand.GetSize(); jj++)
				vb[vnBranchRowsToExpand[jj]]=flexOutlineExpanded;
			SetCollapsed(vb, false);
			///END TREE_BRANCH_COLLAPSED_DEFAULT
		}

		if(bResize)
		{
			//ResizeCols(6.0, 3.0);
			resizeGrid()
		}
		updateGridEnableSettings();
	}
public:
	void Resize(bool bResizeCols = true, bool bResizeRows = false)
	{
		if(bResizeCols)
			resizeGrid();
		
		if(bResizeRows)
			ResizeAllRows();
	}
	/// Frank 3/30/05	TREE_EDIT_SUPPORT_MOVE_ROWS			
	bool	SetTreeNodeMoveRowsAttrib(TreeNode &trShow, string strGridName = "")
	{
		if(!trShow)
			return false;
		return trShow.SetAttribute(TEC_MOVE_ROWS_EDITABLE_ATTRIB, strGridName);
	}	
	/// End	TREE_EDIT_SUPPORT_MOVE_ROWS			
private:	
	void resizeGrid()
	{
		//--------- CPY SY 07/27/2004 QA70-6719 v8.0105 GETN_AUTO_RESIZE_WIDTH_WITH_LONG_LABEL
		//ResizeCols(6.0, 3.0);
		// for reason not completely known, setting ColWidthMin to a bigger value somehow allow AutoSize to
		// to work more correctly, so default to 15 pixel as the min width on the grid col for now
		ResizeCols(6.0, 3.0, 8, 15);
		//---------

		///Danice 11/10/04 	SUPPORT_EMPTY_TREENODE_AND_LABEL_CONTROL
		int nLabel=m_flx.FixedCols;
		if(!m_bShowLabelCol)
			HideCol(nLabel);
		else if(IsColHidden(nLabel))
			HideCol(nLabel, false);
		///end
	}
	uint getDisableColor() {return RGB(128, 128, 128);}
	uint getBranchDisableColor() {return RGB(64, 64, 64);}
	
	void updateGridEnableSettings()
	{
		for(int ii = 0; ii < m_flx.Rows; ii++)
		{
			TreeNode trNode = get_tree_node(ii);
			int nEnable;
			if(trNode && (nEnable=trNode.Enable) >= 0)
			{
				///Danice 12/10/04 DISABLE_ROW_WITHOUT_GRAY_COLOR2
				/*
				for(int nC = 0; nC < m_flx.Cols; nC++)
				{
					///Danice DISABLE_ROW_WITHOUT_GRAY_COLOR : only when .Enable is 0, set Row color gray
					//m_flx.Cell(flexcpForeColor, ii, nC) = trNode.Enable > 0? 0 : getDisableColor();
					m_flx.Cell(flexcpForeColor, ii, nC) = nEnable != 0 ? getEnableColor(nC, nEnable) : getDisableColor();
					///end DISABLE_ROW_WITHOUT_GRAY_COLOR
				}
				*/
				updateRowEnableSetting(trNode, ii, nEnable);
				///end DISABLE_ROW_WITHOUT_GRAY_COLOR2
			}
		}
	}
	///Danice 12/10/04 DISABLE_ROW_WITHOUT_GRAY_COLOR2 : Read only Row or Branch Row
	int updateRowEnableSetting(TreeNode &trRow, int &nBeginRow, int nEnable)
	{
		int nTotalSubRow=0, nNumLeaf=trRow.GetNodeCount();
		for(int ii=0; ii<=nNumLeaf; ii++)
		{
			for(int nC = 0; nC < m_flx.Cols; nC++)
				SetCell(nEnable != 0 ? getEnableColor(nC, nEnable) : getDisableColor(), flexcpForeColor, nBeginRow, nC);
			
			nBeginRow++;		//check next row
			if(nNumLeaf > 0)	//have leaf
			{
				nTotalSubRow++;
				TreeNode trSubNode = get_tree_node(nBeginRow);
				if(trSubNode && trSubNode.GetNodeCount() > 1)
					nTotalSubRow+=updateRowEnableSetting(trSubNode, nBeginRow, nEnable);
			}
		}
		nBeginRow--;
		return nTotalSubRow;
	}
	///end DISABLE_ROW_WITHOUT_GRAY_COLOR2
	bool updateGridColWidth(int nRow, const string& strOldVal) // -1 to scan all rows
	{
		if(nRow < 0)
			return false; // not supported yet
		int nOldLength = strOldVal.GetLength();
		string str = GetCell(flexcpText, nRow, EDIT_COL_INDEX);
		int nNewLength = str.GetLength();
		if(nOldLength < 1) nOldLength = 1;
		if((nNewLength - nOldLength) > nOldLength * 0.2 || (nOldLength - nNewLength) > nOldLength * 0.5 )
		{
			resizeGrid();
			return true;
		}
		return false;
	}

	
	//----------- CPY 6/16/04 QA70-6294 OC_INPUT_DATA_NODE_CLEANUP
	// return number of lines
	/*
	void	createDataRangeCell(int nNodeType, int nRow, int nId, TreeNode& trNode, double& dbRowSizeFactor)
	{
		string strComboStr = get_node_combo_str(trNode);
		int nCol = EDIT_COL_INDEX;
		EditorManager	trNodeManager;
		DWORD dwTemp = trNodeManager.New(nNodeType, nRow, nId, strComboStr);
		
		m_flx.Cell(flexcpData, nRow, nCol) = dwTemp;
		dbRowSizeFactor *= trNodeManager.GetCellHeightFactor(dwTemp);
		PageBase pg = Project.Pages();
		if( pg && pg.GetType() == EXIST_GRAPH )
		{
			DataSelector ds;
			ds = GetDataSelector(GetDataSelectorName(nRow));
			if( !ds )
			{
				ds = CreateDataSelector(GetDataSelectorName(nRow));
			}
			
			if( ds )
			{
				DataRange dr;
				dr.Create(trNode);
				if( !ds.SetDataRange(dr) )
				{
					ds.GetDataRange(dr);
					dr.GetTree(trNode);
				}
				trNodeManager.SetTree(dwTemp, trNode);	
				// trNode.RemoveChildrenWithPrefix(PREFIX_FOR_DATA_RANGE_DATA); // if graph we remove all the children from datarange node
				// trNode.AddNode(trDataRange.FirstNode);
				string strDRDesc = dr.GetDescription();
				dr.Destroy();
				int nLines = strDRDesc.GetNumTokens('\r');
				if( nLines > 0 )
					dbRowSizeFactor += (nLines -1);
			}
		}
		else
		{
			DataRange dr;
			dr.Create(trNode);
			string strDRDesc = dr.GetDescription();
			dr.Destroy();
			trNodeManager.SetTree(dwTemp, trNode);	
			int nLines = strDRDesc.GetNumTokens('\r');
			if( nLines > 0 )
				dbRowSizeFactor += (nLines -1);
		}
	}
	*/
	/// end NEW_DATA_SELECTOR_TOOL
	
	//----------- CPY 6/16/04 QA70-6294 OC_INPUT_DATA_NODE_CLEANUP
	//void prepareBranch(const TreeNode trBranch, int nRow, vector<int>& vnBranchRowsToExpand)	///Danice TREE_ROW_SHOW_ALTERNATE_COLORS
	void prepareBranch(const TreeNode trBranch, int nRow, int nCol, vector<int>& vnBranchRowsToExpand)
	{
		string strTemp;
		DWORD dwTemp;
		//---- CPY 10/22/04 BRANCH_CHECKBOX_IMPROVEMENT
		bool bCheckBranch;
		bool bBranchOpen = false;
		string strValue = getValue(trBranch, &bCheckBranch);
		
		////DG 7/12/05 USE_BRANCH_DEFAULT_CLOSED : we should make this branch work like the normal one, default closed
		/*
		if(bCheckBranch)
			bBranchOpen = updateBranchUseShow(trBranch, nRow, atoi(strValue), false);
		//----
		if(!bCheckBranch && trBranch.GetAttribute(STR_ATTRIB_BRANCH, strTemp))
		*/
		if(bCheckBranch)
			updateBranchUseShow(trBranch, nRow, atoi(strValue), false);
		if(trBranch.GetAttribute(STR_ATTRIB_BRANCH, strTemp))
		///end USE_BRANCH_DEFAULT_CLOSED
		{
			dwTemp = atoi(strTemp);
			if(dwTemp)
				SetRowData(nRow, dwTemp);
			if(dwTemp & GETNBRANCH_OPEN)
				bBranchOpen = true
				//nNew=vnBranchRowsToExpand.Add(nRow);
		}
		if(bBranchOpen)
			vnBranchRowsToExpand.Add(nRow);
		
		///---Danice NEW_WAY_FOR_ALTERNATE_COLORS
		/*
		///Danice TREE_ROW_SHOW_ALTERNATE_COLORS
		int nSize=m_vnTreeRowColors.GetSize();
		if(nSize >= TOTAL_BASIC_ALTERNATE_COLORS)	//user color
		{
			int nBranchBeginColor=TOTAL_BASIC_ALTERNATE_COLORS-1;
			int nLevel = tree_get_level(trBranch) - tree_get_level(m_trEdit), nBranchColor=nBranchBeginColor;
			if(nLevel <= (nSize-nBranchBeginColor))
				nBranchColor+=(nLevel-1);
			else
				nBranchColor=nSize-1;
			
			m_flx.Cell(flexcpBackColor, nRow, nCol) = m_vnTreeRowColors[nBranchColor];
			m_flx.Cell(flexcpBackColor, nRow, LABEL_COL_INDEX) = m_vnTreeRowColors[nBranchColor];	//set label back color as loop don't go to Label Row
		}
		///end TREE_ROW_SHOW_ALTERNATE_COLORS
		*/
		///---end NEW_WAY_FOR_ALTERNATE_COLORS
		
		//---- CPY 10/22/04, the following is problematic, making combo branch shown as disabled, I have moved to code to above and slightly changed
		/*
		///Danice BRANCH_CHECKBOX_IMPROVEMENT
		bool bCheckBranch;
		string strValue=getValue(trBranch, &bCheckBranch);
		if(!strValue.IsEmpty() && !bCheckBranch)
		{
			updateBranchUseShow(trBranch, nRow, false);	//want this to disable [+]
			if(dwTemp & GETNBRANCH_OPEN)
				vnBranchRowsToExpand.RemoveAt(nNew);
			return;
		}
		*/
		///end
	}
	//------------

	//------ CPY 8/27/04 QA70-5890 v8.0125 BRANCH_ALLOW_CHECKBOX
	bool isEditableBranch(TreeNode& trNode, int* pnCheckVal = NULL, bool* pbIsCheck = NULL, string* pComboStr = NULL)
	{
		int nUse = trNode.Use;
		if(nUse >= 0)
		{
			if(pnCheckVal)
				*pnCheckVal = nUse;
			if(pbIsCheck)
			{
				string strCombo;
				if(trNode.GetAttribute(STR_ATTRIB_BRANCH_COMBO, strCombo) && strCombo.GetLength() > 2)
				{
					*pbIsCheck = false; // assume not a check box, more likely a combo
					if(pComboStr)
						*pComboStr = strCombo;
				}
				else
				{
					*pbIsCheck = true;
					if(pComboStr)
						pComboStr->Empty();
				}
			}
			return true;
		}
		return false;
	}
	void setCheckBoxBranch(TreeNode& trNode, int nCheck)
	{
		trNode.Use = nCheck;
	}
	bool isEnableEdit(const TreeNode& trNode)
	{
		///Danice 12/10/04 DISABLE_ROW_WITHOUT_GRAY_COLOR2
		/*
		int nEnable = trNode.Enable;
		if(nEnable < 0 || nEnable == 1) // < 0 if attribute missing
			return true;
		return false;
		*/
		int nEnable;
		for(TreeNode trParent = trNode; trParent.IsValid(); trParent = trParent.Parent())
		{
			nEnable = trParent.Enable;
			if(0 == nEnable || 1 < nEnable) // < 0 if attribute missing, ==1 enable
				return false;
		}
		return true;
		///end DISABLE_ROW_WITHOUT_GRAY_COLOR2
	}
	// not editable or editing is handled separately by special codes
	bool isGeneralEdit(const TreeNode& trNode, int nCol)
	{
		//if(trNode.Enable == 0)		///Danice DISABLE_ROW_WITHOUT_GRAY_COLOR
		if(!isEnableEdit(trNode))
			return false;
		if(isDataRangeInteractiveNode(trNode))
			return false;
		/// TD 8-5-05 DISABLE_PICTURE_EDIT
		if(TRGP_PICTURE == trNode.ID)
			return FALSE;
		//--- CPY 8/26/05 ADD_HELP_TO_XF
		if(TRGP_EXTERNAL_EDIT == trNode.ID)
			return FALSE;
		//---
		/// end DISABLE_PICTURE_EDIT
		
		//---- CPY 9/10/05 IRIS_FOUND_BRANCH_COMBO_SINGLE_ITEM_WITH_SPACE_BECOMES_TWO
		if(isVsFlexStrListCombo(trNode))
		{
			string strCombo = get_node_combo_str(trNode);
			/// YuI 09/22/05 GETN_BUTTON_BRANCH_OPTION
			//	if(strCombo.Find('|') < 0)
			if(strCombo.Find('|') < 0 && strCombo != STR_THREE_DOTS )
			/// end GETN_BUTTON_BRANCH_OPTION
				return false;
		}
		//----
		
		
		if(trNode.ID != TRGP_BRANCH)
			return true;

		// if branch, check if there is check box
		if(EDIT_COL_INDEX == nCol && isEditableBranch(trNode))
			return true;
		
		return false;
	}
	string getValue(const TreeNode& trNode, bool* pbIsBranchCheckBoxVal = NULL)
	{
		string str;
		if(pbIsBranchCheckBoxVal)
			*pbIsBranchCheckBoxVal = false;
		
		switch(trNode.ID)
		{
		case TRGP_DATA_RANGE:
		case TRGP_XY_DATA_RANGE:/// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
		case TRGP_XYZ_DATA_RANGE:/// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
		case TRGP_XY_COMPLEX_DATA_RANGE:/// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
			break;// not supportted
		case TRGP_BRANCH:
			{
				int nCheck = 0;
				bool bCheckBox = false;
				if(isEditableBranch(trNode, &nCheck, &bCheckBox))
					str = nCheck;
				
				if(pbIsBranchCheckBoxVal)
					*pbIsBranchCheckBoxVal = bCheckBox;
			}
			break;
		default:
			str = trNode.strVal;
		}
		return str;
	}
	void setValue(const TreeNode& trNode, EditorManager& edMngr, DWORD dwTemp, bool bModified)
	{
		if( trNode.ID == TRGP_DATA_RANGE 
			|| trNode.ID == TRGP_MULTILINE_TEXT 
			|| trNode.ID ==  ONODETYPE_CODE_EDITOR /// TD 2-16-04 QA70-7368 CODE_EDITOR_IN_DIALOG
			|| trNode.ID == TRGP_XY_DATA_RANGE  /// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
			|| trNode.ID == TRGP_XYZ_DATA_RANGE  /// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
			|| trNode.ID == TRGP_XY_COMPLEX_DATA_RANGE  /// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
			)
			return;
		string str = edMngr.GetText(dwTemp);
		_DBPRINTF("OnAfterEdit str = %s\n", str);
		if(TRGP_BRANCH == trNode.ID)
		{
			int nVal = atof(str);
			setCheckBoxBranch(trNode, nVal);
		}
		else
			trNode.strVal = str;
	}
		
	void setCheckBoxValue(TreeNode& trNode, int nVal)
	{
		if(TRGP_BRANCH == trNode.ID)
			setCheckBoxBranch(trNode, nVal);
		else
			trNode.nVal = nVal;
	}
	///Danice BRANCH_CHECKBOX_IMPROVEMENT
	/*
	bool closeBranch(int nRow, TreeNode& trNode)
	{
		int nState = GetCollapsed(nRow);
		if(nState == 0)
		{
			SetCollapsed(nRow);
			return true;
		}
	}
	*/
	// return true if branch should be Open, false if should be closed
	bool updateBranchUseShow(TreeNode &trBranch, int nRow, int nCheck, bool bDoOpenClose = true)
	{
		uint nColorDisable =  RGB(127, 127, 127);
		int nState = GetCollapsed(nRow);
		if(nCheck)
		{
			//m_flx.Cell(flexcpForeColorFixed, nRow, 0) =  0; //require set header front color
			SetCell(0, flexcpForeColor, nRow, 0);	//temp
			if(bDoOpenClose && nState != 0)
				SetCollapsed(nRow, 0);
		}
		else
		{
			//m_flx.Cell(flexcpForeColorFixed, nRow, 0) =  nColorDisable;
			SetCell(getBranchDisableColor(), flexcpForeColor, nRow, 0);	//Temp
			if(bDoOpenClose && nState == 0)
				SetCollapsed(nRow);
			
			return false;// indicate close/disable
		}
		return true;
	}
	///end BRANCH_CHECKBOX_IMPROVEMENT
	//------ end BRANCH_ALLOW_CHECKBOX
	
//#define	MAX_GETN_PICTURE_HEIGHT 150
	// return flase if cell should be hidden
	//bool prepareEditCell(int nRow, double& dbRowSizeFactor, vector<int>& vnBranchRowsToExpand)
	bool prepareEditCell(int nRow, double& dbRowSizeFactor, vector<int>& vnBranchRowsToExpand, int nCol=EDIT_COL_INDEX);
	//---- CPY v7.5785 12/19/03 QA70-5738 GETN_BOX_COMBO_CHANGE_NEEDED
	bool updateGridComboStrs()
	{
		string strComboChanged;
		if(m_trEdit.GetAttribute(STR_COMBO_CHANGED, strComboChanged))
		{
			m_trEdit.RemoveAttribute(STR_COMBO_CHANGED);
			int nRow = atoi(strComboChanged);
			TreeNode trNode = get_tree_node(nRow);
				///Begin Frank 5/11/04 v8.0870 ADD_MORE_TYPE_SET_COMBO_STRING
		  //if(trNode.IsValid() && trNode.ID == TRGP_ENUM_LIST)
			if(trNode.IsValid() && (trNode.ID == TRGP_ENUM_LIST || trNode.ID == TRGP_SLIDEREDIT|| trNode.ID == TRGP_SLIDER || trNode.ID == TRGP_NUMERIC_LIST || trNode.ID == TRGP_RANGE|| trNode.ID == TRGP_STR_BUTTON))
				///End ADD_MORE_TYPE_SET_COMBO_STRING
				updateComboStr(nRow, EDIT_COL_INDEX, trNode);
		}
		return false;
	}
	bool updateComboStr(int nRow, int nCol, TreeNode trNode)
	{
		DWORD	dwTemp = GetCell(flexcpData, nRow, nCol);
		if(dwTemp)
		{
			EditorManager	trNodeManager;
			string strCombo = get_node_combo_str(trNode);
			trNodeManager.SetComboStr(dwTemp, strCombo);
			setGridCellValue(nRow, nCol, trNode);
			return true;
		}
		return false;
	}
	//---- end GETN_BOX_COMBO_CHANGE_NEEDED
	//----- CPY 7/16/04 BRANCH_NODE_SHOULD_NOT_SHOW_TEXT
	// should really do nothing, but for some reason the lable on branch row is repeated in value col
	void setupBranchRowValueCell(int nRow, int nCol, const TreeNode& trNode )
	{
		/*
		string str1, str2; 
		
		str1 = m_flx.Cell(flexcpText, nRow, nCol);
		str2 = trNode.tagName;
		printf("branch, cell = %s,. tree = %s\n", str1, str2);
		*/
		SetCell(" ", flexcpText, nRow, nCol);
		//-------- CPY 8/27/04 QA70-5890 v8.0125 BRANCH_ALLOW_CHECKBOX
		int nCheck;
		bool bIsCheckBox = false;// support only check and combo
		if(isEditableBranch(trNode, &nCheck, &bIsCheckBox))
		{
			if(bIsCheckBox)
				///m_flx.Cell(flexcpChecked, nRow, nCol) = nCheck? flexChecked : flexUnchecked;
				SetCheck(nRow, nCol, nCheck);
			else // assume combo
			{
				EditorManager	trNodeManager;
				DWORD	dwTemp;
				dwTemp = GetCell(flexcpData, nRow, nCol);
				trNodeManager.SetText(dwTemp, ftoa(nCheck));
				SetCell(trNodeManager.GetText(dwTemp, FALSE), flexcpText, nRow, nCol); // get display text
			}
		}
		//-------- end BRANCH_ALLOW_CHECKBOX
	}
	//-----
	bool setGridCellValue(int nRow, int nCol, const TreeNode& trNode)
	{
		EditorManager	trNodeManager;
		DWORD	dwTemp;
		int nNodeType = trNode.ID;
		string strRowAttribute; //CPY 12/20/04, moved here to clean up Frank's code, use only this str to indicate row height control
		switch(nNodeType)
		{
		case TRGP_BRANCH:
			setupBranchRowValueCell(nRow, nCol, trNode);//CPY 7/16/04 BRANCH_NODE_SHOULD_NOT_SHOW_TEXT
			// default to collaps
			//flx.IsCollapsed(nRow) = flexOutlineSubtotals;
			break;
		case TRGP_CHECK:
			///m_flx.Cell(flexcpChecked, nRow, nCol) = trNode.nVal>0? flexChecked : flexUnchecked;
			SetCheck(nRow, nCol, (trNode.nVal > 0));
			break;
		/// YuI 3/24/04 v7.5846 QA70-6118 NEW_DATA_SELECTOR_TOOL
		/*
		case TRGP_ENUM_LIST:
		case TRGP_COLOR:
		case TRGP_RANGE:
		case TRGP_SLIDEREDIT:///----- YuI 01/14/04 v7.5801 QA70-5799 SLIDER_CONTROL_TO_GETNBOX
		case TRGP_SLIDER:
		case TRGP_INTERACTIVE:///----- YuI 1/26/04 v7.5807 QA70-5797 INTERACTIVE_TEXT_PROPERTY_IMPLEMENTATION
		
			dwTemp = m_flx.Cell(flexcpData, nRow, nCol);
			if (nNodeType == TRGP_RANGE || nNodeType == TRGP_SLIDEREDIT || nNodeType == TRGP_SLIDER || nNodeType == TRGP_INTERACTIVE) //CPY 3/26/04 QA70-6177, was "|| TRGP_INTERACTIVE)" which broke GETN_LIST with default
				trNodeManager.SetText(dwTemp, trNode.Text, OXVT_STRING);
			else
				trNodeManager.SetText(dwTemp, trNode.Text);
			m_flx.Cell(flexcpText, nRow, nCol) = trNodeManager.GetText(dwTemp, FALSE); // get display text
			break;
		*/
		
		case TRGP_ENUM_LIST:
		case TRGP_COLOR:
			dwTemp = GetCell(flexcpData, nRow, nCol);
			trNodeManager.SetText(dwTemp, trNode.strVal);
			SetCell(trNodeManager.GetText(dwTemp, FALSE), flexcpText, nRow, nCol); // get display text
			break;
			
		case TRGP_RANGE:
		case TRGP_SLIDEREDIT:
		case TRGP_SLIDER:
		case TRGP_INTERACTIVE:
			dwTemp = GetCell(flexcpData, nRow, nCol);
			trNodeManager.SetText(dwTemp, trNode.strVal, OXVT_STRING);
			SetCell(trNodeManager.GetText(dwTemp, FALSE), flexcpText, nRow, nCol); // get display text
			break;
		/// end NEW_DATA_SELECTOR_TOOL
		
		/// YuI 7/23/04 v7.5103 QA70-6582 GETN_MULTILINE_TEXT_IMPLEMENTATION
		case TRGP_MULTILINE_TEXT:
		case ONODETYPE_CODE_EDITOR: /// TD 2-16-04 QA70-7368 CODE_EDITOR_IN_DIALOG


			{
				dwTemp = GetCell(flexcpData, nRow, nCol);
				string strTemp = trNode.strVal;
				//strTemp.Replace("\n", "\r\n");
				check_convert_CR_str_to_CRLF(strTemp);
				trNodeManager.SetText(dwTemp, strTemp, OXVT_STRING);
				SetCell(trNodeManager.GetText(dwTemp, FALSE), flexcpText, nRow, nCol); // get display text
				///Frank 12/14/04 AUTO_SET_MULTILINE_EDIT_SHOW_RANGE, CPY 12/20/04
				trNode.GetAttribute(STR_ATTRIB_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE, strRowAttribute); 
				///End AUTO_SET_MULTILINE_EDIT_SHOW_RANGE
			}
			break;
		/// end GETN_MULTILINE_TEXT_IMPLEMENTATION			

		/// YuI 3/24/04 v7.5846 QA70-6118 NEW_DATA_SELECTOR_TOOL
		case TRGP_DATA_RANGE:
		case TRGP_XY_DATA_RANGE:/// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
		case TRGP_XYZ_DATA_RANGE:/// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
		case TRGP_XY_COMPLEX_DATA_RANGE:/// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
			//----------- CPY 6/16/04 QA70-6294 OC_INPUT_DATA_NODE_CLEANUP
			/*
			{
				dwTemp = m_flx.Cell(flexcpData, nRow, nCol);
				PageBase pg = Project.Pages();
				TreeNode trDescription;
				if( pg && pg.GetType() == EXIST_GRAPH )
				{
					trNodeManager.GetTree(dwTemp, trDescription);
				}
				else
				{
					trDescription = trNode;
				}
				
				DataRange dr;
				dr.Create(trDescription);
				string strDesc = dr.GetDescription();
				m_flx.Cell(flexcpText, nRow, nCol) = strDesc;
				dr.Destroy();
			}
			*/
			SetInputDataBranchValue(nRow, nCol, trNode);
			//-----------
			break;

		/// end NEW_DATA_SELECTOR_TOOL
		case TRGP_DOUBLE:
			{
				//---- CPY v7.5723 QA70-5376 GETNBOX_ADD_SIG_DIGITS_SUPPORT
				// we have to go through this to avoid 1.0 displayed as 1. by generic storage in XML for doubles
				//double val = trNode.dVal;
				//string strVal = val;
				//m_flx.Cell(flexcpText, nRow, nCol) = szTemp;
				char szTemp[MAXLINE];
				string strNumFormat = m_strNumFormat;
				
				trNode.GetAttribute(STR_ATTRIB_NUMFMT, strNumFormat);//-------- CPY 10/1/04 QA70-6752 GET_NODE_NUM_FORMAT_CONTROL

				DoubleToStr(trNode.dVal, szTemp, MAXLINE, strNumFormat);
				SetCell(szTemp, flexcpText, nRow, nCol);
				//---- end GETNBOX_ADD_SIG_DIGITS_SUPPORT
			}
			break;
		/// YuI 10/03/04 QA70-4387 GETN_PICTURE_IMPLEMENTATION
		case TRGP_PICTURE:
			///Frank 10/16/04 CELL_WIDTH_NEED_UPDATE_LOAD_PICTURE
			resetPiructRowHight(nRow, nCol, trNode);
			///End CELL_WIDTH_NEED_UPDATE_LOAD_PICTURE
			SetCellPicture(nRow, nCol, trNode.pict);
			break;
		/// end GETN_PICTURE_IMPLEMENTATION
		//---- CPY 4/22/05 QA70-7643 GETN_COMBO_NUMERIC_CHECK_IN_LIST
		case TRGP_NUMERIC_LIST: // edit cell must contain one of the entries in list
			{
				string str, strCombo;
				if(trNode.GetAttribute(STR_COMBO_ATTRIB, strCombo))
					str = find_in_list(atof(trNode.strVal), strCombo); 
				else
					str = trNode.strVal;
					
				SetCell(str, flexcpText, nRow, nCol);
			}
			break;
		//---- end
		//--- CPY 8/26/05 ADD_HELP_TO_XF
		case TRGP_EXTERNAL_EDIT:
			SetCell(getExternalDisplay(trNode), flexcpText, nRow, nCol);
			break;
		//---
		default:
			{
				if(trNode.GetNodeCount() > 0)
				{
					///------Jasmine 09/11/07 not a bug or error, don't print to script window
					//printf("tree %s is not a leaf node\n", trNode.tagName);
					string strError;
					strError.Format("tree %s is not a leaf node", trNode.tagName);
					error_report(strError);
					///------End
				}
				else
				{
					/// EJP 12-16-2004 QA70-6721 ASCIMP_OPTIONS_USE_GETNBOX
					///m_flx.Cell(flexcpText, nRow, nCol) = trNode.strVal;
					string str = trNode.strVal;
					/// Hong 11/11/09 QA80-14625 TREE_EDIT_CTRL_DISPLAY_VECTOR_TREENODE_AS_DEBUG_VARIABLE_TAB
					string	strArrayVal;
					if ( trNode.GetArrayAsString(strArrayVal) )
						str = strArrayVal;
					/// end TREE_EDIT_CTRL_DISPLAY_VECTOR_TREENODE_AS_DEBUG_VARIABLE_TAB
					check_translate(trNode, str, true);
					SetCell(str, flexcpText, nRow, nCol);
					/// end ASCIMP_OPTIONS_USE_GETNBOX
				}
			}
		}

		///Danice MARK_EMPTY_GETN_STR && MARK_EMPTY_GETN_STR_CENTRALIZE
		bool bIsWaitInput;
		if(isCheckWaitInput(trNode, nRow, bIsWaitInput))
			setWaitInputRowLabel(trNode, nRow, bIsWaitInput);
		///end MARK_EMPTY_GETN_STR && MARK_EMPTY_GETN_STR_CENTRALIZE
		
		if(!strRowAttribute.IsEmpty())
		{
			vector<string> vs;
			string strCellValue = trNode.strVal;
			//----- CPY 12/1/04 COUNT_LINES_IN_STR_CLEANUP
			//strCellValue.Replace('{',' '); /// This just because bug #7216. 
			//int nCellRows = strCellValue.GetTokens(vs,'\n');
			//bool bCellEditable = trNode.Enable;
			//setFitedRowHeight( nRow, strRowAttribute, nCellRows+1, bCellEditable);
			int nNumLines = strCellValue.Count('\n') + 1;
			setFittedRowHeight(nRow, strRowAttribute, nNumLines, trNode.Enable);
			//-----
			return true;
		}
		
		return false;// CPY 12/20/04, change void to return true/false to indicate Row Height already adjusted
	}
	//------------- CPY 8/26/05 ADD_HELP_TO_XF
	string getExternalDisplay(const TreeNode& trNode)
	{
		int nNodeType = trNode.TypeID;
		int nSize = -1;
		string str;
		switch(nNodeType)
		{
		case TNVAL_TYPE_CHAR_VECTOR:
			vector<char> vc1;
			{
				try {
					vc1 = trNode.bVals;
				}
				catch(int nErr)
				{
					str.Format("Err getting trNode.bVals");
					return str;
				}
			}
			nSize = vc1.GetSize();
			break;
		default:
			str = trNode.strVal;
			nSize = str.GetLength();
		}
		str.Format("size = %d", nSize);
		return str;
	}
	//------------- end ADD_HELP_TO_XF

	//------- CPY TD 11-30-04 QA70-6582 ADD_COMBO_IMAGE_TO_RIGHT_OF_EDIT_CELL
	void checkShowComboIndicator(int nRow, int nCol, const TreeNode& trNode)
	{
		bool bIsDropDown; // otherwise drop list
		if(isVsFlexCombo(trNode, bIsDropDown)) 
		{
			SetCellBitmap(nRow, nCol, OBM_COMBO, 0, DISPLAY_RIGHT);
		}
	}
	//------- end ADD_COMBO_IMAGE_TO_RIGHT_OF_EDIT_CELL

	///Frank 10/16/04 CELL_WIDTH_NEED_UPDATE_LOAD_PICTURE
	int resetPiructRowHight(int nRow, int nCol, TreeNode &trNode)
	{
		//m_flx.Cell(flexcpAlignment, nRow, nCol) = JUSTIFICATION_CHECKBOX;
		///I think the set the cell picture allignment to flexPicAlignStretch can show entire pircture,
		SetCell(9, flexcpPictureAlignment, nRow, nCol);
		if(trNode.pict)
		{
			int nPictureHeight = trNode.pict.GetHeight();
			int nPictureWidth  = trNode.pict.GetWidth();
			double dAspectRatio = (double) nPictureHeight / nPictureWidth;
			RECT rect; 
			GetCellRect(nRow, nCol, rect);
			int ny = PixelsToTwips((rect.right - rect.left) * dAspectRatio);
			SetRowHeight(nRow, ny);
			return ny;
		}
		return -1;
	}
	///End CELL_WIDTH_NEED_UPDATE_LOAD_PICTURE
	
	//CPY 12/20/04 rewritten
	void setFittedRowHeight(int nRow, string &strRowRange , int nTextRows = -1, bool bReduceRowHeight = true)
	{
		int nMinRows = 0, nMaxRows = 0;
		//str_to_range(strRowRange,nMinRows, nMaxRows);
		if(!str_to_range(strRowRange,nMinRows, nMaxRows))
		{
			nMinRows = MIN_MULTILINE_ROWS;
			nMaxRows = nMinRows + 1;
		}
		
		if(nTextRows > nMinRows)
			nMinRows = nTextRows ;

		if( nMinRows < MIN_MULTILINE_ROWS)
			nMinRows = MIN_MULTILINE_ROWS;
		//else if(nMinRows > nMaxRows )
		else if(nMinRows > nMaxRows && nMaxRows > MIN_MULTILINE_ROWS )
			nMinRows = nMaxRows;

		int ny;
		int nRowHeightOneLine = GetBaseRowHeight(0.95);//CPY, oneline height might be too much as font has leading and etc so we need to slightly reduce it
		ny = nRowHeightOneLine * nMinRows;
		RECT rect;
		GetRect(rect);
		int nGridHeight = PixelsToTwips(RECT_HEIGHT(rect));
		//printf("row h = %d, grid height=%d, edit height = %d\n", nRowHeightOneLine, nGridHeight, ny);
		if(ny > nGridHeight - nRowHeightOneLine) // we should leave at least another line for another control
			ny = nGridHeight - nRowHeightOneLine;
		SetRowHeight(nRow, ny);
	}
	///Frank 9/15/04 QA70-6086	SET_UNEDITABLE_AFTER_UPDATE_GRID 
	void	onAfterUpdateValues() 
	{
		RemoveSelection(); //CPY 1/14/05
		m_bOnAfterEditNeeded = false;
	}
	///End	SET_UNEDITABLE_AFTER_UPDATE_GRID 
	///Danice MARK_EMPTY_GETN_STR
	//bool isWaitInput(TreeNode &trNode, int nRow)	///Danice MARK_EMPTY_GETN_STR_CENTRALIZE
	bool isCheckWaitInput(TreeNode &trNode, int nRow, bool &bIsWaitInput)
	{
		int nNodeType = trNode.ID;
		switch(nNodeType)
		{
		case TRGP_STR:
		case TRGP_MULTILINE_TEXT:
		case TRGP_INTERACTIVE:
		case ONODETYPE_CODE_EDITOR: /// TD 2-16-04 QA70-7368 CODE_EDITOR_IN_DIALOG
			//add more later
			///Frank 4/2/05		NEW_METHOD_CHECK_NODE_EMPTY
			//bIsWaitInput=trNode.strVal.IsEmpty();
			bIsWaitInput=trNode.IsEmpty();
			///End		NEW_METHOD_CHECK_NODE_EMPTY
			return true;
		default:
			return false;
		}
		return false;
	}
	//bool markLabelWithTreeValue(TreeNode &trNode, int nRow)	///Danice MARK_EMPTY_GETN_STR_CENTRALIZE
	bool setWaitInputRowLabel(TreeNode &trNode, int nRow, bool bIsWaitInput)
	{
		if(m_vnIndicatorColors.GetSize() < TOTAL_INDECATOR_COLORS)
			return false;	//user don't set user define color
		if(bIsWaitInput)
		{
			SetCell(m_vnIndicatorColors[COLOR_EMPTY_INDECATOR_FOREGROUND], flexcpForeColor, nRow, LABEL_COL_INDEX);
			SetCell(m_vnIndicatorColors[COLOR_EMPTY_INDECATOR_BACKGROUND], flexcpBackColor, nRow, LABEL_COL_INDEX);
		}
		///Danice 11/29/04 : Now EDIT_COL_INDEX col don't change, use it to roll back color
		/*
		else if(TOTAL_BASIC_ALTERNATE_COLORS <= m_vnTreeRowColors.GetSize())	//user Row Color
		{
			m_flx.Cell(flexcpForeColor, nRow, LABEL_COL_INDEX)=0;		//temp, as before use
			setTreeRowUserColors(trNode, nRow, LABEL_COL_INDEX);
		}
		else	//default
		{
			m_flx.Cell(flexcpForeColor, nRow, LABEL_COL_INDEX)=0;		//temp, as before use
			bool bEvenRow= 0==mod(nRow, 2) ? true : false;
			m_flx.Cell(flexcpBackColor, nRow, LABEL_COL_INDEX) = bEvenRow ? m_flx.BackColor : m_flx.BackColorAlternate;
		}
		*/
		else
		{
			SetCell(GetCell(flexcpForeColor, nRow, EDIT_COL_INDEX), flexcpForeColor, nRow, LABEL_COL_INDEX);
			SetCell(GetCell(flexcpBackColor, nRow, EDIT_COL_INDEX), flexcpBackColor, nRow, LABEL_COL_INDEX);
		}
		return true;
	}
	///end MARK_EMPTY_GETN_STR

	//---- CPY 12/2/04 ENABLE_READ_ONLY_USE_SEPARATE_COLOR
	uint getEnableColor(int nCol, int nEnable)
	{
		if(LABEL_COL_INDEX == nCol || 1 == nEnable)
			return 0;// default
		
		// otherwise, various ReadOnly colors
		uint nColor = COLOR_BLUE;
		if(m_vnIndicatorColors.GetSize() >= COLOR_READ_ONLY_FOREGROUND && m_vnIndicatorColors[COLOR_READ_ONLY_FOREGROUND] > 0)
			nColor = m_vnIndicatorColors[COLOR_READ_ONLY_FOREGROUND];
		return nColor;
	}
	//----
	
	///Danice NEW_WAY_FOR_ALTERNATE_COLORS
	bool setTreeRowUserColors(TreeNode &trNode, int nRow, int nCol)
	{
		int nSize=m_vnTreeRowColors.GetSize();
	
		if(nSize < TOTAL_BASIC_ALTERNATE_COLORS)
		{
			return false;	//user don't set user define color
		}
		
		int nNodeType = trNode.ID;
		uint nRowColorLabel, nRowColorEdit;
		
		switch(nNodeType)
		{
		case TRGP_BRANCH:
		case TRGP_DATA_RANGE:
		case TRGP_XY_DATA_RANGE:/// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
		case TRGP_XYZ_DATA_RANGE:/// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
		case TRGP_XY_COMPLEX_DATA_RANGE:/// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
			{
				//set branch
				int nBranchBeginColor=TOTAL_BASIC_ALTERNATE_COLORS-1, nLevel = tree_get_level(trNode) - tree_get_level(m_trEdit), nBranchColor=nBranchBeginColor;
				if(nLevel <= (nSize-nBranchBeginColor))
					nBranchColor+=(nLevel-1);
				else
					nBranchColor=nSize-1;	//user set less color, use the last color for leavings
				nRowColorLabel = nRowColorEdit =m_vnTreeRowColors[nBranchColor];
			}
			break;
		default:	//set leaf
			TreeNode trPreviousNode = get_tree_node(nRow-1, nCol);
			int nPreviousRowColor=-1;
			if(trPreviousNode)
				nPreviousRowColor= GetCell(flexcpBackColor, nRow-1, EDIT_COL_INDEX);	//label col color sometims change when is waiting input
			if(!trPreviousNode 
				|| TRGP_BRANCH == trPreviousNode.ID 
				|| TRGP_DATA_RANGE == trPreviousNode.ID
				|| TRGP_XY_DATA_RANGE == trPreviousNode.ID /// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
				|| TRGP_XYZ_DATA_RANGE == trPreviousNode.ID /// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
				|| TRGP_XY_COMPLEX_DATA_RANGE == trPreviousNode.ID /// YuI 2/17/05 XYDATARANGE_PROPERTY_IMPLEMENTATION
				|| m_vnTreeRowColors[COLOR_ALTERNATE_COLOR] == nPreviousRowColor)
				nRowColorLabel = m_vnTreeRowColors[COLOR_BACK_GROUND];
			else
				nRowColorLabel = m_vnTreeRowColors[COLOR_ALTERNATE_COLOR];
			//---- CPY 12/2/04 ENABLE_READ_ONLY_USE_SEPARATE_COLOR
			if(trNode.Enable == ENABLE_READ_ONLY && m_vnIndicatorColors.GetSize() >= COLOR_READ_ONLY_BACKGROUND && m_vnIndicatorColors[COLOR_READ_ONLY_BACKGROUND] > 0)
				nRowColorEdit = m_vnIndicatorColors[COLOR_READ_ONLY_BACKGROUND];
			else
				nRowColorEdit = nRowColorLabel;
			//----
			break;
		}
		SetCell(nRowColorEdit, flexcpBackColor, nRow, nCol);
		SetCell(nRowColorLabel, flexcpBackColor, nRow, LABEL_COL_INDEX);
		return true;
	}
	///end NEW_WAY_FOR_ALTERNATE_COLORS
	///Frank 3/30/05	TREE_EDIT_SUPPORT_MOVE_ROWS
	void	setMoveRows(TreeNode &trShow)
	{
		if(!trShow)
			return ;
		string strMoveRows ;
		if(trShow.GetAttribute(TEC_MOVE_ROWS_EDITABLE_ATTRIB, strMoveRows))
			m_bMoveRows = true;
		return ;
	}
	bool	getMoveRows()
	{
		int nFixedCols = m_flx.FixedCols;
		return m_bMoveRows && m_flx.FixedCols >0 ;
	}	
	bool	treeMoveRows(int nRow, int nPosition )
	{
		///bool tree_move_node(TreeNode &tr, int nRow, int nPosition = -1, int nStopLevel=-1, LPCSTR lpcszStopAttribute = NULL, bool bStopAtLastBranch = false, int nCurrentLevel = 0 );
		//return tree_move_node(m_trEdit, nRow - 1, nPosition - 1 , 0); ///DG 4/20/05 REWRITE_TREE_GET_NODE
		return tree_move_node(m_trEdit, nRow - 1, nPosition - 1, ATRN_STOP_LEVEL | 0);
	}
	///End	TREE_EDIT_SUPPORT_MOVE_ROWS

private:
	Dialog*		m_pdlg;
	PEVENT_FUNC	m_pfnEvent;
//	bool 		m_bDataReady;
	bool		m_bIsFlatDialogDisplay;// trying to similate dialog look using gray grid lines etc
	//bool		m_bOnAfterEditNeeded; /// YuI 01/03/2005 v7.5183 QA70-7253 VECTORIAL_NUMERIC_FUNCTIONS
	bool		m_bCheckTreeShow;	///Danice ADD_CHECK_SHOW_OPTION
	bool		m_bShowLabelCol;	///Danice SUPPORT_EMPTY_TREENODE_AND_LABEL_CONTROL
	string		m_strNumFormat;
	//----- CPY 7/19/04 GETN_EDIT_ALIGNMENTS
	int			m_nCheckAlignment;
	int			m_nNumAlignment;
	int			m_nStrAlignment;
	//-----
	///Forest 9/12/04 QA70-6682 SETTINGS_THEME_FILE_SAVE_LOAD
	string		m_strThemeFilePrefix;// str before 1st '-'
	///End SETTINGS_THEME_FILE_SAVE_LOAD
	///Frank 3/30/05	TREE_EDIT_SUPPORT_MOVE_ROWS
	bool		m_bMoveRows;
	///End	TREE_EDIT_SUPPORT_MOVE_ROWS
	
	//---CPY 12/20/04 no need to be data member
	//string		m_strMultiLineEditRange;		///Frank 12/14/04 AUTO_SET_MULTILINE_EDIT_SHOW_RANGE
	
	vector<uint>	m_vnTreeRowColors;			///Danice TREE_ROW_SHOW_ALTERNATE_COLORS
	vector<uint>	m_vnIndicatorColors;	///Danice MARK_EMPTY_GETN_STR

	/// YuI 01/03/2005 v7.5183 QA70-7253 VECTORIAL_NUMERIC_FUNCTIONS
	// table is moved to the base class
	//	TreeTable	m_trTable;	///Danice 9/15/04 SUPPORT_GRID_VIEW
	/// end VECTORIAL_NUMERIC_FUNCTIONS
};
///-----Frank 11/16/05 QA70-8293 RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC
class GetNTreeChanges 
{
public: 
	GetNTreeChanges(){}
	GetNTreeChanges(TreeNode &tr)
	{
		SetTree(tr);
	}
	~GetNTreeChanges(){}
	void SetTree(TreeNode &tr)
	{
		m_tr = tr;
		m_nNodeCount = getGetNValues(m_vShows,m_vEnables, m_vsValue, m_vsCombos,  m_vsLabels);
	}
	DWORD GetMsg();//--- CPY 11/24/05 QA70-8363 COMBO_CHANGE_IN_EVENT_NOT_PROPER_UPDATED
private:
	int getGetNValues( vector<int> &vShows, vector<int> &vEnables, vector<string> &vValues,vector<string> &vsCombos,  vector<string> &vsLabels);
	void getReconstructWpara();
private:
	TreeNode 		m_tr;
	DWORD			m_wParam;
	int 			m_nNodeCount ;
	vector<int> 	m_vShows;
	vector<int> 	m_vEnables;
	vector<string> 	m_vsLabels; 
	vector<string> 	m_vsValue;
	vector<string> 	m_vsCombos; 		
};
///-----End QA70-8293 RETURN_FALSE_IF_NOT_HANDLE_IN_ROW_AND_RC

#endif //_TREE_EDIT_CONTROL_H_
