void EGridCtrl::OnLButtonDblClk( UINT nFlags, CPoint point )
{
	Column* pCol = GetColumn( point.x , true );

	if( pCol != NULL )
	{
		pCol->m_nWidth = 0;

		std::list<Row*>::iterator iter = m_vRows.begin();
		std::list<Row*>::iterator iend = m_vRows.end();

		CDC* pDC = GetDC();
		pDC->SelectObject(&m_Font);

		while( iter != iend )
		{
			Row* pRow = *iter;

			EProperty* pProperty = pRow->GetProperty( pCol->m_sName );

			if( pProperty != NULL )
			{
				pCol->EnsureWidth( pProperty->GetPreferedWidth(pDC) );
			}

			iter++;
		}

		ReleaseDC(pDC);
		RefreshColumnLefts( m_ViewportOrg.x );
		Invalidate();
		m_bWasDoubleClick = true;
	}
}
void EGridCtrl::BuildPropertyMap()
{
	//
	// rebuild propertymap
	//

	if( m_ppPropertyMap != NULL )
	{
		delete m_ppPropertyMap;
	}

	int nNumCells = m_vCols.size() * m_vRows.size();

	m_ppPropertyMap = new EProperty*[nNumCells];
	EProperty** ppMap = m_ppPropertyMap;

	//
	//
	//

	std::list<Row*>::iterator rowiter = m_vRows.begin();
	std::list<Row*>::iterator rowiend = m_vRows.end();
	while( rowiter != rowiend )
	{
		Row* pRow = *rowiter;

		std::list<Column*>::iterator coliter = m_vCols.begin();
		std::list<Column*>::iterator coliend = m_vCols.end();
		while( coliter != coliend )
		{
			Column* pColumn = *coliter;

			*ppMap++ = pRow->GetProperty( pColumn->m_sName );

			coliter++;
		}

		rowiter++;
	}
}
void EGridCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
	if( m_bWasDoubleClick )
	{
		m_bWasDoubleClick = false;
		return;
	}

	bool bOnHeaderRow = ( 0<=point.y && point.y<GetHeaderRowHeight() );

	if( bOnHeaderRow )					//is on header row?
	{
		if( point == m_MouseDownCP )	//mouse up same place as it was down?
		{
			if( m_pDragColumn==NULL )	//not dragging (not on column edge)
			{
				Column* pColumnToSort = GetColumn( point.x );		//get column where mouse was up!

				if( pColumnToSort != NULL )						//column exist here?
				{

					//
					// clear sortstate flag for all columns
					//

					std::list<Column*>::iterator coliter = m_vCols.begin();
					std::list<Column*>::iterator coliend = m_vCols.end();

					while( coliter != coliend )
					{
						Column* pC = *coliter;
						if( pC!=pColumnToSort )	//dont clear flag of column to sort
						{
							pC->m_nSortState = 0;
						}
						coliter++;
					}

					//
					//
					//

					if( m_vRows.size() > 1 )		//more than one column, so that we can actually sort something?
					{
						Row* pF = m_vRows.front();	//first
						Row* pL = m_vRows.back();	//last

						g_sSortProperty = pColumnToSort->m_sName;

						EProperty* pP1 = pF->GetProperty(g_sSortProperty);
						EProperty* pP2 = pL->GetProperty(g_sSortProperty);

						g_bSortGreatestAtTop = true;

						if( pP1 != NULL )
						{
							g_bSortGreatestAtTop = !pP1->GreaterThan(pP2);
						}

						pColumnToSort->m_nSortState = g_bSortGreatestAtTop ? 1 : 2;

						m_vRows.sort( std::greater<Row*>() );
					}
					else
					{
						pColumnToSort->m_nSortState = (pColumnToSort->m_nSortState==1) ? 2 : 1;	//just flip around (only one row, so it doesn't matter, but fells nice if sort indicator flips...)
					}

					BuildPropertyMap();
					Invalidate();

				}
			}
		}
	}

	m_pDragColumn = NULL;
	ReleaseCapture();

}