XTPReportRow.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:26k
- // 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);
- }
- }