/*------------------------------------------------------------------------------*
 * File Name: FindAndReplaceDlg.cpp												*
 * Creation: Kenny 06/24/2009													*
 * Purpose: OriginC Source file													*
 * Copyright (c) OriginLab Corp. 2009											*
 * All Rights Reserved															*
 *																				*
 * Modification Log:															*
 * Iris 7/14/2009 QA80-13941 SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF	*
 * Kenny 07/15/2009 FILL_FINDWHAT_REPLACE_WITH_LAST_USED_VALUE					*
 * Kenny 07/15/2009 DETECT_MULTI_SELECTION_TO_SHOW_HIDE_RELATED_CHECKBOX		*
 *	Kenny 08/04/2009 QA80-13876-P2 FIX_BUG_IN_NUMERIC_FIND_REPLACE_FOR_NOT_EQUAL_CONDITION*
 *	Kenny 09/11/2009 MAKE_TOLERANCE_AVAILABLE_IF_CONDITION_CONTAIN_EQUAL		*
 *	Kenny 09/18/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS	*
 *	Kenny 09/18/2009 INIT_DIALOG_SIZE_NEEDED									*
 *	Kenny 09/29/2009 IMPROVE_FIND_REPLACE_DLG_RESIZING_PROCESS					*
 *	Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT		*
 *	Kenny 10/10/2009 FIND_REPLACE_SUPPORT_GERMAN_DECIMAL						*
 *	Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED*
 *	Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS			*
 *	Folger 11/04/09 FIND_REPLACE_DIALOG_MESS_UP_WHEN_FIRST_RUN					*
 *	Kenny 12/28/2009 FIND_REPLACE_DLG_SHOWN_WITH_UGLY_BK_COLOR					*
 *	Kenny 01/14/2010 FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN			*
 *	Kenny 04/01/2010 CHECK_BOXES_STATUS_FAILED_TO_GET_INIT_ON_REOPEN_DLG		*
 *	Kenny 08/09/2010 ORG-230-P1 FIND_REPLACE_DLG_CLOSE_BUTTON_FLICKER_WHEN_CLICK_SKIP_LINKED_CELLS_BUTTON*
 *------------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/* Include files
/*----------------------------------------------------------------------------*/
#include <Origin.h>
#include <../OriginLab/DialogEx.h>
#include "LayoutHelper.h"
#include "INIFileEx.h"
#include <okocUtils.h>
#include <event_utils.h>  /// Iris 7/14/2009 QA80-13941 SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
#include <ocu.h>		/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
//#include <Profiler.h>

/*----------------------------------------------------------------------------*/
/* Macros/Enums/Consts
/*----------------------------------------------------------------------------*/

/// Kenny 09/18/2009 INIT_DIALOG_SIZE_NEEDED
//#define STR_DLG_NAME 								_L("Find and Replace")
#define STR_DLG_NAME_E 							"Find and Replace"
#define STR_DLG_NAME 							_L(STR_DLG_NAME_E)
/// End INIT_DIALOG_SIZE_NEEDED

enum	// Tab
{
	TAB_FIND,
	TAB_REPLACE,
};

#define STR_TAB_FIND								_L("Find")
#define STR_TAB_REPLACE								_L("Replace")

enum	// Data types
{
	DT_NUMERIC,
	DT_STRING,
};

#define STR_WORKSHEET_TYPE_NAME						_L("Worksheet")
#define STR_WORKBOOK_TYPE_NAME						_L("Workbook")

#define STR_MATRIXOBJECT_TYPE_NAME					_L("MatrixObject")
#define STR_MATRIXSHEET_TYPE_NAME					_L("Matrixsheet")
#define STR_MATRIXBOOK_TYPE_NAME					_L("Matrixbook")
#define STR_LOOK_IN_ACTIVE_OBJECT_FORMAT			_L("Active %s")

#define STR_LOOK_IN_ALL_BOOKS_IN_ACTIVE_FOLDER_FORMAT				_L("All %ss in Active Folder")
#define STR_LOOK_IN_ALL_BOOKS_IN_ACTIVE_FOLDER_RECURSIVE_FORMAT		_L("All %ss in Active Folder (Recursive)")
#define STR_LOOK_IN_ALL_BOOKS_IN_ACTIVE_FOLDER_OPEN_FORMAT			_L("All %ss in Active Folder (Open)")
#define STR_LOOK_IN_ALL_BOOKS_IN_PROJECT_FORMAT						_L("All %ss in Project")

#define STR_TIPS_INSERT_SPECIAL_SYMBOL				_L("Insert Special symbol")	/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT

/// Iris 7/14/2009 QA80-13941 SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
/*
enum
{
	OPTION_ACTIVE_MATRIX_OBJECT		= OPTION_ACTIVE_PAGE - 2,
	OPTION_ACTIVE_SHEET				= OPTION_ACTIVE_PAGE - 1,
};

#define GUI_LOOK_IN_MATRIX_BASE	1

enum
{
	GUI_LOOK_IN_ACTIVE_MATRIX_OBJECT = -1,
	GUI_LOOK_IN_ACTIVE_SHEET,
	GUI_LOOK_IN_ACTIVE_PAGE,
	GUI_LOOK_IN_ACTIVE_FOLDER,
	GUI_LOOK_IN_ACTIVE_FOLDER_RECURSIVE,
	GUI_LOOK_IN_ACTIVE_FOLDER_OPEN,
	GUI_LOOK_IN_PROJECT
};
*/
///end SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF

#define DEFAULT_TOLERANCE_VALUE				1e-8

#define STR_FAILED_TO_FIND_ANY_CELL					_L("Origin cannot find the data you are searching for.")
#define STR_FAILED_TO_FIND_MATCH_DATA_TO_REPLACE	_L("Origin cannot find any match data to replace.")
#define STR_FAILED_TO_REPLACE_LOCKED_CELL			_L("Origin cannot find any match data to replace. If you are sure that matching data exists, it may be locked. Origin cannot replace locked data.")

#define STR_REPLACE_ALL_REPORT_FORMAT				_L("%s: %d occurrences replaced.")
#define STR_REPLACE_ALL_FAILED_TO_REPLACE_PART		_L("Some matched occurances are failed to be replaced, maybe they are locked.")

/*------------------------Condition related-----------------------------------*/
enum	// Numeric replace condition type
{
	NRC_INVALID	= -1,
	NRC_EQ	= 0,
	NRC_LT	= 1,
	NRC_LE	= 2,
	NRC_GT	= 3,
	NRC_GE	= 4,
	NRC_NE	= 5,
	NRC_SIZE,
};

#define STR_NRC_EQ									"="
#define STR_NRC_LT									"<"
#define STR_NRC_LE									"<="
#define STR_NRC_GT									">"
#define STR_NRC_GE									">="
#define STR_NRC_NE									"!="

// recent list relative
#define FIND_WHAT_LIST_MAX_NUM						10
#define FIND_WHAT_RECENT_LIST_INI_FILE				"Origin.ini"
#define FIND_WHAT_RECENT_LIST_SECTION				"WksFindWhatRecentList"
#define REPLACE_WITH_RECENT_LIST_SECTION			"WksReplaceWithRecentList"
#define FIND_WANT_RECENT_LIST_KEY_PREFIX			"List"

// registry relative
#define DATA_TYPE_REG_NAME							"DataType"

#define CONDITION_TYPE_REG_NAME						"Condition"

#define OPTION_GROUP_EXPAND_REG_NAME				"OptionGroupExpanded"

#define OPTION_TOLERANCE_REG_NAME					"Tolerance"

/*----------------------For debugging use only--------------------------------*/

//#define SHOW_PROFILER						Profiler _profiler;

/*----------------------------------------------------------------------------*/
/* Utilities functions
/*----------------------------------------------------------------------------*/
static int _get_active_page_type()
{
	PageBase pbActiveWindow;
	pbActiveWindow = Project.Pages();
	int nPageType = EXIST_NONE;

	if( pbActiveWindow.IsValid() )
	{
		nPageType = pbActiveWindow.GetType();
	}
	return nPageType;
}

static bool _can_do_find_or_replace_on_active_sheet(int* pnPageType = NULL)
{
	BOOL bCanWorkOn = FALSE;
	int nPageType = _get_active_page_type();
	if( EXIST_WKS == nPageType )
	{
		Worksheet wks = Project.ActiveLayer();
		if ( wks )
		{
			if ( !(WP_SHEET_HIERARCHY & wks.GetSystemParam(0)) )
			{
				bCanWorkOn = TRUE;
			}
		}
	}
	else if( EXIST_MATRIX == nPageType )
		bCanWorkOn = TRUE;
	if ( pnPageType )
	{
		*pnPageType = nPageType;
	}
	return bCanWorkOn;
}


static bool _is_str_missing_val(LPCSTR lpcszVal)
{
	static string strMissingVal = ftoa(NANUM);
	if ( NULL == lpcszVal || '\0' == *lpcszVal )
		return false;
	const int nCompareRet = strMissingVal.CompareNoCase(lpcszVal);
	const bool bIsMissingVal = (0 == nCompareRet);
	return bIsMissingVal;
}

/// Iris 7/14/2009 QA80-13941 SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
/*
static bool	_is_matrix(Datasheet& ds)
{
	if ( ds.IsValid() )
	{
		const bool bIsMatrixType = ( EXIST_MATRIX == ds.GetPage().GetType() );
		return bIsMatrixType;
	}
	return false;
}
*/
///end SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF

static bool	_get_sheet_highlighted_cell(Datasheet& ds, int& nCol, int& nRow)
{
	if ( ds.IsValid() )
	{
		Grid gg;
		if ( gg.Attach(ds) )
		{
			const BOOL bTranslate = true;
			int nRet = gg.GetCurrentCell(nRow, nCol, bTranslate);
			///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
			//return 1 == nRet;	// 1 means the cursor is in the data area
			if ( 1 == nRet )	// 1 means the cursor is in the data area
				return true;
			if ( 2 == nRet && nRow >= 0 )	// 2 means the cursor is in the label area
			{
				vector<int>		vnTypes;
				gg.GetShowLabels(vnTypes);
				nRow -= vnTypes.GetSize();
				return true;
			}
			///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
		}
	}
	return false;
}
/// Iris 7/14/2009 QA80-13941 SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
/*
static bool _get_sheet_selection(Datasheet& ds, DataRange& dr)
{
	bool bRet = ds.IsValid();
	if ( bRet )
	{
		vector<int> vr1, vc1, vr2, vc2;
		Grid gg;
		int nTotalRange = 0;
		if ( gg.Attach(ds) )
		{
			int nRegions = gg.GetSelection(vr1, vc1, vr2, vc2);
			for (int ii = 0; ii < nRegions; ++ii)
			{
				int nNumRanges = dr.Add("Range" + ii, ds, vr1[ii], vc1[ii], vr2[ii], vc2[ii]);
				if ( nNumRanges > 0 )
					nTotalRange += nNumRanges;
			}
		}
		bRet &= (nTotalRange > 0);
	}
	return bRet;
}

static int _get_matrix_active_object_index(Datasheet& ds)
{
	int nIndex = -1;
	if ( _is_matrix(ds) )
	{
		MatrixLayer ml(ds);
		MatrixObject mo = ml.MatrixObjects();
		nIndex = mo.GetIndex();
	}
	return nIndex;
}
static bool _get_active_sheet_range(Datasheet& ds, int* pnMatrixObjectIndex = NULL, DataRange* pDataRange = NULL)
{
	bool bRet = true;
	ds = Project.ActiveLayer();
	bRet = ds.IsValid();
	if ( pnMatrixObjectIndex )
	{
		*pnMatrixObjectIndex = _get_matrix_active_object_index(ds);
	}
	if ( pDataRange )
	{
		bRet &= _get_sheet_selection(ds, *pDataRange);
	}
	return bRet;
}
*/
///end SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF

/// Kenny 07/15/2009 DETECT_MULTI_SELECTION_TO_SHOW_HIDE_RELATED_CHECKBOX
static UINT _get_range_cells_count(DataRange& dr)
{
	UINT nCount = 0;
	if ( dr.IsValid() )
	{
		int r1, c1, r2, c2;
		for (int ii = 0; ii < dr.GetNumRanges(); ++ii)
		{
			Datasheet ds;
			if ( dr.GetRange(ii, r1, c1, r2, c2, ds) )
			{
				///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
				//if ( r2 < 0 )
				if ( r1 >= 0 && r2 < 0 )
				///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
					r2 = ds.GetNumRows()-1;
				if ( c2 < 0 )
					c2 = ds.GetNumCols()-1;
				int nCols = abs(c2-c1)+1;
				int nRows = abs(r2-r1)+1;
				int nCells = nCols * nRows;
				nCount += nCells;
			}
		}
	}
	return nCount;
}
/// End DETECT_MULTI_SELECTION_TO_SHOW_HIDE_RELATED_CHECKBOX

/*----------------------------------------------------------------------------*/
/* Global variables
/*----------------------------------------------------------------------------*/

class CFindAndReplaceDlg;
static CFindAndReplaceDlg* s_pCFindAndReplaceDlg;

/*----------------------------------------------------------------------------*/
/* CFindReplaceHelper
/*----------------------------------------------------------------------------*/

class CFindReplaceHelper
{
public:
	CFindReplaceHelper()
	{
		m_nLookInRange = -1;
		m_nBitwiseOptions = 0;
		m_bIsNumericType = FALSE;
		m_bPerformInSelectedRange = FALSE;
		m_pParentWnd = NULL;
	}
public:
	string		m_strFindWhat;
	string		m_strReplaceWith;
	int			m_nLookInRange;
	UINT		m_nBitwiseOptions;
	double		m_dTolerance;
	BOOL		m_bIsNumericType;
	BOOL		m_bPerformInSelectedRange;
	Window*		m_pParentWnd;
public:
	string	GetCurrentCellText()
	{
		Datasheet ds;
		int nCol, nRow, nMatrixObjectIndex;
		string strText;
		if ( getHighlightedCell(ds, nCol, nRow, &nMatrixObjectIndex) )
		{
			strText = ds.TCell(nRow, nCol);
		}
		return strText;
	}
	BOOL	FindNext()
	{
		DataRange dr;
		Datasheet ds;
		BOOL bRet = ( PrepareActiveSheetDataRange(dr, &ds) && DoFindReplace(ds, dr, false) );
		return bRet;
	}
	BOOL	Replace()
	{
		DataRange dr;
		Datasheet ds;
		BOOL bRet = ( PrepareActiveSheetDataRange(dr, &ds) && DoFindReplace(ds, dr, true) );
		return bRet;
	}
	int		ReplaceAll()
	{
		int nRet = DoReplaceAll();
		return nRet;
	}

protected:
	BOOL	DoFindReplace(Datasheet& ds, DataRange& dr, bool bDoReplace = false)
	{
		if ( !ds.IsValid() || !dr.IsValid() )
		{
			ASSERT(FALSE);
			return FALSE;
		}
		int nCol, nRow;
		if ( !_get_sheet_highlighted_cell(ds, nCol, nRow) )
		{
			///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
			//nCol = nRow = -1;
			nCol = nRow = DATARANGE_FIND_REPLACE_INVALID_ROW_INDEX;
			///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
		}
		/// Iris 7/14/2009 QA80-13941 SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
		//int nMatrixObjectIndex = _get_matrix_active_object_index(ds);
		int nMatrixObjectIndex = get_matrix_active_object_index(ds);
		///end SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF

		int 	nRet = 0;
		int 	nRangeIndex = -1; //range index, always be -1, that means including all subranges
		bool	bUndo = true;
		if( m_bIsNumericType )
		{
			double dReplaceWithVal = getReplaceWithNumericVal();
			double* pdReplaceWithVal = bDoReplace ? &dReplaceWithVal : NULL;
			/// Iris 7/14/2009 QA80-13941 SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
			//int* pnMatrixObjectIndex = _is_matrix(ds) ? &nMatrixObjectIndex : NULL;
			int* pnMatrixObjectIndex = is_matrix_sheet(ds) ? &nMatrixObjectIndex : NULL;
			///end SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
			nRet = dr.FindNext(ds, nCol, nRow, getFindWhatNumericVal(), m_nBitwiseOptions, nRangeIndex, m_dTolerance, pdReplaceWithVal, bUndo, pnMatrixObjectIndex);
		}
		else
		{
			Worksheet wks(ds);
			LPCSTR lpcszReplaceWith = bDoReplace ? m_strReplaceWith.GetBuffer(m_strReplaceWith.GetLength()) : NULL;
			nRet = dr.FindNext(wks, nCol, nRow, m_strFindWhat, m_nBitwiseOptions, nRangeIndex, lpcszReplaceWith, bUndo);
		}

		bool bFoundNext	= DATARANGE_FIND_NEXT_SUCCESSFULLY_FOUND & nRet;
		bool bReplaceOK	= DATARANGE_FIND_NEXT_SUCCESSFULLY_REPLACE_INPUT & nRet;

		if ( bFoundNext )
		{
			highlightCell(ds, nCol, nRow, &nMatrixObjectIndex);
		}
		if ( bReplaceOK )
		{
			// We have replaced the input cell but failed to find the next cell
			// if we don't refresh the page here, the user won't be able to see the change after the replacement.
			Page pg = ds.GetPage();
			pg.Refresh(TRUE);
		}

		const BOOL bRet = bFoundNext || bReplaceOK;
		if ( m_pParentWnd )
		{
			if ( bDoReplace )
			{
				if ( !bReplaceOK )
				{
					bool bInputCellMatched	= DATARANGE_FIND_NEXT_INPUT_MATCHED_CONDITIONS & nRet;
					if ( bInputCellMatched )
					{
						// The input cell matched all conditions but we failed to set the value of it
						// this may be because the cell was locked, so prompt the user.
						MessageBox(m_pParentWnd->GetSafeHwnd(), STR_FAILED_TO_REPLACE_LOCKED_CELL);
					}
					else if (!bFoundNext)
					{
						MessageBox(m_pParentWnd->GetSafeHwnd(), STR_FAILED_TO_FIND_MATCH_DATA_TO_REPLACE);
					}
				}
			}
			else if ( !bFoundNext )
			{
				MessageBox(m_pParentWnd->GetSafeHwnd(), STR_FAILED_TO_FIND_ANY_CELL);
			}
		}
		return bRet;
	}
	int		DoReplaceAll(bool bRefreshPage = true)
	{
		int nTotal = 0;

		if ( OPTION_ACTIVE_MATRIX_OBJECT == m_nLookInRange || OPTION_ACTIVE_SHEET == m_nLookInRange )
		{
			const bool bGetActiveMatrixObjectOnly = OPTION_ACTIVE_MATRIX_OBJECT == m_nLookInRange;
			DataRange dr;
			Datasheet ds;
			if ( PrepareActiveSheetDataRange(dr, &ds, bGetActiveMatrixObjectOnly) )
			{
				nTotal = doReplaceAll(dr);
				if ( nTotal > 0 && bRefreshPage && ds.IsValid() )
				{
					Page pg = ds.GetPage();
					pg.Refresh(TRUE);
				}
			}
		}
		else
		{
			vector<string> vsBookNames;
			getTargetBookNames(vsBookNames);
			if( vsBookNames.GetSize() == 0 )
				return false;

			for(int index = 0; index < vsBookNames.GetSize(); index++ )
			{
				Page pg(vsBookNames[index]);
				int nCountInPage = 0;
				foreach(Layer lay in pg.Layers)
				{
					Datasheet ds(lay);
					DataRange dr;

					if (m_bPerformInSelectedRange)
					{
						/// Iris 7/14/2009 QA80-13941 SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
						//_get_sheet_selection(ds, dr);
						///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
						//get_sheet_selection(ds, dr);
						get_sheet_selection(ds, dr, O_QUERY_BOOL(m_nBitwiseOptions, WKSREPL_CHECK_FIND_LABEL_ROWS));
						///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
						///end SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
					}
					else
					{
						dr.Add("Range1", ds, 0, 0, -1, -1);
					}

					int nCountInLayer = doReplaceAll(dr);
					nCountInPage += nCountInLayer;
				}
				nTotal += nCountInPage;
				if ( nCountInPage > 0 && bRefreshPage )
				{
					pg.Refresh(TRUE);
				}
			}
		}

		return nTotal;
	}
	bool	PrepareActiveSheetDataRange(DataRange& dr, Datasheet* pDatasheet = NULL, bool bGetActiveMatrixObjectOnly = true)
	{
		/// Iris 7/14/2009 QA80-13941 SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
		/*
		Datasheet ds;
		int nMatrixObjectIndex = -1;
		bool bRet = _get_active_sheet_range(ds, &nMatrixObjectIndex);
		if ( pDatasheet )
		{
			*pDatasheet = ds;
		}
		if ( !bRet )
		{
			ASSERT(FALSE);
			return false;
		}
		if ( m_bPerformInSelectedRange )
		{
			bRet = _get_sheet_selection(ds, dr);
		}
		else
		{
			int nR1 = 0;
			int nR2 = -1;
			int nC1, nC2;
			if ( _is_matrix(ds) && bGetActiveMatrixObjectOnly )
			{
				nC1 = nC2 = nMatrixObjectIndex;
			}
			else
			{
				nC1 = 0;
				nC2 = -1;
			}
			int nNumRanges = dr.Add("Range1", ds, nR1, nC1, nR2, nC2);
			bRet = (nNumRanges > 0);
		}
		return bRet && dr.IsValid();
		*/
		///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
		//return get_active_sheet_range_ex(dr, m_bPerformInSelectedRange, pDatasheet, bGetActiveMatrixObjectOnly);
		return get_active_sheet_range_ex(dr, m_bPerformInSelectedRange, pDatasheet, bGetActiveMatrixObjectOnly, O_QUERY_BOOL(m_nBitwiseOptions, WKSREPL_CHECK_FIND_LABEL_ROWS));
		///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
		///end SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
	}
private:
	double	getFindWhatNumericVal()		{ return _is_str_missing_val(m_strFindWhat) ? NANUM : atof( m_strFindWhat ); }
	double	getReplaceWithNumericVal()	{ return _is_str_missing_val(m_strReplaceWith) ? NANUM : atof( m_strReplaceWith ); }

	int		doReplaceAll(DataRange& dr, int nRangeIndex = -1, BOOL bUndo = TRUE)
	{
		if ( !dr.IsValid() )
		{
			return 0;
		}
		int nCount = 0;
		int nError = 0;
		if( m_bIsNumericType )
		{
			nCount = dr.Replace( getFindWhatNumericVal(), getReplaceWithNumericVal(), m_nBitwiseOptions, nRangeIndex, m_dTolerance, bUndo, &nError);
		}
		else
		{
			nCount = dr.Replace( m_strFindWhat, m_strReplaceWith, m_nBitwiseOptions, nRangeIndex, bUndo, &nError);				
		}

		const bool bFailedToReplacePart = nError & DATARANGE_REPLACE_FAIL_TO_SET_CELL_VALUES;
		if ( nCount > 0 || bFailedToReplacePart )
		{
			string strResultInfo;
			string strRange;
			dr.GetRangeString(strRange);
			strResultInfo.Format(STR_REPLACE_ALL_REPORT_FORMAT, strRange, nCount);
			if ( bFailedToReplacePart )
			{
				strResultInfo += "\r\n" + STR_REPLACE_ALL_FAILED_TO_REPLACE_PART;
			}
			okoc_out_msg(strResultInfo, 'I');
		}
		return nCount;
	}
	int		getTargetBookNames( vector<string>& vsBookNames )
	{
		vsBookNames.RemoveAll();
		ASSERT ( -1 != m_nLookInRange );
		const bool bWksType = EXIST_WKS == _get_active_page_type();
		get_folder_pages_name(vsBookNames, m_nLookInRange, 0, NULL, NULL, bWksType ? EXIST_WKS : EXIST_MATRIX);
		return vsBookNames.GetSize();
	}
	bool	getHighlightedCell(Datasheet& ds, int& nCol, int& nRow, int* pnMatrixObjectIndex = NULL)
	{
		/// Iris 7/14/2009 QA80-13941 SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
		//if ( _get_active_sheet_range(ds, pnMatrixObjectIndex) )
		if ( get_active_sheet_range(ds, pnMatrixObjectIndex) )
		///end SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
		{
			return _get_sheet_highlighted_cell(ds, nCol, nRow);
		}
		return false;
	}
	bool	highlightCell(Datasheet& ds, int nCol, int nRow, int* pnMatrixObjectIndex = NULL)
	{
		if ( activateSheet(ds, pnMatrixObjectIndex) )
		{
			Grid gg;
			if ( gg.Attach(ds) )
			{
				BOOL bRet = gg.SetCurrentCell(nRow, nCol);
				return bRet;
			}
		}
		return false;
	}
	bool	activateSheet(Datasheet& ds, int* pnMatrixObjectIndex = NULL)
	{
		BOOL bRet = ds.CheckShowActivate();
		if ( bRet )
		{
			/// Iris 7/14/2009 QA80-13941 SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
			//if ( _is_matrix(ds) && pnMatrixObjectIndex )
			if ( is_matrix_sheet(ds) && pnMatrixObjectIndex )
			///end SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
			{
				MatrixLayer ml(ds);
				MatrixObject mo = ml.MatrixObjects();
				bRet = mo.CheckShowActivate();
			}
		}
		return bRet;
	}
};

/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
/*----------------------------------------------------------------------------*/
/* Declaration of CInsertSpecialMenu
/*----------------------------------------------------------------------------*/

enum
{
	INSERT_SPECIAL_MENU_SEPARATOR,

	INSERT_SPECIAL_MENU_MISSING_ONLY,
	INSERT_SPECIAL_MENU_MISSING_BLANK_TEXT,

	INSERT_SPECIAL_MENU_WILDCARD_ZERO_MORE_CHAR,
	INSERT_SPECIAL_MENU_WILDCARD_SINGLE_CHAR,
};

#define STR_SYMBOL_MISSING_BLANK_TEXT				"-"

#define STR_INSERT_MISSING_ONLY						("--\t"	+ _L("Missing value only"))
#define STR_INSERT_MISSING_BLANK_TEXT				("-\t"	+ _L("Missing value/Blank Cell/Text Cell"))
#define STR_INSERT_WILDCARD_ZERO_MORE_CHAR			("*\t"	+ _L("Zero or more of any character"))
#define STR_INSERT_WILDCARD_SINGLE_CHAR				("?\t"	+ _L("Any single character"))

class CInsertSpecialMenu : public MenuBase
{
public:
	CInsertSpecialMenu()
	{
		;
	}
public:
	void Init(const vector<int>& vnIDs, const vector<string>& vsText, const vector<bool>& vbEnables = NULL)
	{
		const int nIDSize = vnIDs.GetSize();
		if ( nIDSize != vsText.GetSize() || (vbEnables && nIDSize != vbEnables.GetSize()) )
		{
			ASSERT(FALSE);
			return;
		}
		for(int ii = 0; ii < nIDSize; ++ii)
		{
			int nFlags;
			if(INSERT_SPECIAL_MENU_SEPARATOR == vnIDs[ii])
				nFlags = MF_SEPARATOR;
			else
			{
				nFlags = MF_STRING;
				if( vbEnables && !vbEnables[ii] )
					nFlags |= MF_GRAYED | MF_DISABLED;
			}
			Add(vsText[ii], OnMenuItem, nFlags, vnIDs[ii]);
		}
	}
};
/// End QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT

/*----------------------------------------------------------------------------*/
/* Declaration of CFindAndReplaceDlg
/*----------------------------------------------------------------------------*/

class CFindAndReplaceDlg : public ResizeDialog
{	
public:
	CFindAndReplaceDlg(BOOL bDeleteOnDestroy = FALSE);
	~CFindAndReplaceDlg();
	// Create the dialog, shows the Replace tab if bDoReplace is true, otherwise switch to show the Find tab
	int		Create(HWND hWndParent = NULL);
	void	SwitchToActionTab(bool bSwitchToReplace = false);
	/// Kenny 09/11/2009 MAKE_TOLERANCE_AVAILABLE_IF_CONDITION_CONTAIN_EQUAL, minor improvement
	void	UpdateFindWhatToCurrentCellValue();
	/// End MAKE_TOLERANCE_AVAILABLE_IF_CONDITION_CONTAIN_EQUAL
	
protected:
	
EVENTS_BEGIN
	ON_INIT(OnInitDialog) 
	ON_READY(OnReady)
	ON_DESTROY(OnDestroy)
	ON_HELPINFO(OnHelp)
	ON_CANCEL(OnClose)
	ON_GETMINMAXINFO(OnMinMaxInfo)
	ON_SIZE(OnDlgResize)
	ON_CHANGE_LAYER(OnActiveLayerChange)
	ON_CHANGE_PAGE(OnActivePageChange)
	ON_CHANGE_SELECTION(OnSelectionChange)
	ON_PAGE_DESTROY(OnPageDestroy)
	ON_RESTORESIZE(OnRestoreSize)	/// Kenny 09/18/2009 INIT_DIALOG_SIZE_NEEDED

	ON_TAB_SEL_CHANGE(IDC_TAB_FIND_REPLACE, OnTabChange)
	ON_CBN_EDITCHANGE(IDC_COMBO_FIND_WHAT, OnFindWhatEditChange)
	ON_CBN_EDITCHANGE(IDC_COMBO_REPLACE_WITH, OnReplaceWithEditChange)
	ON_CBN_SELCHANGE(IDC_COMBO_FIND_WHAT, OnFindWhatSelChange)
	ON_CBN_SELCHANGE(IDC_COMBO_CONDITION, OnConditionSelChange)
	ON_CBN_SELCHANGE(IDC_COMBO_REPLACE_WITH, OnReplaceWithSelChange)
	ON_EN_CHANGE(IDC_EDIT_TOLERANCE, OnToleranceEditChange)
	
	ON_BN_CLICKED(IDC_CHECK_PERFORM_IN_SELECTED_RANGE, OnCheckPerformInSelectedRange)
	ON_BN_CLICKED(IDC_CHECK_SET_AS_MISSING_VAL, OnCheckSetAsMissing)
	ON_BN_CLICKED(IDC_CHECK_USE_WILDCARDS, OnCheckUseWildcards)
	ON_BN_CLICKED(IDC_CHECK_SKIP_LINKED_CELLS, OnCheckSkipLinkedCells)	/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
	ON_BN_CLICKED(IDC_RADIO_DATA_TYPE_NUMERIC, OnChangeDataType)
	ON_BN_CLICKED(IDC_RADIO_DATA_TYPE_STRING, OnChangeDataType)
	ON_BN_CLICKED(IDC_STATIC_OPTIONS, OnExpandOptionsGroup)
	ON_BN_CLICKED(IDC_BTN_FIND_REPLACE_OPTIONS, OnExpandOptionsGroup)

	ON_BN_CLICKED(IDC_BTN_FIND_NEXT, OnFindNext)
	ON_BN_CLICKED(IDC_BTN_REPLACE, OnReplace)
	ON_BN_CLICKED(IDC_BTN_REPLACE_ALL, OnReplaceAll)

	ON_BN_CLICKED(IDC_BTN_FIND_INSERT_SPECIAL, OnFindInsertSpecial)	/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
EVENTS_END

	BOOL 	OnInitDialog();
	BOOL 	OnReady();
	BOOL 	OnDestroy();
	BOOL 	OnHelp(int &nHelpID, int nIdCtrlFocus);
	BOOL 	OnClose();
	BOOL 	OnDlgResize(int nType, int cx, int cy);
	BOOL	OnActiveLayerChange();
	BOOL 	OnActivePageChange();
	BOOL	OnSelectionChange();
	BOOL 	OnPageDestroy(Page pg, DWORD dwCntrl);
	BOOL	OnRestoreSize(DWORD dwSizeInfo);		/// Kenny 09/18/2009 INIT_DIALOG_SIZE_NEEDED

	virtual int GetTotalWidth(bool bGetMin = false);
	virtual int GetTotalHeight(bool bGetMin = false);

	BOOL 	OnTabChange(Control ctrl);
	BOOL 	OnFindWhatEditChange(Control ctrl);
	BOOL 	OnReplaceWithEditChange(Control ctrl);	
	BOOL 	OnFindWhatSelChange(Control ctrl);
	BOOL 	OnConditionSelChange(Control ctrl);
	BOOL 	OnReplaceWithSelChange(Control ctrl);
	BOOL 	OnCheckPerformInSelectedRange(Control ctrl);
	BOOL 	OnCheckSetAsMissing(Control ctrl);
	BOOL 	OnCheckUseWildcards(Control ctrl);
	BOOL	OnCheckSkipLinkedCells(Control ctrl);	/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
	BOOL 	OnChangeDataType(Control ctrl);
	BOOL 	OnToleranceEditChange(Control ctrl);
	BOOL 	OnExpandOptionsGroup(Control ctrl);

	BOOL 	OnFindNext(Control ctrl);
	BOOL 	OnReplace(Control ctrl);
	BOOL 	OnReplaceAll(Control ctrl);
	BOOL	OnFindInsertSpecial(Control ctrl);	/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
protected:
	void	RearrangeControls(BOOL bRepaint = FALSE);
	void	AdjustTabControl(BOOL bRepaint = FALSE);
	/// Kenny 09/29/2009 IMPROVE_FIND_REPLACE_DLG_RESIZING_PROCESS
	void	InitContentOfControls();
	BOOL	InitLayoutHelper();
	/// End IMPROVE_FIND_REPLACE_DLG_RESIZING_PROCESS
	void	UpdateLookInComboLabels(int nSel = -1);
	void	UpdateFindReplaceHelperInfo();

	BOOL	IsOptionGroupExpanded() { return m_bIsOptionGroupExpanded; }
	void	ExpandOptionGroup(BOOL bExpand = TRUE, BOOL bRepaint = TRUE);
	void	GetOptionGroupBoundingRect(RECT& rect);

	void	ResizeDlgToFitControls(BOOL bRepaint = TRUE);	/// Kenny 09/18/2009 INIT_DIALOG_SIZE_NEEDED
private:
	int		getDataType();
	bool	isNumericType();
	bool	isActionReplace();
	// Show/Hide controls
	void	showHideControls();
	void	showHideOptionGroupCtrls();
	///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
	void	showHideCheckLabelRowsCtrl();
	///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
	void	showHideWarningMessageCtrl();	/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
	// Resizing controls
	void	rearrangeOptionGroup(BOOL bRepaint = TRUE);
	void	rearrangeBottomButtons(BOOL bRepaint = TRUE);
	void	rearrangeConditionFindwhatInsertBtn(BOOL bRepaint = TRUE);	/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
	// Update contents of controls
	void	onChangeDataType(bool bForceUpdate = false);
	/// Kenny 09/29/2009 IMPROVE_FIND_REPLACE_DLG_RESIZING_PROCESS
	void	initConditionCombo();

	void	updateInsertSymbolBtnStatus();	/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT

	enum {
		UPDATE_FIND_WHAT_COMBO_DROPPED_ITEMS			= 0x0001,
		UPDATE_REPLACE_WITH_COMBO_DROPPED_ITEMS			= 0x0002,
		UPDATE_CONDITION_COMBO_DROPPED_ITEMS			= 0x0004,
		UPDATE_LOOK_IN_COMBO_DROPPED_ITEMS				= 0x0008,
		UPDATE_ALL_COMBO_DROPPED_ITEMS					= 0xffff,
	};
	void	updateComboboxesToShowAllItems(int nComboboxes = UPDATE_ALL_COMBO_DROPPED_ITEMS);
	/// End IMPROVE_FIND_REPLACE_DLG_RESIZING_PROCESS
	
	/// Kenny 09/18/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	//string 	getComboText(ComboBox& ctrl);
	string 	getComboText(ComboBox& ctrl, bool bIsSelChanging = false);
	/// End QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	int 	getComboList(ComboBox& ctrl, vector<string>& vsList);
	void 	updateComboList(ComboBox& ctrl, LPCSTR lpcszSection);
	string 	getINIFileSectionName(LPCSTR lpcszSectionNameBase);
	void 	saveComboRecentList(ComboBox& ctrl, LPCSTR lpcszSection);
	void 	loadComboRecentList(ComboBox& ctrl, LPCSTR lpcszSection);
	
	bool 	isReadyToFind();
	bool 	isReadyToReplace();
	void 	updateBottomButtonsStatus();
	void	onUpdateCheckboxesStatus();

	bool	isPerformInSelectedRange();

	///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
	BOOL	isCheckLabelRows();
	BOOL	isColLabelSelected();
	///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
	
	void 	saveDataTypeToRegistry();
	void    loadDataTypeFromRegistry();

	void	saveConditionToRegistry();
	void	loadConditionFromRegistry();

	void	saveOptionGroupStatusToRegistry();
	void	loadOptionGroupStatusFromRegistry();
	
	// find next and replace relative
	/// Kenny 09/22/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	//uint	getBitwiseOptions();
	uint	getBitwiseOptions(string& strFindWhat, string& strReplaceWith);
	/// End QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	int		getLookInOptions();

	///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
	void	checkUpdateSelectionType(Datasheet& ds);
	///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
private:
	// Flags
	bool					m_bDeleteOnDestroy;
	int						m_nLastUsedDataType;
	bool					m_bLastTargetIsWks;
	bool					m_bIsOptionGroupExpanded;
	bool					m_bHasSelection;
	/// Kenny 09/18/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	bool					m_bIsFindWhatSelChanging;
	bool					m_bIsReplaceWithSelChanging;
	/// End QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	// Gui related
	TabControl 				m_topTab;
	ComboBox				m_comboFindWhat;
	ComboBox				m_comboCondition;
	ComboBox				m_comboReplaceWith;
	ComboBox				m_comboLookIn;
	Edit					m_edTolerance;
	ColorText				m_ctrlWarningMsg;	/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
	// Others
	CLayoutHelper			m_LayoutHelper;
	CFindReplaceHelper		m_FindReplaceHelper;

	vector<UINT>			m_vnOptionCheckboxesID;
	///------ Folger 11/04/09 FIND_REPLACE_DIALOG_MESS_UP_WHEN_FIRST_RUN
	vector<byte>			m_vbValues;
	///------ End FIND_REPLACE_DIALOG_MESS_UP_WHEN_FIRST_RUN
	///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
	int						m_nSelectionType;
	///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS

	/// Kenny 01/14/2010 FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
	// Note: see the function getBitwiseOptions for more detail about why this is necessary.
	enum GROUPCTRLINDEX
	{
		GROUPCTRLINDEX_IDC_CHECK_SKIP_LINKED_CELLS,
		GROUPCTRLINDEX_IDC_CHECK_PERFORM_IN_SELECTED_RANGE,
		GROUPCTRLINDEX_IDC_CHECK_MATCH_CASE,
		GROUPCTRLINDEX_IDC_CHECK_FULL_MATCH,
		GROUPCTRLINDEX_IDC_CHECK_USE_WILDCARDS,
		GROUPCTRLINDEX_IDC_CHECK_FIND_LABEL_ROWS,
		GROUPCTRLINDEX_IDC_CHECK_USE_ABSOLUTE_VAL,
		GROUPCTRLINDEX_IDC_CHECK_KEEP_SIGN,
		GROUPCTRLINDEX_IDC_CHECK_SET_AS_MISSING_VAL,
		GROUPCTRLINDEX_IDC_CHECK_SEARCH_UP,

		GROUPCTRLINDEX_SIZE
	};
	vector<bool>			m_vbOptionIsAvailable;

#define GROUPCTRL_ID_FROM_INDEX(_index)							m_vnOptionCheckboxesID[ _index ]
#define GROUPCTRL_INDEX_FROM_ID(_ctrlid)						GROUPCTRLINDEX_##_ctrlid
#define GROUPCTRL_AVAILABLE(_ctrlid)							m_vbOptionIsAvailable[ GROUPCTRL_INDEX_FROM_ID(_ctrlid) ]
#define SET_GROUPCTRL_VISIBLE_IF_AVAILABLE_BYID(_ctrlid)		do{ GetItem(_ctrlid).Visible = GROUPCTRL_AVAILABLE(_ctrlid); }while(0)
#define SET_GROUPCTRL_VISIBLE_IF_AVAILABLE_BYINDEX(_index)		do{ GetItem( GROUPCTRL_ID_FROM_INDEX(_index) ).Visible = m_vbOptionIsAvailable[_index]; }while(0)
	/// End FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
};

/*----------------------------------------------------------------------------*/
/* Constructors/Destructors of CFindAndReplaceDlg
/*----------------------------------------------------------------------------*/

CFindAndReplaceDlg::CFindAndReplaceDlg(BOOL bDeleteOnDestroy /*= FALSE*/)
	: ResizeDialog(IDD_FIND_AND_REPLACE, "ODlg8")
{
	m_bDeleteOnDestroy = bDeleteOnDestroy;
	m_bIsOptionGroupExpanded = false;
	m_bHasSelection = false;
	/// Kenny 09/18/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	m_bIsFindWhatSelChanging = false;
	m_bIsReplaceWithSelChanging = false;
	/// End QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS

	///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
	m_nSelectionType = WKS_SEL_NONE;
	///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS

	/// Kenny 01/14/2010 FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
	m_vbOptionIsAvailable.SetSize(GROUPCTRLINDEX_SIZE);
	/// End FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
}

CFindAndReplaceDlg::~CFindAndReplaceDlg()
{
	
}

/*----------------------------------------------------------------------------*/
/* Event handlers of CFindAndReplaceDlg
/*----------------------------------------------------------------------------*/

BOOL CFindAndReplaceDlg::OnInitDialog()
{
	ResizeDialog::OnInitDialog(0, STR_DLG_NAME);
	Text = STR_DLG_NAME;

	m_topTab = GetItem(IDC_TAB_FIND_REPLACE);
	m_topTab.InsertItem(TAB_FIND, STR_TAB_FIND);
	m_topTab.InsertItem(TAB_REPLACE, STR_TAB_REPLACE);

	m_comboFindWhat = GetItem(IDC_COMBO_FIND_WHAT);
	m_comboCondition = GetItem(IDC_COMBO_CONDITION);
	m_comboReplaceWith = GetItem(IDC_COMBO_REPLACE_WITH);
	m_comboLookIn = GetItem(IDC_COMBO_LOOK_IN);
	m_edTolerance = GetItem(IDC_EDIT_TOLERANCE);

	m_bLastTargetIsWks = EXIST_WKS == _get_active_page_type();

	m_FindReplaceHelper.m_pParentWnd = this;

	// init the option separator
	move_control_by_id(*this, IDC_STATIC_OPTION_SEPARATOR, -1, -1, -1, 1, MC_SIZE_HEIGHT);

	// doing, hide controls temp
	vector<UINT> vnCtrlIDs = 
	{
		IDC_BTN_ADD_CONDITION,
		IDC_BTN_CONDITION_AND,
		IDC_BTN_CONDITION_OR,
		IDC_BTN_CONDITION_NOT,
		IDC_BTN_CONDITION_LEFT_PARENTHESIS,
		IDC_BTN_CONDITION_RIGHT_PARENTHESIS
	}
	for (int ii = 0; ii < vnCtrlIDs.GetSize(); ++ii)
	{
		GetItem( vnCtrlIDs[ii] ).Visible = FALSE;
	}

	/// Kenny 09/29/2009 IMPROVE_FIND_REPLACE_DLG_RESIZING_PROCESS
	InitContentOfControls();

	InitLayoutHelper();

	AdjustTabControl(TRUE);
	/// End IMPROVE_FIND_REPLACE_DLG_RESIZING_PROCESS

	/// Kenny 04/02/2010 CHECK_BOXES_STATUS_FAILED_TO_GET_INIT_ON_REOPEN_DLG
	DWORD dwVal;
	dlg_load_registry(STR_DLG_NAME, OPTION_GROUP_EXPAND_REG_NAME, dwVal, 1);
	ExpandOptionGroup(dwVal);
	/// End CHECK_BOXES_STATUS_FAILED_TO_GET_INIT_ON_REOPEN_DLG

	// Perform the layout.
	RearrangeControls(TRUE);

	loadOptionGroupStatusFromRegistry();	/// Kenny 04/01/2010 CHECK_BOXES_STATUS_FAILED_TO_GET_INIT_ON_REOPEN_DLG

	// Align the data type related controls.
	CLayoutTool layoutTool(*this);
	layoutTool.m_nAlignOption = ALIGN_VERTI_CENTER;
	layoutTool.m_szGap.cx = GetControlGap();
	vector<UINT> vnCtrlIDs1 = 
	{
		IDC_STATIC_DATA_TYPE,
		IDC_RADIO_DATA_TYPE_NUMERIC,
		IDC_RADIO_DATA_TYPE_STRING
	};
	layoutTool.PerformLayout(vnCtrlIDs1);

	onChangeDataType();
	OnSelectionChange();

	return TRUE;
}

BOOL CFindAndReplaceDlg::OnReady()
{
	SetInitReady();
	ResizeDlgToFitControls(TRUE);	/// Kenny 09/18/2009 INIT_DIALOG_SIZE_NEEDED
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnDestroy()
{
	saveDataTypeToRegistry();
	saveConditionToRegistry();
	saveOptionGroupStatusToRegistry();
	
	ResizeDialog::OnDestroy();
	if(m_bDeleteOnDestroy)
	{
		delete this;
		s_pCFindAndReplaceDlg = NULL;
	}
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnHelp(int &nHelpID, int nIdCtrlFocus)
{
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnClose()
{
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnDlgResize(int nType, int cx, int cy)
{
	if(!IsInitReady())
		return FALSE;

	// Since the value of the combobox may be changed (by OS) when we resize it,
	// so we have to backup the old value for restoring later
	const string strFindWhatOldVal		= m_comboFindWhat.Text;
	const string strReplaceWithOldVal	= m_comboReplaceWith.Text;

	//MoveControlsHelper _temp(this);

	m_LayoutHelper.PerformLayout(cx, cy);

	updateComboboxesToShowAllItems();	/// Kenny 09/29/2009 IMPROVE_DLG_RESIZING_PROCESS

	InvalidateRect(GetSafeHwnd(), NULL, TRUE);

	// restore the old value
	m_comboFindWhat.Text	= strFindWhatOldVal;
	m_comboReplaceWith.Text	= strReplaceWithOldVal;
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnActiveLayerChange()
{
	const bool bCanWorkOnActiveSheet = _can_do_find_or_replace_on_active_sheet();
	Visible = bCanWorkOnActiveSheet;
	OnSelectionChange();	/// Kenny 07/15/2009 DETECT_MULTI_SELECTION_TO_SHOW_HIDE_RELATED_CHECKBOX
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnActivePageChange()
{
	const bool bCanWorkOnActivePage = _can_do_find_or_replace_on_active_sheet();
	Visible = bCanWorkOnActivePage;
	if ( bCanWorkOnActivePage )
	{
		bool bTargetIsWks = EXIST_WKS == _get_active_page_type();
		if ( bTargetIsWks != m_bLastTargetIsWks )
		{
			UpdateLookInComboLabels();
			onChangeDataType(true);
			m_bLastTargetIsWks = bTargetIsWks;
		}
		OnSelectionChange();
		updateInsertSymbolBtnStatus();	/// Kenny 10/10/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
	}
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnSelectionChange()
{
	Datasheet ds;
	DataRange dr;
	/// Iris 7/14/2009 QA80-13941 SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
	//bool bHasSelection = _get_active_sheet_range(ds, NULL, &dr);
	///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
	//bool bHasSelection = get_active_sheet_range(ds, NULL, &dr);
	bool bHasSelection = get_active_sheet_range(ds, NULL, &dr, TRUE);
	///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
	///end SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
	if ( bHasSelection )
	{
		/// Kenny 07/15/2009 DETECT_MULTI_SELECTION_TO_SHOW_HIDE_RELATED_CHECKBOX
		/*bHasSelection = false;
		int r1, c1, r2, c2;
		Datasheet ds;
		if ( dr.GetRange(0, r1, c1, r2, c2, ds) )
		{
			int nCols = abs(c2-c1)+1;
			int nRows = abs(r2-r1)+1;
			if ( nCols > 1 || nRows > 1 )
			{
				bHasSelection = true;
			}
		}*/
		bHasSelection = _get_range_cells_count(dr) > 1;
		/// End DETECT_MULTI_SELECTION_TO_SHOW_HIDE_RELATED_CHECKBOX
	}
	///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
	//if ( m_bHasSelection != bHasSelection )
	//{
		//m_bHasSelection = bHasSelection;
		//RearrangeControls(TRUE);
	//}
	
	int		nSelectionTypeOld = m_nSelectionType;
	checkUpdateSelectionType(ds);
	if ( m_bHasSelection != bHasSelection || nSelectionTypeOld != m_nSelectionType )
	{
		m_bHasSelection = bHasSelection;
		RearrangeControls(TRUE);
	}
	///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnPageDestroy( Page pg, DWORD dwCntrl )
{
	Page pgActive = Project.Pages();
	if ( !pgActive || 0 == pg.GetName().CompareNoCase(pgActive.GetName())  )
		Visible = FALSE;
	return TRUE;
}

/// Kenny 09/18/2009 INIT_DIALOG_SIZE_NEEDED
BOOL CFindAndReplaceDlg::OnRestoreSize(DWORD dwSizeInfo)
{
	void * p = (void*)dwSizeInfo;
	DLGSIZEINFO *pSz = (DLGSIZEINFO*)p;

	lstrcpyn(pSz->szDialogName, STR_DLG_NAME_E, MAXLINE);
	pSz->top = -1;
	pSz->left = -1;
	pSz->width = GetTotalWidth(true);
	pSz->height = GetTotalHeight(true);
	return TRUE;
}
/// End INIT_DIALOG_SIZE_NEEDED

//virtual
int CFindAndReplaceDlg::GetTotalWidth(bool bGetMin/* = false*/)
{
	if(bGetMin)
	{
		RECT rtDlg;
		GetWindowRect(&rtDlg);
		const int nDlgWidthWithFrame = RECT_WIDTH(rtDlg);
		GetClientRect(&rtDlg);
		const int nDlgWidthClient = RECT_WIDTH(rtDlg);
		const int nDlgFrameWidth = nDlgWidthWithFrame - nDlgWidthClient;

		int nWidth;
		RECT rect;
		GetControlClientRect(IDC_STATIC_FIND_WHAT, rect);
		nWidth = rect.right + GetControlGap()*4;

		GetControlClientRect(IDC_RADIO_DATA_TYPE_STRING, rect);
		nWidth = max(nWidth, rect.right + GetControlGap()*4);

		GetOptionGroupBoundingRect(rect);
		nWidth = max(nWidth, rect.right + GetControlGap() * 5);

		GetControlClientRect(IDC_BTN_FIND_NEXT, rect);
		const int nBottomBtnsLeft = rect.left;

		GetControlClientRect(IDCANCEL, rect);
		const int nBottomBtnsTotalWidth = rect.right - nBottomBtnsLeft;
		const int nBottomBtnsMinWidth = nBottomBtnsTotalWidth + GetControlGap() * 3;

		nWidth = max(nWidth, nBottomBtnsMinWidth);

		return nWidth + nDlgFrameWidth / 2;
	}
	return ResizeDialog::GetTotalWidth(bGetMin);
}

//virtual
int CFindAndReplaceDlg::GetTotalHeight( bool bGetMin /*= false*/ )
{
	if(bGetMin)
	{
		Control btnCancel = GetItem(IDCANCEL);
		RECT rtBtn;
		GetClientRect(btnCancel, rtBtn);

		RECT rtDlg;
		GetWindowRect(&rtDlg);
		const int nDlgHeightWithTitle = RECT_HEIGHT(rtDlg);
		GetClientRect(&rtDlg);
		const int nDlgHeightClient = RECT_HEIGHT(rtDlg);
		int nHeight = nDlgHeightWithTitle - nDlgHeightClient + rtBtn.bottom + GetControlGap();
		return nHeight;
	}
	return ResizeDialog::GetTotalHeight(bGetMin);
}

/*----------------------------------------------------------------------------*/
/* Control event handler
/*----------------------------------------------------------------------------*/

BOOL CFindAndReplaceDlg::OnTabChange( Control ctrl )
{
	RearrangeControls(TRUE);
	updateInsertSymbolBtnStatus();	/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnFindWhatEditChange( Control ctrl )
{
	updateBottomButtonsStatus();
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnReplaceWithEditChange( Control ctrl )
{
	updateBottomButtonsStatus();
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnFindWhatSelChange( Control ctrl )
{
	m_bIsFindWhatSelChanging = true;	/// Kenny 09/18/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	updateBottomButtonsStatus();
	m_bIsFindWhatSelChanging = false;	/// Kenny 09/18/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnConditionSelChange( Control ctrl )
{
	if ( IsOptionGroupExpanded() )
	{
		/// Kenny 09/29/2009 IMPROVE_DLG_RESIZING_PROCESS
		//RearrangeControls(TRUE);
		showHideControls();
		rearrangeOptionGroup();
		AdjustTabControl();
		rearrangeBottomButtons();
		m_LayoutHelper.UpdateAllCtrlRect();
		updateBottomButtonsStatus();
		ResizeDlgToFitControls();
		/// End IMPROVE_DLG_RESIZING_PROCESS
	}
	updateBottomButtonsStatus();	/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnReplaceWithSelChange( Control ctrl )
{
	m_bIsReplaceWithSelChanging = true;	/// Kenny 09/18/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	updateBottomButtonsStatus();
	m_bIsReplaceWithSelChanging = false;	/// Kenny 09/18/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnCheckPerformInSelectedRange( Control ctrl )
{
	onUpdateCheckboxesStatus();
	///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
	RearrangeControls(TRUE);
	///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnCheckSetAsMissing( Control ctrl )
{
	updateBottomButtonsStatus();
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnCheckUseWildcards(Control ctrl)
{
	onUpdateCheckboxesStatus();
	return TRUE;
}

/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
BOOL CFindAndReplaceDlg::OnCheckSkipLinkedCells( Control ctrl )
{
	showHideWarningMessageCtrl();
	/// Kenny 08/09/2010 ORG-230-P1 FIND_REPLACE_DLG_CLOSE_BUTTON_FLICKER_WHEN_CLICK_SKIP_LINKED_CELLS_BUTTON
	//rearrangeBottomButtons();
	rearrangeBottomButtons(false);
	/// End ORG-230-P1 FIND_REPLACE_DLG_CLOSE_BUTTON_FLICKER_WHEN_CLICK_SKIP_LINKED_CELLS_BUTTON
	m_LayoutHelper.UpdateAllCtrlRect();
	ResizeDlgToFitControls();
	return TRUE;
}
/// End QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED

BOOL CFindAndReplaceDlg::OnChangeDataType( Control ctrl )
{
	onChangeDataType();
	updateInsertSymbolBtnStatus();	/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnToleranceEditChange( Control ctrl )
{
	updateBottomButtonsStatus();
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnExpandOptionsGroup( Control ctrl )
{
	const BOOL bIsGroupExpanded = IsOptionGroupExpanded();
	ExpandOptionGroup(!bIsGroupExpanded);
	RearrangeControls(TRUE);
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnFindNext( Control ctrl )
{
	UpdateFindReplaceHelperInfo();
	if ( m_FindReplaceHelper.FindNext() )
	{
		updateComboList(m_comboFindWhat, FIND_WHAT_RECENT_LIST_SECTION);
		updateComboboxesToShowAllItems(UPDATE_FIND_WHAT_COMBO_DROPPED_ITEMS);	/// Kenny 09/30/2009 IMPROVE_DLG_RESIZING_PROCESS
	}
	return TRUE;
}

BOOL CFindAndReplaceDlg::OnReplace( Control ctrl )
{
	UpdateFindReplaceHelperInfo();
	BOOL bRet = m_FindReplaceHelper.Replace();
	if ( bRet )
	{
		updateComboList(m_comboFindWhat, FIND_WHAT_RECENT_LIST_SECTION);
		updateComboList(m_comboReplaceWith, REPLACE_WITH_RECENT_LIST_SECTION);
		updateComboboxesToShowAllItems(UPDATE_FIND_WHAT_COMBO_DROPPED_ITEMS|UPDATE_REPLACE_WITH_COMBO_DROPPED_ITEMS);	/// Kenny 09/30/2009 IMPROVE_DLG_RESIZING_PROCESS
	}
	return FALSE;
}

BOOL CFindAndReplaceDlg::OnReplaceAll( Control ctrl )
{
	UpdateFindReplaceHelperInfo();
	int nCount = m_FindReplaceHelper.ReplaceAll();
	if ( nCount > 0 )
	{
		updateComboList(m_comboFindWhat, FIND_WHAT_RECENT_LIST_SECTION);
		updateComboList(m_comboReplaceWith, REPLACE_WITH_RECENT_LIST_SECTION);
		updateComboboxesToShowAllItems(UPDATE_FIND_WHAT_COMBO_DROPPED_ITEMS|UPDATE_REPLACE_WITH_COMBO_DROPPED_ITEMS);	/// Kenny 09/30/2009 IMPROVE_DLG_RESIZING_PROCESS
	}
	return TRUE;
}

/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
BOOL CFindAndReplaceDlg::OnFindInsertSpecial(Control ctrl)
{
	vector<int> vnIDs;
	vector<string> vsTexts;
	CInsertSpecialMenu myMenu;
	if ( isNumericType() )
	{
		vnIDs.Add(INSERT_SPECIAL_MENU_MISSING_ONLY);
		vnIDs.Add(INSERT_SPECIAL_MENU_MISSING_BLANK_TEXT);
		vsTexts.Add(STR_INSERT_MISSING_ONLY);
		vsTexts.Add(STR_INSERT_MISSING_BLANK_TEXT);
	}
	else
	{
		vnIDs.Add(INSERT_SPECIAL_MENU_WILDCARD_ZERO_MORE_CHAR);
		vnIDs.Add(INSERT_SPECIAL_MENU_WILDCARD_SINGLE_CHAR);
		vsTexts.Add(STR_INSERT_WILDCARD_ZERO_MORE_CHAR);
		vsTexts.Add(STR_INSERT_WILDCARD_SINGLE_CHAR);
	}
	myMenu.Init(vnIDs, vsTexts);

	int nCmd = 0;
	RECT 				rr;
	if ( !ctrl )
		return FALSE;
	ctrl.GetClientRect(&rr);
	ctrl.ClientToScreen(&rr);
	myMenu.TrackPopupMenu(0, rr.right, rr.top, GetSafeHwnd(), &nCmd);

	switch (nCmd)
	{
	case INSERT_SPECIAL_MENU_MISSING_ONLY:
		m_comboFindWhat.Text = "--";
		break;
	case INSERT_SPECIAL_MENU_MISSING_BLANK_TEXT:
		m_comboFindWhat.Text = "-";
		break;
	case INSERT_SPECIAL_MENU_WILDCARD_ZERO_MORE_CHAR:
		m_comboFindWhat.Text += "*";
		break;
	case INSERT_SPECIAL_MENU_WILDCARD_SINGLE_CHAR:
		m_comboFindWhat.Text += "?";
		break;
	default:
		break;
	}
	updateBottomButtonsStatus();
	return TRUE;
}
/// End QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT

/*----------------------------------------------------------------------------*/
/* Protected functions(interfaces) of CFindAndReplaceDlg
/*----------------------------------------------------------------------------*/

void CFindAndReplaceDlg::RearrangeControls(BOOL bRepaint /*= FALSE*/)
{
	// Since the value of the combobox may be changed (by OS) when we resize it,
	// so we have to backup the old value for restoring later
	const string strFindWhatOldVal = m_comboFindWhat.Text;

	// Switch the visible state of related controls.
	showHideControls();

	// Left-align the controls.
	CLayoutTool layoutTool(*this);

	layoutTool.m_nAlignOption = ALIGN_LEFT;
	/// Kenny 09/29/2009 IMPROVE_FIND_REPLACE_DLG_RESIZING_PROCESS
	//layoutTool.m_ptBegin.x = GetControlGap()*3;
	//layoutTool.m_ptBegin.y = GetControlGap()*9;
	RECT rtTab;
	m_topTab.GetWindowRect(&rtTab);
	ScreenToClient(&rtTab);
	m_topTab.AdjustRect(FALSE, &rtTab);
	layoutTool.m_ptBegin.x = rtTab.left + GetControlGap();
	layoutTool.m_ptBegin.y = rtTab.top + GetControlGap();
	/// End IMPROVE_FIND_REPLACE_DLG_RESIZING_PROCESS
	layoutTool.m_szGap.cy = GetControlGap();
	vector<UINT> vnCtrlIDs1 = 
	{
		IDC_STATIC_DATA_TYPE,

		IDC_STATIC_FIND_WHAT,
		IDC_COMBO_FIND_WHAT,

		IDC_STATIC_CONDITION,
		IDC_COMBO_CONDITION,

		IDC_STATIC_REPLACE_WITH,
		IDC_COMBO_REPLACE_WITH,

		IDC_STATIC_LOOK_IN,
		IDC_COMBO_LOOK_IN,

		IDC_BTN_FIND_REPLACE_OPTIONS
	};

	// Hide the "find what" related controls to avoid moving/resizng them when the data type is numeric
	const bool bIsNumericType = isNumericType();
	if (bIsNumericType)
	{
		GetItem(IDC_STATIC_FIND_WHAT).Visible = FALSE;
		m_comboFindWhat.Visible = FALSE;
	}

	layoutTool.PerformLayout(vnCtrlIDs1, bRepaint);

	if (bIsNumericType)
	{
		// Show the previously hidden controls
		GetItem(IDC_STATIC_FIND_WHAT).Visible = TRUE;
		m_comboFindWhat.Visible = TRUE;

		// Make the Condition combobox and its static control to have the same width
		layoutTool.Reset();
		layoutTool.m_nMakeSameSizeOption = MSS_SAME_WIDTH;

		vector<UINT> vnCtrlIDs = 
		{
			IDC_STATIC_CONDITION,
			IDC_COMBO_CONDITION
		};
		layoutTool.PerformLayout(vnCtrlIDs, bRepaint);

		// Top-align the Find what and Condition combobox
		/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
// 		layoutTool.Reset();
// 		layoutTool.m_nAlignOption = ALIGN_TOP;
// 		layoutTool.m_nMakeSameSizeOption = MSS_SAME_HEIGHT;
// 		layoutTool.m_szGap.cx = GetControlGap();

// 		vnCtrlIDs[0] = IDC_COMBO_CONDITION;
// 		vnCtrlIDs[1] = IDC_COMBO_FIND_WHAT;
// 		layoutTool.PerformLayout(vnCtrlIDs, bRepaint);
		/// End QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT

		// Top-align the Find what and Condition static
		layoutTool.Reset();
		layoutTool.m_nAlignOption = ALIGN_TOP;

		vnCtrlIDs[0] = IDC_STATIC_CONDITION;
		vnCtrlIDs[1] = IDC_STATIC_FIND_WHAT;
		layoutTool.PerformLayout(vnCtrlIDs, bRepaint);

		// Left-align the Find what combobox and its static control
		layoutTool.Reset();
		layoutTool.m_nAlignOption = ALIGN_LEFT;
		vnCtrlIDs[0] = IDC_COMBO_FIND_WHAT;
		layoutTool.PerformLayout(vnCtrlIDs, bRepaint);
	}

	rearrangeConditionFindwhatInsertBtn(bRepaint);	/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT

	rearrangeOptionGroup(bRepaint);
	rearrangeBottomButtons(bRepaint);
	updateBottomButtonsStatus();

	m_LayoutHelper.UpdateAllCtrlRect();
	OnDlgResize(0, GetDlgExtent(false), GetDlgExtent(true));

	/// Kenny 09/18/2009 INIT_DIALOG_SIZE_NEEDED
	ResizeDlgToFitControls(bRepaint);
// 	RECT rtDlg;
// 	GetWindowRect(&rtDlg);
// 	const int nMinWidth = GetTotalWidth(true);
// 	const int nMinHeight = GetTotalHeight(true);
// 	if ( RECT_WIDTH(rtDlg) < nMinWidth )
// 	{
// 		rtDlg.right = rtDlg.left + nMinWidth;
// 	}
// 	rtDlg.bottom = rtDlg.top + nMinHeight;
// 	MoveWindow(&rtDlg, bRepaint);
	/// End INIT_DIALOG_SIZE_NEEDED

	InvalidateRect(GetSafeHwnd(), NULL, TRUE);

	m_comboFindWhat.Text = strFindWhatOldVal;	// restore the old value
}

/// Kenny 09/29/2009 IMPROVE_FIND_REPLACE_DLG_RESIZING_PROCESS
void CFindAndReplaceDlg::AdjustTabControl( BOOL bRepaint /*= FALSE*/ )
{
	RECT rtTab;
	GetOptionGroupBoundingRect(rtTab);

	rtTab.left = GetControlGap();
	rtTab.top = GetControlGap();
	rtTab.right = GetDlgExtent(false) - GetControlGap();
	rtTab.bottom += 3*GetControlGap();

	m_topTab.MoveWindow(&rtTab, bRepaint);
	//m_topTab.AdjustRect(FALSE, &rtTab);
}

void CFindAndReplaceDlg::InitContentOfControls()
{
	// Init content only, no resizing here

	/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
	vector<string> vsBtnTips(1);
	vsBtnTips[0] = STR_TIPS_INSERT_SPECIAL_SYMBOL;
	BitmapRadioButton btnInsert = GetItem( IDC_BTN_FIND_INSERT_SPECIAL );
	btnInsert.Init(1, IDB_DROP_DOWN_UP, 16, vsBtnTips);
	/// End QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT

	/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
	m_ctrlWarningMsg.CreateControl( GetDlgItem(IDC_STATIC_WARNING_MSG).GetSafeHwnd() );
	string strText;
	ocu_load_err_msg_str(IDS_LINK_BROKEN_ON_REPLACE, &strText);
	m_ctrlWarningMsg.Text = strText;
	m_ctrlWarningMsg.SetTxtBlink( COLOR_RED, COLOR_BLACK );
	m_ctrlWarningMsg.BlinkText( COLORTEXTBLINK_DEFAULT );
	m_ctrlWarningMsg.SetTxtColor( color_index_to_rgb(SYSCOLOR_RED) );
	/// End QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED

	// init Data Type
	loadDataTypeFromRegistry();

	// init condition control
	initConditionCombo();

	// init Look in control
	UpdateLookInComboLabels(0);

	// init items of find what & replace combobox from ini
	loadComboRecentList( m_comboFindWhat, FIND_WHAT_RECENT_LIST_SECTION );
	loadComboRecentList( m_comboReplaceWith, REPLACE_WITH_RECENT_LIST_SECTION );

	// init find what text
	UpdateFindWhatToCurrentCellValue();

	// init the option controls group
	// Kenny: Make sure the order is corresponding to enum GROUPCTRLINDEX!!
	vector<UINT> vnGroupCtrlIDs = 
	{
		IDC_CHECK_SKIP_LINKED_CELLS,
		IDC_CHECK_PERFORM_IN_SELECTED_RANGE,

		IDC_CHECK_MATCH_CASE,
		IDC_CHECK_FULL_MATCH,
		IDC_CHECK_USE_WILDCARDS,
		IDC_CHECK_FIND_LABEL_ROWS,		///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS

		IDC_CHECK_USE_ABSOLUTE_VAL,
		IDC_CHECK_KEEP_SIGN,
		IDC_CHECK_SET_AS_MISSING_VAL,

		IDC_CHECK_SEARCH_UP
	};

	///------ Folger 11/04/09 FIND_REPLACE_DIALOG_MESS_UP_WHEN_FIRST_RUN
	vector<byte>	vbValues = { 1	/// IDC_CHECK_SKIP_LINKED_CELLS
		, 1		/// IDC_CHECK_PERFORM_IN_SELECTED_RANGE

		, 0		/// IDC_CHECK_MATCH_CASE
		, 0		/// IDC_CHECK_FULL_MATCH
		, 0		/// IDC_CHECK_USE_WILDCARDS
		, 0		/// IDC_CHECK_FIND_LABEL_ROWS

		, 0		/// IDC_CHECK_USE_ABSOLUTE_VAL
		, 0		/// IDC_CHECK_KEEP_SIGN
		, 0		/// IDC_CHECK_SET_AS_MISSING_VAL

		, 0		/// IDC_CHECK_SEARCH_UP
	};
	///------ End FIND_REPLACE_DIALOG_MESS_UP_WHEN_FIRST_RUN
	m_vnOptionCheckboxesID = vnGroupCtrlIDs;
	///------ Folger 11/04/09 FIND_REPLACE_DIALOG_MESS_UP_WHEN_FIRST_RUN
	m_vbValues = vbValues;
	///------ End FIND_REPLACE_DIALOG_MESS_UP_WHEN_FIRST_RUN
	//loadOptionGroupStatusFromRegistry();	/// Kenny 04/02/2010 CHECK_BOXES_STATUS_FAILED_TO_GET_INIT_ON_REOPEN_DLG
}

BOOL CFindAndReplaceDlg::InitLayoutHelper()
{
	// Anchor the controls, make the width of them grows with the dialog
	m_LayoutHelper.Init(*this);
	m_LayoutHelper.RemoveAll();

	CLayoutOption layoutOption;

	vector<int> vnCtrlIDs1 = {
 		/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
//  		IDC_COMBO_FIND_WHAT
//  		, IDC_COMBO_REPLACE_WITH
		IDC_COMBO_REPLACE_WITH
 		/// End QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
		, IDC_COMBO_LOOK_IN
		, IDC_GROUPBOX_FIND_OPTIONS
		, IDC_STATIC_OPTION_SEPARATOR
	};
	layoutOption.SetOption(LOT_LEFT_OFFSET, -1 );
	layoutOption.SetOption(LOT_RIGHT_OFFSET, GetControlGap()*3 );

	BOOL bRet = m_LayoutHelper.Add(vnCtrlIDs1, layoutOption);

	layoutOption.SetOption(LOT_RIGHT_OFFSET, GetControlGap() );
	bRet &= m_LayoutHelper.Add(IDC_TAB_FIND_REPLACE, layoutOption);
	
	bRet &= m_LayoutHelper.Add(IDC_STATIC_WARNING_MSG, layoutOption);	/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED

	/// Kenny 12/28/2009 FIND_REPLACE_DLG_SHOWN_WITH_UGLY_BK_COLOR
	layoutOption.SetOption(LOT_RIGHT_OFFSET, -1);
	bRet &= m_LayoutHelper.Add(IDC_TAB_BACK_PANEL, layoutOption);
	/// End FIND_REPLACE_DLG_SHOWN_WITH_UGLY_BK_COLOR

	// Anchor the bottom buttons, place them onto the rightmost
	vector<int> vnCtrlIDs2 = {
		IDC_BTN_FIND_NEXT
		, IDC_BTN_REPLACE
		, IDC_BTN_REPLACE_ALL
		, IDCANCEL
	};
	layoutOption.Reset();
	layoutOption.SetOption(LOT_RIGHT_OFFSET, -1);
	bRet &= m_LayoutHelper.Add(vnCtrlIDs2, layoutOption);

	/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
	int nRightEdgeMargin = GetControlGap() * 3;
	layoutOption.Reset();
	layoutOption.SetOption(LOT_RIGHT_OFFSET, nRightEdgeMargin);
	bRet &= m_LayoutHelper.Add(IDC_BTN_FIND_INSERT_SPECIAL, layoutOption);

	layoutOption.Reset();
	layoutOption.SetOption(LOT_LEFT_OFFSET, -1 );
	
	if ( GetItem(IDC_BTN_FIND_INSERT_SPECIAL).Visible )
	{
		RECT rtBtn;
		GetControlClientRect(IDC_BTN_FIND_INSERT_SPECIAL, rtBtn);
		nRightEdgeMargin += RECT_WIDTH(rtBtn) + GetControlGap();
	}
	layoutOption.SetOption(LOT_RIGHT_OFFSET, nRightEdgeMargin );
	bRet &= m_LayoutHelper.Add(IDC_COMBO_FIND_WHAT, layoutOption);
	/// End QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT

	ASSERT(bRet);
	return bRet;
}
/// End IMPROVE_FIND_REPLACE_DLG_RESIZING_PROCESS

void CFindAndReplaceDlg::UpdateLookInComboLabels( int nSel /*= -1*/ )
{
	const bool bWksType = EXIST_WKS == _get_active_page_type();
	const int nCurSel = m_comboLookIn.GetCurSel();
	m_comboLookIn.ResetContent();

	string strContent;

	if ( !bWksType )
	{
		strContent.Format(STR_LOOK_IN_ACTIVE_OBJECT_FORMAT, STR_MATRIXOBJECT_TYPE_NAME);
		m_comboLookIn.AddString( strContent );
	}
	strContent.Format(STR_LOOK_IN_ACTIVE_OBJECT_FORMAT, bWksType ? STR_WORKSHEET_TYPE_NAME : STR_MATRIXSHEET_TYPE_NAME);
	m_comboLookIn.AddString( strContent );
	strContent.Format(STR_LOOK_IN_ACTIVE_OBJECT_FORMAT, bWksType ? STR_WORKBOOK_TYPE_NAME : STR_MATRIXBOOK_TYPE_NAME);
	m_comboLookIn.AddString( strContent );
	strContent.Format(STR_LOOK_IN_ALL_BOOKS_IN_ACTIVE_FOLDER_FORMAT, bWksType ? STR_WORKBOOK_TYPE_NAME : STR_MATRIXBOOK_TYPE_NAME);
	m_comboLookIn.AddString( strContent );
	strContent.Format(STR_LOOK_IN_ALL_BOOKS_IN_ACTIVE_FOLDER_RECURSIVE_FORMAT, bWksType ? STR_WORKBOOK_TYPE_NAME : STR_MATRIXBOOK_TYPE_NAME);
	m_comboLookIn.AddString( strContent );
	strContent.Format(STR_LOOK_IN_ALL_BOOKS_IN_ACTIVE_FOLDER_OPEN_FORMAT, bWksType ? STR_WORKBOOK_TYPE_NAME : STR_MATRIXBOOK_TYPE_NAME);
	m_comboLookIn.AddString( strContent );
	strContent.Format(STR_LOOK_IN_ALL_BOOKS_IN_PROJECT_FORMAT, bWksType ? STR_WORKBOOK_TYPE_NAME : STR_MATRIXBOOK_TYPE_NAME);
	m_comboLookIn.AddString( strContent );

	// These following codes may look odd, but we want to always try to keep the look-in level when switching between workbook and matrix
	bool bTargetIsWks = EXIST_WKS == _get_active_page_type();
	int nSelOffset = 0;
	if ( bTargetIsWks != m_bLastTargetIsWks )
	{
		if ( bTargetIsWks && nCurSel > 0)
			nSelOffset = -1;
		else
			nSelOffset = 1;
	}
	m_comboLookIn.SetCurSel(nSel >= 0 ? nSel : nCurSel + nSelOffset);
}

void CFindAndReplaceDlg::UpdateFindReplaceHelperInfo()
{
	m_FindReplaceHelper.m_strFindWhat = getComboText(m_comboFindWhat);
	m_FindReplaceHelper.m_strReplaceWith = getComboText(m_comboReplaceWith);
	m_FindReplaceHelper.m_nLookInRange = getLookInOptions();
	m_FindReplaceHelper.m_bPerformInSelectedRange = isPerformInSelectedRange();
	/// Kenny 09/22/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	//m_FindReplaceHelper.m_nBitwiseOptions = getBitwiseOptions();
	m_FindReplaceHelper.m_nBitwiseOptions = getBitwiseOptions(m_FindReplaceHelper.m_strFindWhat, m_FindReplaceHelper.m_strReplaceWith);
	/// End QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	
	const string strTolerance = m_edTolerance.Text;
	m_FindReplaceHelper.m_dTolerance = strTolerance.IsEmpty() ? DEFAULT_TOLERANCE_VALUE : atof(strTolerance);
	m_FindReplaceHelper.m_bIsNumericType = isNumericType();
}

void CFindAndReplaceDlg::ExpandOptionGroup( BOOL bExpand /*= TRUE*/, BOOL bRepaint /*= TRUE*/ )
{
	Control ctrlGroupBox = GetItem(IDC_GROUPBOX_FIND_OPTIONS);
	Button btnOption = GetItem(IDC_BTN_FIND_REPLACE_OPTIONS);
	Control ctrlOptionSeparator = GetItem(IDC_STATIC_OPTION_SEPARATOR);

	ctrlGroupBox.Visible = bExpand;
	btnOption.Text = bExpand ? "-" : "+";
	ctrlOptionSeparator.Visible = !bExpand;

	m_bIsOptionGroupExpanded = bExpand;

	rearrangeOptionGroup(bRepaint);
}

void CFindAndReplaceDlg::GetOptionGroupBoundingRect( RECT& rectBound )
{
	RECT rtCtrl;
	GetControlClientRect(IDC_BTN_FIND_REPLACE_OPTIONS, rectBound);
	GetControlClientRect(IDC_STATIC_OPTIONS, rtCtrl);
	rectBound.right = rtCtrl.right;

	if ( IsOptionGroupExpanded() )
	{
		vector<UINT> vnGroupCtrlIDs = 
		{
			IDC_CHECK_SKIP_LINKED_CELLS,
			IDC_CHECK_PERFORM_IN_SELECTED_RANGE,

			IDC_CHECK_MATCH_CASE,
			IDC_CHECK_FULL_MATCH,
			IDC_CHECK_USE_WILDCARDS,

			IDC_CHECK_USE_ABSOLUTE_VAL,
			IDC_CHECK_KEEP_SIGN,
			IDC_CHECK_SET_AS_MISSING_VAL,

			IDC_CHECK_SEARCH_UP,

			IDC_STATIC_TOLERANCE,
			IDC_EDIT_TOLERANCE
		};
		const int nCtrlSize = vnGroupCtrlIDs.GetSize();
		for (int ii = 0; ii < nCtrlSize; ++ii)
		{
			Control ctrl = GetDlgItem( vnGroupCtrlIDs[ii] );
			if ( ctrl && ctrl.Visible )
			{
				ctrl.GetWindowRect(&rtCtrl);
				ScreenToClient(&rtCtrl);

				rectBound.left = min(rectBound.left, rtCtrl.left);
				rectBound.top = min(rectBound.top, rtCtrl.top);
				rectBound.right = max(rectBound.right, rtCtrl.right);
				rectBound.bottom = max(rectBound.bottom, rtCtrl.bottom);
			}
		}
	}
}

/// Kenny 09/18/2009 INIT_DIALOG_SIZE_NEEDED
void CFindAndReplaceDlg::ResizeDlgToFitControls(BOOL bRepaint /*= TRUE*/)
{
	RECT rtDlg;
	GetWindowRect(&rtDlg);
	const int nMinWidth = GetTotalWidth(true);
	const int nMinHeight = GetTotalHeight(true);
	if ( RECT_WIDTH(rtDlg) < nMinWidth )
	{
		rtDlg.right = rtDlg.left + nMinWidth;
	}
	rtDlg.bottom = rtDlg.top + nMinHeight;
	MoveWindow(&rtDlg, bRepaint);

	/// Kenny 12/28/2009 FIND_REPLACE_DLG_SHOWN_WITH_UGLY_BK_COLOR
	RECT rtTab;
	m_topTab.GetWindowRect(&rtTab);
	ScreenToClient(&rtTab);
	m_topTab.AdjustRect(FALSE, &rtTab);
	Window themeBkCtrl = GetDlgItem(IDC_TAB_BACK_PANEL);
	SetWindowPos(themeBkCtrl.GetSafeHwnd(), NULL, rtTab.left, rtTab.top, RECT_WIDTH(rtTab), RECT_HEIGHT(rtTab), SWP_NOZORDER);
	SetWindowPos(m_topTab.GetSafeHwnd(), themeBkCtrl.GetSafeHwnd(), 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);

	m_LayoutHelper.GetCtrlLayoutInfoPointer(IDC_TAB_BACK_PANEL)->UpdateRect(*this);
	/// End FIND_REPLACE_DLG_SHOWN_WITH_UGLY_BK_COLOR
}
/// End INIT_DIALOG_SIZE_NEEDED

/*----------------------------------------------------------------------------*/
/* Public functions(interfaces) of CFindAndReplaceDlg
/*----------------------------------------------------------------------------*/

int CFindAndReplaceDlg::Create( HWND hWndParent /*= NULL*/ )
{
	InitMsgMap();
	
	DWORD dwDlgOptions = 0;
	int nRet = ResizeDialog::Create(hWndParent, dwDlgOptions);
	Visible = true;
	return nRet;
}

void CFindAndReplaceDlg::SwitchToActionTab( bool bSwitchToReplace /*= false*/ )
{
	/// Kenny 09/11/2009 MAKE_TOLERANCE_AVAILABLE_IF_CONDITION_CONTAIN_EQUAL, minor improvement
// 	m_topTab.SetCurSel( bSwitchToReplace ? TAB_REPLACE : TAB_FIND );
// 	/// Kenny 07/15/2009 FILL_FINDWHAT_REPLACE_WITH_LAST_USED_VALUE
// 	//OnTabChange(m_topTab);
// 	onChangeDataType(true);
// 	/// End FILL_FINDWHAT_REPLACE_WITH_LAST_USED_VALUE
	const int nSwitchToTab = bSwitchToReplace ? TAB_REPLACE : TAB_FIND;
	if ( nSwitchToTab != m_topTab.GetCurSel() )
	{
		m_topTab.SetCurSel( nSwitchToTab );
		onChangeDataType(true);
	}
	/// End MAKE_TOLERANCE_AVAILABLE_IF_CONDITION_CONTAIN_EQUAL
}

/// Kenny 09/11/2009 MAKE_TOLERANCE_AVAILABLE_IF_CONDITION_CONTAIN_EQUAL
void CFindAndReplaceDlg::UpdateFindWhatToCurrentCellValue()
{
	const string strCell = m_FindReplaceHelper.GetCurrentCellText();
	m_comboFindWhat.Text = strCell;
}
/// End MAKE_TOLERANCE_AVAILABLE_IF_CONDITION_CONTAIN_EQUAL

/*----------------------------------------------------------------------------*/
/* Private functions(implementations) of CFindAndReplaceDlg
/*----------------------------------------------------------------------------*/
int CFindAndReplaceDlg::getDataType()
{
	if( IDC_RADIO_DATA_TYPE_NUMERIC == GetCheckedRadioButton(IDC_RADIO_DATA_TYPE_NUMERIC, IDC_RADIO_DATA_TYPE_STRING) )
		return DT_NUMERIC;
	return DT_STRING;
}

bool CFindAndReplaceDlg::isNumericType()
{
	return ( DT_NUMERIC == getDataType() );
}

bool CFindAndReplaceDlg::isActionReplace()
{
	const bool bIsActionReplace = ( TAB_REPLACE == m_topTab.GetCurSel() );
	return bIsActionReplace;
}

void CFindAndReplaceDlg::showHideControls()
{
	const bool bIsActionReplace = isActionReplace();
	const bool bIsNumericType = isNumericType();
	const bool bIsActivePageWks = EXIST_WKS == _get_active_page_type();
	
	GetItem(IDC_STATIC_CONDITION).Visible = bIsNumericType;
	m_comboCondition.Visible = bIsNumericType;

	GetItem(IDC_STATIC_LOOK_IN).Visible = bIsActionReplace;
	m_comboLookIn.Visible = bIsActionReplace;

	GetItem(IDC_STATIC_REPLACE_WITH).Visible = bIsActionReplace;
	m_comboReplaceWith.Visible = bIsActionReplace;

	GetItem(IDC_BTN_REPLACE).Visible = bIsActionReplace && bIsActivePageWks;
	GetItem(IDC_BTN_REPLACE_ALL).Visible = bIsActionReplace;

	showHideOptionGroupCtrls();

	showHideWarningMessageCtrl();	/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
}

void CFindAndReplaceDlg::showHideOptionGroupCtrls()
{
	const int nConditionType = m_comboCondition.GetCurSel();

	const bool bIsActionReplace = isActionReplace();
	const BOOL bIsNumericType = isNumericType();
	/// Kenny 09/11/2009 MAKE_TOLERANCE_AVAILABLE_IF_CONDITION_CONTAIN_EQUAL, I renamed the variable without codemark since it's not logical change
	//const bool bIsConditionEqual = NRC_EQ == nConditionType;
	const bool bIsConditionContainEqual = NRC_EQ == nConditionType || NRC_GE == nConditionType || NRC_LE == nConditionType;
	/// End MAKE_TOLERANCE_AVAILABLE_IF_CONDITION_CONTAIN_EQUAL
	const bool bIsActivePageWks = EXIST_WKS == _get_active_page_type();

	/// Kenny 01/14/2010 FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
	GROUPCTRL_AVAILABLE(IDC_CHECK_SKIP_LINKED_CELLS)			= bIsActivePageWks;
	GROUPCTRL_AVAILABLE(IDC_CHECK_PERFORM_IN_SELECTED_RANGE)	= bIsActivePageWks && m_bHasSelection;
	GROUPCTRL_AVAILABLE(IDC_CHECK_MATCH_CASE)					= !bIsNumericType;
	GROUPCTRL_AVAILABLE(IDC_CHECK_FULL_MATCH)					= !bIsNumericType;
	GROUPCTRL_AVAILABLE(IDC_CHECK_USE_WILDCARDS)				= !bIsNumericType;
	GROUPCTRL_AVAILABLE(IDC_CHECK_USE_ABSOLUTE_VAL)				= bIsNumericType;
	GROUPCTRL_AVAILABLE(IDC_CHECK_KEEP_SIGN)					= bIsActionReplace && bIsNumericType;
	GROUPCTRL_AVAILABLE(IDC_CHECK_SET_AS_MISSING_VAL)			= bIsActionReplace && bIsNumericType;
	GROUPCTRL_AVAILABLE(IDC_CHECK_SEARCH_UP)					= TRUE;
	GROUPCTRL_AVAILABLE(IDC_CHECK_FIND_LABEL_ROWS)				= !isNumericType() 
																	&& (!isPerformInSelectedRange()
																		|| (WKS_SEL_NONE == m_nSelectionType)
																		|| (WKS_SEL_ALL == m_nSelectionType)
																		|| (WKS_SEL_COLUMN & m_nSelectionType)
																	);
	/// End FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN

	if ( IsOptionGroupExpanded() )
	{
		/// Kenny 01/14/2010 FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
/*
		GetItem(IDC_CHECK_SKIP_LINKED_CELLS).Visible			= bIsActivePageWks;
		GetItem(IDC_CHECK_PERFORM_IN_SELECTED_RANGE).Visible	= bIsActivePageWks && m_bHasSelection;
		GetItem(IDC_CHECK_MATCH_CASE).Visible					= !bIsNumericType;
		GetItem(IDC_CHECK_FULL_MATCH).Visible					= !bIsNumericType;
		GetItem(IDC_CHECK_USE_WILDCARDS).Visible				= !bIsNumericType;
		GetItem(IDC_CHECK_USE_ABSOLUTE_VAL).Visible				= bIsNumericType;
		GetItem(IDC_CHECK_KEEP_SIGN).Visible					= bIsActionReplace && bIsNumericType;
		GetItem(IDC_CHECK_SET_AS_MISSING_VAL).Visible			= bIsActionReplace && bIsNumericType;
		GetItem(IDC_CHECK_SEARCH_UP).Visible					= TRUE;
*/
		for (int ii = 0; ii < m_vnOptionCheckboxesID.GetSize(); ++ii)
		{
			ASSERT( ii < m_vbOptionIsAvailable.GetSize() );
			SET_GROUPCTRL_VISIBLE_IF_AVAILABLE_BYINDEX(ii);
		}
		/// End FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
		GetItem(IDC_STATIC_TOLERANCE).Visible					= bIsNumericType && bIsConditionContainEqual;
		GetItem(IDC_EDIT_TOLERANCE).Visible						= bIsNumericType && bIsConditionContainEqual;
		///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
		//showHideCheckLabelRowsCtrl();		/// Kenny 01/14/2010 FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
		///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS

		m_comboLookIn.Enable = !isPerformInSelectedRange();
	}
	else
	{
		for (int ii = 0; ii < m_vnOptionCheckboxesID.GetSize(); ++ii)
		{
			GetItem( m_vnOptionCheckboxesID[ii] ).Visible = FALSE;
		}
		GetItem(IDC_STATIC_TOLERANCE).Visible = FALSE;
		GetItem(IDC_EDIT_TOLERANCE).Visible = FALSE;
	}
}

///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
void CFindAndReplaceDlg::showHideCheckLabelRowsCtrl()
{
	/// Kenny 01/14/2010 FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
// 	GetItem(IDC_CHECK_FIND_LABEL_ROWS).Visible = !isNumericType() && (!isPerformInSelectedRange()
// 												|| (WKS_SEL_NONE == SELECTION_TYPE)
// 												|| (WKS_SEL_ALL == SELECTION_TYPE)
// 												|| (WKS_SEL_COLUMN & SELECTION_TYPE)
// 												);
	SET_GROUPCTRL_VISIBLE_IF_AVAILABLE_BYID(IDC_CHECK_FIND_LABEL_ROWS);
	/// End FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
}
///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS

/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
void CFindAndReplaceDlg::showHideWarningMessageCtrl()
{
	Button btnSkipLinked = GetItem(IDC_CHECK_SKIP_LINKED_CELLS);
	const BOOL bSkipLinked = btnSkipLinked.Check;
	const BOOL bShowWarning = isActionReplace() && !bSkipLinked && GROUPCTRL_AVAILABLE(IDC_CHECK_SKIP_LINKED_CELLS);
	m_ctrlWarningMsg.Visible = bShowWarning;
}
/// End QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED

void CFindAndReplaceDlg::rearrangeOptionGroup(BOOL bRepaint /*= TRUE*/)
{
	CLayoutTool layoutTool(*this);
	// Vertical-Center the switch button and the tips control
	layoutTool.m_nAlignOption = ALIGN_VERTI_CENTER;
	layoutTool.m_szGap.cx = GetControlGap();
	vector<UINT> vnBtnTips = { IDC_BTN_FIND_REPLACE_OPTIONS, IDC_STATIC_OPTIONS, IDC_STATIC_OPTION_SEPARATOR }
	layoutTool.PerformLayout(vnBtnTips, bRepaint);

	if ( IsOptionGroupExpanded() )
	{
		RECT rect;
		GetControlClientRect(IDC_BTN_FIND_REPLACE_OPTIONS, rect);

		// Left-align the checkboxes and the Tolerance static control
		layoutTool.Reset();
		layoutTool.m_nAlignOption = ALIGN_LEFT;
		layoutTool.m_szGap.cy = GetControlGap();
		layoutTool.m_ptBegin.x = rect.left + GetControlGap();
		layoutTool.m_ptBegin.y = rect.bottom + GetControlGap();
		vector<UINT> vnCtrlIDs;
		vnCtrlIDs = m_vnOptionCheckboxesID;
		vnCtrlIDs.Add(IDC_STATIC_TOLERANCE);
		layoutTool.PerformLayout(vnCtrlIDs, bRepaint);

		// Horizontal center the tolerance related controls.
		layoutTool.Reset();
		layoutTool.m_nAlignOption = ALIGN_VERTI_CENTER;
		layoutTool.m_szGap.cx = 5*GetControlGap();
		vector<UINT> vnTolerancesCtrls = { IDC_STATIC_TOLERANCE, IDC_EDIT_TOLERANCE }
		layoutTool.PerformLayout(vnTolerancesCtrls, bRepaint);

		GetOptionGroupBoundingRect(rect);
		rect.bottom += GetControlGap();
		move_control_by_id(*this, IDC_GROUPBOX_FIND_OPTIONS, rect.left, rect.top, -1, RECT_HEIGHT(rect), MC_MOVE_AND_SIZE, bRepaint);
	}

	AdjustTabControl(bRepaint);
}

void CFindAndReplaceDlg::rearrangeBottomButtons( BOOL bRepaint /*= TRUE*/ )
{
	CLayoutTool layoutTool(*this);

	// Move the cancel button to the bottommost control with some gap.
	layoutTool.m_nAlignOption = ALIGN_LEFT;	/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
	layoutTool.m_szGap.cy = GetControlGap();
	vector<UINT> vnCtrlIDs1 = 
	{
		IDC_TAB_FIND_REPLACE,
		IDC_STATIC_WARNING_MSG,	/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
		IDCANCEL
	};
	layoutTool.PerformLayout(vnCtrlIDs1, bRepaint);

	// Move the cancel button to the rightmost of the dialog with some gap.
	RECT rtCancelBtn;
	Button btnCancel = GetItem(IDCANCEL);
	btnCancel.GetWindowRect(&rtCancelBtn);
	ScreenToClient(&rtCancelBtn);

	const int nNewX = GetDlgExtent(false) - GetControlGap() - RECT_WIDTH(rtCancelBtn);
	update_rect(rtCancelBtn, nNewX, -1, -1, -1, MC_MOVE_X|MC_SIZE_WIDTH);
	btnCancel.MoveWindow(&rtCancelBtn, bRepaint);

	// Align the bottom buttons.
	layoutTool.Reset();
	layoutTool.m_nAlignOption = ALIGN_TOP;
	layoutTool.m_szGap.cx = GetControlGap();
	layoutTool.m_FollowPreviousCtrlRightOrBottom = false;
	vector<UINT> vnBtnIDs = 
	{
		IDCANCEL,
		IDC_BTN_REPLACE_ALL,
		IDC_BTN_REPLACE,
		IDC_BTN_FIND_NEXT
	};
	layoutTool.PerformLayout(vnBtnIDs, bRepaint);
}

/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
void CFindAndReplaceDlg::rearrangeConditionFindwhatInsertBtn( BOOL bRepaint /*= TRUE*/ )
{
	int nRightEdgeMargin = GetControlGap() * 3;
	if ( GetItem(IDC_BTN_FIND_INSERT_SPECIAL).Visible )
	{
		RECT rtBtn;
		GetControlClientRect(IDC_BTN_FIND_INSERT_SPECIAL, rtBtn);
		nRightEdgeMargin += RECT_WIDTH(rtBtn) + GetControlGap();
	}
	RECT rect;
	GetControlClientRect(IDC_COMBO_FIND_WHAT, rect);
	rect.right = GetDlgExtent(false) - nRightEdgeMargin;
	m_comboFindWhat.MoveWindow(&rect, bRepaint);

	// Top align the condition/find what combobox and the insert btn
	CLayoutTool layoutTool(*this);
	layoutTool.m_nAlignOption = ALIGN_TOP;
	layoutTool.m_nMakeSameSizeOption = MSS_SAME_HEIGHT;
	layoutTool.m_szGap.cx = GetControlGap();

	vector<UINT> vnCtrlIDs1 = 
	{
		IDC_COMBO_CONDITION
		, IDC_COMBO_FIND_WHAT
		, IDC_BTN_FIND_INSERT_SPECIAL
	};
	layoutTool.PerformLayout(vnCtrlIDs1, bRepaint);
	
	if ( isNumericType() )
	{
		// Left align the static find what & combobox
		layoutTool.Reset();
		layoutTool.m_nAlignOption = ALIGN_LEFT;
		vector<UINT> vnCtrlIDs2 = 
		{
			IDC_COMBO_FIND_WHAT
			, IDC_STATIC_FIND_WHAT
		};
		layoutTool.PerformLayout(vnCtrlIDs2, bRepaint);
	}
}
/// End QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT

void CFindAndReplaceDlg::onChangeDataType( bool bForceUpdate /*= false*/ )
{
	const bool bIsMatrix = EXIST_MATRIX == _get_active_page_type();
	Control ctrlStringType = GetItem(IDC_RADIO_DATA_TYPE_STRING);
	ctrlStringType.Enable = !bIsMatrix;

	if ( bIsMatrix )
	{
		CheckRadioButton(IDC_RADIO_DATA_TYPE_NUMERIC, IDC_RADIO_DATA_TYPE_STRING, IDC_RADIO_DATA_TYPE_NUMERIC);
	}
	const int nDataType = getDataType();
	if ( bForceUpdate || m_nLastUsedDataType != nDataType )
	{
		RearrangeControls(TRUE);

		loadComboRecentList( m_comboFindWhat, FIND_WHAT_RECENT_LIST_SECTION );
		loadComboRecentList( m_comboReplaceWith, REPLACE_WITH_RECENT_LIST_SECTION );

		m_nLastUsedDataType = nDataType;
	}

	/// Kenny 07/15/2009 FILL_FINDWHAT_REPLACE_WITH_LAST_USED_VALUE
	if ( isActionReplace() && isNumericType() && m_comboReplaceWith.Text.IsEmpty() && m_comboReplaceWith.GetCount() > 0 )
	{
		m_comboReplaceWith.SetCurSel(0);
		updateBottomButtonsStatus();
	}
	/// End FILL_FINDWHAT_REPLACE_WITH_LAST_USED_VALUE

	onUpdateCheckboxesStatus();	/// Kenny 04/02/2010 CHECK_BOXES_STATUS_FAILED_TO_GET_INIT_ON_REOPEN_DLG
}

/// Kenny 09/29/2009 IMPROVE_FIND_REPLACE_DLG_RESIZING_PROCESS
void CFindAndReplaceDlg::initConditionCombo()
{
	vector<string> vsCondition = {
		STR_NRC_EQ,
		STR_NRC_LT,
		STR_NRC_LE,
		STR_NRC_GT,
		STR_NRC_GE,
		STR_NRC_NE
	};
	int ii;
	m_comboCondition.ResetContent();
	for (ii = 0; ii < vsCondition.GetSize(); ++ii)
	{
		m_comboCondition.AddString( vsCondition[ii] );
	}
	loadConditionFromRegistry();
}

/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
void CFindAndReplaceDlg::updateInsertSymbolBtnStatus()
{
	/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
	const bool bIsNumericType = isNumericType();
	bool bInsertSpecial = bIsNumericType && EXIST_WKS == _get_active_page_type();
	if ( !bInsertSpecial && !bIsNumericType )
	{
		Button btnUseWildcards		= GetItem(IDC_CHECK_USE_WILDCARDS);
		const bool bUseWildcards	= GROUPCTRL_AVAILABLE(IDC_CHECK_USE_WILDCARDS) && btnUseWildcards.Check;
		bInsertSpecial				= bUseWildcards;
	}

	BitmapRadioButton btn = GetItem(IDC_BTN_FIND_INSERT_SPECIAL);
	btn.Enable = bInsertSpecial;
	/// End QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
}
/// End QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT

void CFindAndReplaceDlg::updateComboboxesToShowAllItems(int nComboboxes /*= UPDATE_ALL_COMBO_DROPPED_ITEMS*/)
{
	if ( nComboboxes & UPDATE_CONDITION_COMBO_DROPPED_ITEMS )
		m_comboCondition.SetDroppedVisibleItemCount();
	if ( nComboboxes & UPDATE_LOOK_IN_COMBO_DROPPED_ITEMS )
		m_comboLookIn.SetDroppedVisibleItemCount();
	if ( nComboboxes & UPDATE_FIND_WHAT_COMBO_DROPPED_ITEMS )
		m_comboFindWhat.SetDroppedVisibleItemCount();
	if ( nComboboxes & UPDATE_REPLACE_WITH_COMBO_DROPPED_ITEMS)
		m_comboReplaceWith.SetDroppedVisibleItemCount();
}
/// End IMPROVE_FIND_REPLACE_DLG_RESIZING_PROCESS

/// Kenny 09/18/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
//string CFindAndReplaceDlg::getComboText(ComboBox& ctrl)
string CFindAndReplaceDlg::getComboText(ComboBox& ctrl, bool bIsSelChanging /*= false*/)
/// End QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
{
	/// Kenny 09/18/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	// Remarks: When we are inside of a handler procedure for the ON_CBN_SELCHANGE event, 
	//			the text of the combo can ONLY be retrieved by combo.GetLBText(), combo.Text would be the previous content during that event.
	//			For this reason, we have to know whether we are inside of a ON_CBN_SELCHANGE handler.
	//if( -1 != ctrl.GetCurSel() )
	if( bIsSelChanging && -1 != ctrl.GetCurSel() )
	/// End QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	{
		string str;
		ctrl.GetLBText(ctrl.GetCurSel(), str);
		return str;
	}
	
	return ctrl.Text;
}

int CFindAndReplaceDlg::getComboList(ComboBox& ctrl, vector<string>& vsList)
{
	vsList.SetSize(0);
	for(int ii=0; ii<ctrl.GetCount(); ii++)
	{
		string str;
		ctrl.GetLBText(ii, str);	
		vsList.Add(str);
	}
	return vsList.GetSize();
}

void CFindAndReplaceDlg::updateComboList(ComboBox& ctrl, LPCSTR lpcszSection)
{
	string strCurrent = ctrl.Text;
	
	vector<string> vsList;	
	getComboList(ctrl, vsList);
	
	// insert current string to combo list
	if( vsList.Find(strCurrent) < 0 )
	{
		ctrl.InsertString(0, strCurrent);
		
		while( ctrl.GetCount() > FIND_WHAT_LIST_MAX_NUM )
			ctrl.DeleteString( FIND_WHAT_LIST_MAX_NUM );
	}
	
	// save combo list to Origin.ini recent list section
	saveComboRecentList(ctrl, lpcszSection);
}

string CFindAndReplaceDlg::getINIFileSectionName(LPCSTR lpcszSectionNameBase)
{
	string str;
	string strPostfix = isNumericType()? "Numeric" : "String";
	str.Format("%sFor%s", lpcszSectionNameBase, strPostfix);
	return str;
}

void CFindAndReplaceDlg::saveComboRecentList(ComboBox& ctrl, LPCSTR lpcszSection)
{
	vector<string> vsList;
	getComboList( ctrl, vsList );
	
	INIFileEx 	iniFile(FIND_WHAT_RECENT_LIST_INI_FILE);
	string 		strSection = getINIFileSectionName(lpcszSection);
	
	for(int index = 0; index < vsList.GetSize(); index++ )
	{
		string 	strKey = FIND_WANT_RECENT_LIST_KEY_PREFIX + (index + 1);
		bool 	bRet = iniFile.WriteString(strSection, strKey, vsList[index]);
		ASSERT( bRet );
	}	
}

void CFindAndReplaceDlg::loadComboRecentList(ComboBox& ctrl, LPCSTR lpcszSection)
{
	ASSERT(ctrl);
	const string strOldVal = ctrl.Text;
	ctrl.ResetContent();
	ctrl.Text = strOldVal;
	
	int			index = 0;
	INIFileEx 	iniFile(FIND_WHAT_RECENT_LIST_INI_FILE);
	string 		strSection = getINIFileSectionName(lpcszSection);
	
	while(true)
	{
		string 	strKey = FIND_WANT_RECENT_LIST_KEY_PREFIX + (++index);
		string 	strValue = iniFile.ReadString(strSection, strKey, "");	
		if( strValue.IsEmpty() )
			break;
		ctrl.AddString(strValue);
	}
}

/// Kenny 10/16/2009 FIND_REPLACE_SUPPORT_GERMAN_DECIMAL
#define IS_STR_NUMERIC(str)			(atof(str) != NANUM)
/// End FIND_REPLACE_SUPPORT_GERMAN_DECIMAL

bool CFindAndReplaceDlg::isReadyToFind()
{
	/// Kenny 09/18/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
// 	const string strFindWhat = getComboText(m_comboFindWhat);
// 	if( !strFindWhat.IsEmpty() && !m_comboCondition.Text.IsEmpty() )
// 	{
// 		if ( isNumericType() )
// 		{
// 			bool bIsReady = _is_str_missing_val(strFindWhat) || is_str_numeric(strFindWhat);
// 			const bool bIsConditionEqual = NRC_EQ == m_comboCondition.GetCurSel();
// 			if ( bIsReady && bIsConditionEqual )
// 				bIsReady = is_str_numeric(m_edTolerance.Text);
// 			return bIsReady;
// 		}
// 		return true;
// 	}
// 
// 	return false;
	string strFindWhat = getComboText(m_comboFindWhat, m_bIsFindWhatSelChanging);
	const bool bIsNumericType = isNumericType();
	bool bIsReady = true;

	if ( bIsNumericType )
	{
		strFindWhat.TrimLeft();
		strFindWhat.TrimRight();
		if ( m_edTolerance.Visible )
		{
			string strTolerance = m_edTolerance.Text;
			strTolerance.TrimLeft();
			strTolerance.TrimRight();
			bIsReady = !strTolerance.IsEmpty() && is_str_numeric(m_edTolerance.Text);
		}
	}
	if ( bIsReady )
	{
		if ( strFindWhat.IsEmpty() )
		{
			bIsReady = EXIST_WKS == _get_active_page_type();
			/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
			if ( bIsReady && bIsNumericType )
			{
				bIsReady = m_comboCondition.GetCurSel() == NRC_EQ || m_comboCondition.GetCurSel() == NRC_NE;
			}
			/// End QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
		}
		else if ( bIsNumericType )
		{
			/// Kenny 10/10/2009 FIND_REPLACE_SUPPORT_GERMAN_DECIMAL
			//bIsReady = _is_str_missing_val(strFindWhat) || is_str_numeric(strFindWhat);
			/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
			//bIsReady = _is_str_missing_val(strFindWhat) || atof(strFindWhat) != NANUM;
			if ( _is_str_missing_val(strFindWhat) 
				|| strFindWhat.CompareNoCase(STR_SYMBOL_MISSING_BLANK_TEXT) == 0 
				)
			{
				bIsReady = m_comboCondition.GetCurSel() == NRC_EQ || m_comboCondition.GetCurSel() == NRC_NE;
			}
			else
			{
				bIsReady = IS_STR_NUMERIC(strFindWhat);
			}
			/// End QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
			/// End FIND_REPLACE_SUPPORT_GERMAN_DECIMAL
		}
	}
	return bIsReady;
	/// End QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
}

bool CFindAndReplaceDlg::isReadyToReplace()
{
	if ( isReadyToFind() )
	{
		/// Kenny 09/22/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
// 		if ( isNumericType() )
// 		{
// 			const string strReplaceWith = getComboText(m_comboReplaceWith);
// 			return _is_str_missing_val(strReplaceWith) || is_str_numeric(strReplaceWith);
// 		}
//		return true;
		bool bIsReady = true;
		const bool bIsNumericType = isNumericType();
		string strReplaceWith = getComboText(m_comboReplaceWith, m_bIsReplaceWithSelChanging);
		if ( bIsNumericType )
		{
			strReplaceWith.TrimLeft();
			strReplaceWith.TrimRight();
		}
		if ( strReplaceWith.IsEmpty() )
		{
			bIsReady = EXIST_WKS == _get_active_page_type();
			if (bIsReady)
			{
				string strFindWhat = getComboText(m_comboFindWhat, m_bIsFindWhatSelChanging);
				if ( bIsNumericType )
				{
					strFindWhat.TrimLeft();
					strFindWhat.TrimRight();
				}
				/// Kenny 10/15/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
				//if ( strFindWhat.IsEmpty() )
				if ( m_comboCondition.GetCurSel() == NRC_EQ && strFindWhat.IsEmpty() )
				/// End QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
				{
					// We don't allow finding & replacing with blank at the same time.
					return false;
				}
			}
		}
		else if ( bIsNumericType )
		{
			/// Kenny 10/16/2009 FIND_REPLACE_SUPPORT_GERMAN_DECIMAL
			//bIsReady = _is_str_missing_val(strReplaceWith) || is_str_numeric(strReplaceWith);
			bIsReady = _is_str_missing_val(strReplaceWith) || IS_STR_NUMERIC(strReplaceWith);
			/// End FIND_REPLACE_SUPPORT_GERMAN_DECIMAL
		}
		return bIsReady;
		/// End QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
	}
		
	return false;	
}

void CFindAndReplaceDlg::updateBottomButtonsStatus()
{
	GetItem(IDC_BTN_FIND_NEXT).Enable = isReadyToFind();

	/// Kenny 10/10/2009 FIND_REPLACE_SUPPORT_GERMAN_DECIMAL, minor improve
	if ( isActionReplace() )
	{
		Button btnSetAsMissing = GetItem(IDC_CHECK_SET_AS_MISSING_VAL);
		/// Kenny 01/14/2010 FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
		//const BOOL bSetAsMissing = btnSetAsMissing.Check;
		const BOOL bSetAsMissing = GROUPCTRL_AVAILABLE(IDC_CHECK_SET_AS_MISSING_VAL) && btnSetAsMissing.Check;
		/// End FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
		const BOOL bIsNumericType = isNumericType();
		const BOOL bIsReadyToReplace = isReadyToReplace();
	
		GetItem(IDC_BTN_REPLACE).Enable = bIsReadyToReplace && (!bIsNumericType || !bSetAsMissing);
		GetItem(IDC_BTN_REPLACE_ALL).Enable = bIsReadyToReplace;
	}
}

void CFindAndReplaceDlg::onUpdateCheckboxesStatus()
{
	m_comboLookIn.Enable = !isPerformInSelectedRange();

	Button btnUseWildcards = GetItem(IDC_CHECK_USE_WILDCARDS);
	/// Kenny 01/14/2010 FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
	//const BOOL bUseWildcards = btnUseWildcards.Check;
	const BOOL bUseWildcards = GROUPCTRL_AVAILABLE(IDC_CHECK_USE_WILDCARDS) && btnUseWildcards.Check;
	/// End FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN

	Button btnFullMatch = GetItem(IDC_CHECK_FULL_MATCH);
	btnFullMatch.Enable = !bUseWildcards;
	if ( bUseWildcards )
		btnFullMatch.Check = bUseWildcards;

	/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
	updateInsertSymbolBtnStatus();
	/// End QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
}

bool CFindAndReplaceDlg::isPerformInSelectedRange()
{
	Button btnInSelectedRange = GetItem(IDC_CHECK_PERFORM_IN_SELECTED_RANGE);
	/// Kenny 01/14/2010 FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
	//const BOOL bPerformInSelectedRange = btnInSelectedRange.Visible && btnInSelectedRange.Check;
	const BOOL bPerformInSelectedRange = GROUPCTRL_AVAILABLE(IDC_CHECK_PERFORM_IN_SELECTED_RANGE) && btnInSelectedRange.Check;
	/// End FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
	return bPerformInSelectedRange;
}

///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
BOOL	CFindAndReplaceDlg::isCheckLabelRows()
{
	Button btn = GetItem(IDC_CHECK_FIND_LABEL_ROWS);
	return GROUPCTRL_AVAILABLE(IDC_CHECK_FIND_LABEL_ROWS) && btn.Check;
}

///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
BOOL	CFindAndReplaceDlg::isColLabelSelected()
{
	return (m_nSelectionType & WKS_SEL_COL_LABEL) && (m_nSelectionType & WKS_SEL_RANGE);
}
///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS

void CFindAndReplaceDlg::saveDataTypeToRegistry()
{
	DWORD dwVal = getDataType();
	dlg_save_to_registry(STR_DLG_NAME, DATA_TYPE_REG_NAME, dwVal);	
}

void CFindAndReplaceDlg::loadDataTypeFromRegistry()
{
	DWORD dwVal;
	dlg_load_registry(STR_DLG_NAME, DATA_TYPE_REG_NAME, dwVal, DT_NUMERIC);
	
	int nCheckRadioID = (DT_NUMERIC == dwVal)? IDC_RADIO_DATA_TYPE_NUMERIC : IDC_RADIO_DATA_TYPE_STRING;
	CheckRadioButton(IDC_RADIO_DATA_TYPE_NUMERIC, IDC_RADIO_DATA_TYPE_STRING, nCheckRadioID);
	m_nLastUsedDataType = dwVal;
}

void CFindAndReplaceDlg::saveConditionToRegistry()
{
	const int nConditionType = m_comboCondition.GetCurSel();
	dlg_save_to_registry(STR_DLG_NAME, CONDITION_TYPE_REG_NAME, nConditionType);	
}

void CFindAndReplaceDlg::loadConditionFromRegistry()
{
	DWORD dwVal;
	dlg_load_registry(STR_DLG_NAME, CONDITION_TYPE_REG_NAME, dwVal, 0);
	/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
	if ( dwVal <= NRC_INVALID || dwVal >= NRC_SIZE )
	{
		dwVal = NRC_EQ;
	}
	/// End QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
	m_comboCondition.SetCurSel(dwVal);
}

void CFindAndReplaceDlg::saveOptionGroupStatusToRegistry()
{
	const BOOL bIsGroupExpanded = IsOptionGroupExpanded();
	dlg_save_to_registry(STR_DLG_NAME, OPTION_GROUP_EXPAND_REG_NAME, bIsGroupExpanded);

	vector<byte> vbValues(m_vnOptionCheckboxesID.GetSize());
	for (int ii = 0; ii < vbValues.GetSize(); ++ii)
	{
		Button btn = GetItem(m_vnOptionCheckboxesID[ii]);
		vbValues[ii] = btn.Check;
	}
	save_default_checkboxes(STR_DLG_NAME, vbValues);

	string strTolerance = m_edTolerance.Text;
	if ( strTolerance.IsEmpty() )
		strTolerance = DEFAULT_TOLERANCE_VALUE;
	dlg_save_to_registry(STR_DLG_NAME, OPTION_TOLERANCE_REG_NAME, strTolerance);
}

void CFindAndReplaceDlg::loadOptionGroupStatusFromRegistry()
{
	/// Kenny 04/02/2010 CHECK_BOXES_STATUS_FAILED_TO_GET_INIT_ON_REOPEN_DLG
// 	DWORD dwVal;
// 	dlg_load_registry(STR_DLG_NAME, OPTION_GROUP_EXPAND_REG_NAME, dwVal, 1);
// 	ExpandOptionGroup(dwVal);
	/// End CHECK_BOXES_STATUS_FAILED_TO_GET_INIT_ON_REOPEN_DLG

	///------ Folger 11/04/09 FIND_REPLACE_DIALOG_MESS_UP_WHEN_FIRST_RUN
	//vector<byte> vbValues = {1, 1, 0, 0, 0, 0, 0, 0, 0};
	vector<byte> vbValues;
	vbValues = m_vbValues;
	///------ End FIND_REPLACE_DIALOG_MESS_UP_WHEN_FIRST_RUN
	load_default_checkboxes(STR_DLG_NAME, vbValues);

	for (int ii = 0; ii < m_vnOptionCheckboxesID.GetSize(); ++ii)
	{
		Button btn = GetItem(m_vnOptionCheckboxesID[ii]);
		btn.Check = vbValues[ii];
	}

	m_comboLookIn.Enable = !isPerformInSelectedRange();

	string strTolerance;
	dlg_load_registry(STR_DLG_NAME, OPTION_TOLERANCE_REG_NAME, strTolerance, "1e-8");
	m_edTolerance.Text = strTolerance.IsEmpty() ? DEFAULT_TOLERANCE_VALUE : strTolerance;

	onUpdateCheckboxesStatus();
}

/// Kenny 01/14/2010 FIND_REPLACE_NOT_WORK_WHEN_OPTION_GROUP_IS_HIDDEN
// !!!!!!!!!!!!!!!!!!! Note !!!!!!!!!!!!!
// Since the check boxes can be hidden when the whole option group is collapsed,
// we can not simply assume that a checkbox is available if only it's visible.
// So I add a bunch of boolean to indicate whether a specific checkbox is available,
// all the other programmers should follow this logic.

// I also update the following code without commenting out since too much of them
// and the macro I used here can be easily changed.

/// Kenny 09/22/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
//uint CFindAndReplaceDlg::getBitwiseOptions()
uint CFindAndReplaceDlg::getBitwiseOptions(string& strFindWhat, string& strReplaceWith)
/// End QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
{
	uint nBitwiseOptions		= WKSREPL_REPLACE_MATCHING_PART_ONLY;
	Button btnSearchUpward		= GetItem(IDC_CHECK_SEARCH_UP);
	const bool bSearchUpward	= GROUPCTRL_AVAILABLE(IDC_CHECK_SEARCH_UP) && btnSearchUpward.Check;

	if ( bSearchUpward )
		nBitwiseOptions |= WKSREPL_FIND_NEXT_SEARCH_UPWARD;

	Button btnSkipLinkedCells	= GetItem(IDC_CHECK_SKIP_LINKED_CELLS);
	const bool bSkipLinkedCells	= GROUPCTRL_AVAILABLE(IDC_CHECK_SKIP_LINKED_CELLS) && btnSkipLinkedCells.Check;
	if ( bSkipLinkedCells )
		nBitwiseOptions |= WKSREPL_SKIP_LINKED_CELL;

	if( isNumericType() )
	{
		Button btnUseAbsVal			= GetItem(IDC_CHECK_USE_ABSOLUTE_VAL);
		Button btnKeepSign			= GetItem(IDC_CHECK_KEEP_SIGN);
		Button btnSetAsMissing		= GetItem(IDC_CHECK_SET_AS_MISSING_VAL);

		const bool bUseAbsVal		= GROUPCTRL_AVAILABLE(IDC_CHECK_USE_ABSOLUTE_VAL) && btnUseAbsVal.Check;
		const bool bKeepSign		= GROUPCTRL_AVAILABLE(IDC_CHECK_KEEP_SIGN) && btnKeepSign.Check;
		const bool bSetAsMissing	= GROUPCTRL_AVAILABLE(IDC_CHECK_SET_AS_MISSING_VAL) && btnSetAsMissing.Check;

		if ( bUseAbsVal )
			nBitwiseOptions |= WKSREPL_USE_ABSOLUTE_VALUE_IN_TEST;
		if ( bKeepSign )
			nBitwiseOptions |= WKSREPL_KEEP_ORIGINAL_SIGN_WHEN_TEST_RESULT_IS_TRUE;
		if ( bSetAsMissing )
			nBitwiseOptions |= WKSREPL_SET_TO_MISSING_VALUE_WHEN_TEST_RESULT_IS_FALSE;

		const int nConditionType = m_comboCondition.GetCurSel();
		switch (nConditionType)
		{
		case NRC_EQ:
			nBitwiseOptions |= WKSREPL_TEST_EQUAL;
			break;
		case NRC_LT:
			nBitwiseOptions |= WKSREPL_TEST_LESSTHAN;
			break;
		case NRC_LE:
			nBitwiseOptions |= WKSREPL_TEST_LESSTHAN|WKSREPL_TEST_EQUAL;
			break;
		case NRC_GT:
			nBitwiseOptions |= WKSREPL_TEST_GREATER;
			break;
		case NRC_GE:
			nBitwiseOptions |= WKSREPL_TEST_GREATER|WKSREPL_TEST_EQUAL;
			break;
		case NRC_NE:
			/// Kenny 08/04/2009 QA80-13876-P2 FIX_BUG_IN_NUMERIC_FIND_REPLACE_FOR_NOT_EQUAL_CONDITION
			//nBitwiseOptions |= ~WKSREPL_TEST_EQUAL;
			nBitwiseOptions |= WKSREPL_TEST_LESSTHAN | WKSREPL_TEST_GREATER;
			/// End QA80-13876-P2 FIX_BUG_IN_NUMERIC_FIND_REPLACE_FOR_NOT_EQUAL_CONDITION
			break;
		}

		/// Kenny 10/14/2009 QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED
		strFindWhat.TrimLeft();
		strFindWhat.TrimRight();
		/// End QA81-14464-P1 FIND_REPLACE_SHOW_WARNING_MESSAGE_WHEN_SKIP_LINKED_CELLS_NOT_CHECKED

		/// Kenny 09/22/2009 QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS
		if ( strFindWhat.IsEmpty() )
			nBitwiseOptions |= WKSREPL_NUMERIC_FIND_BLANK;
		if ( strReplaceWith.IsEmpty() )
			nBitwiseOptions |= WKSREPL_NUMERIC_REPL_BLANK;
		/// End QA81-13631-P1 FIND_REPLACE_SHOULD_SUPPORT_FIND_BLANK_CELLS

		/// Kenny 10/09/2009 QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
		if ( _is_str_missing_val(strFindWhat) )
		{
			// Find missing value only
			nBitwiseOptions |= WKSREPL_NUMERIC_NANUM_SKIP_BLANK_TEXT;
		}
		else if ( strFindWhat.CompareNoCase(STR_SYMBOL_MISSING_BLANK_TEXT) == 0 )
		{
			// Not equal means we should skip them
			if ( m_comboCondition.GetCurSel() == NRC_NE )
				nBitwiseOptions |= WKSREPL_NUMERIC_NANUM_SKIP_BLANK_TEXT;
			// Find blank/text/missing, we have to change the text to "--", though this may looks odd & tricky
			strFindWhat = ftoa(NANUM);
		}
		/// End QA81-14418 FIND_REPLACE_ALLOW_FLEXIBLE_SKIP_BLANK_TEXT
	}
	else
	{
		Button btnMatchCase			= GetItem(IDC_CHECK_MATCH_CASE);
		Button btnMatchWholeWord	= GetItem(IDC_CHECK_FULL_MATCH);
		Button btnUseWildcards		= GetItem(IDC_CHECK_USE_WILDCARDS);

		const bool bMatchCase		= GROUPCTRL_AVAILABLE(IDC_CHECK_MATCH_CASE) && btnMatchCase.Check;
		const bool bMatchWholeWord	= GROUPCTRL_AVAILABLE(IDC_CHECK_FULL_MATCH) && btnMatchWholeWord.Check;
		const bool bUseWildcards	= GROUPCTRL_AVAILABLE(IDC_CHECK_USE_WILDCARDS) && btnUseWildcards.Check;

		if ( bMatchCase )
			nBitwiseOptions |= WKSREPL_TEST_STR_CASE_SENSITIVE;
		if ( bMatchWholeWord )
			nBitwiseOptions |= WKSREPL_TEST_STR_MATCH_WHOLE_WORD;
		if ( bUseWildcards )
			nBitwiseOptions |= WKSREPL_TEST_STR_WILDCARD_MATCHING;
		///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
		if ( isCheckLabelRows() || isColLabelSelected() )
			nBitwiseOptions |= WKSREPL_CHECK_FIND_LABEL_ROWS;
		///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
	}
	return nBitwiseOptions;
}

int CFindAndReplaceDlg::getLookInOptions()
{
	int nSel = m_comboLookIn.GetCurSel();
	/// Iris 7/14/2009 QA80-13941 SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
	/*
	const bool bIsActivePageMatrix = EXIST_MATRIX == _get_active_page_type();
	const int nBase = bIsActivePageMatrix ? GUI_LOOK_IN_MATRIX_BASE : 0;
	nSel -= nBase;
	switch(nSel)
	{
	case GUI_LOOK_IN_ACTIVE_MATRIX_OBJECT:
		return OPTION_ACTIVE_MATRIX_OBJECT;
	case GUI_LOOK_IN_ACTIVE_SHEET:
		return OPTION_ACTIVE_SHEET;
	case GUI_LOOK_IN_ACTIVE_PAGE:
		return OPTION_ACTIVE_PAGE;
	case GUI_LOOK_IN_ACTIVE_FOLDER:
		return OPTION_ALL_IN_ACTIVE_FOLDER;
	case GUI_LOOK_IN_ACTIVE_FOLDER_RECURSIVE:
		return OPTION_ALL_RECURSIVE_IN_ACTIVE_FOLDER;
	case GUI_LOOK_IN_ACTIVE_FOLDER_OPEN:
		return OPTION_ALL_OPEN_IN_ACTIVE_FOLDER;
	case GUI_LOOK_IN_PROJECT:
		return OPTION_ALL_IN_OPJ;
	default:
		ASSERT(0);
	}
	return -1;
	*/
	return get_lookin_options( nSel, _get_active_page_type() );
	///end SUPPORT_MORE_OPTIONS_FOR_WREPLACE_AND_MREPLACE_XF
}

///------ Folger 11/02/09 QA81-14522 SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS
void	CFindAndReplaceDlg::checkUpdateSelectionType(Datasheet& ds)
{
	Worksheet	wks(ds);
	if ( wks )
	{
		int	r1, c1, r2, c2;
		m_nSelectionType = wks.GetSelectedRange(r1, c1, r2, c2);
	}
	else
	{
		m_nSelectionType = WKS_SEL_NONE;
	}
}
///------ End SUPPORT_FIND_REPLACE_STR_IN_LABEL_ROWS

/*----------------------------------------------------------------------------*/
/* Public interface of CFindAndReplaceDlg
/*----------------------------------------------------------------------------*/

int FindAndReplaceDlg(BOOL bDoReplace = FALSE)
{
	const bool bCanWorkOnActivePage = _can_do_find_or_replace_on_active_sheet();
	if ( !bCanWorkOnActivePage )
	{
		return -1;
	}
	if(s_pCFindAndReplaceDlg)
	{
		s_pCFindAndReplaceDlg->Visible = TRUE;
		/// Kenny 09/11/2009 MAKE_TOLERANCE_AVAILABLE_IF_CONDITION_CONTAIN_EQUAL, minor improvement
		s_pCFindAndReplaceDlg->UpdateFindWhatToCurrentCellValue();
		/// End MAKE_TOLERANCE_AVAILABLE_IF_CONDITION_CONTAIN_EQUAL
	}
	else
	{
		s_pCFindAndReplaceDlg = new CFindAndReplaceDlg(TRUE);
		ASSERT(s_pCFindAndReplaceDlg != NULL);
		s_pCFindAndReplaceDlg->Create(GetWindow());
	}
	if ( s_pCFindAndReplaceDlg )
	{
		s_pCFindAndReplaceDlg->SwitchToActionTab(bDoReplace);
	}
	return 0;
}