//------------------------------------------------------------------------
//! Overrides OnEditBegin() to allow special handling when clicking image or checkbox
//!
//! @param owner The list control starting edit
//! @param nRow The index of the row for the cell to edit
//! @param nCol The index of the column for the cell to edit
//! @param pt The position clicked, in client coordinates.
//! @return Pointer to the cell editor to use (NULL if cell edit is not possible)
//------------------------------------------------------------------------
CWnd* CGridColumnTraitImage::OnEditBegin(CGridListCtrlEx& owner, int nRow, int nCol, CPoint pt)
{
	// Check if the user used a shortcut key to edit the label
	if (pt == CPoint(-1, -1))
		return OnEditBegin(owner, nRow, nCol);

	// Check if mouse click was inside the label-part of the cell
	CRect labelRect;
	if (owner.GetCellRect(nRow, nCol, LVIR_LABEL, labelRect) && labelRect.PtInRect(pt))
		return OnEditBegin(owner, nRow, nCol);

	// Check if mouse click was inside the image-part of the cell
	CRect iconRect;
	if (owner.GetCellRect(nRow, nCol, LVIR_ICON, iconRect) && iconRect.PtInRect(pt))
		return OnEditBeginImage(owner, nRow, nCol);

	if (nCol == 0 && m_ToggleSelection && owner.GetExtendedStyle() & LVS_EX_CHECKBOXES)
	{
		// Check if mouse click was inside the checkbox-part of the label-column
		if (!labelRect.PtInRect(pt))
			return OnEditBeginCheckbox(owner, nRow, nCol);
	}

	return NULL;	// Editor is never really started
}
//------------------------------------------------------------------------
//! Reacts to clicking on the image, and allows all selected rows to be flipped
//!
//! @param owner The list control starting edit
//! @param nRow The index of the row for the cell to edit
//! @param nCol The index of the column for the cell to edit
//! @return Pointer to the cell editor to use (NULL if cell edit is not possible)
//------------------------------------------------------------------------
CWnd* CGridColumnTraitImage::OnEditBeginImage(CGridListCtrlEx& owner, int nRow, int nCol)
{
	if (m_ImageCellText.GetSize() <= 1)
	{
		// No images to flip between
		if (m_IconClickBeginEdit)
			return OnEditBegin(owner, nRow, nCol);
		else
			return NULL;
	}

	int nOldImageIdx = owner.GetCellImage(nRow, nCol);
	int nNewImageIdx = FlipImageIndex(owner, nRow, nCol);
	if (nNewImageIdx == -1)
		return NULL;

	CString strOldImageText, strNewImageText;
	for (int i = 0; i < m_ImageCellText.GetSize(); ++i)
	{
		if (m_ImageCellText.GetKeyAt(i) == nOldImageIdx)
			strOldImageText = m_ImageCellText.GetValueAt(i);
		if (m_ImageCellText.GetKeyAt(i) == nNewImageIdx)
			strNewImageText = m_ImageCellText.GetValueAt(i);
	}

	// Send Notification to parent of ListView ctrl
	LV_DISPINFO dispinfo = { 0 };
	dispinfo.item.mask = LVIF_IMAGE;
	dispinfo.item.iImage = nNewImageIdx;
	if (strNewImageText != strOldImageText)
	{
		dispinfo.item.mask |= LVIF_TEXT;
		dispinfo.item.pszText = strNewImageText.GetBuffer(0);
		dispinfo.item.cchTextMax = strNewImageText.GetLength();
	}
	SendEndLabelEdit(owner, nRow, nCol, dispinfo);

	// Toggle all selected rows to the same image index as the one clicked
	if (m_ToggleSelection)
	{
		// The click event for check-boxes doesn't change selection or focus
		if (owner.IsRowSelected(nRow))
		{
			POSITION pos = owner.GetFirstSelectedItemPosition();
			while (pos != NULL)
			{
				int nSelectedRow = owner.GetNextSelectedItem(pos);
				if (nSelectedRow == nRow)
					continue;	// Don't flip the clicked row

				int nNextOldImageIdx = owner.GetCellImage(nSelectedRow, nCol);
				if (nNextOldImageIdx == nNewImageIdx)
					continue;	// Already flipped

								// Send Notification to parent of ListView ctrl
				LV_DISPINFO nextDispinfo = { 0 };
				nextDispinfo.item.mask = LVIF_IMAGE;
				nextDispinfo.item.iImage = nNewImageIdx;
				if (strNewImageText != strOldImageText)
				{
					nextDispinfo.item.mask |= LVIF_TEXT;
					nextDispinfo.item.pszText = strNewImageText.GetBuffer(0);
					nextDispinfo.item.cchTextMax = strNewImageText.GetLength();
				}
				SendEndLabelEdit(owner, nSelectedRow, nCol, nextDispinfo);
			}
		}
	}

	return NULL;
}
//------------------------------------------------------------------------
//! Reacts to clicking on the cell image, and switch to the next image index
//!
//! @param owner The list control starting edit
//! @param nRow The index of the row for the cell to edit
//! @param nCol The index of the column for the cell to edit
//! @param pt The position clicked, in client coordinates.
//! @return Pointer to the cell editor to use (NULL if cell edit is not possible)
//------------------------------------------------------------------------
CWnd* CGridColumnTraitImage::OnEditBegin(CGridListCtrlEx& owner, int nRow, int nCol, CPoint pt)
{
	// Check if the user used a shortcut key to edit the label
	if (pt==CPoint(-1,-1)) 
		return OnEditBegin(owner, nRow, nCol);

	// Check if mouse click was inside the label-part of the cell
	CRect labelRect;
	if (owner.GetCellRect(nRow, nCol, LVIR_LABEL, labelRect) && labelRect.PtInRect(pt))
		return OnEditBegin(owner, nRow, nCol);

	CRect iconRect;
	if (owner.GetCellRect(nRow, nCol, LVIR_ICON, iconRect) && iconRect.PtInRect(pt))
	{
		int nOldImageIdx = owner.GetCellImage(nRow, nCol);
		int nNewImageIdx = FlipImageIndex(owner, nRow, nCol);
		if (nNewImageIdx == -1)
			return NULL;

		CString strOldImageText, strNewImageText;
		for(int i=0; i < m_ImageIndexes.GetSize(); ++i)
		{
			if (m_ImageIndexes.GetKeyAt(i)==nOldImageIdx)
				strOldImageText = m_ImageIndexes.GetValueAt(i).m_CellText;
			if (m_ImageIndexes.GetKeyAt(i)==nNewImageIdx)
				strNewImageText = m_ImageIndexes.GetValueAt(i).m_CellText;
		}

		// Send Notification to parent of ListView ctrl
		LV_DISPINFO dispinfo = {0};
		dispinfo.hdr.hwndFrom = owner.m_hWnd;
		dispinfo.hdr.idFrom = (UINT_PTR)owner.GetDlgCtrlID();
		dispinfo.hdr.code = LVN_ENDLABELEDIT;

		dispinfo.item.iItem = nRow;
		dispinfo.item.iSubItem = nCol;
		dispinfo.item.mask = LVIF_IMAGE;
		dispinfo.item.iImage = nNewImageIdx;

		if (strNewImageText!=strOldImageText)
		{
			dispinfo.item.mask |= LVIF_TEXT;
			dispinfo.item.pszText = strNewImageText.GetBuffer(0);
			dispinfo.item.cchTextMax = strNewImageText.GetLength();
		}

		owner.GetParent()->SendMessage( WM_NOTIFY, (WPARAM)owner.GetDlgCtrlID(), (LPARAM)&dispinfo );

		// Toggle all selected rows to the same image index as the one clicked
		if (m_ToggleSelection)
		{
			// The click event for check-boxes doesn't change selection or focus
			if (owner.IsRowSelected(nRow))
			{
				POSITION pos = owner.GetFirstSelectedItemPosition();
				while(pos!=NULL)
				{
					int nSelectedRow = owner.GetNextSelectedItem(pos);
					if (nSelectedRow==nRow)
						continue;	// Don't flip the clicked row

					int nNextOldImageIdx = owner.GetCellImage(nSelectedRow, nCol);
					if (nNextOldImageIdx==nNewImageIdx)
						continue;	// Already flipped

					// Send Notification to parent of ListView ctrl
					LV_DISPINFO nextDispinfo = {0};
					nextDispinfo.hdr.hwndFrom = owner.m_hWnd;
					nextDispinfo.hdr.idFrom = (UINT_PTR)owner.GetDlgCtrlID();
					nextDispinfo.hdr.code = LVN_ENDLABELEDIT;

					nextDispinfo.item.iItem = nSelectedRow;
					nextDispinfo.item.iSubItem = nCol;
					nextDispinfo.item.mask = LVIF_IMAGE;
					nextDispinfo.item.iImage = nNewImageIdx;

					if (strNewImageText!=strOldImageText)
					{
						nextDispinfo.item.mask |= LVIF_TEXT;
						nextDispinfo.item.pszText = strNewImageText.GetBuffer(0);
						nextDispinfo.item.cchTextMax = strNewImageText.GetLength();
					}

					owner.GetParent()->SendMessage( WM_NOTIFY, (WPARAM)owner.GetDlgCtrlID(), (LPARAM)&nextDispinfo );
				}
			}
		}
	}
	else if (nCol==0 && m_ToggleSelection && owner.GetExtendedStyle() & LVS_EX_CHECKBOXES)
	{
		// Check if we should toggle the label-column checkboxes for all the selected rows
		if (!labelRect.PtInRect(pt))
		{
			// The click event for check-boxes doesn't change selection or focus
			if (owner.IsRowSelected(nRow))
			{
				BOOL bChecked = FALSE;
				if (owner.GetStyle() & LVS_OWNERDATA)
					bChecked = owner.OnOwnerDataDisplayCheckbox(nRow) ? TRUE : FALSE;
				else
					bChecked = owner.GetCheck(nRow);	// The clicked row have already been changed by the click-event. We flip the other rows

				POSITION pos = owner.GetFirstSelectedItemPosition();
				while(pos!=NULL)
				{
					int nSelectedRow = owner.GetNextSelectedItem(pos);
					if (nSelectedRow==nRow)
						continue;	// Don't flip the clicked row

					if (owner.GetStyle() & LVS_OWNERDATA)
					{
						BOOL bSelChecked = owner.OnOwnerDataDisplayCheckbox(nSelectedRow) ? TRUE : FALSE;
						if (bChecked==bSelChecked)
							continue;	// Already flipped
					}
					else
					{
						if (owner.GetCheck(nSelectedRow)==bChecked)
							continue;	// Already flipped
					}

					if (owner.GetStyle() & LVS_OWNERDATA)
						owner.OnOwnerDataToggleCheckBox(nSelectedRow, bChecked ? true : false);
					else
						owner.SetCheck(nSelectedRow, bChecked);
				}
			}
		}
	}
	return NULL;	// Editor is never really started
}