void CTDLFindTaskExpressionListCtrl::BuildListCtrl()
{
	DeleteAllItems();

	for (int nParam = 0; nParam < GetRuleCount(); nParam++)
	{
		const SEARCHPARAM& sp = m_aSearchParams[nParam];

		// attrib
		CString sAttrib = m_cbAttributes.GetAttributeName(sp);
		int nItem = InsertItem(nParam, sAttrib);

		// operator
		CString sOp = GetOpName(sp.GetOperator());
		SetItemText(nItem, OPERATOR, sOp);

		// value
		UpdateValueColumnText(nItem);

		// and/or (but not for last row)
		if (nParam < GetRuleCount() - 1)
		{
			CEnString sAndOr(sp.GetAnd() ? IDS_FP_AND : IDS_FP_OR);
			SetItemText(nItem, ANDOR, sAndOr);
		}
	}

	ValidateListData();
	SetCurSel(0);
}
void CTDLFindTaskExpressionListCtrl::OnAttribEditOK()
{
	HideControl(m_cbAttributes);

	// update item text and keep data store synched
	int nRow = GetCurSel();

	if (nRow != CB_ERR)
	{
		SEARCHPARAM& sp = m_aSearchParams[nRow];
		SEARCHPARAM spNew(sp);

		if (m_cbAttributes.GetSelectedAttribute(spNew))
		{
			sp = spNew;

			// update list text
			CString sAttrib = m_cbAttributes.GetSelectedAttributeText();
			SetItemText(nRow, ATTRIB, sAttrib);

			// clear the operator cell text if the operator was no longer valid
			if (sp.OperatorIs(FOP_NONE))
				SetItemText(nRow, OPERATOR, _T(""));

			UpdateValueColumnText(nRow);
			ValidateListData();
		}
	}
}
void CTDLFindTaskExpressionListCtrl::OnOperatorEditOK()
{
	HideControl(m_cbOperators);

	// update operator type
	int nSel = m_cbOperators.GetCurSel();

	if (nSel != CB_ERR)
	{
		CString sSel;
		m_cbOperators.GetLBText(nSel, sSel);

		int nRow = GetCurSel();
		SetItemText(nRow, OPERATOR, sSel);

		// keep data store synched
		SEARCHPARAM& rule = m_aSearchParams[nRow];
		FIND_OPERATOR nNewOp = (FIND_OPERATOR)m_cbOperators.GetItemData(nSel);

		rule.SetOperator(nNewOp);

		// if the op is set/notset then clear the field
		if (nNewOp == FOP_SET || nNewOp == FOP_NOT_SET)
		{
			rule.ClearValue();
		}

		UpdateValueColumnText(nRow);
		ValidateListData();
	}
}
void CTDLFindTaskExpressionListCtrl::OnTimeChange()
{
	// update the rule 
	int nRow = GetCurSel();
	SEARCHPARAM& rule = m_aSearchParams[nRow];

	rule.SetValue(m_eTime.GetTime());
	rule.SetFlags(m_eTime.GetUnits());

	UpdateValueColumnText(nRow);
}
void CTDLFindTaskExpressionListCtrl::OnRiskEditOK()
{
	HideControl(m_cbRisk);

	// update value
	int nRow = GetCurSel();
	int nRisk = m_cbRisk.GetSelectedRisk();

	// keep data store synched
	m_aSearchParams[nRow].SetValue(nRisk);
	UpdateValueColumnText(nRow);
}
LRESULT CTDLFindTaskExpressionListCtrl::OnTimeUnitsChange(WPARAM /*wp*/, LPARAM /*lp*/)
{
	// update the rule 
	int nRow = GetCurSel();
	SEARCHPARAM& rule = m_aSearchParams[nRow];

	rule.SetFlags(m_eTime.GetUnits());

	UpdateValueColumnText(nRow);

	return 0L;
}
void CTDLFindTaskExpressionListCtrl::OnListValuesEditOK()
{
	HideControl(m_cbListValues);

	// update rule and cell text
	int nRow = GetCurSel();

	CStringArray aSel;
	m_cbListValues.GetChecked(aSel);

	m_aSearchParams[nRow].SetValue(Misc::FormatArray(aSel));
	UpdateValueColumnText(nRow);
}
void CTDLFindTaskExpressionListCtrl::OnDateChange(NMHDR* pNMHDR, LRESULT* pResult)
{
	LPNMDATETIMECHANGE pDTHDR = (LPNMDATETIMECHANGE)pNMHDR;
	COleDateTime dt(pDTHDR->st);

	// update the rule 
	int nRow = GetCurSel();

	m_aSearchParams[nRow].SetValue(dt);
	UpdateValueColumnText(nRow);
	
	*pResult = 0;
}
int CTDLFindTaskExpressionListCtrl::InsertRule(int nRow, const SEARCHPARAM& sp)
{
	m_aSearchParams.InsertAt(nRow, SEARCHPARAM(sp));

	CString sItem = m_cbAttributes.GetAttributeName(sp);
	int nNew = InsertItem(nRow, sItem);

	SetItemText(nNew, OPERATOR, GetOpName(sp.GetOperator()));

	UpdateValueColumnText(nRow);
	
	// Fixup And/or column
	RefreshAndOrColumnText();

	return nNew;
}
int CTDLFindTaskExpressionListCtrl::InsertRule(int nRow, const SEARCHPARAM& sp)
{
	m_aSearchParams.InsertAt(nRow, sp);

	CString sItem = m_cbAttributes.GetAttributeName(sp);
	int nNew = InsertItem(nRow, sItem);

	SetItemText(nNew, OPERATOR, GetOpName(sp.GetOperator()));

	UpdateValueColumnText(nRow);
	
	// omit and/or for last rule
	if (nRow < GetRuleCount() - 1)
	{
		CEnString sAndOr(sp.GetAnd() ? IDS_FP_AND : IDS_FP_OR);
		SetItemText(nNew, ANDOR, sAndOr);
	}

	return nNew;
}