1035 lines
25 KiB
C++
1035 lines
25 KiB
C++
|
|
// XTPReportRow.cpp : implementation of the CXTPReportRow class.
|
||
|
|
//
|
||
|
|
// This file is a part of the XTREME REPORTCONTROL MFC class library.
|
||
|
|
// (c)1998-2008 Codejock Software, All Rights Reserved.
|
||
|
|
//
|
||
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
||
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
||
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
||
|
|
//
|
||
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
||
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
||
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
||
|
|
// SINGLE COMPUTER.
|
||
|
|
//
|
||
|
|
// CONTACT INFORMATION:
|
||
|
|
// support@codejock.com
|
||
|
|
// http://www.codejock.com
|
||
|
|
//
|
||
|
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
#include "stdafx.h"
|
||
|
|
#include "Resource.h"
|
||
|
|
|
||
|
|
#include "Common/XTPDrawHelpers.h"
|
||
|
|
#include "Common/XTPToolTipContext.h"
|
||
|
|
|
||
|
|
#include "XTPReportRecord.h"
|
||
|
|
#include "XTPReportControl.h"
|
||
|
|
#include "XTPReportPaintManager.h"
|
||
|
|
#include "XTPReportRow.h"
|
||
|
|
#include "XTPReportColumns.h"
|
||
|
|
#include "XTPReportColumn.h"
|
||
|
|
#include "XTPReportRecordItem.h"
|
||
|
|
#include "XTPReportRecordItemText.h"
|
||
|
|
#include "XTPReportTip.h"
|
||
|
|
#include "XTPReportInplaceControls.h"
|
||
|
|
#include "XTPReportHeader.h"
|
||
|
|
|
||
|
|
#ifdef _DEBUG
|
||
|
|
#define new DEBUG_NEW
|
||
|
|
#undef THIS_FILE
|
||
|
|
static char THIS_FILE[] = __FILE__;
|
||
|
|
#endif
|
||
|
|
|
||
|
|
IMPLEMENT_DYNAMIC(CXTPReportRow, CCmdTarget)
|
||
|
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
// CXTPReportRow
|
||
|
|
|
||
|
|
|
||
|
|
CXTPReportRow::CXTPReportRow()
|
||
|
|
: m_pParentRow(NULL), m_pRecord(NULL), m_pControl(NULL), m_pParentRows(NULL)
|
||
|
|
{
|
||
|
|
m_nGroupLevel = m_nRowLevel = 0;
|
||
|
|
|
||
|
|
|
||
|
|
m_bVisible = FALSE;
|
||
|
|
m_pChilds = NULL;
|
||
|
|
m_bExpanded = TRUE;
|
||
|
|
|
||
|
|
m_rcRow.SetRectEmpty();
|
||
|
|
m_rcCollapse.SetRectEmpty();
|
||
|
|
m_nChildIndex = m_nIndex = -1;
|
||
|
|
|
||
|
|
m_nPreviewHeight = 0;
|
||
|
|
m_nRowType = xtpRowTypeBody;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void CXTPReportRow::InitRow(CXTPReportControl* pControl, CXTPReportRecord* pRecord)
|
||
|
|
{
|
||
|
|
ASSERT(pRecord || IsGroupRow());
|
||
|
|
|
||
|
|
m_pControl = pControl;
|
||
|
|
|
||
|
|
if (pRecord)
|
||
|
|
{
|
||
|
|
m_pRecord = pRecord;
|
||
|
|
m_bExpanded = pRecord->m_bExpanded;
|
||
|
|
m_pRecord->InternalAddRef();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void CXTPReportRow::InitRow(CXTPReportRow* pRow)
|
||
|
|
{
|
||
|
|
ASSERT(pRow->m_pRecord);
|
||
|
|
ASSERT(pRow->m_pParentRow == NULL);
|
||
|
|
|
||
|
|
m_pControl = pRow->m_pControl;
|
||
|
|
m_pRecord = pRow->m_pRecord;
|
||
|
|
if (m_pRecord) m_pRecord->InternalAddRef();
|
||
|
|
m_rcRow = pRow->m_rcRow;
|
||
|
|
m_nIndex = pRow->m_nIndex;
|
||
|
|
m_nPreviewHeight = pRow->m_nPreviewHeight;
|
||
|
|
m_nRowLevel = pRow->m_nRowLevel;
|
||
|
|
m_nGroupLevel = pRow->m_nGroupLevel;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
CXTPReportRows* CXTPReportRow::GetChilds()
|
||
|
|
{
|
||
|
|
if (!m_pChilds)
|
||
|
|
{
|
||
|
|
m_pChilds = new CXTPReportRows();
|
||
|
|
}
|
||
|
|
return m_pChilds;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
CXTPReportRow::~CXTPReportRow()
|
||
|
|
{
|
||
|
|
if (m_pChilds)
|
||
|
|
{
|
||
|
|
m_pChilds->InternalRelease();
|
||
|
|
}
|
||
|
|
|
||
|
|
if (m_pRecord)
|
||
|
|
{
|
||
|
|
m_pRecord->InternalRelease();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
int CXTPReportRow::GetHeight(CDC* pDC, int nWidth)
|
||
|
|
{
|
||
|
|
ASSERT(m_pControl);
|
||
|
|
if (!m_pControl)
|
||
|
|
return 0;
|
||
|
|
int nHeight = m_pControl->GetPaintManager()->GetRowHeight(pDC, this, nWidth);
|
||
|
|
|
||
|
|
if (!IsGroupRow() && !IsItemsVisible())
|
||
|
|
nHeight = 0;
|
||
|
|
|
||
|
|
if (pDC->IsPrinting())
|
||
|
|
return nHeight;
|
||
|
|
|
||
|
|
m_nPreviewHeight = 0;
|
||
|
|
|
||
|
|
if (IsPreviewVisible())
|
||
|
|
{
|
||
|
|
CXTPReportRecordItemPreview* pItem = GetRecord()->GetItemPreview();
|
||
|
|
|
||
|
|
m_nPreviewHeight = pItem->GetPreviewHeight(pDC, this, m_pControl->GetReportHeader()->GetWidth());
|
||
|
|
m_nPreviewHeight = m_pControl->GetPaintManager()->GetPreviewItemHeight(pDC, this, m_pControl->GetReportHeader()->GetWidth(), m_nPreviewHeight);
|
||
|
|
|
||
|
|
return nHeight + m_nPreviewHeight;
|
||
|
|
}
|
||
|
|
|
||
|
|
return nHeight;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
BOOL CXTPReportRow::IsFocused() const
|
||
|
|
{
|
||
|
|
switch(m_nRowType)
|
||
|
|
{
|
||
|
|
case xtpRowTypeBody:
|
||
|
|
return m_pControl->m_nFocusedRow == m_nIndex;
|
||
|
|
case xtpRowTypeHeader:
|
||
|
|
return m_pControl->m_nFocusedHeaderRow == m_nIndex;
|
||
|
|
case xtpRowTypeFooter:
|
||
|
|
return m_pControl->m_nFocusedFooterRow == m_nIndex;
|
||
|
|
}
|
||
|
|
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL CXTPReportRow::IsSelected() const
|
||
|
|
{
|
||
|
|
return m_pControl->GetSelectedRows()->Contains(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
void CXTPReportRow::SetSelected(BOOL bSelected)
|
||
|
|
{
|
||
|
|
if (bSelected)
|
||
|
|
{
|
||
|
|
if (!m_pControl->IsMultipleSelection())
|
||
|
|
m_pControl->GetSelectedRows()->Clear();
|
||
|
|
|
||
|
|
m_pControl->GetSelectedRows()->Add(this);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
m_pControl->GetSelectedRows()->Remove(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
m_pControl->RedrawControl();
|
||
|
|
}
|
||
|
|
|
||
|
|
int CXTPReportRow::GetLastChildRow(CXTPReportRows* pChilds) const
|
||
|
|
{
|
||
|
|
CXTPReportRow* pRow = pChilds->GetAt(pChilds->GetCount() - 1);
|
||
|
|
return pRow->HasChildren() && pRow->IsExpanded() ? GetLastChildRow(pRow->GetChilds()) : pRow->GetIndex();
|
||
|
|
}
|
||
|
|
|
||
|
|
void CXTPReportRow::SelectChilds()
|
||
|
|
{
|
||
|
|
if (!(m_pControl->IsMultipleSelection() && HasChildren() && IsExpanded() && m_nIndex != -1))
|
||
|
|
return;
|
||
|
|
|
||
|
|
m_pControl->BeginUpdate();
|
||
|
|
|
||
|
|
int nIndexBegin = m_nIndex + 1;
|
||
|
|
int nIndexEnd = GetLastChildRow(GetChilds());
|
||
|
|
|
||
|
|
m_pControl->GetSelectedRows()->AddBlock(nIndexBegin, nIndexEnd);
|
||
|
|
|
||
|
|
m_pControl->EndUpdate();
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL CXTPReportRow::IsItemsVisible() const
|
||
|
|
{
|
||
|
|
return TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
BOOL CXTPReportRow::IsPreviewVisible() const
|
||
|
|
{
|
||
|
|
return !IsGroupRow() && m_pRecord && m_pControl->IsPreviewMode() && m_pRecord->GetItemPreview() != NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
void CXTPReportRow::Draw(CDC* pDC, CRect rcRow, int nLeftOffset)
|
||
|
|
{
|
||
|
|
ASSERT(m_pControl);
|
||
|
|
if (!m_pControl)
|
||
|
|
return;
|
||
|
|
|
||
|
|
BOOL bControlFocused = m_pControl->HasFocus();
|
||
|
|
int nFreezeCols = m_pControl->m_nFreezeColumnsCount;
|
||
|
|
CRect rcClipBox = m_pControl->GetReportRectangle();
|
||
|
|
|
||
|
|
m_rcRow = rcRow;
|
||
|
|
m_rcRow.left -= nLeftOffset;
|
||
|
|
m_rcRow.right -= nLeftOffset;
|
||
|
|
|
||
|
|
if (nFreezeCols == 0)
|
||
|
|
{
|
||
|
|
rcRow = m_rcRow;
|
||
|
|
}
|
||
|
|
|
||
|
|
XTP_REPORTRECORDITEM_DRAWARGS drawArgs;
|
||
|
|
drawArgs.pDC = pDC;
|
||
|
|
drawArgs.pControl = m_pControl;
|
||
|
|
drawArgs.pRow = this;
|
||
|
|
int nIndentWidth = m_pControl->GetHeaderIndent();
|
||
|
|
CXTPReportPaintManager* pPaintManager = m_pControl->GetPaintManager();
|
||
|
|
|
||
|
|
CXTPReportColumns arrVisibleColumns(m_pControl);
|
||
|
|
m_pControl->GetColumns()->GetVisibleColumns(arrVisibleColumns);
|
||
|
|
int nVisColCount = arrVisibleColumns.GetCount();
|
||
|
|
nFreezeCols = min(nFreezeCols, nVisColCount);
|
||
|
|
|
||
|
|
// paint row background
|
||
|
|
pPaintManager->FillRow(pDC, this, m_rcRow);
|
||
|
|
|
||
|
|
CRect rcItem(m_rcRow.left, m_rcRow.top, m_rcRow.right, m_rcRow.bottom - m_nPreviewHeight);
|
||
|
|
|
||
|
|
CRect rcIndent(nFreezeCols ? rcRow : m_rcRow);
|
||
|
|
rcIndent.right = rcIndent.left + nIndentWidth;
|
||
|
|
|
||
|
|
if (m_pRecord) // if drawing record, not group
|
||
|
|
{
|
||
|
|
int xMinCol_0 = rcRow.left + nIndentWidth;
|
||
|
|
// paint record items
|
||
|
|
for (int nColumn = nVisColCount-1; nColumn >= 0; nColumn--)
|
||
|
|
{
|
||
|
|
BOOL bFreezeCol = nColumn < nFreezeCols;
|
||
|
|
int nColIdx = bFreezeCol ? nFreezeCols - 1 - nColumn : nColumn;
|
||
|
|
|
||
|
|
CXTPReportColumn* pColumn = arrVisibleColumns.GetAt(nColIdx);
|
||
|
|
ASSERT(pColumn && pColumn->IsVisible());
|
||
|
|
|
||
|
|
if (pColumn && IsItemsVisible())
|
||
|
|
{
|
||
|
|
rcItem.left = pColumn->GetRect().left;
|
||
|
|
if (nColIdx == 0)
|
||
|
|
{
|
||
|
|
rcItem.left = max(xMinCol_0, rcItem.left);
|
||
|
|
}
|
||
|
|
rcItem.right = pColumn->GetRect().right;
|
||
|
|
|
||
|
|
if (!CRect().IntersectRect(rcClipBox, rcItem))
|
||
|
|
continue;
|
||
|
|
|
||
|
|
if (bFreezeCol)
|
||
|
|
{
|
||
|
|
pDC->FillSolidRect(rcItem, pPaintManager->GetControlBackColor(GetControl()));
|
||
|
|
pPaintManager->FillRow(pDC, this, rcItem);
|
||
|
|
}
|
||
|
|
|
||
|
|
CRect rcGridItem(rcItem);
|
||
|
|
rcGridItem.left--;
|
||
|
|
|
||
|
|
// draw shade background if sorted by this row
|
||
|
|
if (pColumn->IsSorted())
|
||
|
|
{
|
||
|
|
pPaintManager->FillItemShade(pDC, rcItem);
|
||
|
|
}
|
||
|
|
|
||
|
|
CXTPReportRecordItem* pItem = m_pRecord->GetItem(pColumn);
|
||
|
|
|
||
|
|
if (pItem)
|
||
|
|
{
|
||
|
|
// draw item
|
||
|
|
drawArgs.pColumn = pColumn;
|
||
|
|
drawArgs.rcItem = rcItem;
|
||
|
|
drawArgs.nTextAlign = pColumn->GetAlignment();
|
||
|
|
drawArgs.pItem = pItem;
|
||
|
|
// draw item
|
||
|
|
int nItemTextWidth = pItem->Draw(&drawArgs);
|
||
|
|
|
||
|
|
pColumn->m_nMaxItemWidth = max(pColumn->m_nMaxItemWidth, nItemTextWidth);
|
||
|
|
}
|
||
|
|
|
||
|
|
pPaintManager->DrawGrid(pDC, TRUE, rcGridItem);
|
||
|
|
|
||
|
|
if (nColIdx == nFreezeCols - 1)
|
||
|
|
pPaintManager->DrawFreezeColsDivider(pDC, rcGridItem, GetControl(), this);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (IsPreviewVisible())
|
||
|
|
{
|
||
|
|
CRect rcPreviewItem(m_rcRow);
|
||
|
|
rcPreviewItem.DeflateRect(nIndentWidth, rcPreviewItem.Height() - m_nPreviewHeight, 0, 0);
|
||
|
|
|
||
|
|
drawArgs.rcItem = rcPreviewItem;
|
||
|
|
drawArgs.nTextAlign = DT_LEFT;
|
||
|
|
drawArgs.pItem = m_pRecord->GetItemPreview();
|
||
|
|
drawArgs.pColumn = NULL;
|
||
|
|
|
||
|
|
drawArgs.pItem->Draw(&drawArgs);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (nIndentWidth > 0)
|
||
|
|
{
|
||
|
|
// draw indent column
|
||
|
|
pPaintManager->FillIndent(pDC, rcIndent);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL bGridVisible = pPaintManager->IsGridVisible(FALSE);
|
||
|
|
|
||
|
|
//CRect rcFocus(m_rcRow.left + nIndentWidth, m_rcRow.top, m_rcRow.right, m_rcRow.bottom - (bGridVisible ? 1 : 0));
|
||
|
|
CRect rcFocus(rcIndent.right, m_rcRow.top, m_rcRow.right, m_rcRow.bottom - (bGridVisible ? 1 : 0));
|
||
|
|
|
||
|
|
if (IsFocused() && bControlFocused && m_pControl->IsRowFocusVisible())
|
||
|
|
pPaintManager->DrawFocusedRow(pDC, rcFocus);
|
||
|
|
|
||
|
|
|
||
|
|
if (m_nIndex < m_pControl->GetRows()->GetCount() - 1 && nIndentWidth > 0)
|
||
|
|
{
|
||
|
|
CXTPReportRow* pNextRow = m_pControl->GetRows()->GetAt(m_nIndex + 1);
|
||
|
|
ASSERT(pNextRow);
|
||
|
|
if (pNextRow) rcFocus.left = rcIndent.left + min(nIndentWidth, pPaintManager->m_nTreeIndent * pNextRow->GetTreeDepth());
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
rcFocus.left = m_rcRow.left;
|
||
|
|
}
|
||
|
|
|
||
|
|
pPaintManager->DrawGrid(pDC, FALSE, rcFocus);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int CXTPReportRow::GetTreeDepth() const
|
||
|
|
{
|
||
|
|
return m_nRowLevel;
|
||
|
|
}
|
||
|
|
|
||
|
|
INT_PTR CXTPReportRow::OnToolHitTest(CPoint point, TOOLINFO* pTI)
|
||
|
|
{
|
||
|
|
CRect rcItem;
|
||
|
|
CXTPReportRecordItem* pItem = HitTest(point, &rcItem);
|
||
|
|
|
||
|
|
if (!pItem)
|
||
|
|
return -1;
|
||
|
|
|
||
|
|
INT_PTR nHit = (INT_PTR)pItem;
|
||
|
|
CString strTip = pItem->GetTooltip();
|
||
|
|
|
||
|
|
m_pControl->OnGetToolTipInfo(this, pItem, strTip);
|
||
|
|
|
||
|
|
if (strTip.IsEmpty() || strTip == _T(" "))
|
||
|
|
return -1;
|
||
|
|
|
||
|
|
CXTPToolTipContext::FillInToolInfo(pTI, m_pControl->m_hWnd, rcItem,
|
||
|
|
nHit, strTip);
|
||
|
|
|
||
|
|
return nHit;
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL CXTPReportRow::OnLButtonDown(XTP_REPORTRECORDITEM_CLICKARGS* pClickArgs)
|
||
|
|
{
|
||
|
|
if(pClickArgs->pItem && pClickArgs->pItem->OnLButtonDown(pClickArgs))
|
||
|
|
return TRUE;
|
||
|
|
return (BOOL)m_pControl->SendMessageToParent(this, pClickArgs->pItem, pClickArgs->pColumn, XTP_NM_REPORT_LBUTTONDOWN, &pClickArgs->ptClient);
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL CXTPReportRow::OnLButtonUp(XTP_REPORTRECORDITEM_CLICKARGS* pClickArgs)
|
||
|
|
{
|
||
|
|
if(pClickArgs->pItem)
|
||
|
|
pClickArgs->pItem->OnLButtonUp(pClickArgs);
|
||
|
|
return TRUE;
|
||
|
|
}
|
||
|
|
|
||
|
|
void CXTPReportRow::OnClick(CPoint ptClicked)
|
||
|
|
{
|
||
|
|
XTP_REPORTRECORDITEM_CLICKARGS clickArgs;
|
||
|
|
clickArgs.pControl = m_pControl;
|
||
|
|
clickArgs.pRow = this;
|
||
|
|
clickArgs.ptClient = ptClicked;
|
||
|
|
clickArgs.pColumn = NULL;
|
||
|
|
|
||
|
|
// find clicked item
|
||
|
|
clickArgs.pItem = HitTest(ptClicked, &clickArgs.rcItem, &clickArgs.pColumn);
|
||
|
|
|
||
|
|
if(m_pControl->IsVirtualMode())
|
||
|
|
{
|
||
|
|
if (m_nRowLevel == 0 && m_rcCollapse.PtInRect(ptClicked)
|
||
|
|
&& clickArgs.pColumn && clickArgs.pColumn->IsTreeColumn())
|
||
|
|
{
|
||
|
|
m_pControl->SendMessageToParent(this, NULL, NULL, XTP_NM_REPORT_ROWEXPANDED, NULL);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (HasChildren() && m_rcCollapse.PtInRect(ptClicked)
|
||
|
|
&& clickArgs.pColumn && clickArgs.pColumn->IsTreeColumn())
|
||
|
|
{
|
||
|
|
SetExpanded(!IsExpanded());
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// notify item if found
|
||
|
|
if (!clickArgs.pItem)
|
||
|
|
return;
|
||
|
|
|
||
|
|
clickArgs.pItem->OnClick(&clickArgs);
|
||
|
|
}
|
||
|
|
|
||
|
|
void CXTPReportRow::OnDblClick(CPoint ptClicked)
|
||
|
|
{
|
||
|
|
XTP_REPORTRECORDITEM_CLICKARGS clickArgs;
|
||
|
|
clickArgs.pControl = m_pControl;
|
||
|
|
clickArgs.pRow = this;
|
||
|
|
clickArgs.ptClient = ptClicked;
|
||
|
|
clickArgs.pColumn = NULL;
|
||
|
|
|
||
|
|
// find clicked item
|
||
|
|
clickArgs.pItem = HitTest(ptClicked, &clickArgs.rcItem, &clickArgs.pColumn);
|
||
|
|
|
||
|
|
// notify item if found
|
||
|
|
if (clickArgs.pItem != NULL)
|
||
|
|
{
|
||
|
|
clickArgs.pItem->OnDblClick(&clickArgs);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
// just notify parent
|
||
|
|
m_pControl->SendMessageToParent(this, NULL, clickArgs.pColumn, NM_DBLCLK, &ptClicked, -1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
CRect CXTPReportRow::GetItemRect(CXTPReportRecordItem* pItem)
|
||
|
|
{
|
||
|
|
if (!IsItemsVisible() || !pItem || !m_pRecord)
|
||
|
|
return CRect(0, 0, 0, 0);
|
||
|
|
|
||
|
|
if (IsPreviewVisible() && pItem == GetRecord()->GetItemPreview())
|
||
|
|
{
|
||
|
|
return CRect(m_rcRow.left + m_pControl->GetHeaderIndent(),
|
||
|
|
m_rcRow.bottom - m_nPreviewHeight, m_rcRow.right, m_rcRow.bottom);
|
||
|
|
}
|
||
|
|
|
||
|
|
CXTPReportColumns* pColumns = m_pControl->GetColumns();
|
||
|
|
int nColumnCount = pColumns->GetCount();
|
||
|
|
|
||
|
|
CRect rcItem(0, m_rcRow.top, 0, m_rcRow.bottom - m_nPreviewHeight);
|
||
|
|
|
||
|
|
int nFreezeColCount = m_pControl->GetFreezeColumnsCount();
|
||
|
|
int nLeft = nFreezeColCount ? pColumns->GetAt(nFreezeColCount - 1)->GetRect().right : 0;
|
||
|
|
|
||
|
|
for (int nColumn = 0; nColumn < nColumnCount; nColumn++)
|
||
|
|
{
|
||
|
|
CXTPReportColumn* pColumn = pColumns->GetAt(nColumn);
|
||
|
|
if (pColumn && pColumn->IsVisible())
|
||
|
|
{
|
||
|
|
if (m_pRecord->GetItem(pColumn) != pItem)
|
||
|
|
continue;
|
||
|
|
|
||
|
|
rcItem.left = pColumn->GetRect().left;
|
||
|
|
rcItem.right = pColumn->GetRect().right;
|
||
|
|
if(pColumn->GetIndex() >= nFreezeColCount)
|
||
|
|
{
|
||
|
|
rcItem.left = max(rcItem.left, nLeft);
|
||
|
|
rcItem.right = max(rcItem.right, nLeft);
|
||
|
|
}
|
||
|
|
if(rcItem.Width() <= 0)
|
||
|
|
return CRect(0, 0, 0, 0);
|
||
|
|
ShiftTreeIndent(rcItem, pColumn);
|
||
|
|
return rcItem;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return CRect(0, 0, 0, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
void CXTPReportRow::ShiftTreeIndent(CRect& rcItem, CXTPReportColumn* pColumn) const
|
||
|
|
{
|
||
|
|
if (pColumn->IsTreeColumn())
|
||
|
|
{
|
||
|
|
int nTreeDepth = GetTreeDepth() - m_nGroupLevel;
|
||
|
|
if (nTreeDepth > 0)
|
||
|
|
nTreeDepth++;
|
||
|
|
rcItem.left += m_pControl->GetIndent(nTreeDepth);
|
||
|
|
|
||
|
|
CRect rcBitmap(rcItem);
|
||
|
|
int nIndent = m_pControl->GetPaintManager()->DrawCollapsedBitmap(NULL, this, rcBitmap).cx;
|
||
|
|
|
||
|
|
rcItem.left += nIndent + 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
CXTPReportRecordItem* CXTPReportRow::HitTest(CPoint ptPoint, CRect* pRectItem, CXTPReportColumn** ppColumn) const
|
||
|
|
{
|
||
|
|
if (!m_pRecord)
|
||
|
|
return NULL;
|
||
|
|
|
||
|
|
// find record item
|
||
|
|
int x = m_rcRow.left + m_pControl->GetHeaderIndent();
|
||
|
|
|
||
|
|
CXTPReportColumns* pColumns = m_pControl->GetColumns();
|
||
|
|
int nColumnCount = pColumns->GetCount();
|
||
|
|
|
||
|
|
|
||
|
|
// if hittes for Preview item
|
||
|
|
if (IsPreviewVisible())
|
||
|
|
{
|
||
|
|
CXTPReportRecordItemPreview* pPreviewItem = GetRecord()->GetItemPreview();
|
||
|
|
if (pPreviewItem)
|
||
|
|
{
|
||
|
|
CRect rcItem(x, m_rcRow.bottom - m_nPreviewHeight, m_rcRow.right, m_rcRow.bottom);
|
||
|
|
if (rcItem.PtInRect(ptPoint))
|
||
|
|
{
|
||
|
|
if (pRectItem)
|
||
|
|
{
|
||
|
|
*pRectItem = rcItem;
|
||
|
|
}
|
||
|
|
return pPreviewItem;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
CRect rcItem(0, m_rcRow.top, 0, m_rcRow.bottom - m_nPreviewHeight);
|
||
|
|
|
||
|
|
if (!IsItemsVisible())
|
||
|
|
return NULL;
|
||
|
|
|
||
|
|
int nFreezeColCount = m_pControl->GetFreezeColumnsCount();
|
||
|
|
int nLeft = nFreezeColCount ? pColumns->GetAt(nFreezeColCount - 1)->GetRect().right : 0;
|
||
|
|
|
||
|
|
for (int nColumn = 0; nColumn < nColumnCount; nColumn++)
|
||
|
|
{
|
||
|
|
CXTPReportColumn* pColumn = pColumns->GetAt(nColumn);
|
||
|
|
if (pColumn && pColumn->IsVisible())
|
||
|
|
{
|
||
|
|
rcItem.left = pColumn->GetRect().left;
|
||
|
|
rcItem.right = pColumn->GetRect().right;
|
||
|
|
if(pColumn->GetIndex() >= nFreezeColCount)
|
||
|
|
{
|
||
|
|
rcItem.left = max(rcItem.left, nLeft);
|
||
|
|
rcItem.right = max(rcItem.right, nLeft);
|
||
|
|
}
|
||
|
|
if(!rcItem.Width())
|
||
|
|
continue;
|
||
|
|
|
||
|
|
if (rcItem.PtInRect(ptPoint) && ppColumn)
|
||
|
|
{
|
||
|
|
*ppColumn = pColumn;
|
||
|
|
}
|
||
|
|
// make tooltip shift if tree view (see also Draw function)
|
||
|
|
ShiftTreeIndent(rcItem, pColumn);
|
||
|
|
|
||
|
|
// check point
|
||
|
|
if (rcItem.PtInRect(ptPoint))
|
||
|
|
{
|
||
|
|
if (pRectItem)
|
||
|
|
{
|
||
|
|
*pRectItem = rcItem;
|
||
|
|
}
|
||
|
|
|
||
|
|
return m_pRecord->GetItem(pColumn);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
void CXTPReportRow::OnMouseMove(UINT nFlags, CPoint point)
|
||
|
|
{
|
||
|
|
|
||
|
|
// find clicked item
|
||
|
|
CRect rcItem;
|
||
|
|
CXTPReportRecordItem* pItem = HitTest(point, &rcItem);
|
||
|
|
|
||
|
|
// notify item if found
|
||
|
|
if (pItem != NULL)
|
||
|
|
{
|
||
|
|
pItem->OnMouseMove(nFlags, point, m_pControl);
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void CXTPReportRow::FillMetrics(CXTPReportColumn* pColumn, CXTPReportRecordItem* pItem, XTP_REPORTRECORDITEM_METRICS* pMetrics)
|
||
|
|
{
|
||
|
|
m_pControl->m_nLockUpdateCount++;
|
||
|
|
XTP_REPORTRECORDITEM_DRAWARGS drawArgs;
|
||
|
|
drawArgs.pDC = NULL;
|
||
|
|
drawArgs.pColumn = pColumn;
|
||
|
|
drawArgs.pControl = m_pControl;
|
||
|
|
drawArgs.pRow = this;
|
||
|
|
drawArgs.rcItem.SetRectEmpty();
|
||
|
|
drawArgs.pItem = pItem;
|
||
|
|
drawArgs.nTextAlign = pColumn ? pColumn->GetAlignment() : DT_LEFT;
|
||
|
|
GetItemMetrics(&drawArgs, pMetrics);
|
||
|
|
m_pControl->m_nLockUpdateCount--;
|
||
|
|
}
|
||
|
|
|
||
|
|
void CXTPReportRow::ShowToolTip(CPoint ptTip, CXTPReportTip* pTipWnd)
|
||
|
|
{
|
||
|
|
CRect rcItem(0, 0, 0, 0);
|
||
|
|
CXTPReportColumn* pColumn = NULL;
|
||
|
|
CXTPReportRecordItem* pItem = HitTest(ptTip, &rcItem, &pColumn);
|
||
|
|
// show tooltip
|
||
|
|
if (!(pItem && (pItem->IsPreviewItem() || !pItem->IsPreviewItem() && pColumn)))
|
||
|
|
{
|
||
|
|
pTipWnd->m_pItem = NULL;
|
||
|
|
pTipWnd->m_nRowIndex = -1;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!CXTPDrawHelpers::IsTopParentActive(m_pControl->GetSafeHwnd()) || m_pControl->GetActiveItem())
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((pItem != pTipWnd->m_pItem) || (m_nIndex != pTipWnd->m_nRowIndex))
|
||
|
|
{
|
||
|
|
pTipWnd->m_pItem = pItem;
|
||
|
|
pTipWnd->m_nRowIndex = m_nIndex;
|
||
|
|
|
||
|
|
CString strTip = pItem->GetTooltip();
|
||
|
|
m_pControl->OnGetToolTipInfo(this, pItem, strTip);
|
||
|
|
|
||
|
|
if (!strTip.IsEmpty() || strTip == _T(" ") || pColumn && (pColumn->GetAlignment() & DT_WORDBREAK))
|
||
|
|
return;
|
||
|
|
|
||
|
|
if (pItem->GetMarkupUIElement() != 0)
|
||
|
|
return;
|
||
|
|
|
||
|
|
XTP_REPORTRECORDITEM_METRICS* pMetrics = new XTP_REPORTRECORDITEM_METRICS();
|
||
|
|
pMetrics->strText = pItem->GetCaption(pColumn);
|
||
|
|
FillMetrics(pColumn, pItem, pMetrics);
|
||
|
|
|
||
|
|
CString strText(pMetrics->strText);
|
||
|
|
|
||
|
|
strText.TrimRight();
|
||
|
|
|
||
|
|
if (strText.IsEmpty())
|
||
|
|
{
|
||
|
|
pMetrics->InternalRelease();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
XTP_REPORTRECORDITEM_ARGS itemArgs;
|
||
|
|
itemArgs.pControl = m_pControl;
|
||
|
|
itemArgs.pRow = this;
|
||
|
|
|
||
|
|
pItem->GetCaptionRect(&itemArgs, rcItem);
|
||
|
|
|
||
|
|
m_pControl->ClientToScreen(&rcItem);
|
||
|
|
|
||
|
|
if (!pTipWnd->GetSafeHwnd())
|
||
|
|
{
|
||
|
|
pTipWnd->Create(m_pControl);
|
||
|
|
}
|
||
|
|
|
||
|
|
CWindowDC dc(m_pControl);
|
||
|
|
CXTPFontDC font(&dc, pMetrics->pFont);
|
||
|
|
CRect rcTooltip(rcItem);
|
||
|
|
BOOL bActivate = FALSE;
|
||
|
|
if (pItem->IsPreviewItem())
|
||
|
|
{
|
||
|
|
CRect rcCalc(rcTooltip.left, 0, rcTooltip.right, 0);
|
||
|
|
dc.DrawText(strText, rcCalc, DT_WORDBREAK | DT_CALCRECT | DT_NOPREFIX);
|
||
|
|
bActivate = (rcCalc.Height() / dc.GetTextExtent(_T(" "), 1).cy) > m_pControl->GetPaintManager()->GetMaxPreviewLines();
|
||
|
|
rcTooltip.bottom = rcTooltip.top + rcCalc.Height();
|
||
|
|
rcTooltip.right++;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
CSize sz = dc.GetTextExtent(strText);
|
||
|
|
bActivate = sz.cx > (rcTooltip.Width() - 4);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (bActivate)
|
||
|
|
{
|
||
|
|
rcTooltip.InflateRect(1, 1, 0, 0);
|
||
|
|
|
||
|
|
pTipWnd->SetFont(pMetrics->pFont);
|
||
|
|
pTipWnd->SetTooltipText(strText);
|
||
|
|
pTipWnd->SetHoverRect(rcTooltip);
|
||
|
|
pTipWnd->Activate(TRUE, pItem->IsPreviewItem());
|
||
|
|
|
||
|
|
TRACKMOUSEEVENT tme =
|
||
|
|
{
|
||
|
|
sizeof(TRACKMOUSEEVENT), TME_LEAVE, m_pControl->GetSafeHwnd(), 0
|
||
|
|
};
|
||
|
|
_TrackMouseEvent (&tme);
|
||
|
|
}
|
||
|
|
|
||
|
|
pMetrics->InternalRelease();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL CXTPReportRow::HasParent(CXTPReportRow* pRow)
|
||
|
|
{
|
||
|
|
if (m_pParentRow == NULL)
|
||
|
|
return FALSE;
|
||
|
|
if (pRow == m_pParentRow)
|
||
|
|
return TRUE;
|
||
|
|
return m_pParentRow->HasParent(pRow);
|
||
|
|
}
|
||
|
|
|
||
|
|
void CXTPReportRow::SetExpanded(BOOL bExpanded)
|
||
|
|
{
|
||
|
|
if (bExpanded != m_bExpanded && HasChildren())
|
||
|
|
{
|
||
|
|
if (bExpanded)
|
||
|
|
{
|
||
|
|
m_pControl->_DoExpand(this);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
m_pControl->_DoCollapse(this);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (m_pRecord)
|
||
|
|
{
|
||
|
|
m_pRecord->m_bExpanded = bExpanded;
|
||
|
|
}
|
||
|
|
|
||
|
|
m_bExpanded = bExpanded;
|
||
|
|
|
||
|
|
m_pControl->_RefreshIndexes();
|
||
|
|
m_pControl->SendMessageToParent(this, NULL, NULL, XTP_NM_REPORT_ROWEXPANDED, NULL);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
m_bExpanded = bExpanded;
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
CXTPReportRow* CXTPReportRow::AddChild(CXTPReportRow* pRow)
|
||
|
|
{
|
||
|
|
GetChilds()->Add(pRow);
|
||
|
|
pRow->m_pParentRow = this;
|
||
|
|
|
||
|
|
return pRow;
|
||
|
|
}
|
||
|
|
|
||
|
|
void CXTPReportRow::OnContextMenu(CPoint ptClick)
|
||
|
|
{
|
||
|
|
CXTPReportColumn* pColumn = NULL;
|
||
|
|
CXTPReportRecordItem* pItem = HitTest(ptClick, NULL, &pColumn);
|
||
|
|
|
||
|
|
m_pControl->ClientToScreen(&ptClick);
|
||
|
|
|
||
|
|
// send process notification to the user and wait for the reaction
|
||
|
|
m_pControl->SendMessageToParent(this, pItem, pColumn, NM_RCLICK, &ptClick);
|
||
|
|
}
|
||
|
|
|
||
|
|
void CXTPReportRow::GetItemMetrics(XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs, XTP_REPORTRECORDITEM_METRICS* pItemMetrics)
|
||
|
|
{
|
||
|
|
ASSERT(m_pRecord);
|
||
|
|
ASSERT(pDrawArgs->pRow == this);
|
||
|
|
ASSERT(pDrawArgs->pItem != NULL);
|
||
|
|
if (!m_pRecord || !pDrawArgs->pItem)
|
||
|
|
return;
|
||
|
|
|
||
|
|
CXTPReportPaintManager* pPaintManager = pDrawArgs->pControl->GetPaintManager();
|
||
|
|
|
||
|
|
pItemMetrics->pFont = &pPaintManager->m_fontText;
|
||
|
|
pItemMetrics->clrForeground = pPaintManager->m_clrWindowText;
|
||
|
|
pItemMetrics->clrBackground = XTP_REPORT_COLOR_DEFAULT;
|
||
|
|
pItemMetrics->nColumnAlignment = pDrawArgs->nTextAlign;
|
||
|
|
pItemMetrics->nItemIcon = XTP_REPORT_NOICON;
|
||
|
|
|
||
|
|
m_pRecord->GetItemMetrics(pDrawArgs, pItemMetrics);
|
||
|
|
pDrawArgs->pItem->GetItemMetrics(pDrawArgs, pItemMetrics);
|
||
|
|
|
||
|
|
m_pControl->GetItemMetrics(pDrawArgs, pItemMetrics);
|
||
|
|
pDrawArgs->nTextAlign = pItemMetrics->nColumnAlignment;
|
||
|
|
|
||
|
|
if (IsSelected() && (pDrawArgs->pDC && !pDrawArgs->pDC->IsPrinting()))
|
||
|
|
{
|
||
|
|
if (pDrawArgs->pColumn && IsFocused() && m_pControl->m_pFocusedColumn == pDrawArgs->pColumn)
|
||
|
|
return;
|
||
|
|
|
||
|
|
if (GetControl()->HasFocus())
|
||
|
|
{
|
||
|
|
pItemMetrics->clrForeground = pPaintManager->m_clrHighlightText;
|
||
|
|
pItemMetrics->clrBackground = pPaintManager->m_clrHighlight;
|
||
|
|
}
|
||
|
|
else if (!pPaintManager->m_bHideSelection)
|
||
|
|
{
|
||
|
|
pItemMetrics->clrForeground = pPaintManager->m_clrSelectedRowText;
|
||
|
|
pItemMetrics->clrBackground = pPaintManager->m_clrSelectedRow;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL CXTPReportRow::HasChildren() const
|
||
|
|
{
|
||
|
|
return m_pChilds && m_pChilds->GetCount() > 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int CXTPReportRow::GetIndex() const
|
||
|
|
{
|
||
|
|
return m_nIndex;
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL CXTPReportRow::IsGroupRow() const
|
||
|
|
{
|
||
|
|
return FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL CXTPReportRow::IsExpanded() const
|
||
|
|
{
|
||
|
|
return m_bExpanded;
|
||
|
|
}
|
||
|
|
|
||
|
|
BOOL CXTPReportRow::IsLastTreeRow() const
|
||
|
|
{
|
||
|
|
if (!m_pParentRow)
|
||
|
|
return FALSE;
|
||
|
|
|
||
|
|
CXTPReportRows* pRows = m_pParentRow->GetChilds();
|
||
|
|
|
||
|
|
return pRows->GetCount() > 0 && pRows->GetAt(pRows->GetCount() - 1) == this;
|
||
|
|
}
|
||
|
|
|
||
|
|
void CXTPReportRow::EnsureVisible()
|
||
|
|
{
|
||
|
|
m_pControl->EnsureVisible(this);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
CXTPReportRow* CXTPReportRow::GetNextSiblingRow() const
|
||
|
|
{
|
||
|
|
if (!m_pParentRows)
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
if (m_nChildIndex == -1)
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
ASSERT(m_pParentRows->GetAt(m_nChildIndex) == this);
|
||
|
|
|
||
|
|
if (m_nChildIndex < m_pParentRows->GetCount() - 1)
|
||
|
|
return m_pParentRows->GetAt(m_nChildIndex + 1);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void CXTPReportRow::DrawFixed(CDC* pDC, CRect rcRow, int nLeftOffset, CRect rcArea)
|
||
|
|
{
|
||
|
|
ASSERT(m_pControl);
|
||
|
|
if (!m_pControl)
|
||
|
|
return;
|
||
|
|
|
||
|
|
// BOOL bControlFocused = m_pControl->HasFocus();
|
||
|
|
int nFreezeCols = m_pControl->m_nFreezeColumnsCount;
|
||
|
|
|
||
|
|
CRect rcClipBox = rcArea ;
|
||
|
|
|
||
|
|
m_rcRow = rcRow;
|
||
|
|
m_rcRow.left -= nLeftOffset;
|
||
|
|
m_rcRow.right -= nLeftOffset;
|
||
|
|
|
||
|
|
if (nFreezeCols == 0)
|
||
|
|
{
|
||
|
|
rcRow = m_rcRow;
|
||
|
|
}
|
||
|
|
|
||
|
|
XTP_REPORTRECORDITEM_DRAWARGS drawArgs;
|
||
|
|
drawArgs.pDC = pDC;
|
||
|
|
drawArgs.pControl = m_pControl;
|
||
|
|
drawArgs.pRow = this;
|
||
|
|
int nIndentWidth = m_pControl->GetHeaderIndent();
|
||
|
|
|
||
|
|
CXTPReportPaintManager* pPaintManager = m_pControl->GetPaintManager();
|
||
|
|
|
||
|
|
// whether to draw header's last horizontal grid depends on header divider style.
|
||
|
|
BOOL bDrawLastHeaderGrid = TRUE;
|
||
|
|
if (GetType() == xtpRowTypeHeader)
|
||
|
|
{
|
||
|
|
bDrawLastHeaderGrid = xtpReportFixedRowsDividerNone == (pPaintManager->GetHeaderRowsDividerStyle() & ~xtpReportFixedRowsDividerShade);
|
||
|
|
}
|
||
|
|
|
||
|
|
// whether to draw footer's first horizontal grid depends on footer divider style.
|
||
|
|
BOOL bDrawFirstFooterGrid = TRUE;
|
||
|
|
if (GetType() == xtpRowTypeFooter)
|
||
|
|
{
|
||
|
|
bDrawFirstFooterGrid = xtpReportFixedRowsDividerNone == (pPaintManager->GetFooterRowsDividerStyle() & ~xtpReportFixedRowsDividerShade);
|
||
|
|
}
|
||
|
|
|
||
|
|
CXTPReportColumns arrVisibleColumns(m_pControl);
|
||
|
|
m_pControl->GetColumns()->GetVisibleColumns(arrVisibleColumns);
|
||
|
|
int nVisColCount = arrVisibleColumns.GetCount();
|
||
|
|
nFreezeCols = min(nFreezeCols, nVisColCount);
|
||
|
|
|
||
|
|
// paint row background
|
||
|
|
pDC->FillSolidRect(m_rcRow, pPaintManager->GetControlBackColor(GetControl()));
|
||
|
|
|
||
|
|
CRect rcItem(m_rcRow.left, m_rcRow.top, m_rcRow.right, m_rcRow.bottom - m_nPreviewHeight);
|
||
|
|
|
||
|
|
CRect rcIndent(nFreezeCols ? rcRow : m_rcRow);
|
||
|
|
rcIndent.right = rcIndent.left + nIndentWidth;
|
||
|
|
|
||
|
|
if (m_pRecord) // if drawing record, not group
|
||
|
|
{
|
||
|
|
int xMinCol_0 = rcRow.left + nIndentWidth;
|
||
|
|
// paint record items
|
||
|
|
for (int nColumn = nVisColCount-1; nColumn >= 0; nColumn--)
|
||
|
|
{
|
||
|
|
BOOL bFreezeCol = nColumn < nFreezeCols;
|
||
|
|
int nColIdx = bFreezeCol ? nFreezeCols - 1 - nColumn : nColumn;
|
||
|
|
|
||
|
|
CXTPReportColumn* pColumn = arrVisibleColumns.GetAt(nColIdx);
|
||
|
|
ASSERT(pColumn && pColumn->IsVisible());
|
||
|
|
|
||
|
|
if (pColumn && IsItemsVisible())
|
||
|
|
{
|
||
|
|
rcItem.left = pColumn->GetRect().left;
|
||
|
|
if (nColIdx == 0)
|
||
|
|
{
|
||
|
|
rcItem.left = max(xMinCol_0, rcItem.left);
|
||
|
|
}
|
||
|
|
rcItem.right = pColumn->GetRect().right;
|
||
|
|
|
||
|
|
if (!CRect().IntersectRect(rcClipBox, rcItem))
|
||
|
|
continue;
|
||
|
|
|
||
|
|
if (bFreezeCol)
|
||
|
|
{
|
||
|
|
pDC->FillSolidRect(rcItem, pPaintManager->GetControlBackColor(GetControl()));
|
||
|
|
pPaintManager->FillRow(pDC, this, rcItem);
|
||
|
|
}
|
||
|
|
|
||
|
|
CRect rcGridItem(rcItem);
|
||
|
|
rcGridItem.left--;
|
||
|
|
|
||
|
|
// draw shade background if sorted by this row
|
||
|
|
if (pColumn->IsSorted())
|
||
|
|
{
|
||
|
|
pPaintManager->FillItemShade(pDC, rcItem);
|
||
|
|
}
|
||
|
|
|
||
|
|
CXTPReportRecordItem* pItem = m_pRecord->GetItem(pColumn);
|
||
|
|
|
||
|
|
if (pItem)
|
||
|
|
{
|
||
|
|
// draw item
|
||
|
|
drawArgs.pColumn = pColumn;
|
||
|
|
drawArgs.rcItem = rcItem;
|
||
|
|
drawArgs.nTextAlign = pColumn->GetAlignment();
|
||
|
|
drawArgs.pItem = pItem;
|
||
|
|
// draw item
|
||
|
|
int nItemTextWidth = pItem->Draw(&drawArgs);
|
||
|
|
|
||
|
|
pColumn->m_nMaxItemWidth = max(pColumn->m_nMaxItemWidth, nItemTextWidth);
|
||
|
|
}
|
||
|
|
|
||
|
|
// is vertical grid required
|
||
|
|
if (GetType() == xtpRowTypeHeader)
|
||
|
|
{
|
||
|
|
if (pColumn->GetDrawHeaderRowsVGrid())
|
||
|
|
pPaintManager->DrawGrid(pDC, TRUE, rcGridItem);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
if (GetType() == xtpRowTypeFooter)
|
||
|
|
{
|
||
|
|
if (pColumn->GetDrawFooterRowsVGrid())
|
||
|
|
pPaintManager->DrawGrid(pDC, TRUE, rcGridItem);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (bDrawFirstFooterGrid)
|
||
|
|
{
|
||
|
|
// horizontal grid above
|
||
|
|
CRect rcTop(rcGridItem);
|
||
|
|
rcTop.bottom = --rcGridItem.top;
|
||
|
|
pPaintManager->DrawGrid(pDC, FALSE, rcTop);
|
||
|
|
}
|
||
|
|
bDrawFirstFooterGrid = TRUE;
|
||
|
|
|
||
|
|
if (nColIdx == nFreezeCols - 1)
|
||
|
|
pPaintManager->DrawFreezeColsDivider(pDC, rcGridItem, GetControl(), this);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (nIndentWidth > 0)
|
||
|
|
{
|
||
|
|
// draw indent column
|
||
|
|
pPaintManager->FillIndent(pDC, rcIndent);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// draw focus
|
||
|
|
BOOL bControlFocused = m_pControl->HasFocus();
|
||
|
|
BOOL bGridVisible = pPaintManager->IsGridVisible(FALSE);
|
||
|
|
CRect rcFocus(rcIndent.right, m_rcRow.top, m_rcRow.right, m_rcRow.bottom - (bGridVisible ? 1 : 0));
|
||
|
|
|
||
|
|
if (IsFocused() && bControlFocused && m_pControl->IsRowFocusVisible())
|
||
|
|
pPaintManager->DrawFocusedRow(pDC, rcFocus);
|
||
|
|
|
||
|
|
// last header grid line
|
||
|
|
if (bDrawLastHeaderGrid)
|
||
|
|
{
|
||
|
|
pPaintManager->DrawGrid(pDC, FALSE, rcFocus);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|