/*------------------------------------------------------------------------------*
 * File Name:				 													*
 * Creation: 																	*
 * Purpose: OriginC Source C file												*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 * EJP 2005-07-26 v8.0275 QA70-7886 ADD_CUSTOM_FORMAT_TO_OBJECT_LEVEL			*
 * DG 9/14/05 QA70-7883 v8.0306 CHECK_INVALID_LONGNAME_IN_SET_COLVALDLG			*
 * EJP 2005-09-27 v8.0311 QA70-7620 FIX_COL_DUPLICATE_SHORT_NAME				*
 * Leo 2005-11-4 FIX_COLUMN_SELECTION_BUG										*
 *	Kevin 11/12/05 QA70-8292-3 MAKE_STRING_CONST								*
 *	Kevin 11/12/05 QA70-8292-3 COL_INTERNAL_DATATYPE_COMPLEX_NOT_WORKING		*
 *	Frank 12/09/05 CHECK_DUPLICATE_LONG_NAME_COLUMN								*
 *	CPY 2/22/2006 COL_PROP_DIALOG_NOT_USING_ACTIVE_MAT_OBJ						*
 *	Jasmine 03/17/06 v8.0375 SET_TRUE_TO_UPDATE_DYNA_CONTROL					*
 *	CPY 3/18/06 SET_COL_FORMAT_DLG_CANNOT_SET_COL_FROM_NUMERIC_TO_TEXTNUMERIC	*
 *	Jasmine 04/24/06 QA70-8625 SET_COL_VAL_DLG_MODELESS							*
 *  Joseph 08/24/06 WKS_SEL_EDIT_IS_SEL_VALID									*
 *	Jasmine 08/28/06 SHARE_SET_VAL_DLG											*
 *	Jasmine 09/18/06 QA70-6599 APPLY_WIDTH_TO_ALL_COL							*
 *	Jasmine 0/10/08/06 HIDE_NO_USE_OPTION										*
 *	Jasmine 10/19/06 HIDE_DLG_IF_SEL_INVALID									*
 *	Jasmine 10/20/06 DIVIDE_INTO_THREE_GROUP									*
 *	Jasmine 10/23/06 CHANGE_TEXT_TO_EASY_UNDERSTAND								*
 *	EJP 2006-10-23 v8.0499 QA70-8741 THEME_ACCESS_COL_CUSTOM_DATE_FORMAT		*
 *	Jasmine 10/27/06 GET_RANGE_STRING											*
 *	Jasmine 11/10/06 APPLY_OPTION_TO_ALL_RIGHT_COL								*
 *	Jasmine 11/28/06 ENUMERATE_LABELS											*
 *	Jasmine 11/29/06 QA70-7883 LNAME_WITH_SPACE_IS_OK_IN_LT						*
 *	Jasmine 11/29/06 ADD_TAB_FOR_MORE_CONTENT									*
 *	Jasmine 12/08/06 ADD_USER_INFO_TAB											*
 *	Jasmine 01/08/07 MODIFICATION_GET_SET_USER_INFO								*
 *	Hong 01/29/07 MORE_APPLY_OPTION_TO_ALL_RIGHT_COL							*
 *	Hong 01/29/07 FIX_ERROR_COUNT_COL_NUM										*
 *	Jasmine 01/29/07 QA70-9287 EDIT_USER_TREE									*
 *	Jasmine 02/06/07 REMOVE_TREENODE_IF_ENUM									*
 *	Jasmine 02/15/06 ALLOW_EDIT_STOP_COL_COMBO_AND_CHECK_INPUT					*
 *	Jasmine 02/15/07 FIX_ENUM_SAME_SHORT_NAME_BUG								*
 *	Jasmine 03/24/07 MOVE_TO_COL_PROPERTIES										*
 *	Jake 04/18/07 ADD_FIRST_AND_LAST_BUTTON										*
 *	Nicole 07/05/2007 v8.0655 REMOVE_SPACE_FOR_LOCATION_STRING						*
 *	AW 07/13/07 QA80-10056 NEED_DEL_OP_AFTER_UNDO_SETVALUE_WITH_AUTO			*
 *	Jasmine 08/10/07 FIX_INTERNAL_DATA_NOT_MATCH_FORMAT_BUG						*
 *	Jasmine 08/13/07 MAKE_APPLY_UNDOABLE										*
 *	Jasmine 09/04/07 DISABLE_CONTROLS_FOR_IMAGE_DATA							*
 *	CPY 11/3/2007 SET_COL_VALUES_AUTO_NEED_LOCALIZATION							*
 *	Folger 01/15/08 CENTRALIZE_CODE_OF_APPLY_FORMAT								*
 *	Jasmine 02/18/08 QA80-11034 PROBLEMATIC_WORKSHEET_SELECT					*
 *	Folger 04/10/08 QA80-11391 USE_INTEGER_FORMATTING_GETN_IN_COLUMN_WIDTH_AND_SIGNIFICANT_DIGITS
 *	Folger 04/15/08 QA80-11377 FIX_APPLY_DEFAULT_NUMERIC_FORMAT_CAUSE_SET_THEME_ERROR
 *	Jasmine 07/22/08 CHECK_SHORT_NAME_EMPTY										*
 *	Kyle 11/06/2008 QA80-12531 PROVIDE_HINT_FOR_CUSTOM_DATE_FORMAT_IN_WKS_COL_PROPERTIES_DIALOG
 *	CPY 12/03/2008 QA70-12709 BAD_NUMERIC_CONVERT_TO_DATE_LEAD_TO_JUNK			*
 *	Kyle 12/08/2008 CHECK_IF_RANGE_SELECTED_DIFFERENT_FROM_FORMULA_RANGE		*
 *	CPY 12/30/08 QA70-12890-P2 CONVERT_TEXT_TO_CUSTOM_DATE_FAILED_FROM_CSV_IMPORT
 *	Kyle 12/31/2008 QA70-12890-P3 IMPORVE_CUSTOM_LIST_AFTER_USER_ENTERED_AND_RUN_SUCCESSFULLY_TO_ORIGIN_INI
 *	Kyle 01/04/2009 QA70-12890-P4 CENTRALIZE_CODE_TO_GET_AND_UPDATE_CUSTOM_DATE_FORMAT
 *	Jasmine 02/01/09 MATRIX_PROPERTIES_NOT_USE_COLOR_MAP						*
 *	Jasmine 02/16/09 SET_DIGIT_WITH_NUMERIC_DISPLAY_IF_CHANGED_FROM_DEFAULT		*
 *	Kyle 04/30/2009 SUPPORT_DEFINING_VARIABLES_IN_SET_VALUES_DIALOG				*
 *	CPY 5/11/09 QA70-12554 MAT_SET_VALUES_NEED_RANGE_SUPPORT					*
 *	Kyle 07/14/2009 QA80-13746 SHOWING_BOTH_LN_AND_SN_WITH_STANDARD_NOTATION_IN_THE_MENU_OF_SET_COLUMN_VALUE_DLG
 *	Kyle 07/20/2009 QA80-13746-P2 SCV_COL_COLUMN_BROWSER_AND_RANGE_BROWSER_SHOW_SN_LN_CLEANUP
 *	Sophy 8/7/2009 QA80-14101 SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
 *	Sophy 9/10/2009 QA80-14297 HIDE_SET_COL_VALS_DLG_WHEN_NO_VALID_DATA_SELECTED*
 *	Kenny 09/15/2009 QA81-14241 SET_COL_VAL_DLG_NEED_REMEMBER_VAR_INDICES_INTO_EACH_COL*
 *	Sophy 9/16/2009 QA80-14297 HIDE_SET_COL_VALS_DLG_WHEN_NO_VALID_DATA_SELECTED*
 *	Sophy 10/20/2009 QA80-14101-P1 FAIL_TO_SET_UNDEFINED_STATE_WHEN_COLUMNS_HAVE_DIFF_FORMAT
 *	Sophy 12/19/2009 QA80-14101 CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES	*
 *	Kyle 01/21/2010 QA80-14998 DIGITS_WILL_BE_RESET_TO_DEFAULT_WHILE_CHANGING_THE_DIGIT_MODE
 *	Hong 02/03/10 QA80-15063 COL_PROPS_DLG_ADD_FILE_INFO						*
 *	Hong 05/27/10 ORG-131 MATRIX_PROPERTIES_DLG_NEED_NORMAL_HEADER_ACCESS		*
 *------------------------------------------------------------------------------*/
   
////////////////////////////////////////////////////////////////////////////////////
// Including the system header file Origin.h should be sufficient for most Origin
// applications and is recommended. Origin.h includes many of the most common system
// header files and is automatically pre-compiled when Origin runs the first time.
// Programs including Origin.h subsequently compile much more quickly as long as
// the size and number of other included header files is minimized. All NAG header
// files are now included in Origin.h and no longer need be separately included.
// 
// Right-click on the line below and select 'Open "Origin.h"' to open the Origin.h
// system header file.
#include <Origin.h>
////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////
// Include your own header files here.
#include <GetNBox.h>
#include "okThemeID.h"
#include "DataObjectManager.h"

////////////////////////////////////////////////////////////////////////////////////
// Start your functions here.
///Jasmine 11/29/06 ADD_TAB_FOR_MORE_CONTENT
static bool _on_change_enum(TreeNode& tr, int nRow, int nType, Dialog& Dlg)
{
	TreeNode trRow = tree_get_node(tr, nRow);
///Jasmine 02/15/07 FIX_ENUM_SAME_SHORT_NAME_BUG
	return _after_change_enum(trRow);
}
static bool _after_change_enum(TreeNode& trRow)
{
	if(!trRow)
		return false;
	int nVal = trRow.Use;
	foreach(TreeNode cNode in trRow.Children)
		cNode.Enable = nVal != 0;
	if(trRow.FirstNode.IsValid())
		trRow.FirstNode.Enable = 2;
	if(trRow.StartIndex.IsValid())
	{
		trRow.StartIndex.Show = nVal == 1;
		trRow.StartIndex.Enable = nVal == 1;
	}
	return true;
}
///End FIX_ENUM_SAME_SHORT_NAME_BUG
///End ADD_TAB_FOR_MORE_CONTENT
DataObjectManager::DataObjectManager(DataObject& ob)
{
	m_object = ob;
}
bool DataObjectManager::SetRange(const vector<int>& vnRows, const vector<int>& vnCols, int nColSelWay)
{
	if(NULL != vnRows)
		m_vnRowRanges = vnRows;
	if(NULL != vnCols)
		m_vnColRanges = vnCols;
	
	m_nColSelWay = nColSelWay;
	return true;
}
DataObjectManager::~DataObjectManager()
{
	
}
bool DataObjectManager::Attach(DataObject& ob)
{
	m_object = ob;
	return true;
}
void DataObjectManager::GetTree(TreeNode& trProperties, int nSubBranchID)
{
	m_trProperties = trProperties;
	ConstructTree(m_trProperties);
	
	GetObjectSettings(trProperties);
	UpdateTreeShown(trProperties);
}
bool DataObjectManager::SetTree(TreeNode& trProperties, TreeNode &trChange)
{
	if(NULL == trProperties || !trProperties)
		return false;
	
	m_trProperties=trProperties;
	
	Tree trTemp;
	trTemp = m_trProperties;
	
	OnBeforeSettings(trTemp);
	
	Tree trFmt;
	///Jasmine 02/01/09 MATRIX_PROPERTIES_NOT_USE_COLOR_MAP
	//trFmt = m_object.GetFormat(FPB_ALL, FOB_ALL, true, true);
	trFmt = m_object.GetFormat(FPB_ALL, FOB_ALL & ~FOB_COLORMAP, true, true);
	///End MATRIX_PROPERTIES_NOT_USE_COLOR_MAP
	TreeNode trProp;
	trProp = trFmt.Root;	

	octree_copy_values_by_id(&trTemp, &trProp, true, STR_DATAID_ATTRIB, STR_ID_ATTRIB);
	//---- CPY 12/30/08 QA70-12890-P2 CONVERT_TEXT_TO_CUSTOM_DATE_FAILED_FROM_CSV_IMPORT
	// move this inside ApplySettings
	// del all nodes that are not changed
	//octree_delete_nodes_by_missing_attribute(&trProp, STR_CHANGED_ATTRIB);
	//----
	ApplySettings(trProp, m_object);
	
	OnAfterSettings(m_trProperties);
	return true;
}
void DataObjectManager::GetName(string &strName)
{
	strName = m_object.GetName();
}
void DataObjectManager::GetObjectSettings(TreeNode& trGUI)
{
	Tree trFmt;
	///Jasmine 02/01/09 MATRIX_PROPERTIES_NOT_USE_COLOR_MAP
	//trFmt = m_object.GetFormat(FPB_ALL, FOB_ALL, true, true);
	trFmt = m_object.GetFormat(FPB_ALL, FOB_ALL & ~FOB_COLORMAP, true, true);
	///End MATRIX_PROPERTIES_NOT_USE_COLOR_MAP
	TreeNode trProp = trFmt.Root;

	octree_copy_values_by_id(&trProp, &trGUI, false, STR_ID_ATTRIB, STR_DATAID_ATTRIB);

///Kevin 11/15/05 QA70-8292-3 COL_INTERNAL_DATATYPE_COMPLEX_NOT_WORKING
	ConvertFormatTree(trGUI);
///End	COL_INTERNAL_DATATYPE_COMPLEX_NOT_WORKING
	CopyLabelValues(trGUI);	///Jasmine 11/29/06 ADD_TAB_FOR_MORE_CONTENT
}
//----- CPY 5/11/09 QA70-12554 MAT_SET_VALUES_NEED_RANGE_SUPPORT
static void _chk_order(int& n1, int &n2)
{
	if(n2 > -1 && n1 > n2)
	{
		int nn = n1;
		n1 = n2;
		n2 = nn;
	}
}
//------

bool DataObjectManager::GetRowRange(int& nBegin, int& nEnd)
{
	int nSize = m_vnRowRanges.GetSize();
	if(0 == nSize)
	{
		nBegin = -1;
		nEnd = -1;
	}
	else
	{
		nBegin = m_vnRowRanges[0];
		nEnd = m_vnRowRanges[nSize-1];
	}
	//----- CPY 5/11/09 QA70-12554 MAT_SET_VALUES_NEED_RANGE_SUPPORT
	/*
	///DG 9/1/05 ROW_BEGIN_BIGGER_THAN_END_WORKS
	if(-1<nEnd && nBegin > nEnd)
	{
		int nTemp=nBegin;
		nBegin=nEnd;
		nEnd=nTemp;
	}
	///end ROW_BEGIN_BIGGER_THAN_END_WORKS
	*/
	_chk_order(nBegin, nEnd);
	//----- end MAT_SET_VALUES_NEED_RANGE_SUPPORT
	return true;
}
//----- CPY 5/11/09 QA70-12554 MAT_SET_VALUES_NEED_RANGE_SUPPORT
bool DataObjectManager::GetColRange(int& nBegin, int& nEnd)
{
	int nSize = m_vnColRanges.GetSize();
	if(0 == nSize)
	{
		nBegin = -1;
		nEnd = -1;
		return true;
	}
	nBegin = m_vnColRanges[0];
	nEnd = m_vnColRanges[1];
	_chk_order(nBegin, nEnd);	
	return true;
}
//-----end MAT_SET_VALUES_NEED_RANGE_SUPPORT

/*
void DataObjectManager::SetName(LPCSTR lpcstrName, bool &bCheckUpdateStruct, bool bForbidReload)
{
	bool bRet = m_object.SetName(lpcstrName);
	if(!bRet && !bForbidReload)
		GetTree(m_trProperties);
	bCheckUpdateStruct=!bRet;
}
void DataObjectManager::GetLongName(string &strName)
{
	strName = m_object.GetLongName();
}
void DataObjectManager::SetLongName(LPCSTR lpcstrName, bool &bCheckUpdateStruct, bool bForbidReload)
{
	bool bRet = m_object.SetLongName(lpcstrName);
	if(!bRet && !bForbidReload)
		GetTree(m_trProperties);
	bCheckUpdateStruct=!bRet;
}
void DataObjectManager::GetComments(string &strComments)
{
	strComments = m_object.GetComments();
}
void DataObjectManager::SetComments(LPCSTR lpcstrComments, bool &bCheckUpdateStruct, bool bForbidReload)
{
	bool bRet = m_object.SetComments(lpcstrComments);
	if(!bRet && !bForbidReload)
		GetTree(m_trProperties);
	bCheckUpdateStruct=!bRet;
}
*/
///Kevin 11/15/05 QA70-8292-3 COL_INTERNAL_DATATYPE_COMPLEX_NOT_WORKING
void DataObjectManager::ConvertFormatTree(TreeNode& trFmt, bool bToGUI /* = true */)
{
	TreeNode trDataFormat = tree_get_node_by_id(trFmt, OTID_WKSCOLUMN_FORMAT, true);
	
	//--- CPY 11/29/05 MAT_PROP_DIALOG_RUNTIME_ERR
	if(trDataFormat)
	{
		/////////Convert InternalData//////////////
		if(OKCOLTYPE_NUMERIC != trDataFormat.nVal)
			return;
	}
	//---

	//Since the FSI_TEXT, FSI_MIXED will not show in the GUI, so we must remove/add them when convert between GUI and InternalData
	
	int nDataTypeNonNumeric = FSI_BYTE - FSI_CHAR - 1;	// the number of non-numeric between BYTE and CHAR
	
	TreeNode trInternalData = tree_get_node_by_id(trFmt, OTID_WKSCOLUMN_INTDATA, true);
	if(trInternalData)
	{
		int nInternalData = trInternalData.nVal;
	
		if (bToGUI) 
		{
			if (nInternalData >= FSI_BYTE) 
				nInternalData -= nDataTypeNonNumeric;
		}
		else
		{
			if (nInternalData > FSI_CHAR) 
				nInternalData += nDataTypeNonNumeric;
		}
	
		trInternalData.nVal = nInternalData;
	}
}
///End COL_INTERNAL_DATATYPE_COMPLEX_NOT_WORKING

	//------ Folger 01/15/08 CENTRALIZE_CODE_OF_APPLY_FORMAT
	bool	DataObjectManager::ApplySettings(TreeNode &trProp, OriginObject &object)
	{
		///Jasmine 02/16/09 SET_DIGIT_WITH_NUMERIC_DISPLAY_IF_CHANGED_FROM_DEFAULT 
		int nVal;
		///Kyle 01/21/2010 QA80-14998 DIGITS_WILL_BE_RESET_TO_DEFAULT_WHILE_CHANGING_THE_DIGIT_MODE
		//if( trProp.NumericDisplay && trProp.NumericDisplay.GetAttribute(STR_CHANGED_ATTRIB, nVal) && nVal == NUMERIC_DEFAULT_DECIMAL)
		if( trProp.NumericDisplay && trProp.NumericDisplay.GetAttribute(STR_CHANGED_ATTRIB, nVal) )
		///End DIGITS_WILL_BE_RESET_TO_DEFAULT_WHILE_CHANGING_THE_DIGIT_MODE
		{
			if(trProp.Digits)
				trProp.Digits.SetAttribute(STR_CHANGED_ATTRIB, 0);
		}
		///End SET_DIGIT_WITH_NUMERIC_DISPLAY_IF_CHANGED_FROM_DEFAULT
		
		//---- CPY 12/30/08 QA70-12890-P2 CONVERT_TEXT_TO_CUSTOM_DATE_FAILED_FROM_CSV_IMPORT
		Tree trTemp;
		trTemp = trProp; // save a copy
		octree_delete_nodes_by_missing_attribute(&trProp, STR_CHANGED_ATTRIB);// del all nodes that are not changed
		//----
		bool		bRet = false;
		TreeNode	trFormat = trProp.Parent();
		if(trProp.Format.IsValid() && trProp.InternalData.IsValid() && trProp.Format.nVal != OKCOLTYPE_NUMERIC)
		{
			trProp.InternalData.Remove(); // this is later in the theme tree, so we must remove otherwise it will set col back to Numeric
		}
		
		//------ Folger 04/15/08 QA80-11377 FIX_APPLY_DEFAULT_NUMERIC_FORMAT_CAUSE_SET_THEME_ERROR
		if ( trProp.Digits )
		{
			if ( trProp.NumericDisplay && trProp.NumericDisplay.nVal == NUMERIC_DEFAULT_DECIMAL )
				trProp.Digits.Remove();
		}
		//------
		
		if ( trFormat )
		{
			UndoBlock ub;
			LT_set_var(STR_LT_VAR_APPLY_FORMAT, 1);
			if ( trProp.Format )
			{
				Column col;
				if ( col = object )
				{
					if ( trProp.CustomFormat )
					{
						col.SetCustomDisplay(trProp.CustomFormat.strVal);
					}
					//---- CPY 12/30/08 QA70-12890-P2 CONVERT_TEXT_TO_CUSTOM_DATE_FAILED_FROM_CSV_IMPORT
					//col.SetFormat(trProp.Format.nVal, trProp.Display ? trProp.Display.nVal : 0, true);
					//format and subformat must be set together
					int nSubFormat;
					if(trProp.Display)
						nSubFormat = trProp.Display.nVal;
					else
						nSubFormat = trTemp.Display.nVal;
					col.SetFormat(trProp.Format.nVal, nSubFormat, true);
					//---- end QA70-12890-P2
				}
				trProp.Format.Remove();
				if ( trProp.Display )
					trProp.Display.Remove();
			}
			bRet = object.ApplyFormat(trFormat, TRUE, TRUE, TRUE);
			LT_set_var(STR_LT_VAR_APPLY_FORMAT, 0);
		}
		return bRet;
	}
	//------

///Kyle 12/31/2008 QA70-12890-P3 IMPORVE_CUSTOM_LIST_AFTER_USER_ENTERED_AND_RUN_SUCCESSFULLY_TO_ORIGIN_INI
void DataObjectManager::UpdateCustomFormatList(TreeNode& trCustomFormat)
{
	if(!trCustomFormat || !trCustomFormat.Enable)
		return;
	
	string strNewDis = trCustomFormat.strVal;
	///Kyle 01/04/2009 QA70-12890-P4 CENTRALIZE_CODE_TO_GET_AND_UPDATE_CUSTOM_DATE_FORMAT
	//if(strNewDis.IsEmpty())
		//return;
//
	//string strCustomFormatList;
	//vector<string> vsCustomDisList;
//
	//trCustomFormat.GetAttribute(STR_COMBO_ATTRIB, strCustomFormatList);
	//strCustomFormatList.TrimLeft('|');
	//strCustomFormatList.GetTokens(vsCustomDisList, '|');
//
	//int nRemove = vsCustomDisList.Find(strNewDis);
	//if(nRemove == 0)		// the first one, not changed
		//return;
//
	//if(nRemove < 0 && vsCustomDisList.GetSize() >= CUSTOM_FORMAT_LIST_MAX_NUM)
		//nRemove = vsCustomDisList.GetSize() -1;
	//if(nRemove >= 0)
		//vsCustomDisList.RemoveAt(nRemove);
	//vsCustomDisList.InsertAt(0, strNewDis);
	//
	//strCustomFormatList.SetTokens(vsCustomDisList, '|');
	//strCustomFormatList = "|" + strCustomFormatList;
	//trCustomFormat.SetAttribute(STR_COMBO_ATTRIB, strCustomFormatList);
	//
	//saveCustomFormatIni(vsCustomDisList);
	if(0 == update_custom_date_format_last_used(strNewDis))
	{
		vector<string> vsList;
		get_custom_date_format_list(vsList);
		string strCustomFormatList;
		strCustomFormatList.SetTokens(vsList, '|');
		strCustomFormatList = "|" + strCustomFormatList;
		trCustomFormat.SetAttribute(STR_COMBO_ATTRIB, strCustomFormatList);
	}
	///End CENTRALIZE_CODE_TO_GET_AND_UPDATE_CUSTOM_DATE_FORMAT
}
///Kyle 01/04/2009 QA70-12890-P4 CENTRALIZE_CODE_TO_GET_AND_UPDATE_CUSTOM_DATE_FORMAT
//void DataObjectManager::saveCustomFormatIni(const vector<string>& vsList)
//{
	//clearCustomFormatIni();
//
	//INIFile	iniFile(STR_CUSTOM_FORMAT_LIST_FILE);
	//for(int ii=0; ii<vsList.GetSize(); ii++)
		//update_ini_line(iniFile, STR_CUSTOM_FORMAT_LIST_SECTION, STR_CUSTOM_FORMAT_LIST_PREFIX + (string)ii, vsList[ii]);
//}
//
//void DataObjectManager::checkLoadCustomFormatIni(vector<string>& vsList)
//{
	//vsList.SetSize(0);
//
	//vector<string> vsKeyNames;
	//INIFile	iniFile(STR_CUSTOM_FORMAT_LIST_FILE);
//
	//iniFile.GetKeyNames(vsKeyNames, STR_CUSTOM_FORMAT_LIST_SECTION);
	//for ( int ii = 0; ii < vsKeyNames.GetSize(); ii++ )
		//vsList.Add(iniFile.ReadString(STR_CUSTOM_FORMAT_LIST_SECTION, vsKeyNames[ii]));
	//
	//if(vsList.GetSize() > CUSTOM_FORMAT_LIST_MAX_NUM)
		//vsList.SetSize(CUSTOM_FORMAT_LIST_MAX_NUM);
	//
	//if(vsList.GetSize() <= 0)
	//{
		//string strDefFormat = STR_CUSTOM_DATE_FORMAT_LIST;
		//strDefFormat.TrimLeft('|');
		//strDefFormat.GetTokens(vsList, '|');
//
		//saveCustomFormatIni(vsList);
	//}
//}
//
//void DataObjectManager::clearCustomFormatIni()
//{
	//INIFile	iniFile(STR_CUSTOM_FORMAT_LIST_FILE);
	//update_ini_line(iniFile, STR_CUSTOM_FORMAT_LIST_SECTION, NULL, NULL );//clean list
//}
/////End CENTRALIZE_CODE_TO_GET_AND_UPDATE_CUSTOM_DATE_FORMAT
///End IMPORVE_CUSTOM_LIST_AFTER_USER_ENTERED_AND_RUN_SUCCESSFULLY_TO_ORIGIN_INI

/// Kenny 09/15/2009 QA81-14241 SET_COL_VAL_DLG_NEED_REMEMBER_VAR_INDICES_INTO_EACH_COL

#define STR_VAR_INFO_STORAGE_NAME		"VarInfo"

bool DataObjectManager::SetVarInfo( const DataObjectVarInfo& info )
{
	if ( m_object )
	{
		Tree trInfo;
		trInfo = info;
		BOOL bRet = m_object.PutBinaryStorage(STR_VAR_INFO_STORAGE_NAME, trInfo);
		return bRet;
	}
	return false;
}

bool DataObjectManager::GetVarInfo( DataObjectVarInfo& info )
{
	if ( m_object )
	{
		Tree trInfo;
		BOOL bRet = m_object.GetBinaryStorage(STR_VAR_INFO_STORAGE_NAME, trInfo);
		if ( bRet )
		{
			info = trInfo;
		}
		else
		{
			memset(&info, 0, sizeof(DataObjectVarInfo));
		}
		return bRet;
	}
	return false;
}
/// End QA81-14241 SET_COL_VAL_DLG_NEED_REMEMBER_VAR_INDICES_INTO_EACH_COL
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////         ColAccess  		////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
ColAccess::ColAccess()
{
	m_nPageType = EXIST_WKS;
}
ColAccess::ColAccess(Column& col) : DataObjectManager(col)
{
	m_nPageType = EXIST_WKS;
	m_Col = col;
	m_Col.GetParent(m_wks);
}
ColAccess::ColAccess(Worksheet& wks)
{
	m_nPageType = EXIST_WKS;
	m_wks = wks;
}
bool ColAccess::Attach(Worksheet &wks, UINT iColNum)
{
	m_wks = wks;
	bool bRet = m_Col.Attach(wks, iColNum);
	DataObjectManager::Attach(m_Col);
	return bRet;
}
bool ColAccess::IsValid()
{
	return m_Col.IsValid();
}
///Jasmine 10/19/06 HIDE_DLG_IF_SEL_INVALID, ColProperties Dlg update for label selection
bool is_wks_sel_valid(Layer& lay, bool bAllowLabel, LPCSTR lpcszDebugFrom)//= false = NULL
{
	Worksheet wks(lay);
	if(!wks)
		return false;
	
	///Sophy 9/16/2009 QA80-14297 HIDE_SET_COL_VALS_DLG_WHEN_NO_VALID_DATA_SELECTED
	//the method Worksheet::GetSelectedRange(int&, int&, int&, int&, string*)can not get select range when change selection on the same layer from NONE to one column, in Set Column Values dialog,
	//so I use another overloaded method go get selection
	/*
	int nBeginRow, nEndRow, nBeginCol, nEndCol;
	vector<int> vnSelCols, vnSelRows;
	int nSelection = wks.GetSelectedRange(nBeginRow, nBeginCol, nEndRow, nEndCol);
	//---- CPY 10/25/06 SWITCH_WIN_BY_SEL_COL_EVENT_PROPER_HANDLE
	if(lpcszDebugFrom)
	{
		//printf("From %s: wks sel = %d\n", lpcszDebugFrom, nSelection);
	}
	//----
	
	if(bAllowLabel && ((WKS_SEL_ONE_COL | WKS_SEL_DISCONTIGUOUS | WKS_SEL_COLUMN | WKS_SEL_EDIT | WKS_SEL_LABEL) & nSelection))
		return true;
///End HIDE_DLG_IF_SEL_INVALID
	///Joseph 08/24/06 
	//if((WKS_SEL_ONE_COL | WKS_SEL_DISCONTIGUOUS | WKS_SEL_COLUMN) & nSelection) //is_wks_sel_valid = true when just select one cell in wks;
	if((WKS_SEL_ONE_COL | WKS_SEL_DISCONTIGUOUS | WKS_SEL_COLUMN | WKS_SEL_EDIT) & nSelection)	
	///End WKS_SEL_EDIT_IS_SEL_VALID
		return true;
	*/
	int nSelection = 0;
	if ( bAllowLabel )
	{
		int nBeginRow, nEndRow, nBeginCol, nEndCol;
		nSelection = wks.GetSelectedRange(nBeginRow, nBeginCol, nEndRow, nEndCol);
		if ( (WKS_SEL_ONE_COL | WKS_SEL_DISCONTIGUOUS | WKS_SEL_COLUMN | WKS_SEL_EDIT | WKS_SEL_LABEL) & nSelection )
			return true;
	}
	vector<int> vnR1, vnC1, vnR2, vnC2;
	nSelection = wks.GetSelectedRange(vnR1, vnC1, vnR2, vnC2);
	if ( nSelection > 0 )
	{
		if ( bAllowLabel )
			return true;
		else if ( vnC1.GetSize() == 1 && (vnC1[0] - vnC2[0] == 0) ) //set column value not allow select label and only allow select one column as valid range,
			return true;
	}
	///end HIDE_SET_COL_VALS_DLG_WHEN_NO_VALID_DATA_SELECTED
	return false;
}
void ColAccess::GetSelection(Layer& lay)
{
	Worksheet wks(lay);
	if(!wks)
	{
		error_report("Invalid Worksheet");
		return;
	}
	int nBeginRow, nEndRow, nBeginCol, nEndCol;
	vector<int> vnSelCols, vnSelRows;
	int nSelection = wks.GetSelectedRange(nBeginRow, nBeginCol, nEndRow, nEndCol);

	int nSelectionWay = DATAOB_COL_SEL_CONTIGUOUS;
	if((WKS_SEL_ONE_COL & nSelection) && !(WKS_SEL_RANGE & nSelection))
	{
		vnSelCols.Add(nBeginCol);
	}
	else if((WKS_SEL_DISCONTIGUOUS | WKS_SEL_COLUMN) & nSelection)
	{
		vector<int> vnSelCols2;
		wks.GetSelectedRange(vnSelCols2, vnSelCols, vnSelCols2, vnSelCols2);
		nSelectionWay = DATAOB_COL_SEL_DISCONTIGUOUS;
		if(1 == vnSelCols.GetSize() && 1 == vnSelCols2.GetSize())
		{
			//contiguous columns selected
			int nFirstCol = vnSelCols[0];
			vnSelCols.Data(nFirstCol, vnSelCols2[0], 1);
		}
	}
	else	//WKS_SEL_RANGE
	{
		vnSelRows.Add(nBeginRow+1);
		vnSelRows.Add(nEndRow+1);
		
		vnSelCols.Data(nBeginCol, nEndCol);
	}
	//vnSelRows empty means all rows
	SetRange(vnSelRows, vnSelCols, nSelectionWay);
	if(0 < vnSelCols.GetSize())	///Jasmine 10/19/06 HIDE_DLG_IF_SEL_INVALID, avoid invalid access
		Attach(wks, vnSelCols[0]);
}
void ColAccess::GetAllObjectsLongNames(vector<string>& vsNames)
{
	vsNames.SetSize(0);
	string strName;
	vector<string> vsColNames;
	foreach(Column col in m_wks.Columns)
	{
		//vsNames.Add(col.GetName());
		strName = col.GetLongName();
		///DG CHECK_INVALID_LONGNAME_IN_SET_COLVALDLG
		//if(strName.IsEmpty())
		string strTemp("_"+strName);
		strTemp.Remove(' ');	///Jasmine 11/29/06 LNAME_WITH_SPACE_IS_OK_IN_LT
		if(strName.IsEmpty() || !is_str_valid_for_filename(strTemp)) //file name have the same rule as Variable name
		///end CHECK_INVALID_LONGNAME_IN_SET_COLVALDLG
			strName = col.GetName();
			
		///-----Frank 12/09/05 CHECK_DUPLICATE_LONG_NAME_COLUMN
		vsColNames.Add(col.GetName());
		int nDupliInd=-1;	
		if((nDupliInd = vsNames.Find(strName))>=0)
		{
			vsNames[nDupliInd] = vsColNames[nDupliInd];
			strName = col.GetName();			
		}
		///-----eND CHECK_DUPLICATE_LONG_NAME_COLUMN
		
		vsNames.Add(strName);
	}
}

///Kyle 07/14/2009 QA80-13746 SHOWING_BOTH_LN_AND_SN_WITH_STANDARD_NOTATION_IN_THE_MENU_OF_SET_COLUMN_VALUE_DLG
void ColAccess::GetAllObjectsNames(vector<string>& vsSNames, vector<string>& vsLNames)
{
	vsSNames.SetSize(0);
	vsLNames.SetSize(0);
	foreach(Column col in m_wks.Columns)
	{
		vsLNames.Add(col.GetLongName());
		vsSNames.Add(col.GetName());
	}
}
///END SHOWING_BOTH_LN_AND_SN_WITH_STANDARD_NOTATION_IN_THE_MENU_OF_SET_COLUMN_VALUE_DLG

bool ColAccess::HasPreviousObject()
{
	int nSize = m_vnColRanges.GetSize();
	if(1 != nSize)
		return false;	//multiple column select don't support previous
	
	if(0 != m_vnColRanges[0])
		return true;
	
	return false;
}
bool ColAccess::HasNextObject()
{
	int nSize = m_vnColRanges.GetSize();
	if(1 != nSize)
		return false;	//multiple column select don't support previous
	
	if(m_wks.Columns.Count()-1 != m_vnColRanges[0])
		return true;
	
	return false;
}
void ColAccess::ActivePreviousObject()
{
	/// Leo 2005-11-4 FIX_COLUMN_SELECTION_BUG	
	// int nPrevious = m_vnColRanges[0] - 1;
	int nPrevious = m_vnColRanges[0];
	ActiveColumn(nPrevious);
	wks_scroll_into_view(m_wks, nPrevious - 1);//----Jake 04/18/07 ADD_FIRST_AND_LAST_BUTTON
}
void ColAccess::ActiveNextObject()
{
	/// Leo 2005-11-4 FIX_COLUMN_SELECTION_BUG	
	// int nNext = m_vnColRanges[0] + 1;
	int nNext = m_vnColRanges[0] + 2;
	ActiveColumn(nNext);
	wks_scroll_into_view(m_wks, nNext - 1);//----Jake 04/18/07 ADD_FIRST_AND_LAST_BUTTON
}

//----Jake 04/18/07 ADD_FIRST_AND_LAST_BUTTON	
void ColAccess::ActiveFirstObject()
{
	int nFirst = 1;
	ActiveColumn(nFirst);
	wks_scroll_into_view(m_wks, nFirst - 1);
}
void ColAccess::ActiveLastObject()
{
	int nLast = m_wks.Columns.Count();
	ActiveColumn(nLast);
	wks_scroll_into_view(m_wks, nLast - 1);
}
//----end ADD_FIRST_AND_LAST_BUTTON

void ColAccess::ActiveColumn(int nColIndex)
{
	///Jasmine 02/18/08 QA80-11034 PROBLEMATIC_WORKSHEET_SELECT, LT script "worksheet -s" still doesn't work fine, I change to "wks.colSel" instead
	/// Leo 2005-11-4 FIX_COLUMN_SELECTION_BUG	
	// LT_execute("work -s "+nColIndex+" 0 "+nColIndex+" -1");
	//LT_execute("work -s "+nColIndex+" 1 "+nColIndex+" 0");	///Jasmine 11/01/07 QA70-10635 "worksheet -s c1 1 c2 0" will delete data in column
	//LT_execute("work -s "+nColIndex+" 0 "+nColIndex+" 0");	///Jasmine 01/31/08 cannot reproduce above problem in 796, so change back	
	m_wks.SetSelectedRange(NULL);
	string strLT;
	/// Sophy 5/14/2008 FIX_BUG_COLUNM_SELECTION_ERROR_ON_SET_VALUES
	//strLT.Format("wks.colSel(%d, 1)", nColIndex);
	strLT.Format("work -s %d 0", nColIndex); //"wks.colSel" doesn't work properly on some machine, this code is changed temporary.
	/// End FIX_BUG_COLUNM_SELECTION_ERROR_ON_SET_VALUES
	LT_execute(strLT);
	///End PROBLEMATIC_WORKSHEET_SELECT
}




////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////         ColProperties  		////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
ColProperties::ColProperties() : ColAccess()
{
}
ColProperties::ColProperties(Column& col) : ColAccess(col)
{
}
ColProperties::ColProperties(Worksheet& wks) : ColAccess(wks)
{
}
bool ColProperties::Attach(Worksheet &wks, UINT iColNum)
{
	bool bRet = ColAccess::Attach(wks, iColNum);
	return bRet;
}
bool ColProperties::IsProcessSelChange(Layer& lay) //--- CPY 2/20/06 MAT_DIALOG_SHOULD_HAVE_NO_SEL_CHANGE_HANLDING
{
	return is_wks_sel_valid(lay, true);///Jasmine 10/19/06 HIDE_DLG_IF_SEL_INVALID, ColProperties Dlg update for label selection
}
///Jasmine 11/10/06 APPLY_OPTION_TO_ALL_RIGHT_COL	
///Jasmine 11/29/06 ADD_TAB_FOR_MORE_CONTENT
void ColProperties::EnumColsNamesToRight(LPCSTR lpcszName, int nIndex, int nStop, bool &bCheckUpdateStruct, bool bForbidReload)
{
	string strName(lpcszName), strNewName;
	int nCol=nIndex - 1, nFirstCol = m_vnColRanges[0];
	bool bRet=true;
	foreach(Column col in m_wks.Columns)
	{
		if(col.GetIndex() < nFirstCol || (nStop != -1 && col.GetIndex() > nStop))//ignore cols on the left
///End ADD_TAB_FOR_MORE_CONTENT		
			continue;
		strNewName = strName+(string)(nCol+1);
		if(0 != col.GetName().CompareNoCase(strNewName) && ColProperties::IsSameNameColumnExist(strNewName, true, nStop))
		{
			//auto rename
			for(int ii=1; ;ii++)
			{
				string str('A', ii);
				str+=strNewName;
				if(!ColProperties::IsSameNameColumnExist(str, true, nStop))
				{
					strNewName = str;
					break;
				}
			}
		}
		///Jasmine 08/13/07 MAKE_APPLY_UNDOABLE
		//bRet &= col.SetName(strNewName);
		Tree trFmt;
		trFmt.Root.ShortName.strVal = strNewName;  
		int iRet = col.UpdateThemeIDs(trFmt.Root, "Error", "Unknown tag");
		bRet &= col.ApplyFormat(trFmt, TRUE, TRUE, TRUE);
		///End MAKE_APPLY_UNDOABLE
		nCol++;
	}	
	bCheckUpdateStruct = true;	//name has been changed by enum
}

/// Hong 01/29/07 MORE_APPLY_OPTION_TO_ALL_RIGHT_COL
typedef enum
{
	LABEL_LONG_NAME = 0,
	LABEL_UNIT,
	LABEL_COMMENTS,
}LABEL_TYPE;

typedef enum
{
	UPDATE_NONE = 0,
	UPDATE_ENUM,
	UPDATE_DUP,
}UPDATE_TYPE;

void ColProperties::ChangeColsLabelsToRight(LPCSTR lpcszName, int nIndex, int nStop, bool &bCheckUpdateStruct, bool bForbidReload, int nLabelType, int nUpdateType) // 1, -1, false, false, 0, 0
{
	string strName(lpcszName), strNewName;
	int nCol=nIndex - 1, nFirstCol = m_vnColRanges[0];
	bool bRet=true;
	
	strNewName = strName; // initial by UPDATE_DUP
	
	foreach(Column col in m_wks.Columns)
	{
		if(col.GetIndex() < nFirstCol || (nStop != -1 && col.GetIndex() > nStop))//ignore cols on the left		
			continue;
		if( UPDATE_ENUM == nUpdateType ) // reassign if UPDATE_ENUM
			strNewName = strName+(string)(nCol+1);		
		///Jasmine 08/13/07 MAKE_APPLY_UNDOABLE
		Tree trFmt;
		switch(nLabelType)
		{
		case LABEL_LONG_NAME:
			//bRet &= col.SetLongName(strNewName);
			trFmt.Root.LongName.strVal = strNewName;  
			break;
		case LABEL_UNIT:
			//bRet &= col.SetUnits(strNewName);
			trFmt.Root.Unit.strVal = strNewName;  
			break;
		case LABEL_COMMENTS:
			//bRet &= col.SetComments(strNewName);
			trFmt.Root.Comment.strVal = strNewName;  
			break;
		}		
		int iRet = col.UpdateThemeIDs(trFmt.Root, "Error", "Unknown tag");
		bRet &= col.ApplyFormat(trFmt, TRUE, TRUE, TRUE);
		///End MAKE_APPLY_UNDOABLE
		nCol++;
	}	
	bCheckUpdateStruct = true;
}
/// end MORE_APPLY_OPTION_TO_ALL_RIGHT_COL

void ColProperties::OnBeforeSettings(TreeNode& trColProperties)
{
	///DG 8/3/05 DUP_NAME_NOT_ALLOW
	TreeNode trSName = trColProperties.SName;
	string strSName = trSName.strVal;
	bool bUpdate;
	TreeNode trEnumNames = trColProperties.LabelOption.EnumSName;//trColProperties.Enumnames;	///Jasmine 11/28/06 ENUMERATE_LABELS
	///Jasmine 11/29/06 ADD_TAB_FOR_MORE_CONTENT
	int nIndex = trColProperties.LabelOption.EnumSName.StartIndex.nVal, nStop = trColProperties.LabelOption.EnumSName.StopCol.nVal - 1;
	if(trEnumNames && 1 == trEnumNames.Use)
	{
		EnumColsNamesToRight(strSName, nIndex, nStop, bUpdate, true);
	///End ADD_TAB_FOR_MORE_CONTENT
		trSName.Remove();
		trEnumNames.Remove();
	}
	///Jasmine 07/22/08 CHECK_SHORT_NAME_EMPTY		
	else if( strSName.IsEmpty() )
	{
		MessageBox(GetWindow(), _L("Column name cannot be empty."), _L("Attention!"), MB_OK | MB_ICONEXCLAMATION);		
		trSName.Remove();
	}
	///End CHECK_SHORT_NAME_EMPTY
	else if(ColProperties::IsSameNameColumnExist(strSName))
	{
		//same name column exist, not allow duplicate column name
		string strPrompts;
		strPrompts.Format(_L("Column name %s is already used by another column. Please choose another name."), strSName);
		MessageBox(GetWindow(), strPrompts, _L("Attention!"), MB_OK | MB_ICONEXCLAMATION);
		
		trSName.Remove();
	}
	///end DUP_NAME_NOT_ALLOW
///End APPLY_OPTION_TO_ALL_RIGHT_COL
	/// Hong 01/29/07 MORE_APPLY_OPTION_TO_ALL_RIGHT_COL
	TreeNode trLName = trColProperties.LName;
	string strLName = trLName.strVal;
	TreeNode trEnumLongNames = trColProperties.LabelOption.EnumLName;
	nIndex = trColProperties.LabelOption.EnumLName.StartIndex.nVal;
	nStop = trColProperties.LabelOption.EnumLName.StopCol.nVal - 1;
///Jasmine 02/06/07 REMOVE_TREENODE_IF_ENUM
// enumerate will set label, so after then, we should remove the label treenode
// so that it won't set label once more in SetTree	
	if(trEnumLongNames && 0 != trEnumLongNames.Use)
	{
		ChangeColsLabelsToRight(strLName, nIndex, nStop, bUpdate, true, LABEL_LONG_NAME, trEnumLongNames.Use);
		trLName.Remove();
		trEnumLongNames.Remove();	
	}	
	TreeNode trUnit = trColProperties.Unit;
	string strUnit = trUnit.strVal;
	TreeNode trEnumUnit = trColProperties.LabelOption.ApplyUnit;
	nStop = trColProperties.LabelOption.ApplyUnit.StopCol.nVal - 1;

	if(trEnumUnit && 0 != trEnumUnit.Use)
	{
		ChangeColsLabelsToRight(strUnit, -1, nStop, bUpdate, true, LABEL_UNIT, UPDATE_DUP); // only UPDATE_DUP for units 
		trUnit.Remove();
		trEnumUnit.Remove();
	}
	TreeNode trComments = trColProperties.Comments;
	string strComments = trComments.strVal;
	TreeNode trEnumComment = trColProperties.LabelOption.ApplyComment;
	nIndex = trColProperties.LabelOption.ApplyComment.StartIndex.nVal;
	nStop = trColProperties.LabelOption.ApplyComment.StopCol.nVal - 1;
	if(trEnumComment && 0 != trEnumComment.Use)
	{
		ChangeColsLabelsToRight(strComments, nIndex, nStop, bUpdate, true, LABEL_COMMENTS, trEnumComment.Use);
		trComments.Remove();
		trEnumComment.Remove();
	}
///End REMOVE_TREENODE_IF_ENUM
	/// end MORE_APPLY_OPTION_TO_ALL_RIGHT_COL
	RemoveDigitsIfValidInput(trColProperties);
}
void ColProperties::RemoveDigitsIfValidInput(TreeNode& trColProperties)
{
	TreeNode trOptions = GetFormatSettingsNode(trColProperties);
	TreeNode trNumeric = trOptions.Numeric;
	TreeNode trDigits = trOptions.Digits;
	int nNumeric = trNumeric.nVal;
	int nInput = trDigits.nVal;
	
	string strErrorPrompts;
	if(NUMERIC_SET_DECIMAL_PLACES == nNumeric)
	{
		if(MAX_DECIMAL_PLACES < nInput)
			strErrorPrompts = (string)nInput+" "+_L("is invalid input for decimal number,\nMax supported number is")+" "+(string)MAX_DECIMAL_PLACES;
	}
	else if(NUMERIC_SET_SIGNIFICANT_DIGITS == nNumeric)
	{
		if(MAX_SIGNIFICANT_DIGITS < nInput)
			strErrorPrompts = (string)nInput+" "+_L("is invalid input for significant digits,\nMax supported digits is")+" "+(string)MAX_SIGNIFICANT_DIGITS;
	}
	
	if(!strErrorPrompts.IsEmpty())
	{
		MessageBox(GetWindow(), strErrorPrompts, _L("Attention!"), MB_OK | MB_ICONEXCLAMATION);
		trDigits.Remove();
	}
}
TreeNode ColProperties::GetFormatSettingsNode(TreeNode& tr)
{
	return tr;
}
void ColProperties::OnAfterSettings(TreeNode& trColProperties)
{
	//------ CPY 4/14/08 QA70-11421 COL_PROP_DIALOG_ALWAYS_RUN_FORMULA_WHEN_ANY_THING_CHANGED
	/////formula need apply
	//m_Col.ExecuteFormula();
	//------ end COL_PROP_DIALOG_ALWAYS_RUN_FORMULA_WHEN_ANY_THING_CHANGED
	
	if(IsWrongDataFormat(m_Col))
	{
		string strPrompts;
		strPrompts.Format(_L("The specified format does not appear to match the data in the column(%s).\nSelect Edit: Undo or Press Ctrl+Z to undo this change."), m_Col.GetName());
		MessageBox(GetWindow(), strPrompts, _L("Attention!"), MB_ICONEXCLAMATION);
	}
	
	GetObjectSettings(trColProperties);	//reload to ensure change
	UpdateTreeShown(trColProperties);
}
void DataObjectManager::ConstructInfoTree(TreeNode &tr)
{
	GETN_USE(tr)
	GETN_STR(SName, STR_SHORT_NAME_LABEL, "") 									GETN_ID(OTID_WKSCOLUMN_SHORTNAME)
	///Jasmine 11/28/06 ENUMERATE_LABELS
	//GETN_CHECK(Enumnames, "Enumerate all to the right", 0)						GETN_ID(CMD_COL_ENUM_NAMES)	///Jasmine 11/10/06 APPLY_OPTION_TO_ALL_RIGHT_COL
	GETN_STR(LName, STR_LONG_NAME_LABEL, "") 									GETN_ID(OTID_WKSCOLUMN_LONGNAME)
	GETN_STR(Unit, STR_UNIT_LABEL, "") 											GETN_ID(OTID_WKSCOLUMN_UNIT)
	GETN_MULTILINE_TEXT(Comments, STR_COMMENTS_LABEL, "") 						GETN_ID(OTID_WKSCOLUMN_COMMENT) GETN_MULTILINE_EDIT_DISPLAY_ROW_HEIGHT_RANGE("2-5")
//------ CPY 4/14/08 QA70-11421 COL_PROP_DIALOG_ALWAYS_RUN_FORMULA_WHEN_ANY_THING_CHANGED
//	GETN_STR(Formula, STR_FORMULA_LABEL, "") 									GETN_ID(OTID_WKSCOLUMN_FORMULA)
//------
	///Jasmine 10/20/06 DIVIDE_INTO_THREE_GROUP
	GETN_BEGIN_BRANCH(WidthOption, _L("Width"))	GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
		//------ Folger 04/10/08 QA80-11391 USE_INTEGER_FORMATTING_GETN_IN_COLUMN_WIDTH_AND_SIGNIFICANT_DIGITS
		//GETN_STR(ColumnWidth, STR_WIDTH_LABEL, "4") 								GETN_ID(OTID_WKSCOLUMN_WIDTH)
		GETN_NUM(ColumnWidth, STR_WIDTH_LABEL, 4) 								GETN_ID(OTID_WKSCOLUMN_WIDTH)
		//------
		GETN_CHECK(ApplyAllCol, STR_APPLY_LABEL, false) ///Jasmine 09/18/06 QA70-6599 APPLY_WIDTH_TO_ALL_COL, no id for it isn't a col property
	GETN_END_BRANCH(WidthOption)
	///End DIVIDE_INTO_THREE_GROUP
}
///Jasmine 11/29/06 ADD_TAB_FOR_MORE_CONTENT
void ColProperties::ConstructEnumTree(TreeNode &tr, bool bShowStopCol)
{
	int nCurrent = m_Col.GetIndex() + 1, nCols = m_wks.GetNumCols(), nSize = min(nCols, 100);
	///Jasmine 02/15/06 ALLOW_EDIT_STOP_COL_COMBO_AND_CHECK_INPUT
	//string strCombo = nCurrent;
	//for(nCurrent += 1; nCurrent <= min(nCols, 100); nCurrent++)//now the upper limit of GETN_COMBO is 100 items
	string strCombo;
	for(; nCurrent <= nSize; nCurrent++)
	///End ALLOW_EDIT_STOP_COL_COMBO_AND_CHECK_INPUT
		strCombo += "|" + nCurrent;
	GETN_USE(tr)
	GETN_BEGIN_BRANCH(LabelOption, _L("Label Options(to columns to the right)"))	GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
	
	GETN_BEGIN_BRANCH(EnumSName, STR_SHORT_NAME_LABEL) GETN_OPTION_BRANCH(GETNBRANCH_OPEN) GETN_ID(CMD_COL_ENUM_NAMES) GETN_COMBO_BRANCH(0, "None|Enumerate") GETN_OPTION_EVENT(_on_change_enum)
		GETN_STR(SName, STR_SHORT_NAME_LABEL, "") GETN_READ_ONLY_COLOR
		GETN_NUM(StartIndex, _L("Start Index"), 1)
		GETN_COMBO(StopCol,_L("Stop Column"), nCols, strCombo) //temp, doing...
		GETN_CURRENT_SUBNODE.Show = bShowStopCol;
	GETN_END_BRANCH(EnumSName)
	GETN_BEGIN_BRANCH(EnumLName, STR_LONG_NAME_LABEL)  GETN_OPTION_BRANCH(GETNBRANCH_OPEN) GETN_COMBO_BRANCH(0, "None|Enumerate|Duplicate") GETN_OPTION_EVENT(_on_change_enum)
		GETN_STR(LName, STR_LONG_NAME_LABEL, "") GETN_READ_ONLY_COLOR 
		GETN_NUM(StartIndex, _L("Start Index"), 1)
		GETN_COMBO(StopCol,_L("Stop Column"), nCols, strCombo) //temp, doing...
		GETN_CURRENT_SUBNODE.Show = bShowStopCol;
	GETN_END_BRANCH(EnumLName)
	GETN_BEGIN_BRANCH(ApplyUnit, STR_UNIT_LABEL)  GETN_OPTION_BRANCH(GETNBRANCH_OPEN) GETN_COMBO_BRANCH(0, "None|Duplicate") GETN_OPTION_EVENT(_on_change_enum)
		GETN_STR(Unit, STR_UNIT_LABEL, "") GETN_READ_ONLY_COLOR  
		GETN_COMBO(StopCol,_L("Stop Column"), nCols, strCombo) //temp, doing...
		GETN_CURRENT_SUBNODE.Show = bShowStopCol;
	GETN_END_BRANCH(ApplyUnit)
	GETN_BEGIN_BRANCH(ApplyComment, STR_COMMENTS_LABEL)  GETN_OPTION_BRANCH(GETNBRANCH_OPEN) GETN_COMBO_BRANCH(0, "None|Enumerate|Duplicate") GETN_OPTION_EVENT(_on_change_enum)
		GETN_STR(Comments, STR_COMMENTS_LABEL, "") GETN_READ_ONLY_COLOR  
		GETN_NUM(StartIndex, _L("Start Index"), 1)
		GETN_COMBO(StopCol,_L("Stop Column"), nCols, strCombo) //temp, doing...
		GETN_CURRENT_SUBNODE.Show = bShowStopCol;
	GETN_END_BRANCH(ApplyComment)
	//GETN_BEGIN_BRANCH(ApplyPara1, _L("Parameter1"))  GETN_OPTION_BRANCH(GETNBRANCH_OPEN) GETN_COMBO_BRANCH(0, "None|Duplicate") GETN_OPTION_EVENT(_on_change_enum)
		////temp, doing...
	//GETN_END_BRANCH(ApplyPara1)
	
	GETN_END_BRANCH(LabelOption)
}
void ColProperties::CopyLabelValues(TreeNode& trGUI)
{
	vector<string> vs = {"SName", "LName", "Unit", "Comments"};
	TreeNode trSc, trDest;
	for(int ii = 0; ii < vs.GetSize(); ii++)
	{
		trSc = tree_get_node_by_tagname(trGUI, vs[ii], true);
		trDest = tree_get_node_by_tagname(trGUI.LabelOption, vs[ii], true);
		if(trSc && trDest)
		{
			trDest.strVal = trSc.strVal;
			if(trDest.Parent().IsValid())	///Jasmine 02/06/07 after enumerate, set back to none
			{
				trDest.Parent().Use = 0;
				_after_change_enum(trDest.Parent());	///Jasmine 02/15/07 FIX_ENUM_SAME_SHORT_NAME_BUG
			}
		}
	}
}
///End ADD_TAB_FOR_MORE_CONTENT
///Jasmine 12/08/06 ADD_USER_INFO_TAB
void ColProperties::ConstructUserInfoTree(TreeNode &tr, bool bMulti)// = false
{
	GETN_USE(tr)
	GETN_STR(RightClickHint, STR_RIGHT_CLICK_HINT, "")	GETN_HINT	///Jasmine 02/02/10 QA81-15064 SHOW_RIGHT_CLICK_HINT_IN_ONE_ROW_TO_SAVE_SPACE
	GETN_BEGIN_BRANCH(UserInfo, _L("User Tree"))	GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
		GETN_STR(NoInfo, "", _L("No User Tree")) GETN_READ_ONLY_COLOR
	GETN_END_BRANCH(UserInfo)
	//if(bMulti || !get_user_info(m_Col, NULL, tr.UserInfo))//get_user_info(m_Col, tr.UserInfo, false))	///Jasmine 01/08/07 MODIFICATION_GET_SET_USER_INFO
	Tree trStorage;
	if(bMulti || !tree_get_binary_storage(trStorage, m_Col, "TREE"))///Jasmine 01/15/07 CHANGE_USER_INFO_TO_TREE, "user_info"->"tree"
		return;
	tr.UserInfo.Replace(trStorage, true, true);
	tr.UserInfo.SetAttribute(STR_ATTRIB_BRANCH, GETNBRANCH_OPEN);
	tr.UserInfo.SetAttribute(STR_LABEL_ATTRIB, _L("User Tree"));
	///Jasmine 01/23/07 user parameters aren't storaged in binary storage, they're in column heading, so comment these codes
	/*
	//Convert ColUserVars
	vector<string> vsNames, vsValues;
	if(!get_user_parameters(m_Col, vsNames, vsValues))
		return;
	TreeNode trUserVar =  tree_get_node_by_tagname(tr.UserInfo, "ColUserVars", true);
	trUserVar.Reset();
	int nValues = vsValues.GetSize();
	for(int ii = 0; ii < vsNames.GetSize(); ii++)
		trUserVar.AddTextNode(ii<nValues? vsValues[ii] : "", vsNames[ii]);
	*/
}
///End ADD_USER_INFO_TAB

/// Hong 02/03/10 QA80-15063 COL_PROPS_DLG_ADD_FILE_INFO
void ColProperties::ConstructFileInfoTree(TreeNode &tr, bool bMulti)// = false
{
	return ; // Hong, rollback without remove code, see sim's comment in tracker
	Tree 		trStorage;
	if ( bMulti || !get_import_file_info(m_Col, trStorage) )
		return;
	GETN_USE(tr)
	GETN_BEGIN_BRANCH(FileInfo, _L("Imported File"))	GETN_OPTION_BRANCH(GETNBRANCH_OPEN)	GETN_READ_ONLY_COLOR
	GETN_END_BRANCH(FileInfo)
	GETN_CURRENT_SUBNODE.Replace(trStorage, true, true, true);
}
/// end COL_PROPS_DLG_ADD_FILE_INFO

///Jasmine 01/29/07 QA70-9287 EDIT_USER_TREE
void ColProperties::ApplyUserInfoTree(TreeNode &tr)
{
	TreeNode trUserInfo = tree_get_node_by_tagname(tr, "UserInfo", true);
	if(trUserInfo.IsValid())
		tree_put_binary_storage(trUserInfo, m_Col, "TREE");	
}
///End EDIT_USER_TREE
void DataObjectManager::ConstructFormatTree(TreeNode &tr)
{
	GETN_USE(tr)
	GETN_LIST(Display, STR_DISPLAY_LABEL, 0, STR_DATA_DISPLAY_MODE_LIST)				GETN_ID(OTID_WKSCOLUMN_DISPLAY)
	GETN_LIST(Numeric, STR_NUMERIC_DISPLAY_LABEL, 0, STR_DECIMAL_DIGITS_MODE_LIST)		GETN_ID(OTID_WKSCOLUMN_NUMDISPLAY)
	//------ Folger 04/10/08 QA80-11391 USE_INTEGER_FORMATTING_GETN_IN_COLUMN_WIDTH_AND_SIGNIFICANT_DIGITS
	//GETN_STR(Digits, STR_SIGNIFICANT_PLACES_LABEL, "")							GETN_ID(OTID_WKSCOLUMN_DIGITS)
	GETN_NUM(Digits, STR_SIGNIFICANT_PLACES_LABEL, 0)							GETN_ID(OTID_WKSCOLUMN_DIGITS)
	//------
	GETN_LIST(InternalData, STR_INTERNAL_DATA_TYPE_LABEL, 0, STR_COL_INTERNAL_DATA_LIST) GETN_ID(OTID_WKSCOLUMN_INTDATA)	
	/// EJP 2006-10-23 v8.0499 QA70-8741 THEME_ACCESS_COL_CUSTOM_DATE_FORMAT
	///Kyle 11/06/2008 QA80-12531 PROVIDE_HINT_FOR_CUSTOM_DATE_FORMAT_IN_WKS_COL_PROPERTIES_DIALOG
	//GETN_STR(CustomFormat, STR_CUSTOM_FORMAT_LABEL, "") 								GETN_ID(OTID_WKSCOLUMN_CUSTOMFORMAT)
	///Kyle 12/31/2008 QA70-12890-P3 IMPORVE_CUSTOM_LIST_AFTER_USER_ENTERED_AND_RUN_SUCCESSFULLY_TO_ORIGIN_INI
	//GETN_STRLIST(CustomFormat, STR_CUSTOM_FORMAT_LABEL, "", STR_CUSTOM_DATE_FORMAT_LIST) 								GETN_ID(OTID_WKSCOLUMN_CUSTOMFORMAT)
	string strCustomDateFmtList;
	vector<string> vsCustomList;
	///Kyle 01/04/2009 QA70-12890-P4 CENTRALIZE_CODE_TO_GET_AND_UPDATE_CUSTOM_DATE_FORMAT
	//checkLoadCustomFormatIni(vsCustomList);
	get_custom_date_format_list(vsCustomList);
	///End CENTRALIZE_CODE_TO_GET_AND_UPDATE_CUSTOM_DATE_FORMAT
	ASSERT( vsCustomList.GetSize() );
	strCustomDateFmtList.SetTokens(vsCustomList, '|');
	strCustomDateFmtList = "|" + strCustomDateFmtList;
	GETN_STRLIST(CustomFormat, STR_CUSTOM_FORMAT_LABEL, "", strCustomDateFmtList) 								GETN_ID(OTID_WKSCOLUMN_CUSTOMFORMAT)
	///End IMPORVE_CUSTOM_LIST_AFTER_USER_ENTERED_AND_RUN_SUCCESSFULLY_TO_ORIGIN_INI
	///End PROVIDE_HINT_FOR_CUSTOM_DATE_FORMAT_IN_WKS_COL_PROPERTIES_DIALOG
	/// end THEME_ACCESS_COL_CUSTOM_DATE_FORMAT
	GETN_CHECK(ApplyToRight, STR_APPLY_TO_RIGHT_LABEL, false) ///Jasmine 11/10/06 APPLY_OPTION_TO_ALL_RIGHT_COL
}

void ColProperties::ConstructFormatTree(TreeNode &tr)
{
	GETN_USE(tr)
	GETN_LIST(PlotDesignation, STR_PLOT_DESIGNATION_LABEL, 0, STR_COL_DESIGNATION_LIST)	GETN_ID(OTID_WKSCOLUMN_TYPE)
	GETN_LIST(Format, STR_FORMAT_LABEL, 0, STR_COL_FORMAT_LIST)							GETN_ID(OTID_WKSCOLUMN_FORMAT)
	
	DataObjectManager::ConstructFormatTree(tr);
}

void ColProperties::UpdateTreeShown(TreeNode& tr)
{
	TreeNode trOptions = GetFormatSettingsNode(tr);
	TreeNode trFormat = trOptions.Format;
	int nFormat = trFormat.nVal;
	
	TreeNode trDisplay = trOptions.Display;
	int nDisplay = trDisplay.nVal;
	TreeNode trNumeric = trOptions.Numeric;
	TreeNode trDigits = trOptions.Digits;
	TreeNode trInternalData = trOptions.InternalData;
	
	/// EJP 2006-10-23 v8.0499 QA70-8741 THEME_ACCESS_COL_CUSTOM_DATE_FORMAT
	TreeNode trCustomFormat = trOptions.CustomFormat;
	trCustomFormat.Show = false;
	/// end THEME_ACCESS_COL_CUSTOM_DATE_FORMAT

	trDisplay.Show = true;
	trNumeric.Show = false;
	trDigits.Show = false;
	trInternalData.Show = false;
	
	string strCombo;
	switch(nFormat)
	{
	case OKCOLTYPE_NUMERIC:
		trInternalData.Show = true;
	case GUI_COLUMNTYPE_TEXT_NUMERIC:
		trNumeric.Show = true;
		trDigits.Show = NUMERIC_SET_DECIMAL_PLACES==trNumeric.nVal || NUMERIC_SET_SIGNIFICANT_DIGITS==trNumeric.nVal;
		string strLabel = NUMERIC_SET_DECIMAL_PLACES==trNumeric.nVal ? STR_DECIMAL_PLACES_LABEL : STR_SIGNIFICANT_PLACES_LABEL;
		trDigits.SetAttribute(STR_LABEL_ATTRIB, strLabel);

		strCombo=STR_DATA_DISPLAY_MODE_LIST;
		break;
	case OKCOLTYPE_TIME:
		strCombo=STR_COL_TIME_DISPLAY_LIST;
		break;
	case OKCOLTYPE_DATE:
		strCombo=GetCurrentDataDisplayList();
		/// EJP 2006-10-23 v8.0499 QA70-8741 THEME_ACCESS_COL_CUSTOM_DATE_FORMAT
		trCustomFormat.Show = true;
		trCustomFormat.Enable = (GetListSize(strCombo)-1 == nDisplay);///Jasmine 03/24/07 "Custom Display" should be disabled unless "Custom Display" is selected in "Display".	
		/// end THEME_ACCESS_COL_CUSTOM_DATE_FORMAT
		break;
	case OKCOLTYPE_MONTH:
		strCombo=STR_COL_MONTH_DISPLAY_LIST;
		break;
	case OKCOLTYPE_WEEKDAY:
		strCombo=STR_COL_WEEK_DISPLAY_LIST;
		break;
	case OKCOLTYPE_TEXT:
	default:
		trDisplay.Show = false;
		break;
	}
	trDisplay.SetAttribute(STR_COMBO_ATTRIB, strCombo);
	trDisplay.nVal = GetListSize(strCombo) <= nDisplay? 0 : nDisplay;///Jasmine 03/24/07 Display value may need to change as strCombo change
	
	///Kyle 12/31/2008 QA70-12890-P3 IMPORVE_CUSTOM_LIST_AFTER_USER_ENTERED_AND_RUN_SUCCESSFULLY_TO_ORIGIN_INI
	UpdateCustomFormatList(trCustomFormat);
	///End IMPORVE_CUSTOM_LIST_AFTER_USER_ENTERED_AND_RUN_SUCCESSFULLY_TO_ORIGIN_INI
}
bool ColProperties::IsWrongDataFormat(Column& col)
{
	if(!col)
		return false;
	int nFormat = col.GetFormat();
	switch(nFormat)
	{
	case OKCOLTYPE_NUMERIC:
	case OKCOLTYPE_TEXT:
	case OKCOLTYPE_TEXT_NUMERIC:
		return false;	//this format fit all data
	case OKCOLTYPE_TIME:
	case OKCOLTYPE_DATE:
	case OKCOLTYPE_MONTH:
	case OKCOLTYPE_WEEKDAY:
	default:
		break;
	}
	
	Dataset ds(col);
	vector vec;
	vec = ds;
	//----- CPY 12/03/2008 QA70-12709 BAD_NUMERIC_CONVERT_TO_DATE_LEAD_TO_JUNK
	//the following lead to the crash, which should be fixed separately, but I also
	//do not see a reason for this very slow call(if dataset is large
	//vector<string> vs;
	//ds.GetStringArray(vs);
	//-----
	int nBeginIndex = ds.GetLowerBound();
	if(0 < nBeginIndex)
		vec.RemoveAt(0, nBeginIndex);
	
	int nSize = vec.GetSize();
	if(0 >= nSize)
		return false;	//no data
	
	int nMissing = ocmath_count(NANUM, nSize, vec);
	if(nMissing == nSize)
		return true;
	return false;
}
///Jasmine 11/10/06 APPLY_OPTION_TO_ALL_RIGHT_COL
///DG QA70-7883 8/1/05 v8.0277 DUP_NAME_NOT_ALLOW
///Jasmine 02/15/07 FIX_ENUM_SAME_SHORT_NAME_BUG
//bOutSideOnly : only check columns on the left of m_Col or right of StopCol
bool ColProperties::IsSameNameColumnExist(LPCSTR lpcszColName, bool bOutSideOnly, int nStopCol)//= false, 0
{
	///DG 8/3/05
	if(0==m_Col.GetName().CompareNoCase(lpcszColName))	//same name, no change
		return false;
	///end
	
	/// EJP 2005-09-27 v8.0311 QA70-7620 FIX_COL_DUPLICATE_SHORT_NAME
	///	string strDatasetName = m_wks.GetPage().GetName()+"_"+lpcszColName;
	///	Dataset ds(strDatasetName);	//if this constructor fail, we have to do it by following way
	///	//Dataset ds;
	///	//for(int ii=0; ii<m_wks.Columns.Count() && ds.Attach(m_wks, ii); ii++)
	///	//{
	///		//if(0 == ds.GetName().CompareNoCase(strDatasetName))
	///			//break;
	///		//ds.Detach();
	///	//}
	///	return ds.IsValid();
	Column col = m_wks.Columns(lpcszColName);
	//return ;
	if(col.IsValid())
	{
		//return bLeftOnly? (col.GetIndex() < m_Col.GetIndex()) : true;
		return bOutSideOnly? (col.GetIndex() < m_Col.GetIndex() || col.GetIndex() > nStopCol) : true;
	}
	return false;
	/// end FIX_COL_DUPLICATE_SHORT_NAME
}
///End FIX_ENUM_SAME_SHORT_NAME_BUG
///end DUP_NAME_NOT_ALLOW
///End APPLY_OPTION_TO_ALL_RIGHT_COL
string ColProperties::GetCurrentDataDisplayList()
{
	//Get today date
	time_t ltime;
	time( &ltime );
	
	string strShort, strFormat1, strFormat2;
	strShort=get_date_str(ltime, LDF_SHORT);
	for(int nFormat=LDF_SHORT; nFormat<=LDF_NUMERICYEAR_2DIGIT; nFormat++)
		strFormat1+=get_date_str(ltime, nFormat)+"|";
	
	for(nFormat=LDF_ALPHAMON_3CHR; nFormat<=LDF_QUARTER; nFormat++)
		strFormat2+=get_date_str(ltime, nFormat)+"|";
	
	/// EJP 2005-07-26 v8.0275 QA70-7886 ADD_CUSTOM_FORMAT_TO_OBJECT_LEVEL
	///strFormat2+=get_date_str(ltime, LDF_CUSTOM1)+_L(" (Custom1)|");
	///strFormat2+=get_date_str(ltime, LDF_CUSTOM2)+_L(" (Custom2)");
	
	/// Nicole 07/05/2007 v8.0655 REMOVE_SPACE_FOR_LOCATION_STRING
	/*
	strFormat2+=get_date_str(ltime, LDF_CUSTOM1)+_L(" (Global Custom1)|");
	strFormat2 += get_date_str(ltime, LDF_CUSTOM2)+_L(" (Global Custom2)|");
	*/
	strFormat2+=get_date_str(ltime, LDF_CUSTOM1)+ " " + _L("(Global Custom1)|");
	strFormat2 += get_date_str(ltime, LDF_CUSTOM2)+ " " +_L("(Global Custom2)|");
	/// END REMOVE_SPACE_FOR_LOCATION_STRING
	
	/// EJP 2006-10-23 v8.0499 QA70-8741 THEME_ACCESS_COL_CUSTOM_DATE_FORMAT
	//string strCustFmt;
	//Tree tr;
	//if( info_get_section(m_Col, tr, "system.display") )
		/////DG 8/22/05 COMMENT_RUN_TIME_ERROR_LINE: this code cause run time error, break col properties, so I temporary comment it
		////strCustFmt = tr.CustomFormat.strVal;
		//{
			//TreeNode trCustom = tr.CustomFormat;
			//if(trCustom)
				//strCustFmt = trCustom.strVal;
		//}
		/////end COMMENT_RUN_TIME_ERROR_LINE
	//if( strCustFmt.IsEmpty() )
		//strCustFmt = _L("<none>");
	//strFormat2 += strCustFmt + _L(" (Custom)");
	strFormat2 += STR_CUSTOM_FORMAT_LABEL;
	/////// end THEME_ACCESS_COL_CUSTOM_DATE_FORMAT
	/// end ADD_CUSTOM_FORMAT_TO_OBJECT_LEVEL

	/// EJP 2005-08-04 v8.0282 QA70-7886 ADD_CUSTOM_FORMAT_TO_OBJECT_LEVEL
	///return strFormat1+strShort+" HH:mm|"+strShort+" HH:mm:ss|"+"yyMMdd|yyMMdd HH:mm|yyMMdd HH:mm:ss|yyMMdd HHmm|yyMMdd HHmmss|";
	return strFormat1+strShort+" HH:mm|"+strShort+" HH:mm:ss|"+"yyMMdd|yyMMdd HH:mm|yyMMdd HH:mm:ss|yyMMdd HHmm|yyMMdd HHmmss|"+strFormat2;
	/// end QA70-7886 ADD_CUSTOM_FORMAT_TO_OBJECT_LEVEL
}

string ColProperties::get_date_str(time_t &ltime, WORD wFormat)
{
	SYSTEMTIME st;
	TM tmLocal;
	double dDate;
	
	convert_time_to_local( &ltime , &tmLocal);
    tm_to_systemtime(&tmLocal, &st);
	SystemTimeToJulianDate(&dDate, &st);
	return get_date_str(dDate, wFormat);
}
///Jasmine 03/24/07 MOVE_TO_COL_PROPERTIES	
int ColProperties::GetListSize(LPCSTR lpcszList, char ch)
{
	string str(lpcszList);
	vector<string> vs;
	int nSize = str.GetTokens(vs, ch);
	return nSize;
}
///End MOVE_TO_COL_PROPERTIES
////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////       MulColsProperties	    ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////

MulColsProperties::MulColsProperties() : ColProperties()
{
}
MulColsProperties::MulColsProperties(Column& col) : ColProperties(col)
{
	col.GetParent(m_wks);
}
MulColsProperties::MulColsProperties(Worksheet& wks) : ColProperties(wks)
{
	ColProperties::GetSelection(m_wks);
}
bool MulColsProperties::Attach(Worksheet &wks, UINT iColNum)
{
	return ColProperties::Attach(m_wks, iColNum);
}
bool MulColsProperties::attach(uint iColNum)
{
	return ColProperties::Attach(m_wks, iColNum);
}
bool MulColsProperties::isMulCols()
{
	return m_vnColRanges.GetSize() > 1;
}
int MulColsProperties::getCurrentDesignation(const vector<string>& vsList)
{
	//get current column designation string
	string strCurr;
	int nCol=0, nFirstCol = m_vnColRanges[0];
	Column col(m_wks, nFirstCol);
	do
	{
		strCurr+=getDesignationStr(col.GetType());
		nCol++;
	}
	while(nCol<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[nCol]));
	
	//check designation type
	string strCheck, strRepeat;
	for(int ii=0;ii<vsList.GetSize(); ii++)
	{
		strCheck = vsList[ii];
		
		//bool bRepeat = is_repeat_str(strTemp);
		bool bRepeat = 0<strCheck.Count(' ');
		strRepeat=strCheck.GetToken(1, ' ');
		strCheck.Remove(' ');
		int nCheckLength = strCheck.GetLength(), nCurrLength = strCurr.GetLength();
		
		if(nCheckLength < nCurrLength)
		{
			string strTemp;
			if(!bRepeat)
			{
				int nNum=nCurrLength/nCheckLength;
				for(int jj=0; jj<nNum; jj++)
					strTemp+=strCheck;
				if(strTemp == strCurr)
					return ii;	//simple duplicate
			}
			strTemp=strCurr;
			for(;0 == strTemp.Find(strCheck);)
				strTemp.Delete(0, nCheckLength);
			if(bRepeat)
			{
				int nRepeatLen = strRepeat.GetLength();
				for(;0 == strTemp.Find(strRepeat);)
					strTemp.Delete(0, nRepeatLen);
				if(strRepeat.Match(strTemp+"*"))
					return ii;
			}
			else
			{
				//check if the last type repeated
				int nLengthLeft = strTemp.GetLength();
				for(int jj=nCheckLength-1; jj>0; jj--)
				{
					//construct string
					strRepeat="";
					for(int kk=jj; kk<nCheckLength; kk++)
						strRepeat+=strCheck.GetAt(kk);
					
					//repeat time
					string strLeft;
					for(kk=0; kk<nLengthLeft/strRepeat.GetLength(); kk++)
						strLeft+=strRepeat;
					if(strLeft == strTemp)
						return ii;
				}
			}
		}
		else //nCheckLength >= nCurrLength
		{
			if(strCheck.Match(strCurr+"*"))
				return ii;
		}
	}
	return vsList.GetSize();	//not matched designation found
}
string MulColsProperties::getDesignationStr(int nDesignation)
{
	switch(nDesignation)
	{
	case OKDATAOBJ_DESIGNATION_X:
		return "X";
	case OKDATAOBJ_DESIGNATION_Y:
		return "Y";
	case OKDATAOBJ_DESIGNATION_Z:
		return "Z";
	case OKDATAOBJ_DESIGNATION_X_ERROR:
		return "XErr";
	case OKDATAOBJ_DESIGNATION_ERROR:
		return "YErr";
	case OKDATAOBJ_DESIGNATION_L:
		return "L";
	default :	//OKDATAOBJ_DESIGNATION_NONE
		return "Disregard";
	}
	return "";
}
void MulColsProperties::SetMulColsDesignation(LPCSTR lpcszDesignation, bool &bCheckUpdateStruct, bool bForbidReload)
{
	vector<int> vnFirstColDesignations, vnRepeatType;
	int nMulColsDesignation = atoi(lpcszDesignation);
	switch(nMulColsDesignation)
	{
	case MUL_COLS_DESIGNATION_X:
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_X);
		break;
	case MUL_COLS_DESIGNATION_Y:
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_Y);
		break;
	case MUL_COLS_DESIGNATION_Z:
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_Z);
		break;
	case MUL_COLS_DESIGNATION_DISREGARD:
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_NONE);
		break;
	case MUL_COLS_DESIGNATION_XYY:
		vnFirstColDesignations.Add(OKDATAOBJ_DESIGNATION_X);
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_Y);
		break;
	case MUL_COLS_DESIGNATION_XY_XY:
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_X);
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_Y);
		break;
	case MUL_COLS_DESIGNATION_XYY_XYY:
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_X);
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_Y);
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_Y);
		break;
	case MUL_COLS_DESIGNATION_XYYY_XYYY:
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_X);
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_Y);
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_Y);
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_Y);
		break;
	case MUL_COLS_DESIGNATION_XYYERR:
		vnFirstColDesignations.Add(OKDATAOBJ_DESIGNATION_X);
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_Y);
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_ERROR);
		break;
	case MUL_COLS_DESIGNATION_XYYERR_XYYERR:
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_X);
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_Y);
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_ERROR);
		break;
	case MUL_COLS_DESIGNATION_XYZZ:
		vnFirstColDesignations.Add(OKDATAOBJ_DESIGNATION_X);
		vnFirstColDesignations.Add(OKDATAOBJ_DESIGNATION_Y);
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_Z);
		break;
	case MUL_COLS_DESIGNATION_XYZ_XYZ:
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_X);
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_Y);
		vnRepeatType.Add(OKDATAOBJ_DESIGNATION_Z);
		break;
	default:
		//Don't set designation
		return;
	}
	
	int nCol=0, nFirstCol = m_vnColRanges[0], nFirstSize=vnFirstColDesignations.GetSize(), nRepeatSize=vnRepeatType.GetSize();
	bool bRet=true;
	Column col(m_wks, nFirstCol);
	int nType;
	do
	{
		if(nCol < nFirstSize)
			nType=vnFirstColDesignations[nCol];
		else
			nType=vnRepeatType[mod(nCol-nFirstSize, nRepeatSize)];
		///Jasmine 08/13/07 MAKE_APPLY_UNDOABLE
		//bRet &= col.SetType(nType);
		Tree trFmt;
		trFmt.Root.Designation.nVal = _convert_designation(nType) ;
		int iRet = col.UpdateThemeIDs(trFmt.Root, "Error", "Unknown tag");
		bRet &= col.ApplyFormat(trFmt, TRUE, TRUE, TRUE);
		///End MAKE_APPLY_UNDOABLE
		nCol++;
	}
	while(nCol<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[nCol]));
}
///Jasmine 08/13/07 MAKE_APPLY_UNDOABLE
static int _convert_designation(int nDesig)
{
	int nType;
	switch(nDesig)
	{
	case OKDATAOBJ_DESIGNATION_NONE:
		nType = SET_AS_NONE; break;
	case OKDATAOBJ_DESIGNATION_ERROR:
		nType = SET_AS_ERR_BAR; break;
	case OKDATAOBJ_DESIGNATION_X:
		nType = SET_AS_X; break;
	case OKDATAOBJ_DESIGNATION_L:
		nType = SET_AS_LABEL; break;
	case OKDATAOBJ_DESIGNATION_Z:
		nType = SET_AS_Z; break;
	case OKDATAOBJ_DESIGNATION_X_ERROR:
		nType = SET_AS_X_ERR_BAR; break;
	case OKDATAOBJ_DESIGNATION_GROUP:
		nType = SET_AS_GROUP; break;
	case OKDATAOBJ_DESIGNATION_SUBJECT:
		nType = SET_AS_SUBJECT; break;	
	case OKDATAOBJ_DESIGNATION_Y:
	default:
		nType = SET_AS_Y; break;
	}
	return nType;
}
///End MAKE_APPLY_UNDOABLE
///Jasmine 11/29/06 ADD_TAB_FOR_MORE_CONTENT
void MulColsProperties::EnumColsNames(LPCSTR lpcszName, int nIndex, bool &bCheckUpdateStruct, bool bForbidReload)
{
	string strName(lpcszName), strNewName;
	//int nCol=nIndex - 1, nFirstCol = m_vnColRanges[0]; 
	int nCol=nIndex - 1, nFirstCol = m_vnColRanges[0], nCount = 0; // Hong 01/29/07 FIX_ERROR_COUNT_COL_NUM
///End ADD_TAB_FOR_MORE_CONTENT
	bool bRet=true;
	Column col(m_wks, nFirstCol), colSameName;
	do
	{
		///DG DUP_NAME_NOT_ALLOW : auto change name while column with that name already exist
		//bRet &= col.SetName(strName+(string)(nCol+1));
		strNewName = strName+(string)(nCol+1);
		if(0 != col.GetName().CompareNoCase(strNewName) && IsSameNameColumnExist(strNewName))
		{
			//auto rename
			for(int ii=1; ;ii++)
			{
				string str('A', ii);
				str+=strNewName;
				if(!IsSameNameColumnExist(str))
				{
					strNewName = str;
					break;
				}
			}
		}
		///Jasmine 08/13/07 MAKE_APPLY_UNDOABLE
		//bRet &= col.SetName(strNewName);
		Tree trFmt;
		trFmt.Root.ShortName.strVal = strNewName;  
		int iRet = col.UpdateThemeIDs(trFmt.Root, "Error", "Unknown tag");
		bRet &= col.ApplyFormat(trFmt, TRUE, TRUE, TRUE);
		///End MAKE_APPLY_UNDOABLE
		///end DUP_NAME_NOT_ALLOW
		nCol++;
		nCount++; // Hong 01/29/07 FIX_ERROR_COUNT_COL_NUM
	}
	//while(nCol<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[nCol]));
	while(nCount<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[nCount])); // Hong 01/29/07 FIX_ERROR_COUNT_COL_NUM
	
	bCheckUpdateStruct = true;	//name has been changed by enum
}
/// Hong 01/29/07 MORE_APPLY_OPTION_TO_ALL_RIGHT_COL
void MulColsProperties::ChangeColsLabelNames(LPCSTR lpcszName, int nIndex, bool &bCheckUpdateStruct, bool bForbidReload, int nLabelType, int nUpdateType)
{
	string strName(lpcszName), strNewName;
	int nCol=nIndex, nCount = 0;

	bool bRet=true;
	Column col(m_wks, m_vnColRanges[nCount]);	
	strNewName = strName; // initial by UPDATE_DUP
	do
	{
		///Jasmine 08/13/07 MAKE_APPLY_UNDOABLE
		Tree trFmt;
		if( UPDATE_ENUM == nUpdateType ) // reassign if UPDATE_ENUM
			strNewName = strName+(string)(nCol++);
		
		switch(nLabelType)
		{
		case LABEL_LONG_NAME:
			//bRet &= col.SetLongName(strNewName);
			trFmt.Root.LongName.strVal = strNewName;  
			break;
		case LABEL_UNIT:
			//bRet &= col.SetUnits(strNewName);
			trFmt.Root.Unit.strVal = strNewName;  
			break;
		case LABEL_COMMENTS:
			//bRet &= col.SetComments(strNewName);
			trFmt.Root.Comment.strVal = strNewName;  
			break;
		}		
		int iRet = col.UpdateThemeIDs(trFmt.Root, "Error", "Unknown tag");
		bRet &= col.ApplyFormat(trFmt, TRUE, TRUE, TRUE);
		///End MAKE_APPLY_UNDOABLE
		nCount++;
	}
	while(nCount<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[nCount]));
	
	bCheckUpdateStruct = true;	//name has been changed by enum
}
/// end MORE_APPLY_OPTION_TO_ALL_RIGHT_COL
string MulColsProperties::GetSelectionStr()
{
	///Jasmine 10/27/06 GET_RANGE_STRING
	//OriginObject::GetRangeString
	//Column : [book]sheet!Col(A) or  [book]sheet!Col(LongName)
	//Matrix : [book]sheet!Mat(1) or  [book]sheet!Mat(LongName) 
	//string str = "["+m_wks.GetPage().GetName()+"]"+m_wks.GetName()+"(";
	string str;
	m_wks.GetRangeString(str);
	str+= "(";
	///End GET_RANGE_STRING
	Column col;
	for(int ii=0; ii<m_vnColRanges.GetSize(); ii++)
	{
		col.Attach(m_wks, m_vnColRanges[ii]);
		if(col)
			str += col.GetName();
		if(m_vnColRanges.GetSize()-1 != ii)
			str+=",";
	}
	str+=")";
	return str;
}
bool MulColsProperties::OnAfterValueChange(TreeNode& trRow, int nRow, bool& bUpdateGUI, bool& bInitGUI)
{
	if(!trRow)
		return false;
	///Jasmine 02/15/06 ALLOW_EDIT_STOP_COL_COMBO_AND_CHECK_INPUT
	if(trRow.tagName == "StopCol")
	{
		bool bChange;
		int nOldVal, nVal = trRow.nVal, nCurrent = m_Col.GetIndex() + 1, nCols = m_wks.GetNumCols();		
		trRow.GetAttribute(STR_CHANGED_ATTRIB, nOldVal);
		if(nVal < nCurrent || nVal > nCols)
			nVal = nOldVal;
		trRow.nVal = nVal;
		bUpdateGUI = true;
		return nVal != nOldVal;
	}
	///End ALLOW_EDIT_STOP_COL_COMBO_AND_CHECK_INPUT
	int nDataID = trRow.DataID;
	switch(nDataID)
	{
	///Jasmine 11/29/06 ADD_TAB_FOR_MORE_CONTENT
	case OTID_WKSCOLUMN_SHORTNAME:
	case OTID_WKSCOLUMN_LONGNAME:
	case OTID_WKSCOLUMN_UNIT:
	case OTID_WKSCOLUMN_COMMENT:
		TreeNode trDest = tree_get_node_by_tagname(trRow.Parent().LabelOption, trRow.tagName, true);
		trDest.strVal = trRow.strVal;
		break;
	///End ADD_TAB_FOR_MORE_CONTENT
	case OTID_WKSCOLUMN_NUMDISPLAY:
		TreeNode trDigits = trRow.Parent().Digits;
		trDigits.nVal = NUMERIC_SET_DECIMAL_PLACES == trRow.nVal ? 3 : 6;
	case OTID_WKSCOLUMN_FORMAT:
		///Kevin 11/15/05 TEXT_CHANGE_TO_NUMERIC_SHOW_ERROR
		///Jasmine 08/10/07 FIX_INTERNAL_DATA_NOT_MATCH_FORMAT_BUG
		//if(OKCOLTYPE_NUMERIC == m_trProperties.Options.Format.nVal)
		TreeNode trInternalData = m_trProperties.Options.InternalData;
		//trInternalData.SetAttribute(STR_CHANGED_ATTRIB, trInternalData.nVal);
		TreeNode trFormat = m_trProperties.Options.Format;	///Jasmine 08/10/07 FIX_INTERNAL_DATA_NOT_MATCH_FORMAT_BUG
		switch(trFormat.nVal)
		{
		case OKCOLTYPE_TEXT:
			trInternalData.nVal = FSI_TEXT;
			break;
		case OKCOLTYPE_TIME:
		case OKCOLTYPE_DATE:
		case OKCOLTYPE_MONTH:
		case OKCOLTYPE_WEEKDAY:
		case OKCOLTYPE_NUMERIC:
			trInternalData.nVal = FSI_DOUBLE;
			break;
		default:
			trInternalData.nVal = FSI_MIXED;
			break;
		}
		///End FIX_INTERNAL_DATA_NOT_MATCH_FORMAT_BUG
		///End TEXT_CHANGE_TO_NUMERIC_SHOW_ERROR
		UpdateTreeShown(m_trProperties);
		bInitGUI = true;	///Jasmine 03/17/06	SET_TRUE_TO_UPDATE_DYNA_CONTROL
		bUpdateGUI = true;
		break;
	//---Jasmine 03/24/07 "Custom Display" should be disabled unless "Custom Display" is selected in "Display".	
	case OTID_WKSCOLUMN_DISPLAY:
		TreeNode trOptions = trRow.Parent();
		TreeNode trFormat = trOptions.Format;
		TreeNode trCustomFormat = trOptions.CustomFormat;
		if(OKCOLTYPE_DATE == trFormat.nVal)
		{
			string strCombo=GetCurrentDataDisplayList();
			trCustomFormat.Enable = GetListSize(strCombo)-1 == trRow.nVal;
		}
		break;
	//---End 
	case CMD_COL_ENUM_NAMES:
		bUpdateGUI = true;
		
		TreeNode trName = trRow.Parent().Parent().SName;//trRow.Parent().SName;	///Jasmine 11/28/06 ENUMERATE_LABELS
		int nVal = trRow.Use;
		if(nVal || !isMulCols())///Jasmine 11/10/06 APPLY_OPTION_TO_ALL_RIGHT_COL
			trName.Enable = true;
		else
		{
			trName.Enable = 2;
			return false;	//don't mark as change
		}
		break;
		///Kevin 11/15/05

		///End------
	default:
		break;
	}
	return true;
}
void MulColsProperties::GetTree(TreeNode& trProperties, int nSubBranchID) //=0
{
	ColProperties::GetTree(trProperties, nSubBranchID);
	
	if(isMulCols())
		UpdateMulColsProperties(trProperties);
}
bool MulColsProperties::SetTree(TreeNode& trProperties, TreeNode &trChange)
{
	///Jasmine 03/23/07 should ConvertFormatTree first
///Kevin 11/15/05 QA70-8292-3	COL_INTERNAL_DATATYPE_COMPLEX_NOT_WORKING
	ConvertFormatTree(trProperties, false);
///End COL_INTERNAL_DATATYPE_COMPLEX_NOT_WORKING
	Tree trColsProperties;
	trColsProperties = trProperties;
		
	///Jasmine 09/18/06 QA70-6599 APPLY_WIDTH_TO_ALL_COL
	Tree trColFmt;
	TreeNode trColProp;
	///Jasmine 10/20/06 DIVIDE_INTO_THREE_GROUP
	//if(trColsProperties.ApplyAllCol.nVal)
	///Sophy 8/7/2009 QA80-14101 SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
	//if(trColsProperties.WidthOption.ApplyAllCol.nVal)
	BOOL bUndefinedColWidth = FALSE;
	trColsProperties.WidthOption.ColumnWidth.GetAttribute(STR_ATTRIB_DYNACONTROL_UNDEFINED, bUndefinedColWidth);
	if( trColsProperties.WidthOption.ApplyAllCol.nVal && !bUndefinedColWidth ) //if column width is undefined, can not apply to all columns
	///end SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
	{
		//------- CPY 8/17/2007 QA70-10240 DEFAULT_COL_ROW_SIZE_ACCESS
		/*
		foreach(Column col in m_wks.Columns)
		{
			TreeNode trScWidth, trTgWidth;
			trColFmt = col.GetFormat(FPB_ALL, FOB_ALL, true, true);
			trColProp = trColFmt.Root;
			//update col width
			octree_get_node_by_id(&trColsProperties, &trScWidth, OTID_WKSCOLUMN_WIDTH, true);
			octree_get_node_by_id(&trColProp, &trTgWidth, OTID_WKSCOLUMN_WIDTH, true);
			if(trScWidth.IsValid())
			{
				trTgWidth.SetAttribute(STR_CHANGED_ATTRIB, trTgWidth.strVal);
				trTgWidth.strVal = trScWidth.strVal;
			}
			// del all nodes that are not changed
			octree_delete_nodes_by_missing_attribute(&trColProp, STR_CHANGED_ATTRIB);
			col.ApplyFormat(trColFmt, TRUE, TRUE, TRUE);	///Jasmine 08/13/07 MAKE_APPLY_UNDOABLE		
			col.ExecuteFormula();
		}
		*/
		TreeNode trScWidth;
		octree_get_node_by_id(&trColsProperties, &trScWidth, OTID_WKSCOLUMN_WIDTH, true);
		if(trScWidth.IsValid())
		{
			foreach(Column col in m_wks.Columns)
			{
				Tree trTgWidth;
				trColFmt.Root.Width.dVal = trScWidth.dVal;
				if(col.UpdateThemeIDs(trColFmt.Root) == 0)
					col.ApplyFormat(trColFmt, true, true, true);
			}
			string strLT;
			strLT.Format("wks.colwidth=%f", trScWidth.dVal);
			m_wks.LT_execute(strLT);
		}
		//--------- end DEFAULT_COL_ROW_SIZE_ACCESS 
	}
	///End APPLY_WIDTH_TO_ALL_COL
	if(!isMulCols())
	{
		ApplyUserInfoTree(trColsProperties);	///Jasmine 01/29/07 QA70-9287 EDIT_USER_TREE
		///End APPLY_USER_TREE
		///Jasmine 11/10/06 APPLY_OPTION_TO_ALL_RIGHT_COL	
		TreeNode trOptions = trColsProperties.Options;
		if(trOptions.ApplyToRight && trOptions.ApplyToRight.nVal)
		{
			foreach(Column col in m_wks.Columns) 
			{
				if(col.GetIndex() <= m_vnColRanges[0])//ignore cols on the left
					continue;
				trColFmt = col.GetFormat(FPB_ALL, FOB_ALL, true, true);
				trColProp = trColFmt.Root;
				//---- CPY 12/30/08 QA70-12890-P2 CONVERT_TEXT_TO_CUSTOM_DATE_FAILED_FROM_CSV_IMPORT
				/*
				octree_copy_values_by_id(&trOptions, &trColProp, true, STR_DATAID_ATTRIB, STR_ID_ATTRIB);
				octree_delete_nodes_by_missing_attribute(&trColProp, STR_CHANGED_ATTRIB);// del all nodes that are not changed
				//------ Folger 01/15/08 CENTRALIZE_CODE_OF_APPLY_FORMAT
				//if(trColProp.Format.IsValid() && trColProp.InternalData.IsValid() && trColProp.Format.nVal != OKCOLTYPE_NUMERIC)
				//{
					//trColProp.InternalData.Remove(); // this is later in the theme tree, so we must remove otherwise it will set col back to Numeric
				//}
				//col.ApplyFormat(trColFmt, TRUE, TRUE, TRUE);	///Jasmine 08/13/07 MAKE_APPLY_UNDOABLE		
				ApplySettings(trColProp, col);
				//------
				//------ CPY 4/14/08 QA70-11421 COL_PROP_DIALOG_ALWAYS_RUN_FORMULA_WHEN_ANY_THING_CHANGED
				//col.ExecuteFormula();
				//------
				*/
				octree_copy_values_by_id(&trOptions, &trColProp, true, STR_DATAID_ATTRIB, STR_ID_ATTRIB);
				ApplySettings(trColProp, col);
				//---- end QA70-12890-P2
				
			}
		}
		///End	APPLY_OPTION_TO_ALL_RIGHT_COL
		return ColProperties::SetTree(trProperties, trChange); 
	}
	
	OnBeforeSettings(trColsProperties);
	
	int nCol=0, nFirstCol = m_vnColRanges[0];
	bool bRet=true;
	Column col(m_wks, nFirstCol), colSameName;
	///Jasmine 09/18/06 APPLY_WIDTH_TO_ALL_COL
	/*
	Tree trColFmt;
	TreeNode trColProp;
	*/
	///End APPLY_WIDTH_TO_ALL_COL

	///Sophy 8/7/2009 QA80-14101 SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
	tree_remove_children_by_attrib(trColsProperties, STR_ATTRIB_DYNACONTROL_UNDEFINED, TRUE, true); //recursively find undefined nodes and remove them.
	///end SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
	do
	{
		trColFmt = col.GetFormat(FPB_ALL, FOB_ALL, true, true);
		trColProp = trColFmt.Root;
		octree_copy_values_by_id(&trColsProperties, &trColProp, true, STR_DATAID_ATTRIB, STR_ID_ATTRIB);
		///Kyle 01/21/2010 QA80-14998 DIGITS_WILL_BE_RESET_TO_DEFAULT_WHILE_CHANGING_THE_DIGIT_MODE
		int nVal;
		TreeNode trNumericDisplay = trColProp.NumericDisplay;
		if( trNumericDisplay && trNumericDisplay.GetAttribute(STR_CHANGED_ATTRIB, nVal) )
			trColProp.Digits.SetAttribute(STR_CHANGED_ATTRIB, 0);
		if( NUMERIC_DEFAULT_DECIMAL == trNumericDisplay.nVal )
			trColProp.Digits.Remove();
		///End DIGITS_WILL_BE_RESET_TO_DEFAULT_WHILE_CHANGING_THE_DIGIT_MODE
		// del all nodes that are not changed
		octree_delete_nodes_by_missing_attribute(&trColProp, STR_CHANGED_ATTRIB);
		col.ApplyFormat(trColFmt, TRUE, TRUE, TRUE);	///Jasmine 08/13/07 MAKE_APPLY_UNDOABLE
		//------ CPY 4/14/08 QA70-11421 COL_PROP_DIALOG_ALWAYS_RUN_FORMULA_WHEN_ANY_THING_CHANGED
		//col.ExecuteFormula();
		//------
		nCol++;
	}
	while(nCol<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[nCol]));
	
	OnAfterSettings(trProperties);
	return true;
}
void MulColsProperties::OnBeforeSettings(TreeNode& trColsProperties)
{
	if(!isMulCols())
	{
		ColProperties::OnBeforeSettings(trColsProperties);
		return;
	}

	bool bUpdate;
	///Jasmine 11/28/06 ENUMERATE_LABELS
	TreeNode trEnumNames = trColsProperties.LabelOption.EnumSName;//trColsProperties.Enumnames;
	TreeNode trName = trColsProperties.SName;
	///Jasmine 11/29/06 ADD_TAB_FOR_MORE_CONTENT
	int nIndex = trColsProperties.LabelOption.EnumSName.StartIndex.nVal;
	if(trEnumNames && 1 == trEnumNames.Use)
		EnumColsNames(trName.strVal, nIndex, bUpdate, true);
	///End ADD_TAB_FOR_MORE_CONTENT
	trName.Remove();
	trEnumNames.Remove();
	/// Hong 01/29/07 MORE_APPLY_OPTION_TO_ALL_RIGHT_COL
	/*
	TreeNode trLName = trColsProperties.LName;
	TreeNode trUnit = trColsProperties.Unit;
	TreeNode trComments = trColsProperties.Comments;
	if(trLName && !trColsProperties.LabelOption.EnumLName.Use)
		trLName.Remove();
	if(trUnit && !trColsProperties.LabelOption.ApplyUnit.Use)
		trUnit.Remove();
	if(trComments && !trColsProperties.LabelOption.ApplyComment.Use)
		trComments.Remove();	
	*/
	TreeNode trLName = trColsProperties.LName;
	string strLName = trLName.strVal;
	TreeNode trEnumLongNames = trColsProperties.LabelOption.EnumLName;
	nIndex = trColsProperties.LabelOption.EnumLName.StartIndex.nVal;
	
	if(trEnumLongNames && 0 != trEnumLongNames.Use)
		ChangeColsLabelNames(strLName, nIndex, bUpdate, true, LABEL_LONG_NAME, trEnumLongNames.Use);
	
	trLName.Remove();
	trEnumLongNames.Remove();	
	
	TreeNode trUnit = trColsProperties.Unit;
	string strUnit = trUnit.strVal;
	TreeNode trEnumUnit = trColsProperties.LabelOption.ApplyUnit;

	if(trEnumUnit && 0 != trEnumUnit.Use)
		ChangeColsLabelNames(strUnit, -1, bUpdate, true, LABEL_UNIT, UPDATE_DUP); // only UPDATE_DUP for units 

	trUnit.Remove();
	trEnumUnit.Remove();
	
	TreeNode trComments = trColsProperties.Comments;
	string strComments = trComments.strVal;
	TreeNode trEnumComment = trColsProperties.LabelOption.ApplyComment;
	nIndex = trColsProperties.LabelOption.ApplyComment.StartIndex.nVal;

	if(trEnumComment && 0 != trEnumComment.Use)
		ChangeColsLabelNames(strComments, nIndex, bUpdate, true, LABEL_COMMENTS, trEnumComment.Use);
		
	trComments.Remove();
	trEnumComment.Remove();
	/// end MORE_APPLY_OPTION_TO_ALL_RIGHT_COL
	///End ENUMERATE_LABELS
	
	TreeNode trMulDesignations = trColsProperties.Options.PlotDesignation;
	if(trMulDesignations)
		SetMulColsDesignation(trMulDesignations.strVal, bUpdate, true);
	trMulDesignations.Remove();
	
	///there are some options diff with this cols, when user not change, it's invalid seletion, we should remove it
	///Jasmine 10/20/06 DIVIDE_INTO_THREE_GROUP
	//TreeNode trWidth = trColsProperties.ColumnWidth;	
	TreeNode trWidth = trColsProperties.WidthOption.ColumnWidth;
	TreeNode trOptions = trColsProperties.Options;
	TreeNode trFormat = trOptions.Format;
	TreeNode trDisplay = trOptions.Display;
	TreeNode trNumeric = trOptions.Numeric;
	TreeNode trDigits = trOptions.Digits;
	TreeNode trInternalData = trOptions.InternalData;
	
	if(trWidth.strVal.IsEmpty())
		trWidth.Remove();
	
	RemoveDigitsIfValidInput(trColsProperties);
	
	if(GetListSize(STR_COL_FORMAT_LIST) == trFormat.nVal)
	{
		trFormat.Remove();
		trDisplay.Remove();
		trNumeric.Remove();
		trDigits.Remove();
		trInternalData.Remove();
	}
	else
	{
		if(GetListSize(STR_COL_TIME_DISPLAY_LIST) == trDisplay.nVal)
			trDisplay.Remove();
		if(GetListSize(STR_DECIMAL_DIGITS_MODE_LIST) == trNumeric.nVal)
		{
			trNumeric.Remove();
			trDigits.Remove();
		}
		else if(trDigits.strVal.IsEmpty())
			trDigits.Remove();
		if(GetListSize(STR_COL_INTERNAL_DATA_LIST) == trInternalData.nVal)
			trInternalData.Remove();
	}
	///
}
void MulColsProperties::OnAfterSettings(TreeNode& tr)
{
	if(!isMulCols())
	{
		ColProperties::OnAfterSettings(tr);
		return;
	}
	
	GetTree(tr);	//reload to ensure change
}
///Jasmine 11/10/06 APPLY_OPTION_TO_ALL_RIGHT_COL
bool MulColsProperties::IsSameNameColumnExist(LPCSTR lpcszColName, bool bOutSideOnly, int nStopCol)//= false, 0
{
	string strDatasetName = m_wks.GetPage().GetName()+"_"+lpcszColName;
	Dataset ds(strDatasetName);	//if this constructor fail, we have to do it by following way
	//Dataset ds;
	//for(int ii=0; ii<m_wks.Columns.Count() && ds.Attach(m_wks, ii); ii++)
	//{
		//if(0 == ds.GetName().CompareNoCase(strDatasetName))
			//break;
		//ds.Detach();
	//}
	if(ds.IsValid())
	{
		for(int ii=0; ii<m_vnColRanges.GetSize(); ii++)
		{
			//Dataset ds2(m_wks, ii);
			Dataset ds2(m_wks, m_vnColRanges[ii]);
			if(0==strDatasetName.CompareNoCase(ds2.GetName()))
				return false;	//this duplicate name in the selection, ignore
		}
		return true;
	}
	return false;
}
///End APPLY_OPTION_TO_ALL_RIGHT_COL
///Sophy 12/19/2009 QA80-14101 CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
/*
bool MulColsProperties::IsColsSameWidth()
{
	Column col(m_wks, m_vnColRanges[0]);
	double dWidth = col.GetWidth(), dOtherWidth;
	for(int ii=1; ii<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[ii]); ii++)
	{
		dOtherWidth = col.GetWidth();
		if(!is_equal(round(dWidth, 4), round(dOtherWidth, 4)))
			return false;
	}
	return true;
}
bool MulColsProperties::IsColsSameFormat()
{
	Column col(m_wks, m_vnColRanges[0]);
	int nFormat = col.GetFormat(), nOtherFormat;
	for(int ii=1; ii<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[ii]); ii++)
	{
		nOtherFormat = col.GetFormat();
		if(nFormat != nOtherFormat)
			return false;
	}
	return true;
}
bool MulColsProperties::IsColsSameDisplay()
{
	Column col(m_wks, m_vnColRanges[0]);
	int nDisplay = col.GetSubFormat(), nOtherDisplay;
	for(int ii=1; ii<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[ii]); ii++)
	{
		nOtherDisplay = col.GetSubFormat();
		if(nDisplay != nOtherDisplay)
			return false;
	}
	return true;
}
bool MulColsProperties::IsColsSameDigitMode()
{
	Column col(m_wks, m_vnColRanges[0]);
	int nDigitMode = col.GetDigitMode(), nOtherDigitMode;
	for(int ii=1; ii<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[ii]); ii++)
	{
		nOtherDigitMode = col.GetDigitMode();
		if(nDigitMode != nOtherDigitMode)
			return false;
	}
	return true;
}
bool MulColsProperties::IsColsSameDigits()
{
	Column col(m_wks, m_vnColRanges[0]);
	int nDigits = col.GetDigits(), nOtherDigits;
	for(int ii=1; ii<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[ii]); ii++)
	{
		nOtherDigits = col.GetDigits();
		if(nDigits != nOtherDigits)
			return false;
	}
	return true;
}
bool MulColsProperties::IsColsSameInternalData()
{
	Column col(m_wks, m_vnColRanges[0]);
	int nInternalData = col.GetInternalData(), nOtherInternalData;
	for(int ii=1; ii<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[ii]); ii++)
	{
		nOtherInternalData = col.GetInternalData();
		if(nInternalData != nOtherInternalData)
			return false;
	}
	return true;
}

///Sophy 8/7/2009 QA80-14101 SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
bool MulColsProperties::IsColsSameLongName()
{
	Column col(m_wks, m_vnColRanges[0]);
	string strLongName = col.GetLongName();
	string strOtherLongName;
	for ( int ii; ii < m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[ii]); ii++ )
	{
		strOtherLongName = col.GetLongName();
		if ( strLongName.CompareNoCase(strOtherLongName) != 0 )
			return false;
	}
	return true;
}

bool MulColsProperties::IsColsSameUnits()
{
	Column col(m_wks, m_vnColRanges[0]);
	string strUnits = col.GetUnits();
	string strOtherUnits;
	for ( int ii; ii < m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[ii]); ii++ )
	{
		strOtherUnits = col.GetUnits();
		if ( strUnits.CompareNoCase(strOtherUnits) != 0 )
			return false;
	}
	return true;
}

bool MulColsProperties::IsColsSameComments()
{
	Column col(m_wks, m_vnColRanges[0]);
	string strComments = col.GetComments();
	string strOtherComments;
	for ( int ii; ii < m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[ii]); ii++ )
	{
		strOtherComments = col.GetComments();
		if ( strComments.CompareNoCase(strOtherComments) != 0 )
			return false;
	}
	return true;
}
///end SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
*/
bool MulColsProperties::isColsSameProp(int nPropID)
{
	Column col(m_wks, m_vnColRanges[0]);
	int nPropVal, nPropVal2;
	string strPropVal, strPropVal2;
	switch(nPropID)
	{
	case MULTI_COLS_PROP_WIDTH:
		nPropVal = col.GetWidth();
		break;
	case MULTI_COLS_PROP_FORMAT:
		nPropVal = col.GetFormat();
		break;
	case MULTI_COLS_PROP_DISPLAY:
		nPropVal = col.GetSubFormat();
		break;
	case MULTI_COLS_PROP_DIGITMODE:
		nPropVal = col.GetDigitMode();
		break;
	case MULTI_COLS_PROP_DIGITS:
		nPropVal = col.GetDigits();
		break;
	case MULTI_COLS_PROP_INTER_DATA:
		nPropVal = col.GetInternalData();
		break;
	case MULTI_COLS_PROP_LONGNAME:
		strPropVal = col.GetLongName();
		break;
	case MULTI_COLS_PROP_UNITS:
		strPropVal = col.GetUnits();
		break;
	case MULTI_COLS_PROP_COMMENTS:
		strPropVal = col.GetComments();
		break;
	default:
		ASSERT(FALSE);
		return false;
	}
	
	for ( int ii = 1; ii < m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[ii]); ii++ )
	{
		switch(nPropID)
		{
		case MULTI_COLS_PROP_WIDTH:
			nPropVal2 = col.GetWidth();
			if ( nPropVal2 != nPropVal )
				return false;
			break;
			
		case MULTI_COLS_PROP_FORMAT:
			nPropVal2 = col.GetFormat();
			if ( nPropVal2 != nPropVal )
				return false;
			break;
			
		case MULTI_COLS_PROP_DISPLAY:
			nPropVal2 = col.GetSubFormat();
			if ( nPropVal2 != nPropVal )
				return false;
			break;
			
		case MULTI_COLS_PROP_DIGITMODE:
			nPropVal2 = col.GetDigitMode();
			if ( nPropVal2 != nPropVal )
				return false;
			break;
			
		case MULTI_COLS_PROP_DIGITS:
			nPropVal2 = col.GetDigits();
			if ( nPropVal2 != nPropVal )
				return false;
			break;
			
		case MULTI_COLS_PROP_INTER_DATA:
			nPropVal2 = col.GetInternalData();
			if ( nPropVal2 != nPropVal )
				return false;
			break;
			
		case MULTI_COLS_PROP_LONGNAME:
			strPropVal2 = col.GetLongName();
			if ( strPropVal.CompareNoCase(strPropVal2) != 0 )
				return false;
			break;
		
		case MULTI_COLS_PROP_UNITS:
			strPropVal2 = col.GetUnits();
			if ( strPropVal.CompareNoCase(strPropVal2) != 0 )
				return false;
			break;
			
		case MULTI_COLS_PROP_COMMENTS:
			strPropVal2 = col.GetComments();
			if ( strPropVal.CompareNoCase(strPropVal2) != 0 )
				return false;
			break;
			
		default:
			ASSERT(FALSE);
		}
	}
	return true;
}
///end CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
void ColProperties::ConstructTree(TreeNode &tr)
{
	tr.Reset();
	ConstructInfoTree(tr);
	ConstructFormatTree(tr);
///Jasmine 11/29/06 ADD_TAB_FOR_MORE_CONTENT
	ConstructEnumTree(tr);
	///End ENUMERATE_LABELS
	tr.LabelOption.Show = false;
	tr.RightClickHint.Show 	= 		///Jasmine 02/02/10 SHOW_RIGHT_CLICK_HINT_IN_ONE_ROW_TO_SAVE_SPACE
	tr.UserInfo.Show 		= false;
}

void MulColsProperties::ConstructTree(TreeNode &tr)
{
	tr.Reset();
	ConstructInfoTree(tr);
	GETN_USE(tr)
	GETN_BEGIN_BRANCH(Options, _L("Options")) GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
		ConstructFormatTree(GETN_CURRENT_SUBNODE);
	GETN_END_BRANCH(Options)
	ConstructEnumTree(tr, m_vnColRanges.GetSize() == 1);
///End ADD_TAB_FOR_MORE_CONTENT
	ConstructUserInfoTree(tr, isMulCols());///Jasmine 12/08/06 ADD_USER_INFO_TAB
	ConstructFileInfoTree(tr, isMulCols()); /// Hong 02/03/10 QA80-15063 COL_PROPS_DLG_ADD_FILE_INFO
	if(isMulCols())
	{
		UpdateMulColsProperties(tr);
	}
}
void MulColsProperties::UpdateMulColsProperties(TreeNode& tr)
{
	TreeNode trLName = tr.LName;
	TreeNode trUnit = tr.Unit;
	TreeNode trComments = tr.Comments;
	//------ CPY 4/14/08 QA70-11421 COL_PROP_DIALOG_ALWAYS_RUN_FORMULA_WHEN_ANY_THING_CHANGED
	//TreeNode trFormula = tr.Formula;
	//------
	///Jasmine 11/28/06 ENUMERATE_LABELS
	if(trLName)
		trLName.Enable = 2;//trLName.Remove();
	if(trUnit)
		trUnit.Enable = 2;//trUnit.Remove();
	if(trComments)
		trComments.Enable = 2;//trComments.Remove();
	//------ CPY 4/14/08 QA70-11421 COL_PROP_DIALOG_ALWAYS_RUN_FORMULA_WHEN_ANY_THING_CHANGED
	//if(trFormula)
	//	trFormula.Remove();
	//------
	
	///Sophy 8/7/2009 QA80-14101 SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
	///Sophy 12/19/2009 QA80-14101 CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
	//if ( !IsColsSameLongName() )
	if ( !isColsSameProp(MULTI_COLS_PROP_LONGNAME) )
	///end CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
		trLName.SetAttribute(STR_ATTRIB_DYNACONTROL_UNDEFINED, TRUE);
	///Sophy 12/19/2009 QA80-14101 CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
	//if ( !IsColsSameUnits() )
	if ( !isColsSameProp(MULTI_COLS_PROP_UNITS) )
	///end CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
		trUnit.SetAttribute(STR_ATTRIB_DYNACONTROL_UNDEFINED, TRUE);

	///Sophy 12/19/2009 QA80-14101 CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
	//if ( !IsColsSameComments() )
	if ( !isColsSameProp(MULTI_COLS_PROP_COMMENTS) )
	///end CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
	{
		trComments.SetAttribute(STR_ATTRIB_DYNACONTROL_UNDEFINED, TRUE);
	}
	///end SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
	///Sophy 12/19/2009 QA80-14101 CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
	//if(!IsColsSameWidth())
	if ( !isColsSameProp(MULTI_COLS_PROP_WIDTH) )
	///end CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
	///Jasmine 10/20/06 DIVIDE_INTO_THREE_GROUP
		//tr.ColumnWidth.strVal = "";
		///Sophy 8/7/2009 QA80-14101 SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
		//tr.WidthOption.ColumnWidth.strVal = "";
		tr.WidthOption.ColumnWidth.SetAttribute(STR_ATTRIB_DYNACONTROL_UNDEFINED, TRUE);
		///end SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
	
	string str = STR_MUL_COLS_DESIGNATION_LIST;
	vector<string> vs;
	str.GetTokens(vs, '|');
	
	GETN_TREE(trTemp)
	///Jasmine 11/10/06 APPLY_OPTION_TO_ALL_RIGHT_COL
	//GETN_CHECK(Enumnames, "Enumerate All Names", 0)					GETN_ID(CMD_COL_ENUM_NAMES)
	GETN_LIST(PlotDesignation, STR_PLOT_DESIGNATION_LABEL, 0, str)	GETN_ID(OTID_WKSCOLUMN_TYPE)
	/*
	if(!tr.Enumnames.IsValid())
	{
		/Jasmine 10/20/06 DIVIDE_INTO_THREE_GROUP
		TreeNode trEnumNames = tr.InsertNode(tr.ColumnWidth, "empty");
		TreeNode trEnumNames = tr.InsertNode(tr.WidthOption, "empty");
		trEnumNames.Replace(trTemp.Enumnames);
		tr.SName.Enable = 2;	//GETN_READ_ONLY_COLOR
	}
	tr.Enumnames.SetAttribute(STR_LABEL_ATTRIB, "Enumerate All Names");
	*/
	///End ENUMERATE_LABELS
	tr.SName.Enable = 2;
	///End APPLY_OPTION_TO_ALL_RIGHT_COL
	int nPlotDesignation = getCurrentDesignation(vs);
	
	TreeNode trOptions = tr.Options;
	TreeNode trPlotDesignation = trOptions.PlotDesignation;
	trPlotDesignation.Replace(trTemp.PlotDesignation);
	trPlotDesignation.nVal = nPlotDesignation;
	///Sophy 8/7/2009 QA80-14101 SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
	if ( nPlotDesignation == vs.GetSize() ) //not matched, set as undefined
		trPlotDesignation.SetAttribute(STR_ATTRIB_DYNACONTROL_UNDEFINED, TRUE);
	///end SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
	///Sophy 12/19/2009 QA80-14101 CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
	//if(!IsColsSameFormat())
	if ( !isColsSameProp(MULTI_COLS_PROP_FORMAT) )
	///end CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
		///Sophy 8/7/2009 QA80-14101 SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
		//trOptions.Format.nVal = GetListSize(STR_COL_FORMAT_LIST);//invalid selection
		trOptions.Format.SetAttribute(STR_ATTRIB_DYNACONTROL_UNDEFINED, TRUE);
		///end SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
	///Sophy 10/20/2009 QA80-14101-P1 FAIL_TO_SET_UNDEFINED_STATE_WHEN_COLUMNS_HAVE_DIFF_FORMAT
	//I comment out "else {}" to make it always called regardless of column format's difference
	//else
	//{
	///end FAIL_TO_SET_UNDEFINED_STATE_WHEN_COLUMNS_HAVE_DIFF_FORMAT
		TreeNode trDisplay = tr.FindNodeByAttribute(STR_DATAID_ATTRIB, OTID_WKSCOLUMN_DISPLAY);
		///Sophy 12/19/2009 QA80-14101 CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
		//if(!IsColsSameDisplay())
		if ( !isColsSameProp(MULTI_COLS_PROP_DISPLAY) )
		///end CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
			///Sophy 8/7/2009 QA80-14101 SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
			//trDisplay.nVal = GetListSize(STR_COL_TIME_DISPLAY_LIST);//it's the max invalid number
			trDisplay.SetAttribute(STR_ATTRIB_DYNACONTROL_UNDEFINED, TRUE);
			///end SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
		///Sophy 12/19/2009 QA80-14101 CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
		//if(!IsColsSameDigitMode())
		if ( !isColsSameProp(MULTI_COLS_PROP_DIGITMODE) )
		///end CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
			///Sophy 8/7/2009 QA80-14101 SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
			//trOptions.Numeric.nVal = GetListSize(STR_DECIMAL_DIGITS_MODE_LIST);
			trOptions.Numeric.SetAttribute(STR_ATTRIB_DYNACONTROL_UNDEFINED, TRUE);
			///end SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
		///Sophy 10/20/2009 QA80-14101-P1 FAIL_TO_SET_UNDEFINED_STATE_WHEN_COLUMNS_HAVE_DIFF_FORMAT
		//else if(!IsColsSameDigits())
		///Sophy 12/19/2009 QA80-14101 CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
		//if ( !IsColsSameDigits() )
		if ( !isColsSameProp(MULTI_COLS_PROP_DIGITS) )
		///end CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
		///end FAIL_TO_SET_UNDEFINED_STATE_WHEN_COLUMNS_HAVE_DIFF_FORMAT
			///Sophy 8/7/2009 QA80-14101 SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
			//trOptions.Digits.strVal = "";
			trOptions.Digits.SetAttribute(STR_ATTRIB_DYNACONTROL_UNDEFINED, TRUE);
			///end SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
		///Sophy 12/19/2009 QA80-14101 CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
		//if(!IsColsSameInternalData())
		if ( !isColsSameProp(MULTI_COLS_PROP_INTER_DATA) )
		///end CENTRALIZE_CODE_CHECK_MULT_COLS_SAME_PROPERTIES
			///Sophy 8/7/2009 QA80-14101 SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
			//trOptions.InternalData.nVal = GetListSize(STR_COL_INTERNAL_DATA_LIST);
			trOptions.InternalData.SetAttribute(STR_ATTRIB_DYNACONTROL_UNDEFINED, TRUE);
			///end SET_GETN_NODES_AS_UNDEFINED_WHEN_SEL_MULTI_COLS_WITH_DIFF_PROPERTY
	///Sophy 10/20/2009 QA80-14101 FAIL_TO_SET_UNDEFINED_STATE_WHEN_COLUMNS_HAVE_DIFF_FORMAT
	//}
	///end FAIL_TO_SET_UNDEFINED_STATE_WHEN_COLUMNS_HAVE_DIFF_FORMAT
	///Jasmine 11/10/06 APPLY_OPTION_TO_ALL_RIGHT_COL
	if(trOptions.ApplyToRight)
		trOptions.ApplyToRight.Remove();
	///End APPLY_OPTION_TO_ALL_RIGHT_COL
}
TreeNode MulColsProperties::GetFormatSettingsNode(TreeNode& tr)
{
	return tr.Options;
}


////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////   MatrixObjectAccess   ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
MatrixObjectAccess::MatrixObjectAccess()
{
	m_nPageType = EXIST_MATRIX;
}
MatrixObjectAccess::MatrixObjectAccess(MatrixObject& mo) : DataObjectManager(mo)
{
	m_nPageType = EXIST_MATRIX;
	
	mo.GetParent(m_ml);
}
MatrixObjectAccess::MatrixObjectAccess(MatrixLayer& ml)
{
	m_nPageType = EXIST_MATRIX;
	m_ml = ml;
	GetSelection(ml);
}
void MatrixObjectAccess::GetSelection(Layer& lay)
{
	MatrixLayer ml(lay);
	if(!ml)
	{
		error_report("Invalid MatrixLayer");
		return;
	}
	//---- CPY 2/22/2006 COL_PROP_DIALOG_NOT_USING_ACTIVE_MAT_OBJ
	//m_mo = ml.MatrixObjects(0);
	m_mo = ml.MatrixObjects();
	//----
	DataObjectManager::Attach(m_mo);
}
///Jasmine 08/28/06 SHARE_SET_VAL_DLG
void MatrixObjectAccess::GetAllObjectsLongNames(vector<string>& vsNames)
{
	vsNames.SetSize(0);
	string strName;
	vector<string> vsMoNames;
	foreach(MatrixObject mo in m_ml.MatrixObjects)
	{
		strName = mo.GetLongName();
		string strTemp("_"+strName);
		if(strName.IsEmpty() || !is_str_valid_for_filename(strTemp)) //file name have the same rule as Variable name
			strName = mo.GetName();
			
		vsMoNames.Add(mo.GetName());
		int nDupliInd=-1;	
		if((nDupliInd = vsNames.Find(strName))>=0)
		{
			vsNames[nDupliInd] = vsMoNames[nDupliInd];
			strName = mo.GetName();			
		}		
		vsNames.Add(strName);
	}
}

///Kyle 07/14/2009 QA80-13746 SHOWING_BOTH_LN_AND_SN_WITH_STANDARD_NOTATION_IN_THE_MENU_OF_SET_COLUMN_VALUE_DLG
void MatrixObjectAccess::GetAllObjectsNames(vector<string>& vsSNames, vector<string>& vsLNames)
{
	vsSNames.SetSize(0);
	vsLNames.SetSize(0);
	foreach(MatrixObject mo in m_ml.MatrixObjects)
	{
		vsSNames.Add(mo.GetName());
		vsLNames.Add(mo.GetLongName());
	}
	
}
///END SHOWING_BOTH_LN_AND_SN_WITH_STANDARD_NOTATION_IN_THE_MENU_OF_SET_COLUMN_VALUE_DLG

bool MatrixObjectAccess::HasPreviousObject()
{
	return (m_mo.GetIndex() - 1)>-1;
}
bool MatrixObjectAccess::HasNextObject()
{
	MatrixObject mo(m_ml, m_mo.GetIndex() + 1);
	if(mo)	
		return true;	
	return false;
}
///End SHARE_SET_VAL_DLG

////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////   MatrixObjectProperties   ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
MatrixObjectProperties::MatrixObjectProperties() : MatrixObjectAccess()
{
	
}
MatrixObjectProperties::MatrixObjectProperties(MatrixObject& mo) : MatrixObjectAccess(mo)
{
}
MatrixObjectProperties::MatrixObjectProperties(MatrixLayer& ml) : MatrixObjectAccess(ml)
{
}

bool MatrixObjectProperties::SetTree(TreeNode& trProperties, TreeNode &trChange)
{
	/*
	if(NULL == trProperties || !trProperties)
		return false;
	
	//MatrixObjectAccess::SetTree(trProperties, trChange);	//set common settings first
	
	bool bRet=true;
	
	int nColWidth = trProperties.Width.nVal;
	bRet &= m_mo.SetColumnWidth(nColWidth);
	
	TreeNode trDimensions = trProperties.dimensions;
	int nCols = trDimensions.columns.nVal;
	int nRows = trDimensions.rows.nVal;
	bRet &= m_mo.SetNumCols(nCols);
	bRet &= m_mo.SetNumRows(nRows);
	
	TreeNode trCoordinates = trProperties.coordinates;
	double dXMin, dYMin, dXMax, dYMax;
	dXMin = trCoordinates.xmin.dVal;
	dXMax = trCoordinates.xmax.dVal;
	dYMin = trCoordinates.ymin.dVal;
	dYMax = trCoordinates.ymax.dVal;
	bRet &= m_mo.SetXY(dXMin, dYMin, dXMax, dYMax);
	
///Kevin 11/15/05 COL_INTERNAL_DATATYPE_COMPLEX_NOT_WORKING
	//int nDataType = trProperties.datatype.nVal;
	//bRet &= m_mo.SetInternalData(ConvertGUIInternalData(nDataType, false));
	ConvertFormatTree(trProperties, false);
	int nDataType = trProperties.datatype.nVal;
	bRet &= m_mo.SetInternalData(nDataType);
///End COL_INTERNAL_DATATYPE_COMPLEX_NOT_WORKING
	int nDataFormat = trProperties.dataformat.nVal;
	//bRet &= m_mo.SetFormat(nDataFormat); //don't know which function to set subformat
	int nDisplay = trProperties.displaymode.nVal;
	bRet &= m_mo.SetDigitMode(nDisplay);
	if(NUMERIC_DEFAULT_DECIMAL != nDisplay)
	{
		int nDigits = trProperties.digits.nVal;
		bRet &= m_mo.SetDigits(nDigits);
	}
	
	//we need to reload the tree to make sure the change has been applied
	GetObjectSettings(m_trProperties);
	return true;
	*/
	Tree trColsProperties;
	trColsProperties = trProperties;
	
	ConvertFormatTree(trProperties, false);

	return DataObjectManager::SetTree(trProperties, trChange);

}

void MatrixObjectProperties::OnAfterSettings(TreeNode& trProperties) 
{	
	GetObjectSettings(trProperties);	//reload to ensure change
	UpdateTreeShown(trProperties);
}
void MatrixObjectProperties::ConstructTree(TreeNode &tr)
{
	tr.Reset();
	
	ConstructDimensionsTree(m_trProperties);
	ConstructInfoTree(m_trProperties);
	//--- some prop not for matrix obj to be shown
	m_trProperties.SName.Remove();
	//---
	///Jasmine 10/20/06 DIVIDE_INTO_THREE_GROUP
	//ConstructFormatTree(m_trProperties);
	GETN_USE(m_trProperties)
	GETN_BEGIN_BRANCH(Options, _L("Options")) GETN_OPTION_BRANCH(GETNBRANCH_OPEN)
		ConstructFormatTree(GETN_CURRENT_SUBNODE);
	GETN_END_BRANCH(Options)
	///End DIVIDE_INTO_THREE_GROUP
}
string MatrixObjectProperties::GetSelectionStr()
{
	/// YuI 11/24/06 GET_RANGE_STRING_SHOULD_BE_EXPOSED_TO_OC
	/*
	///Jasmine 10/23/06 CHANGE_TEXT_TO_EASY_UNDERSTAND	
	//string str = "["+m_ml.GetPage().GetName()+"]"+m_ml.GetName();
	string str = wks_get_book_sheet_name(m_ml);
	if(m_mo)
		//str += "("+ m_mo.GetName() + ")";
		str += "("+ (string)(m_mo.GetIndex()+1) + ")";
	///End CHANGE_TEXT_TO_EASY_UNDERSTAND
	return str;
	*/
	string str;
	if( m_mo )
		m_mo.GetRangeString(str);
	else if( m_ml )
		m_ml.GetRangeString(str);
	
	return str;
	/// end GET_RANGE_STRING_SHOULD_BE_EXPOSED_TO_OC
}
bool MatrixObjectProperties::OnAfterValueChange(TreeNode& trRow, int nRow, bool& bUpdateGUI, bool& bInitGUI)
{
	if(!trRow)
		return false;
	
	int nDataID = trRow.DataID;
	switch(nDataID)
	{
	case OTID_WKSCOLUMN_NUMDISPLAY:
		TreeNode trDigits = trRow.Parent().digits;
		trDigits.nVal = NUMERIC_SET_DECIMAL_PLACES == trRow.nVal ? 3 : 6;
		
		UpdateTreeShown(m_trProperties);
		
		bUpdateGUI = true;
		//bInitGUI = true;
		break;
	default:
		break;
	}
	return true;
}
void MatrixObjectProperties::UpdateTreeShown(TreeNode& tr)
{
	///Jasmine 10/20/06 DIVIDE_INTO_THREE_GROUP
	//TreeNode trNumeric = tr.Numeric;
	//TreeNode trDigits = tr.Digits;
	TreeNode trNumeric = tr.Options.Numeric;
	TreeNode trDigits = tr.Options.Digits;
	///End DIVIDE_INTO_THREE_GROUP
	int nNumeric = trNumeric.nVal;
	
	trDigits.Show = NUMERIC_SET_DECIMAL_PLACES==nNumeric || NUMERIC_SET_SIGNIFICANT_DIGITS==nNumeric;
	
	string strLabel = NUMERIC_SET_SIGNIFICANT_DIGITS==nNumeric ? STR_SIGNIFICANT_PLACES_LABEL : STR_DECIMAL_PLACES_LABEL;
	trDigits.SetAttribute(STR_LABEL_ATTRIB, strLabel);
	///Jasmine 0/10/08/06 HIDE_NO_USE_OPTION
	//tr.Unit.Show = false;
	//tr.Formula.Show = false;
	tr.LabelOption.Show = false;//tr.Enumnames.Show = false;	///Jasmine 11/10/06 APPLY_OPTION_TO_ALL_RIGHT_COL	///Jasmine 11/28/06 ENUMERATE_LABELS
	tr.RightClickHint.Show 	= 		///Jasmine 02/02/10 SHOW_RIGHT_CLICK_HINT_IN_ONE_ROW_TO_SAVE_SPACE
	tr.UserInfo.Show 		= false;
	bool bData = m_mo? m_mo.HasData(FALSE) : false;	//exclude gray scale image as well
	tr.WidthOption.Show = bData;//tr.ApplyAllCol.Show = false;///Jasmine 10/20/06 DIVIDE_INTO_THREE_GROUP
	tr.WidthOption.ApplyAllCol.Show = false;
	//tr.Display.Show = bData;
	//tr.Numeric.Show = bData;
	//tr.Digits.Show = bData? tr.Digits.Show : bData;
	//tr.InternalData.Show = bData;
	tr.Options.Show = bData;
	tr.Options.ApplyToRight.Show = false;	///Jasmine 11/10/06 APPLY_OPTION_TO_ALL_RIGHT_COL
	tr.Options.CustomFormat.Show = false;
	///End HIDE_NO_USE_OPTION
	///---------Jasmine 02/16/07 no Long name, unit, Comments.
	/// Hong 05/27/10 ORG-131 MATRIX_PROPERTIES_DLG_NEED_NORMAL_HEADER_ACCESS
	//tr.LName.Remove();
	//tr.Unit.Remove();
	//tr.Comments.Remove();
	/// end MATRIX_PROPERTIES_DLG_NEED_NORMAL_HEADER_ACCESS
	//------ CPY 4/14/08 QA70-11421 COL_PROP_DIALOG_ALWAYS_RUN_FORMULA_WHEN_ANY_THING_CHANGED
	//tr.Formula.Remove();	///Jasmine 05/04/07 no formula, either
	//------
	///---------end
///Jasmine 09/04/07 DISABLE_CONTROLS_FOR_IMAGE_DATA
	if(!bData)
	{
		_disable_tree_node(tr);
		/// Bill 07/12/2010 ORG-550-P1 ENABLE_LNAME_UNIT_COMMENT_FOR_IMAGE_DATA
		tr.LName.Enable = ENABLE;
		tr.Unit.Enable = ENABLE;
		tr.Comments.Enable = ENABLE;
		/// End ENABLE_LNAME_UNIT_COMMENT_FOR_IMAGE_DATA
	}
}
static void _disable_tree_node(TreeNode& trNode)
{
	foreach(TreeNode trn in trNode.Children)
	{
		if(trn.GetNodeCount() > 0)
			_disable_tree_node(trn);
		else
		{
			if ( ENABLE_READONLY_SCROLL != trn.Enable )
				trn.Enable = DISABLE;
		}
	}
}
///End DISABLE_CONTROLS_FOR_IMAGE_DATA

void MatrixObjectProperties::ConstructDimensionsTree(TreeNode& tr, int nCols, int nRows, string strXMin, string strXMax, string strYMin, string strYMax)
{
	if(-1 == nCols)
		nCols = m_mo.GetNumCols();
	if(-1 == nRows)
		nRows = m_mo.GetNumRows();
	
	double dXMin, dXMax, dYMin, dYMax;
	m_mo.GetXY(dXMin, dYMin, dXMax, dYMax);
	if("" == strXMin)
		strXMin = dXMin;
	if("" == strXMax)
		strXMax = dXMax;
	if("" == strYMin)
		strYMin = dYMin;
	if("" == strYMax)
		strYMax = dYMax;
	
	GETN_USE(tr)/*
	GETN_BEGIN_BRANCH(dimensions, "Dimensions") GETN_OPTION_BRANCH(GETNBRANCH_OPEN) 			GETN_ID_BRANCH(CMD_MAT_DIMENSIONS)
		GETN_NUM(columns, "Columns", nCols) 				GETN_ID(CMD_MAT_COLUMNS)
		GETN_NUM(rows, "Rows", nRows) 						GETN_ID(CMD_MAT_ROWS)
	GETN_END_BRANCH(dimensions)
	GETN_BEGIN_BRANCH(coordinates, "Coordinates") 			GETN_ID_BRANCH(CMD_MAT_COORDINATES)
		GETN_STR(xmin, "X Min(First Col)", strXMin) 		GETN_ID(CMD_MAT_XMIN)
		GETN_STR(xmax, "X Max(Last Col)", strXMax) 			GETN_ID(CMD_MAT_XMAX)
		GETN_STR(ymin, "Y Min(First Row)", strYMin) 		GETN_ID(CMD_MAT_YMIN)
		GETN_STR(ymax, "Y Max(Last Row)", strYMax) 			GETN_ID(CMD_MAT_YMAX)
	GETN_END_BRANCH(dimensions)*/
}

///Kevin 11/12/05 QA70-8292-3 COL_INTERNAL_DATATYPE_COMPLEX_NOT_WORKING
//move the code to the DataObjectManager
/*
int MatrixObjectProperties::ConvertGUIInternalData(int nInternalData, bool bToGUI)//=true
{
	if(bToGUI)
	{
		if(FSI_COMPLEX == nInternalData)
			return GUI_MATRIX_INTERNAL_DATA_COMPLEX;
	}
	else if(GUI_MATRIX_INTERNAL_DATA_COMPLEX == nInternalData)
		return FSI_COMPLEX;

	return nInternalData;
}*/
///End COL_INTERNAL_DATATYPE_COMPLEX_NOT_WORKING

////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////     	ColumnValues	    ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////

ColumnValues::ColumnValues() : ColAccess()
{
}
ColumnValues::ColumnValues(Worksheet& lay) : ColAccess(lay)
{
	GetSelection(lay);
}
ColumnValues::~ColumnValues()
{
}
bool ColumnValues::Attach(DataObject& ob)
{
	m_Col = (Column)ob;
	
	return ColAccess::Attach(ob);
}
///Jasmine 04/24/06 SET_COL_VAL_DLG_MODELESS
bool ColumnValues::IsProcessSelChange(Layer& lay)
{
	MatrixLayer ml(lay);
	if(ml)
		return true;
	return is_wks_sel_valid(lay);
}
///End
///Sophy 9/10/2009 QA80-14297 HIDE_SET_COL_VALS_DLG_WHEN_NO_VALID_DATA_SELECTED
//for in ColAccess::GetSelection, wks.GetSelectedRange(int, int, int, int) can not get real-time selection and I use wks.GetSelectedRange(vector, vector, vector, vector) to get selection
//in order not to break old logic, I virtual this method
void ColumnValues::GetSelection(Layer& lay)
{
	Worksheet wks(lay);
	if(!wks)
	{
		error_report("Invalid Worksheet");
		return;
	}
	
	vector<int> vnSelCols, vnSelRows;
	
	vector<int> vnC1, vnR1, vnC2, vnR2;
	int nSelection = wks.GetSelectedRange(vnR1, vnC1, vnR2, vnC2);	
	
	if ( nSelection == 1 ) //allow only one region selected
	{
		vnSelCols.Data(vnC1[0], vnC2[0], 1);
		if ( vnR2[0] >= 0 )
		{
			vnSelRows.Add(vnR1[0] + 1);
			vnSelRows.Add(vnR2[0] + 1)
		}
	}
	int nSelectionWay = DATAOB_COL_SEL_CONTIGUOUS;

	SetRange(vnSelRows, vnSelCols, nSelectionWay);
	if ( 0 < vnSelCols.GetSize() )
		Attach(wks, vnSelCols[0]);
}
///end end HIDE_SET_COL_VALS_DLG_WHEN_NO_VALID_DATA_SELECTED
//"[page]layer|col index|row index"
//index: |nBegin|nEnd
string ColumnValues::GetSelectionStr()
{
	///Jasmine 10/27/06 GET_RANGE_STRING
	//string str = "["+m_wks.GetPage().GetName()+"]"+m_wks.GetName();
	string str;
	///Kyle 07/20/2009 QA80-13746-P2 SCV_COL_COLUMN_BROWSER_AND_RANGE_BROWSER_SHOW_SN_LN_CLEANUP
	//m_Col.GetRangeString(str);
	m_Col.GetRangeString(str, NTYPE_GOOD_LN_OR_SN);		// [Book1]Sheet1!Col(LN) or [Book1]Sheet1!Col(SN)
	///End SCV_COL_COLUMN_BROWSER_AND_RANGE_BROWSER_SHOW_SN_LN_CLEANUP
	///Jasmine 10/23/06 CHANGE_TEXT_TO_EASY_UNDERSTAND
	str+="|"+m_vnColRanges[0];
	//str+="|"+(string)(m_vnColRanges[0]+1);
	///End CHANGE_TEXT_TO_EASY_UNDERSTAND
	///End GET_RANGE_STRING
	int nSize = m_vnRowRanges.GetSize();
	if(1 > nSize)
	//----- CPY 11/3/2007 SET_COL_VALUES_AUTO_NEED_LOCALIZATION
	//	str+="|Auto|Auto";
	{
		str+="|" + STR_AUTO + "|" + STR_AUTO;
	}
	//----- end SET_COL_VALUES_AUTO_NEED_LOCALIZATION
	else
		str+="|"+m_vnRowRanges[0]+"|"+m_vnRowRanges[nSize-1];
	
	return str;
}
///Kyle 12/08/2008 CHECK_IF_RANGE_SELECTED_DIFFERENT_FROM_FORMULA_RANGE
//string ColumnValues::GetFormula()
string ColumnValues::GetFormula(vector<int>& vnRows, vector<int>& vnCols, int* pnColSelWay)
///End CHECK_IF_RANGE_SELECTED_DIFFERENT_FROM_FORMULA_RANGE
{
	int nFirstCol = m_vnColRanges[0];
	Column col(m_wks, nFirstCol);
	string strFormula = col.GetFormula(), strOtherFormula;
	///Kyle 12/08/2008 CHECK_IF_RANGE_SELECTED_DIFFERENT_FROM_FORMULA_RANGE
	int nBegin = -2, nEnd = -2;
	col.IsFormulaAutoUpdate(&nBegin, &nEnd);
	///End CHECK_IF_RANGE_SELECTED_DIFFERENT_FROM_FORMULA_RANGE
	for(int ii=1; ii<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[ii]); ii++)
	{
		strOtherFormula = col.GetFormula();
		if(strFormula != strOtherFormula)
		{
			///Kyle 12/08/2008 CHECK_IF_RANGE_SELECTED_DIFFERENT_FROM_FORMULA_RANGE
			//return "";
			strFormula = "";
			break;
			///End CHECK_IF_RANGE_SELECTED_DIFFERENT_FROM_FORMULA_RANGE
		}
	}
	///Kyle 12/08/2008 CHECK_IF_RANGE_SELECTED_DIFFERENT_FROM_FORMULA_RANGE
	if(vnRows && vnCols && pnColSelWay)
	{
		if(strFormula.IsEmpty())
		{
			vnRows.SetSize(0);
			vnCols.SetSize(0);
		}
		else
		{
			vnRows.SetSize(2);
			vnRows[0] = nBegin;
			vnRows[1] = nEnd;
			vnCols = m_vnColRanges;
			*pnColSelWay = DATAOB_COL_SEL_DISCONTIGUOUS;
		}
	}
	///End CHECK_IF_RANGE_SELECTED_DIFFERENT_FROM_FORMULA_RANGE
	
	return strFormula;
}

// return from 1st only
int ColumnValues::GetFormulaAutoUpdateMode()
{
	int nBeginRow, nEndRow;
	GetRowRange(nBeginRow, nEndRow);
	
	int nCol=0, nFirstCol = m_vnColRanges[0];
	Column col(m_wks, nFirstCol);
/*	do
	{
		if(!col.IsFormulaAutoUpdate(&nBeginRow, &nEndRow))
			return false;
		nCol++;
	}
	while(nCol<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[nCol]));
	return true;*/
	return col.IsFormulaAutoUpdate();
}
//---- CPY 5/17/06 COL_FORMULA_AUTO_UPDATE_CLEANUP
/*
void ColumnValues::SetFormulaAutoUpdate(BOOL bOn)
{
	int nBeginRow, nEndRow;
	GetRowRange(nBeginRow, nEndRow);
	
	int nCol=0, nFirstCol = m_vnColRanges[0];
	Column col(m_wks, nFirstCol);
	do
	{
		col.SetFormulaAutoUpdate(nBeginRow, nEndRow, bOn);
		nCol++;
	}
	while(nCol<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[nCol]));
}
bool ColumnValues::SetFormula(LPCSTR lpcszFormula)
{
	int nBeginRow, nEndRow;
	GetRowRange(nBeginRow, nEndRow);
	
	int nCol=0, nFirstCol = m_vnColRanges[0];
	Column col(m_wks, nFirstCol);
	bool bRet = true;
	do
	{
		if(col.SetFormula(lpcszFormula))
			col.ExecuteFormula(nBeginRow, nEndRow);
		else
			bRet = false;
		nCol++;
	}
	while(nCol<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[nCol]));
	return bRet;
}
*/
// support 1st in sel only
bool ColumnValues::SetFormula(LPCSTR lpcszFormula, int nAutoUpdate)
{
	int nBeginRow, nEndRow;
	GetRowRange(nBeginRow, nEndRow);
	
	int nCol=0, nFirstCol = m_vnColRanges[0];
	Column col(m_wks, nFirstCol);
	/*bool bRet = true;
	do
	{
		col.SetFormulaAutoUpdate(nBeginRow, nEndRow, false);//clear auto update first
		if(col.SetFormula(lpcszFormula) && col.ExecuteFormula(nBeginRow, nEndRow))
		{
			col.SetFormulaAutoUpdate(nBeginRow, nEndRow, bAutoUpdate);
		}
		else
			return false;
		nCol++;
	}
	while(nCol<m_vnColRanges.GetSize() && col.Attach(m_wks, m_vnColRanges[nCol]));
	return true;*/
	if(col)
		/// AW 07/13/07 QA80-10056 NEED_DEL_OP_AFTER_UNDO_SETVALUE_WITH_AUTO
		//return col.SetFormula(lpcszFormula, nAutoUpdate, nBeginRow, nEndRow); 
		return col.SetFormula(lpcszFormula, nAutoUpdate, nBeginRow, nEndRow, TRUE);   // need undo creating op
		/// END NEED_DEL_OP_AFTER_UNDO_SETVALUE_WITH_AUTO
	
	return false;
}
bool ColumnValues::ExecuteFormula(BOOL bUndo)
{
	int nBeginRow, nEndRow;
	GetRowRange(nBeginRow, nEndRow);
	
	int nCol=0, nFirstCol = m_vnColRanges[0];
	Column col(m_wks, nFirstCol);
	if( col )
		return col.ExecuteFormula(nBeginRow, nEndRow, bUndo);
	
	return FALSE;
}
//---- end COL_FORMULA_AUTO_UPDATE_CLEANUP

////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////     MatrixObjectValues	    ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////

MatrixObjectValues::MatrixObjectValues() : MatrixObjectAccess()
{
}
///Jasmine 08/28/06 SHARE_SET_VAL_DLG
MatrixObjectValues::MatrixObjectValues(MatrixLayer& lay) : MatrixObjectAccess(lay)
{
	if(m_mo)
		m_matOB = m_mo;
}
MatrixObjectValues::~MatrixObjectValues()
{
}
bool MatrixObjectValues::IsProcessSelChange(Layer& lay)
{
	MatrixLayer ml(lay);
	if(ml)
		return true;
	return is_wks_sel_valid(lay);
}
string MatrixObjectValues::GetSelectionStr()
{
	MatrixLayer ml;
	m_matOB.GetParent(ml);
	///Jasmine 10/27/06 GET_RANGE_STRING
	/*
	///Jasmine 10/23/06 CHANGE_TEXT_TO_EASY_UNDERSTAND
	//string str = "["+ml.GetPage().GetName()+"]"+ml.GetName() + "|" + m_matOB.GetName();
	string str = wks_get_book_sheet_name(ml) + "|" + (string)(m_matOB.GetIndex()+1);
	//End CHANGE_TEXT_TO_EASY_UNDERSTAND
	*/
	string str;
	///Kyle 07/20/2009 QA80-13746-P2 SCV_COL_COLUMN_BROWSER_AND_RANGE_BROWSER_SHOW_SN_LN_CLEANUP
	//m_matOB.GetRangeString(str);
	m_matOB.GetRangeString(str, NTYPE_GOOD_LN_OR_SN);		// [MBook1]MSheet1!Mat(LN) or [MBook1]MSheet1!Mat(LN)
	///End SCV_COL_COLUMN_BROWSER_AND_RANGE_BROWSER_SHOW_SN_LN_CLEANUP
	int nRow = ml.GetNumRows(), nCol= ml.GetNumCols();
	str += "|" + m_matOB.GetIndex() + "|" + nRow + "|" + nCol;
	///End GET_RANGE_STRING
	return str;
}
///Kyle 12/08/2008 CHECK_IF_RANGE_SELECTED_DIFFERENT_FROM_FORMULA_RANGE
///string MatrixObjectValues::GetFormula()
string MatrixObjectValues::GetFormula(vector<int>& vnRows, vector<int>& vnCols, int* pnColSelWay)	//to do, not finished
///End CHECK_IF_RANGE_SELECTED_DIFFERENT_FROM_FORMULA_RANGE
{
	return m_matOB.GetFormula();
}
bool MatrixObjectValues::SetFormula(LPCSTR lpcszFormula, int nAutoUpdate)
{
	if(m_matOB)
		return m_matOB.SetFormula(lpcszFormula, nAutoUpdate);//, nBeginRow, nEndRow);
	return true;
}
bool MatrixObjectValues::ExecuteFormula(BOOL bUndo)// = TRUE
{
	if( m_matOB )
	{
		//----- CPY 5/11/09 QA70-12554 MAT_SET_VALUES_NEED_RANGE_SUPPORT
		//return m_matOB.ExecuteFormula(-1, -1, bUndo);
		int nBeginRow, nEndRow;
		int nBeginCol, nEndCol;
		if(GetRowRange(nBeginRow, nEndRow) && GetColRange(nBeginCol, nEndCol))
			return m_matOB.ExecuteFormula(nBeginRow, nEndRow, bUndo, nBeginCol, nEndCol);
		//-----
	}
	//----- CPY 5/11/09 QA70-12554 MAT_SET_VALUES_NEED_RANGE_SUPPORT
	//return FALSE;
	return error_report("MatrixObjectValues::ExecuteFormula(");
	//-----
}
int MatrixObjectValues::GetFormulaAutoUpdateMode()
{
	return m_matOB.IsFormulaAutoUpdate();
}
///Emd SHARE_SET_VAL_DLG

