You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1896 lines
48 KiB
C++

// XTPReportRecordItem.cpp : implementation of the CXTPReportRecordItem class.
//
// This file is a part of the XTREME REPORTCONTROL MFC class library.
// (c)1998-2012 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 <locale.h>
#include "Common/XTPDrawHelpers.h"
#include "Common/XTPMarkupRender.h"
#include "Common/XTPResourceManager.h"
#include "Common/XTPPropExchange.h"
#include "Common/XTPCustomHeap.h"
#include "Common/XTPSystemHelpers.h"
#include "Common/XTPSmartPtrInternalT.h"
#include "Common/XTPColorManager.h"
#include "XTPReportDefines.h"
#include "XTPReportRow.h"
#include "XTPReportRecords.h"
#include "XTPReportColumns.h"
#include "XTPReportColumn.h"
#include "XTPReportControl.h"
#include "XTPReportPaintManager.h"
#include "XTPReportHyperlink.h"
#include "XTPReportRecord.h"
#include "XTPReportRecordItem.h"
#include "XTPReportRecordItemConstraint.h"
#include "XTPReportInplaceControls.h"
#include "XTPReportRecordItemControls.h"
#include "XTPReportBorder.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#ifndef IDC_HAND
#define IDC_HAND MAKEINTRESOURCE(32649)
#endif
//////////////////////////////////////////////////////////////////////////
// XTP_REPORTRECORDITEM_ARGS
XTP_REPORTRECORDITEM_ARGS::XTP_REPORTRECORDITEM_ARGS()
{
pControl = NULL;
pRow = NULL;
pColumn = NULL;
pItem = NULL;
rcItem.SetRectEmpty();
}
XTP_REPORTRECORDITEM_ARGS::XTP_REPORTRECORDITEM_ARGS(
CXTPReportControl *pControl,
CXTPReportRow *pRow,
CXTPReportColumn *pColumn)
{
ASSERT(pControl && pRow && pColumn);
this->pControl = pControl;
this->pRow = pRow;
this->pColumn = pColumn;
this->pItem = pRow->GetRecord()->GetItem(pColumn);
this->rcItem = pRow->GetItemRect(pItem);
}
XTP_REPORTRECORDITEM_ARGS::~XTP_REPORTRECORDITEM_ARGS()
{
}
void XTP_REPORTRECORDITEM_ARGS::AddRef()
{
CMDTARGET_ADDREF(pRow);
CMDTARGET_ADDREF(pColumn);
CMDTARGET_ADDREF(pItem);
}
void XTP_REPORTRECORDITEM_ARGS::Release()
{
if (pRow)
pRow->InternalRelease();
if (pColumn)
pColumn->InternalRelease();
if (pItem)
pItem->InternalRelease();
}
const XTP_REPORTRECORDITEM_ARGS& XTP_REPORTRECORDITEM_ARGS::operator=(const XTP_REPORTRECORDITEM_ARGS& src)
{
pControl = src.pControl;
pRow = src.pRow;
pColumn = src.pColumn;
pItem = src.pItem;
rcItem = src.rcItem;
return *this;
}
CXTPReportInplaceButtons::CXTPReportInplaceButtons()
{
}
//////////////////////////////////////////////////////////////////////////
// CXTPReportRecordItem
IMPLEMENT_SERIAL(CXTPReportRecordItem, CCmdTarget, VERSIONABLE_SCHEMA | _XTP_SCHEMA_CURRENT)
CXTPReportRecordItem::CXTPReportRecordItem()
: m_pMergeItem(NULL)
, m_checkState(xtpReportCheckStateUnchecked)
, m_pControl(NULL)
, m_pRecord (NULL)
, m_pBorder (NULL)
{
static const CString g_strFormatStringDef = _T("%s");
m_strFormatString = g_strFormatStringDef;
m_strFormula.Empty();
m_bEditable = TRUE;
m_pFontCaption = NULL;
m_bBoldText = FALSE;
m_clrText = XTP_REPORT_COLOR_DEFAULT;
m_clrBackground = XTP_REPORT_COLOR_DEFAULT;
m_nIconIndex = XTP_REPORT_NOICON;
m_dwData = 0;
m_nSortPriority = -1;
m_nGroupPriority = -1;
m_Alignment = (XTPReportColumnIconAlignment)(-1);
m_bHasCheckbox = FALSE;
m_bCanEditCheckboxItem = FALSE;
m_bTristateCheckbox = FALSE;
m_pEditOptions = NULL;
m_pItemControls = NULL;
m_pFocusedItemControl = NULL;
m_bItemControlUnderMouse = FALSE;
m_pItemControlHookWnd = NULL;
m_bFocusable = TRUE;
m_pHyperlinks = NULL;
m_pMarkupUIElement = NULL;
m_rcGlyph.SetRectEmpty();
}
CXTPReportRecordItem::~CXTPReportRecordItem()
{
if (m_pItemControlHookWnd)
{
m_pItemControlHookWnd->DestroyWindow();
delete m_pItemControlHookWnd;
m_pItemControlHookWnd = NULL;
}
CMDTARGET_RELEASE(m_pEditOptions);
CMDTARGET_RELEASE(m_pItemControls);
CMDTARGET_RELEASE(m_pHyperlinks);
XTPMarkupReleaseElement(m_pMarkupUIElement);
}
double CXTPReportRecordItem::StringToDouble(CString strText)
{
TCHAR* locale = _tsetlocale(LC_NUMERIC, NULL);
if (locale == NULL || _tcscmp(locale, _T("C")) == 0) // Not set
{
strText.Replace(',', '.');
}
double res = atof(XTP_CT2CA(strText));
return res;
}
void CXTPReportRecordItem::ParseBBCode(CString &strText)
{
GetHyperlinks()->RemoveAll();
//////////////////////////////////////////////////////////////////////////
// Left [url=address]name[/url] Right
//////////////////////////////////////////////////////////////////////////
const CString sUrlTagOpen = _T("[url");
const CString sUrlTagClose = _T("[/url]");
int nOpenTagStart = strText.Find(sUrlTagOpen);
int nOpenTagEnd;
int nCloseTagStart;
int nCloseTagEnd;
while (-1 != nOpenTagStart)
{
nOpenTagEnd = strText.Find(_T("]"), nOpenTagStart);
CString sLeft = strText.Left(nOpenTagStart);
nCloseTagStart = strText.Find(sUrlTagClose);
CString sName = strText.Mid(nOpenTagEnd+1, nCloseTagStart-nOpenTagEnd-1);
nCloseTagEnd = nCloseTagStart + sUrlTagClose.GetLength();
CString sRight = strText.Right(strText.GetLength()-nCloseTagEnd);
strText = sLeft + sName + sRight;
GetHyperlinks()->Add(new CXTPReportHyperlink(nOpenTagStart, nCloseTagStart-nOpenTagEnd-1));
nOpenTagStart = strText.Find(sUrlTagOpen);
}
}
void CXTPReportRecordItem::SetCaption(LPCTSTR lpszCaption)
{
CString strCaption(lpszCaption);
if (!m_strFormula.IsEmpty()
&& m_pRecord != NULL)
{
COLORREF clrSum = RGB(255,0,0);
COLORREF clrSubSum = RGB(0,0,255);
if (m_pControl)
{
clrSum = m_pControl->GetPaintManager()->m_clrFormulaSum;
clrSubSum = m_pControl->GetPaintManager()->m_clrFormulaSubSum;
}
//CODE FOR RECALC
double d(0.0);
int m(0), M(0), n(0), N(0);
CString s, t, u, v;
CString sFormula(m_strFormula);
int pos = sFormula.Find(_T("SUMSUB("));
//pattern SUMSUB(R#C#:R#C#) or * instead of # - means all row or column
if (pos > -1 && m_pRecord->GetChilds() != NULL)
{
int mMax = m_pRecord->GetChilds()->GetCount();
int nMax = m_pRecord->GetItemCount();
sFormula.Replace(_T(" "), _T(""));
sFormula = sFormula.Mid(pos + 7);
pos = sFormula.Find(_T(":"));
if (pos > -1)
{
s = sFormula.Left(pos);
t = sFormula.Mid(pos + 1);
pos = s.Find(_T("C"));
if (pos > -1)
{
u = s.Left(pos);
s = s.Mid(pos + 1);
u.Replace(_T("R"), _T(""));
if (u == _T("*"))
m = 0;
else
m = _ttoi(u);
if (s == _T("*"))
n = 0;
else
n = _ttoi(s);
pos = t.Find(_T("C"));
if (pos > -1)
{
u = t.Left(pos);
t = t.Mid(pos + 1);
u.Replace(_T("R"), _T(""));
if (u == _T("*"))
M = mMax;
else
M = _ttoi(u);
t.Replace(_T(")"), _T(""));
if (t == _T("*"))
N = nMax;
else
N = _ttoi(t);
CXTPReportRecord* pRec = NULL;
CXTPReportRecordItem* pItem = NULL;
if (mMax > 0)
{
for (int row = m; row < M; row++)
{
for (int col = n; col < N; col++)
{
if (row < mMax)
{
pRec = m_pRecord->GetChilds()->GetAt(row);
if (pRec)
{
if (col < pRec->GetItemCount())
{
pItem = pRec->GetItem(col);
if (pItem && pItem != this) //no circular ref!)
{
s = pItem->GetCaption(NULL);
d += StringToDouble(s);
}
}
}
}
}
}
CString sFmt = GetFormatString();
if (sFmt.IsEmpty() || sFmt == _T("%s"))
sFmt = _T("%f");
else if (sFmt == _T("%d"))
sFmt = _T("%.0f");
strCaption.Format(sFmt, d);
SetTextColor(clrSubSum );
}
}
}
}
}
sFormula = m_strFormula;
pos = sFormula.Find(_T("SUM("));
//pattern SUM(R#C#:R#C#) or * instead of # - means all row or column
if (pos > -1 && m_pRecord->GetRecords() != NULL)
{
int mMax = m_pRecord->GetRecords()->GetCount();
int nMax = m_pRecord->GetItemCount();
sFormula.Replace(_T(" "), _T(""));
sFormula = sFormula.Mid(pos + 4);
pos = sFormula.Find(_T(":"));
if (pos > -1)
{
s = sFormula.Left(pos);
t = sFormula.Mid(pos + 1);
pos = s.Find(_T("C"));
if (pos > -1)
{
u = s.Left(pos);
s = s.Mid(pos + 1);
u.Replace(_T("R"), _T(""));
if (u == _T("*"))
m = 0;
else
m = _ttoi(u);
if (s == _T("*"))
n = 0;
else
n = _ttoi(s);
pos = t.Find(_T("C"));
if (pos > -1)
{
u = t.Left(pos);
t = t.Mid(pos + 1);
u.Replace(_T("R"), _T(""));
if (u == _T("*"))
M = mMax;
else
M = _ttoi(u);
t.Replace(_T(")"), _T(""));
if (t == _T("*"))
N = nMax;
else
N = _ttoi(t);
CXTPReportRecord* pRec = NULL;
CXTPReportRecordItem* pItem = NULL;
if (m_pRecord->GetRecords())
{
for (int row = m; row < M; row++)
{
for (int col = n; col < N; col++)
{
if (row < mMax)
{
pRec = m_pRecord->GetRecords()->GetAt(row);
if (pRec)
{
if (col < pRec->GetItemCount())
{
pItem = pRec->GetItem(col);
if (pItem && pItem != this) //no circular ref!
{
s = pItem->GetCaption(NULL);
d += StringToDouble(s);
}
}
}
}
}
}
CString sFmt = GetFormatString();
if (sFmt.IsEmpty() || sFmt == _T("%s"))
sFmt = _T("%f");
else if (sFmt == _T("%d"))
sFmt = _T("%.0f");
strCaption.Format(sFmt, d);
SetTextColor(clrSum );
}
}
}
}
}
}
//else if (m_strFormula.IsEmpty())
//{
// CString sFmt = GetFormatString();
// if (sFmt.Find(_T("%")) > -1)
// {
// if (sFmt.Find(_T("d")) > -1)
// strCaption.Format(sFmt, _ttoi(strCaption));
// else if (sFmt.Find(_T("f")) > -1 || sFmt.Find(_T("g")) > -1)
// strCaption.Format(sFmt, _tstof(strCaption));
// else
// strCaption.Format(sFmt, strCaption);
// }
//}
if (m_strCaption == strCaption)
return;
m_strCaption = strCaption;
XTPMarkupReleaseElement(m_pMarkupUIElement);
if (m_pRecord == NULL) return;
CXTPMarkupContext* pMarkupContext = m_pRecord->GetMarkupContext();
if (pMarkupContext)
m_pMarkupUIElement = XTPMarkupParseText(pMarkupContext, strCaption);
else if (m_pRecord->m_pRecords) //extra source of markup
{
pMarkupContext = m_pRecord->m_pRecords->GetMarkupContext();
if (pMarkupContext)
m_pMarkupUIElement = XTPMarkupParseText(pMarkupContext, strCaption);
}
}
void CXTPReportRecordItem::DoMouseButtonClick()
{
mouse_event(GetSystemMetrics(SM_SWAPBUTTON) ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(GetSystemMetrics(SM_SWAPBUTTON) ? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
void CXTPReportRecordItem::GetCaptionRect(XTP_REPORTRECORDITEM_ARGS* pDrawArgs, CRect& rcItem)
{
ASSERT(pDrawArgs->pControl);
if (!pDrawArgs->pControl)
return;
m_pControl = pDrawArgs->pControl;
CXTPReportPaintManager* pPaintManager = pDrawArgs->pControl->GetPaintManager();
if (GetIconIndex() != XTP_REPORT_NOICON)
{
if (GetAlignment() != -1 && (GetAlignment() & xtpColumnIconRight) != 0)
rcItem.right -= pPaintManager->DrawBitmap(NULL, pDrawArgs->pControl, rcItem, GetIconIndex());
else
rcItem.left += pPaintManager->DrawBitmap(NULL, pDrawArgs->pControl, rcItem, GetIconIndex());
}
if (m_bHasCheckbox)
rcItem.left += 15;
if (m_pItemControls && m_pItemControls->GetSize())
{
for (int i = 0; i < m_pItemControls->GetSize() && rcItem.Width() > 0; i++)
{
int nWidth = m_pItemControls->GetAt(i)->GetSize().cx;
nWidth = nWidth < 0 ? rcItem.Width() : nWidth;
if (m_pItemControls->GetAt(i)->GetAlignment() == xtpItemControlRight)
rcItem.right -= nWidth;
else
rcItem.left += nWidth;
}
}
// Adjust for new lock icon
BOOL bShowLock = !IsEditable() && pPaintManager->m_bShowLockIcon;
if (bShowLock && !pDrawArgs->pControl->IsIconView()) //to prevent reaction on always read-only IconColumn / NumberColumn
{
rcItem.left += 18;
}
}
void CXTPReportRecordItem::DrawCheckBox(XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs, CRect& rcItem)
{
BOOL bEditable = IsEditable()
&& (pDrawArgs->pColumn == NULL || pDrawArgs->pColumn->IsEditable());
CDC *pDC = pDrawArgs->pDC;
XTPReportGlyph eState = xtpReportGlyphInvalid;
if ( bEditable && !IsChecked()) { eState = xtpReportGlyphEnabledUnchecked; }
else if ( bEditable && IsChecked()) { eState = xtpReportGlyphEnabledChecked; }
else if (!bEditable && !IsChecked()) { eState = xtpReportGlyphDisabledUnchecked; }
else if (!bEditable && IsChecked()) { eState = xtpReportGlyphDisabledChecked; }
if (m_bTristateCheckbox && GetCheckedState() == xtpReportCheckStateIndeterminate)
{
eState = xtpReportGlyphEnabledTristate;
}
CXTPReportPaintManager *pPaintManager = pDrawArgs->pControl->GetPaintManager();
int nIconAlign = pDrawArgs->nTextAlign & xtpColumnIconMask;
int nIconAlignV = nIconAlign & 0x0F000000;
int nIconAlignH = nIconAlign & 0x00F00000;
m_rcGlyph = rcItem;
CSize sizeGlyph = pPaintManager->DrawGlyph(NULL, m_rcGlyph, eState);
CRect rcGlyph(m_rcGlyph);
// horizontal alignment
switch (nIconAlignH)
{
case xtpColumnIconRight:
rcGlyph.left = rcItem.right - sizeGlyph.cx - 2;
// shift text box to the left
rcItem.right -= (2 + sizeGlyph.cx);
break;
case xtpColumnIconCenter:
rcGlyph.left = rcItem.CenterPoint().x - sizeGlyph.cx / 2 - 1;
rcGlyph.right = rcGlyph.left + sizeGlyph.cx;
break; // left text box as is - draw on image...
case xtpColumnIconLeft:
default:
// shift text box to the right
rcItem.left += 2 + sizeGlyph.cx;
rcGlyph.left += 2;
rcGlyph.right = rcItem.left - 1;
break;
}
// vertical alignment
switch (nIconAlignV)
{
case xtpColumnIconTop:
rcGlyph.bottom = rcItem.top + sizeGlyph.cy + 2;
break;
case xtpColumnIconBottom:
rcGlyph.top = rcItem.bottom - sizeGlyph.cy - 2;
break;
}
// draw the glyph
pPaintManager->DrawGlyph(pDC, rcGlyph, eState);
m_rcGlyph = rcGlyph; //to restrict click on Glyph area only
}
void CXTPReportRecordItem::OnDrawCaption(
XTP_REPORTRECORDITEM_DRAWARGS *pDrawArgs,
XTP_REPORTRECORDITEM_METRICS *pMetrics)
{
ASSERT(pDrawArgs->pItem == this);
CXTPReportPaintManager *pPaintManager = pDrawArgs->pControl->GetPaintManager();
BOOL bForceMarkUp(FALSE);
if (pPaintManager)
bForceMarkUp = pPaintManager->m_bForceDynamicMarkupForCell;
//THIS CONDITION - IsVirtualMode() [Rev 7687 Oct 2008] PREVENTS MARKUP in Non-Virtual mode
//if (pDrawArgs->pControl->IsVirtualMode() && pDrawArgs->pControl->GetMarkupContext())
//if (pDrawArgs->pControl->GetMarkupContext()
// && !m_pMarkupUIElement) - rev 9113
//if (pDrawArgs->pControl->IsVirtualMode()
// && pDrawArgs->pControl->GetMarkupContext() && !m_pMarkupUIElement) - rev 9114
// FIXED BACK! Only for virtual mode! Developer have to set Caption of Item to have markup
// FIXED AGAIN WITH SPECIAL Flag to use
if ((pDrawArgs->pControl->IsVirtualMode() || bForceMarkUp)
&& pDrawArgs->pControl->GetMarkupContext() && !m_pMarkupUIElement)
{
CXTPMarkupUIElement* pMarkupUIElement = XTPMarkupParseText(pDrawArgs->pControl->GetMarkupContext(), pMetrics->strText);
if (pMarkupUIElement)
{
CRect rcItem = pDrawArgs->rcItem;
rcItem.DeflateRect(2, 1, 2, 0);
XTPMarkupSetDefaultFont(XTPMarkupElementContext(pMarkupUIElement), (HFONT)pMetrics->pFont->GetSafeHandle(), pMetrics->clrForeground);
XTPMarkupMeasureElement(pMarkupUIElement, rcItem.Width(), INT_MAX);
XTPMarkupRenderElement(pMarkupUIElement, pDrawArgs->pDC->GetSafeHdc(), &rcItem);
XTPMarkupReleaseElement(pMarkupUIElement);
return;
}
}
if (m_pMarkupUIElement)
{
CRect rcItem = pDrawArgs->rcItem;
rcItem.DeflateRect(2, 1, 2, 0);
XTPMarkupSetDefaultFont(XTPMarkupElementContext(m_pMarkupUIElement), (HFONT)pMetrics->pFont->GetSafeHandle(), pMetrics->clrForeground);
XTPMarkupMeasureElement(m_pMarkupUIElement, rcItem.Width(), INT_MAX);
XTPMarkupRenderElement(m_pMarkupUIElement, pDrawArgs->pDC->GetSafeHdc(), &rcItem);
}
else
{
if (pPaintManager)
{
pPaintManager->DrawItemCaption(pDrawArgs, pMetrics);
}
}
}
void CXTPReportRecordItem::OnDrawControls(XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs, CRect& rcItem)
{
ASSERT(pDrawArgs->pItem == this);
if (!m_pItemControls)
return;
for (int i = 0; i < m_pItemControls->GetSize() && rcItem.Width(); i++)
{
pDrawArgs->pControl->GetPaintManager()->DrawItemControl(pDrawArgs, m_pItemControls->GetAt(i), rcItem);
}
}
int CXTPReportRecordItem::Draw(XTP_REPORTRECORDITEM_DRAWARGS *pDrawArgs)
{
ASSERT(pDrawArgs->pControl);
if (!pDrawArgs->pControl)
return 0;
else
m_pControl = pDrawArgs->pControl;
CDC* pDC = pDrawArgs->pDC;
CRect& rcItem = pDrawArgs->rcItem;
CXTPReportPaintManager* pPaintManager = pDrawArgs->pControl->GetPaintManager();
XTP_REPORTRECORDITEM_METRICS* pMetrics = new XTP_REPORTRECORDITEM_METRICS();
pMetrics->strText = GetCaption(pDrawArgs->pColumn);
pDrawArgs->pRow->GetItemMetrics(pDrawArgs, pMetrics);
ASSERT(pMetrics->pFont);
ASSERT(pMetrics->clrForeground != XTP_REPORT_COLOR_DEFAULT);
if (pMetrics->clrBackground != XTP_REPORT_COLOR_DEFAULT)
{
pDC->FillSolidRect(rcItem, pMetrics->clrBackground);
}
int nItemGlyphs = rcItem.left;
// draw tree inside item rect (see also HitTest function)
if (pDrawArgs->pColumn && pDrawArgs->pColumn->IsTreeColumn())
{
int nTreeDepth = pDrawArgs->pRow->GetTreeDepth() - pDrawArgs->pRow->GetGroupLevel();
if (nTreeDepth > 0)
nTreeDepth++;
BOOL bHasChildren = TRUE;
if (pDrawArgs->pControl->IsVirtualMode())
{
bHasChildren = (pMetrics->nVirtRowFlags & xtpVirtRowHasChildren) > 0;
if (!bHasChildren)
pDrawArgs->pRow->m_rcCollapse = CRect(NULL);
if (pDrawArgs->pColumn == pDrawArgs->pControl->GetColumns()->GetIndentColumn())
pDrawArgs->nTextAlign = DT_LEFT; //to make compact tree presentation
}
else
{
bHasChildren = pDrawArgs->pRow->HasChildren();
}
rcItem.left += pDrawArgs->pControl->GetIndent(nTreeDepth);
if (pPaintManager->m_nBaseParentRecordIndent != 0)
{
if ((pDrawArgs->pRow->GetParentRow() != NULL ? pDrawArgs->pRow->GetParentRow()->IsGroupRow() : FALSE)
&& pDrawArgs->pRow->HasChildren() && (nTreeDepth == 0))
rcItem.left += pPaintManager->m_nBaseParentRecordIndent;
if ((pDrawArgs->pRow->GetParentRow() != NULL ? !pDrawArgs->pRow->GetParentRow()->IsGroupRow() : FALSE)
&& (nTreeDepth > 0) && pDrawArgs->pControl->GetColumns()->GetGroupsOrder()->GetCount() > 0)
rcItem.left += pPaintManager->m_nBaseParentRecordIndent;
}
// EXTRA TREE INDENT
if (pPaintManager->m_bBaseTreeIndent)
{
rcItem.left += pPaintManager->m_nTreeIndent;
}
CRect rcBitmap(rcItem);
CSize sizeBitmap = pPaintManager->DrawCollapsedBitmap(NULL, pDrawArgs->pRow, rcBitmap);
pPaintManager->DrawTreeStructure(pDrawArgs, pMetrics, rcItem, sizeBitmap);
int nIconAlign = pDrawArgs->nTextAlign & xtpColumnIconMask;
// horizontal alignment
switch (nIconAlign)
{
case xtpColumnIconRight:
rcBitmap.left = rcBitmap.right - sizeBitmap.cx - 2;
break;
case xtpColumnIconLeft:
rcBitmap.right = rcBitmap.left + sizeBitmap.cx + 2;
break;
}
// vertical alignment
switch (nIconAlign)
{
case xtpColumnIconTop:
rcBitmap.bottom = rcBitmap.top + sizeBitmap.cy + 2;
break;
case xtpColumnIconBottom:
rcBitmap.top = rcBitmap.bottom - sizeBitmap.cy - 2;
break;
}
int nTreeTextIndent = 0;
if (bHasChildren)
{
sizeBitmap = pPaintManager->DrawCollapsedBitmap(pDC, pDrawArgs->pRow, rcBitmap);
if (!pDC->IsPrinting())
{
pDrawArgs->pRow->SetCollapseRect(rcBitmap);
}
nTreeTextIndent = pPaintManager->m_nTreeTextIndentRowParent;
}
else
{
nTreeTextIndent = pPaintManager->m_nTreeTextIndentRowChildren;
}
rcItem.left = rcBitmap.left;
rcItem.left += sizeBitmap.cx;
rcItem.left += nTreeTextIndent;
}
pDC->SetTextColor(pMetrics->clrForeground);
CFont* pOldFont = (CFont*)pDC->SelectObject(pMetrics->pFont);
if (pMetrics->clrBackground != XTP_REPORT_COLOR_DEFAULT)
{
pDC->SetBkColor(pMetrics->clrBackground);
}
else
{
pDC->SetBkColor(pPaintManager->m_clrControlBack);
}
// Draw checkbox
if (m_bHasCheckbox)
{
DrawCheckBox(pDrawArgs, rcItem);
}
BOOL bShowLock = !IsEditable() && pDrawArgs->pControl->GetPaintManager()->m_bShowLockIcon;
// Do the draw bitmap pDC, rcItem, GetIconIndex()
if (bShowLock && !pDrawArgs->pControl->IsIconView()) //to prevent reaction on always read-only IconColumn / NumberColumn
{
rcItem.left++;
if (pDrawArgs->pControl->GetPaintManager()->m_bUseShellIcon) //variant without resources
{
pPaintManager->DrawShellIcon(pDC, rcItem, xtpReportShellIconLock);
}
else //variant with resources
{
pPaintManager->DrawGlyph(pDC, rcItem, xtpReportGlyphItemLocked);
}
rcItem.left += 17;
}
else if (pMetrics->nItemIcon != XTP_REPORT_NOICON || GetIconIndex() != XTP_REPORT_NOICON)
{
pPaintManager->DrawItemBitmap(pDrawArgs, rcItem, pMetrics->nItemIcon != XTP_REPORT_NOICON ? pMetrics->nItemIcon : GetIconIndex());
}
else
{
CXTPReportRecordItemEditOptions* pEditOptions = GetEditOptions(pDrawArgs->pColumn);
if (pEditOptions && pEditOptions->arrInplaceButtons.GetSize() > 0)
{
CXTPReportInplaceButton *pButton = pEditOptions->GetButton(0);
if (pButton && pButton->IsInsideCellButton())
{
CRect rc(rcItem);
rc.left = rc.right - 17;//like CXTPReportInplaceButton::m_nWidth
if (pPaintManager->IsFixedInplaceButtonHeight())
rc.bottom = min(rc.bottom, rc.top + 19); //like CXTPReportInplaceButton::m_nFixedHeight
BOOL bShift(FALSE);
//to keep focused frame not touched
rc.top++;
rc.bottom -= 2;
rc.left--;
if (pButton->GetID() == XTP_ID_REPORT_COMBOBUTTON)
rc.right--;
if (pButton->GetID() == XTP_ID_REPORT_COMBOBUTTON)
bShift = pPaintManager->DrawInplaceComboButton(pDC, &rc);
else if (pButton->GetID() == XTP_ID_REPORT_EXPANDBUTTON)
bShift = pPaintManager->DrawInplaceExpandButton(pDC, &rc);
else if (pButton->GetID() == XTP_ID_REPORT_SPINBUTTON)
bShift = pPaintManager->DrawInplaceSpinButton(pDC, &rc);
if (bShift)
pDrawArgs->rcItem.right -= 17;
}
}
}
nItemGlyphs = (rcItem.left - nItemGlyphs);
OnDrawControls(pDrawArgs, rcItem);
if (rcItem.Width() > 2)
{
OnDrawCaption(pDrawArgs, pMetrics);
}
int nItemTextWidth = nItemGlyphs + 7;
if (m_pMarkupUIElement)
{
nItemTextWidth += XTPMarkupMeasureElement(m_pMarkupUIElement, rcItem.Width() - 4, INT_MAX).cx;
}
else
{
CString sFirst(pMetrics->strText);
CString sLast;
int jPos = sFirst.Find(_T('\n'), 0);
int wd(0);
while (jPos > -1)
{
sLast = sFirst.Mid(jPos + 1);
sFirst = sFirst.Left(jPos - 1);
wd = max(wd, pDC->GetTextExtent(sFirst).cx + 7);
sFirst = sLast;
jPos = sFirst.Find(_T('\n'), 0);
}
if (!sFirst.IsEmpty())
{
nItemTextWidth = max(wd, pDC->GetTextExtent(sFirst).cx + 7);
}
}
pDC->SelectObject(pOldFont);
pMetrics->InternalRelease();
return nItemTextWidth;
}
CXTPReportRecordItemControl* CXTPReportRecordItem::HitTest(CPoint ptPoint)
{
if (!(m_pItemControls && m_pItemControls->GetSize()))
return NULL;
for (int i = 0; i < m_pItemControls->GetSize(); i++)
{
CRect rcControl = m_pItemControls->GetAt(i)->GetRect();
if (rcControl.PtInRect(ptPoint))
return m_pItemControls->GetAt(i);
}
return NULL;
}
BOOL CXTPReportRecordItem::OnLButtonDown(XTP_REPORTRECORDITEM_CLICKARGS* pClickArgs)
{
CXTPReportRecordItemControl* pItemControl = HitTest(pClickArgs->ptClient);
if (!pItemControl)
return FALSE;
pItemControl->OnLButtonDown(pClickArgs);
// create item control window
if (m_pItemControlHookWnd == NULL)
{
m_pItemControlHookWnd = new CXTPReportRecordItemControlHookWnd(pClickArgs);
m_pItemControlHookWnd->Create(AfxRegisterWndClass(0), _T(""), WS_CHILD, pItemControl->GetRect(), pClickArgs->pControl, 0);
m_pItemControlHookWnd->SetCapture();
}
// redraw control
pClickArgs->pControl->RedrawControl();
return TRUE;
}
BOOL CXTPReportRecordItem::OnLButtonUp(XTP_REPORTRECORDITEM_CLICKARGS* pClickArgs)
{
//>>attempt for 23588 issue case
CXTPSmartPtrInternalT<CXTPReportRecordItem> xSafety(this, TRUE);
//>>attempt for 23588 issue case
if (m_pItemControlHookWnd && m_pFocusedItemControl)
{
ReleaseCapture();
pClickArgs->pControl->ScreenToClient(&pClickArgs->ptClient);
m_pFocusedItemControl->OnLButtonUp(pClickArgs);
pClickArgs->pControl->RedrawControl();
// destroy item control window
m_pItemControlHookWnd->DestroyWindow();
delete m_pItemControlHookWnd;
m_pItemControlHookWnd = NULL;
return TRUE;
}
CXTPReportRecordItemControl* pItemControl = HitTest(pClickArgs->ptClient);
if (!pItemControl)
return FALSE;
pItemControl->OnLButtonUp(pClickArgs);
pClickArgs->pControl->RedrawControl();
return TRUE;
}
void CXTPReportRecordItem::OnClick(XTP_REPORTRECORDITEM_CLICKARGS* pClickArgs)
{
if (!pClickArgs || !pClickArgs->pControl)
return;
if (OnLButtonUp(pClickArgs)) //old version (10) did not have this call
return;
InternalAddRef();
CMDTARGET_ADDREF(pClickArgs->pColumn);
CMDTARGET_ADDREF(pClickArgs->pControl);
CXTPReportRow* pRow = pClickArgs->pRow;
CMDTARGET_ADDREF(pRow);
BOOL bCheckBoxClicked = FALSE;
CXTPReportControl* pControl = pClickArgs->pControl;
if (IsEditable()
&& m_bHasCheckbox &&
(pClickArgs->pColumn == NULL || pClickArgs->pColumn->IsEditable())
&& OnRequestEdit(pClickArgs))
{
// adjust vertical coordinates if virtual mode
if (pControl->IsVirtualMode())
{
m_rcGlyph.top = pClickArgs->rcItem.top;
m_rcGlyph.bottom = pClickArgs->rcItem.bottom;
}
// check whether we're clicking glyph area
if (m_rcGlyph.PtInRect(pClickArgs->ptClient) &&
m_rcGlyph.PtInRect(pControl->m_mouseDownState.ptMouse))
{
if (pControl->IsAutoCheckItems())
{
if (!m_bTristateCheckbox)
{
SetChecked(!IsChecked());
}
else
{
SetCheckedState((GetCheckedState() + 1) % xtpReportCheckStateCount);
}
}
pControl->RedrawControl();
pControl->SendMessageToParent(pClickArgs->pRow, this, pClickArgs->pColumn, XTP_NM_REPORT_CHECKED, &pClickArgs->ptClient);
bCheckBoxClicked = TRUE;
}
}
if (!bCheckBoxClicked && IsAllowEdit(pClickArgs))
{
if (pControl->IsEditOnDelayClick())
{
if ( pControl->GetLastRqstEditCol() != pClickArgs->pColumn->GetItemIndex()
|| pControl->GetLastRqstEditRow() != pClickArgs->pRow->GetIndex())
{
pControl->EnsureStopLastRqstTimer();
pControl->SetLastRqstEdit(pClickArgs->pRow->GetIndex(), pClickArgs->pColumn->GetItemIndex());
}
else if(!pControl->GetDelayEditTimer())
{
// Start the timer for this request.
pControl->StartDelayEditTimer();
}
}
if (pControl->IsEditOnClick())
{
pControl->EditItem(pClickArgs);
CPoint pt(pClickArgs->ptClient);
pControl->ClientToScreen(&pt);
CXTPReportInplaceEdit* pEdit = DYNAMIC_DOWNCAST(CXTPReportInplaceEdit, CWnd::FromHandle(WindowFromPoint(pt)));
if (pEdit && pEdit->GetItem() == this)
{
CXTPReportRecordItemEditOptions* pEditOptions = GetEditOptions(pClickArgs->pColumn);
if (pEditOptions->m_bSelectTextOnEdit)
pEdit->SetSel(0, -1);
else
DoMouseButtonClick();
}
}
}
pClickArgs->pControl->SendMessageToParent(pClickArgs->pRow, this, pClickArgs->pColumn,
NM_CLICK, &pClickArgs->ptClient);
// Determine Hyperlink Click
int nHyperlink = HitTestHyperlink(pClickArgs->ptClient);
int mHyperlink = HitTestHyperlink(pControl->m_mouseDownState.ptMouse);
if (nHyperlink >= 0 && mHyperlink >= 0)
pClickArgs->pControl->SendMessageToParent(pClickArgs->pRow, this, pClickArgs->pColumn, XTP_NM_REPORT_HYPERLINK, &pClickArgs->ptClient, nHyperlink);
CMDTARGET_RELEASE(pRow);
CMDTARGET_RELEASE(pClickArgs->pColumn);
CMDTARGET_RELEASE(pClickArgs->pControl);
InternalRelease();
}
int CXTPReportRecordItem::HitTestHyperlink(CPoint ptClick)
{
int nHitTest = -1;
int nHyperlinks = GetHyperlinksCount();
CXTPReportHyperlink *pHyperlink;
for (int nHyperlink = 0; nHyperlink < nHyperlinks; nHyperlink++)
{
pHyperlink = GetHyperlinkAt(nHyperlink);
ASSERT(pHyperlink);
if (pHyperlink && pHyperlink->m_rcHyperSpot.PtInRect(ptClick))
{
ASSERT(-1 == nHitTest);
nHitTest = nHyperlink;
}
}
return nHitTest;
}
void CXTPReportRecordItem::OnDblClick(XTP_REPORTRECORDITEM_CLICKARGS *pClickArgs)
{
if (!pClickArgs || !pClickArgs->pControl)
return;
if (OnLButtonDown(pClickArgs)) //old version (10) did not have this call
return;
CXTPReportControl *pControl = pClickArgs->pControl;
if (IsAllowEdit(pClickArgs)
&& !pControl->IsEditOnClick()
&& pControl->IsEditOnDoubleClick()
&& pControl->GetInplaceEdit()->GetItem() != this)
{
pControl->EditItem(pClickArgs);
CPoint pt(pClickArgs->ptClient);
pControl->ClientToScreen(&pt);
CXTPReportInplaceEdit* pEdit = DYNAMIC_DOWNCAST(CXTPReportInplaceEdit, CWnd::FromHandle(WindowFromPoint(pt)));
if (pEdit && pEdit->GetItem() == this)
{
CXTPReportRecordItemEditOptions* pEditOptions = GetEditOptions(pClickArgs->pColumn);
if (pEditOptions->m_bSelectTextOnEdit)
pEdit->SetSel(0, -1);
else
DoMouseButtonClick();
}
}
pControl->SendMessageToParent(pClickArgs->pRow, this, pClickArgs->pColumn, NM_DBLCLK, &pClickArgs->ptClient, -1);
}
void CXTPReportRecordItem::OnMouseMove(UINT nFlags, CPoint point, CXTPReportControl* pControl)
{
int nHyperlink = HitTestHyperlink(point);
if (nHyperlink >= 0)
{
SetCursor(AfxGetApp()->LoadStandardCursor(IDC_HAND));
return;
}
CXTPReportRecordItemControl* pItemControl = HitTest(point);
if (m_pItemControlHookWnd && m_pFocusedItemControl && (nFlags & MK_LBUTTON))
{
pControl->ScreenToClient(&point);
if (m_bItemControlUnderMouse && !m_pFocusedItemControl->GetRect().PtInRect(point))
{
m_pFocusedItemControl->OnMouseLeave(nFlags, point);
m_bItemControlUnderMouse = FALSE;
}
else if (!m_bItemControlUnderMouse && m_pFocusedItemControl->GetRect().PtInRect(point))
{
m_pFocusedItemControl->OnMouseEnter(nFlags, point);
m_bItemControlUnderMouse = TRUE;
}
else
m_pFocusedItemControl->OnMouseMove(nFlags, point);
if (pControl != NULL && !pControl->IsEditMode())
pControl->RedrawControl();
return;
}
if (pItemControl)
{
if (pItemControl != m_pFocusedItemControl)
{
if (m_pFocusedItemControl)
{
m_pFocusedItemControl->OnMouseLeave(nFlags, point);
m_bItemControlUnderMouse = FALSE;
}
pItemControl->OnMouseEnter(nFlags, point);
m_bItemControlUnderMouse = TRUE;
}
pItemControl->OnMouseMove(nFlags, point);
if (pControl != NULL && !pControl->IsEditMode())
pControl->RedrawControl();
}
else
{
if (m_pFocusedItemControl)
{
m_pFocusedItemControl->OnMouseLeave(nFlags, point);
m_bItemControlUnderMouse = FALSE;
if (pControl != NULL && !pControl->IsEditMode())
pControl->RedrawControl();
}
}
m_pFocusedItemControl = pItemControl;
}
void CXTPReportRecordItem::SetFont(CFont* pFont)
{
m_pFontCaption = pFont;
}
void CXTPReportRecordItem::SetBold(BOOL bBold)
{
m_bBoldText = bBold;
}
void CXTPReportRecordItem::SetTextColor(COLORREF clrText)
{
m_clrText = clrText;
}
COLORREF CXTPReportRecordItem::GetTextColor()
{
return m_clrText;
}
void CXTPReportRecordItem::SetBackgroundColor(COLORREF clrBackground)
{
m_clrBackground = clrBackground;
}
COLORREF CXTPReportRecordItem::GetBackgroundColor()
{
return m_clrBackground;
}
int CXTPReportRecordItem::Compare(CXTPReportColumn* pColumn, CXTPReportRecordItem* pItem)
{
if (!pItem)
return 0;
if (m_nSortPriority != -1 || pItem->m_nSortPriority != -1)
return m_nSortPriority - pItem->m_nSortPriority;
return m_pRecord->GetRecords()->Compare(GetCaption(pColumn), pItem->GetCaption(pColumn));
}
CFont* CXTPReportRecordItem::GetFont()
{
return m_pFontCaption;
}
CString CXTPReportRecordItem::GetGroupCaption(CXTPReportColumn* pColumn)
{
if (!m_strGroupCaption.IsEmpty())
return m_strGroupCaption;
int nID = GetGroupCaptionID(pColumn);
if (nID > 0)
{
CString str;
if (str.LoadString(nID))
return str;
}
if (m_pMarkupUIElement || pColumn->GetMarkupUIElement())
return GetCaption(pColumn);
return pColumn->GetCaption() + _T(": ") + GetCaption(pColumn);
}
int CXTPReportRecordItem::CompareGroupCaption(CXTPReportColumn* pColumn, CXTPReportRecordItem* pItem)
{
if (m_nGroupPriority != -1)
return m_nGroupPriority - pItem->m_nGroupPriority;
if (!m_strGroupCaption.IsEmpty())
return m_pRecord->GetRecords()->Compare(m_strGroupCaption, pItem->m_strGroupCaption);
int nID = GetGroupCaptionID(pColumn);
if (nID > 0)
return nID - pItem->GetGroupCaptionID(pColumn);
return Compare(pColumn, pItem);
}
int CXTPReportRecordItem::GetGroupCaptionID(CXTPReportColumn* /*pColumn*/)
{
return m_nGroupPriority;
}
void CXTPReportRecordItem::GetItemMetrics(XTP_REPORTRECORDITEM_DRAWARGS* pDrawArgs, XTP_REPORTRECORDITEM_METRICS* pItemMetrics)
{
if (m_clrBackground != XTP_REPORT_COLOR_DEFAULT)
pItemMetrics->clrBackground = m_clrBackground;
if (m_clrText != XTP_REPORT_COLOR_DEFAULT)
pItemMetrics->clrForeground = m_clrText;
if (m_pFontCaption != NULL)
pItemMetrics->pFont = m_pFontCaption;
else if (m_bBoldText)
pItemMetrics->pFont = &pDrawArgs->pControl->GetPaintManager()->m_fontBoldText;
if (m_Alignment != (XTPReportColumnIconAlignment)(-1))
pItemMetrics->nColumnAlignment = m_Alignment;
}
int CXTPReportRecordItem::GetIndex() const
{
return m_pRecord ? m_pRecord->IndexOf(this) : -1;
}
CXTPReportColumn* CXTPReportRecordItem::GetColumn()
{
if (m_pControl)
{
int nItemIndex = GetIndex();
CXTPReportColumns* pCols = m_pControl->GetColumns();
if (pCols)
return pCols->Find(nItemIndex);
}
return NULL;
}
BOOL CXTPReportRecordItem::IsEditable() const
{
if (this == NULL)
return FALSE;
if (!m_pRecord)
return FALSE;
return m_pRecord ? m_pRecord->m_bEditable && m_bEditable && IsFocusable() : FALSE;
}
BOOL CXTPReportRecordItem::IsFocusable() const
{
if (this == NULL)
return FALSE;
return m_bFocusable;
}
BOOL CXTPReportRecordItem::GetCanEditCheckboxItem() const
{
if (this == NULL)
return FALSE;
return m_bCanEditCheckboxItem;
}
void CXTPReportRecordItem::SetCanEditCheckboxItem(BOOL bSet)
{
m_bCanEditCheckboxItem = bSet;
}
void CXTPReportRecordItem::OnBeginEdit(XTP_REPORTRECORDITEM_ARGS* pItemArgs)
{
ASSERT(pItemArgs);
if (!pItemArgs)
return;
if (IsEditable() && OnRequestEdit(pItemArgs))
{
CXTPReportControl* pControl = pItemArgs->pControl;
CXTPReportInplaceEdit* pEdit = pControl->GetInplaceEdit();
CRect rcCaption(pItemArgs->rcItem);
GetCaptionRect(pItemArgs, rcCaption);
CXTPReportRecordItemEditOptions* pEditOptions = GetEditOptions(pItemArgs->pColumn);
ASSERT(pEditOptions);
CXTPReportInplaceButtons* pInpaceButtons = &pEditOptions->arrInplaceButtons;
CRect rcButtons(pItemArgs->rcItem);
CXTPClientRect rcControl(pItemArgs->pControl);
int i;
// calculate right-aligned item controls width
int nControlsWidthRight = 0;
if (m_pItemControls && m_pItemControls->GetSize() > 0)
{
for (i = 0; m_pItemControls && i < m_pItemControls->GetSize(); i++)
{
CXTPReportRecordItemControl* pControl = m_pItemControls->GetAt(i);
if (pControl->GetAlignment() == xtpItemControlRight)
nControlsWidthRight += pControl->GetRect().Width();
else
pItemArgs->rcItem.left += pControl->GetRect().Width();
}
}
// calculate inplace buttons widths
int nButtonsWidthIn = 0, nButtonsWidthOut = 0;
for (i = 0; i < pInpaceButtons->GetSize(); i++)
{
CXTPReportInplaceButton* pButton = pInpaceButtons->GetAt(i);
if (pButton->IsInsideCellButton())
nButtonsWidthIn += pButton->GetWidth();
else
nButtonsWidthOut += pButton->GetWidth();
}
// adjust buttons rect
if (rcButtons.right + nButtonsWidthOut > rcControl.right)
rcButtons.right = rcControl.right - nButtonsWidthOut;
rcButtons.left = min(rcButtons.right, pItemArgs->rcItem.right - nControlsWidthRight);
// create buttons
for (i = 0; i < pInpaceButtons->GetSize(); i++)
{
CXTPReportInplaceButton* pButton = pInpaceButtons->GetAt(i);
pButton->Create(pItemArgs, rcButtons);
pControl->GetInplaceButtons()->Add(pButton);
}
// adjust item rect
pItemArgs->rcItem.right = rcButtons.left;
if (pEditOptions->m_bAllowEdit)
{ if (m_bHasCheckbox && !m_bCanEditCheckboxItem)
return;
else
pEdit->Create(pItemArgs);
}
if (!pEditOptions->m_bAllowEdit && pInpaceButtons->GetSize() > 0)
{
CXTPReportInplaceButton *pButton = pInpaceButtons->GetAt(0);
OnInplaceButtonDown(pButton);
}
XTP_NM_REPORTRECORDITEM nm;
::ZeroMemory(&nm, sizeof(nm));
nm.pItem = this;
nm.pRow = pItemArgs->pRow;
nm.pColumn = pItemArgs->pColumn;
pControl->SendNotifyMessage(XTP_NM_REPORT_BEGINEDIT, (NMHDR*)&nm);
}
}
void CXTPReportRecordItem::OnCancelEdit(CXTPReportControl *pControl, BOOL bApply)
{
if (NULL == pControl)
return;
CXTPReportInplaceButtons* pInpaceButtons = pControl->GetInplaceButtons();
for (int i = 0; i < pInpaceButtons->GetSize(); i++)
{
CXTPReportInplaceButton* pButton = pInpaceButtons->GetAt(i);
if (pButton->GetSafeHwnd())
pButton->DestroyWindow();
if (pButton)
{
pButton->SetItemArgs(0);
}
}
pInpaceButtons->RemoveAll();
CXTPReportInplaceList* pInpaceList = pControl->GetInplaceList();
if (pInpaceList->GetSafeHwnd())
pInpaceList->DestroyWindow();
CXTPReportInplaceEdit* pEdit = pControl->GetInplaceEdit();
if (pEdit == NULL) return;
if (pEdit->GetSafeHwnd())
{
if (bApply && pEdit->GetItem() == this)
OnValidateEdit((XTP_REPORTRECORDITEM_ARGS*) pEdit);
pEdit->HideWindow();
pEdit->SetItemArgs(0);
pEdit->DestroyWindow();
}
}
void CXTPReportRecordItem::OnConstraintChanged(XTP_REPORTRECORDITEM_ARGS* pItemArgs, CXTPReportRecordItemConstraint* pConstraint)
{
OnEditChanged(pItemArgs, pConstraint->m_strConstraint);
}
BOOL CXTPReportRecordItem::OnEditChanging(XTP_REPORTRECORDITEM_ARGS* pItemArgs, CString& rstrNewText)
{
UNREFERENCED_PARAMETER(pItemArgs);
UNREFERENCED_PARAMETER(rstrNewText);
return TRUE;
}
void CXTPReportRecordItem::OnEditChanged(XTP_REPORTRECORDITEM_ARGS* pItemArgs, LPCTSTR szText)
{
if (pItemArgs)
{
int r = pItemArgs->pRow->GetIndex();
int i = pItemArgs->pItem->GetIndex();
CXTPReportRecord* pRec = pItemArgs->pRow->GetRecord();
if (pRec)
pRec->UpdateRecordField(r, i, szText);
}
}
void CXTPReportRecordItem::OnValidateEdit(XTP_REPORTRECORDITEM_ARGS* pItemArgs)
{
ASSERT(pItemArgs);
if (!pItemArgs)
return;
CXTPReportControl* pControl = pItemArgs->pControl;
CXTPReportInplaceEdit* pEdit = pControl->GetInplaceEdit();
XTP_REPORTRECORDITEM_ARGS args = *pItemArgs;
if (pEdit->GetSafeHwnd() && pEdit->GetItem() == this)
{
args.AddRef();
BOOL bRedraw = FALSE;
CMDTARGET_RELEASE(pEdit->pItem); //pEdit->pItem = NULL;
if (GetEditOptions(args.pColumn)->m_bConstraintEdit)
{
if (pEdit->m_pSelectedConstraint)
{
OnConstraintChanged(&args, pEdit->m_pSelectedConstraint);
bRedraw = TRUE;
}
}
else
{
CString strValue;
pEdit->GetWindowText(strValue);
CString sOldValue = GetCaption(args.pColumn);
if (sOldValue != strValue || pControl->IsVirtualMode())
{
OnEditChanged(&args, strValue);
bRedraw = TRUE;
}
//else if (GetCaption(args.pColumn) != strValue) //<<>>
//{
// OnEditChanged(&args, strValue);
// bRedraw = TRUE;
//}
}
if (bRedraw)
{
pControl->RedrawControl();
pControl->SendMessageToParent(args.pRow, this, args.pColumn, XTP_NM_REPORT_VALUECHANGED, 0);
}
else
{
OnEditCanceled(pItemArgs);
pControl->SendMessageToParent(args.pRow, this, args.pColumn, XTP_NM_REPORT_EDIT_CANCELED, 0);
}
pEdit->SetItemArgs(0);
args.Release();
}
}
BOOL CXTPReportRecordItem::IsAllowEdit(XTP_REPORTRECORDITEM_ARGS *pItemArgs)
{
BOOL bIsAllowEdit = pItemArgs->pControl->IsAllowEdit();
if (m_pRecord)
{
// Header record
if (m_pRecord->m_pRecords == pItemArgs->pControl->GetHeaderRecords())
{
bIsAllowEdit = pItemArgs->pControl->IsHeaderRowsAllowEdit();
}
// Footer record
else if (m_pRecord->m_pRecords == pItemArgs->pControl->GetFooterRecords())
{
bIsAllowEdit = pItemArgs->pControl->IsFooterRowsAllowEdit();
}
}
bIsAllowEdit = bIsAllowEdit && IsEditable();
if (pItemArgs->pColumn)
{
bIsAllowEdit = bIsAllowEdit && pItemArgs->pColumn->IsEditable();
}
else
{
if (m_pEditOptions)
{
bIsAllowEdit = bIsAllowEdit && m_pEditOptions->m_bAllowEdit;
}
}
return bIsAllowEdit;
}
BOOL CXTPReportRecordItem::OnRequestEdit(XTP_REPORTRECORDITEM_ARGS* pItemArgs)
{
CXTPReportControl* pControl = pItemArgs->pControl;
XTP_NM_REPORTREQUESTEDIT nm;
::ZeroMemory(&nm, sizeof(nm));
nm.bCancel = FALSE;
nm.pItem = this;
nm.pRow = pItemArgs->pRow;
nm.pColumn = pItemArgs->pColumn;
pControl->SendNotifyMessage(XTP_NM_REPORT_REQUESTEDIT, (NMHDR*)&nm);
return !nm.bCancel;
}
BOOL CXTPReportRecordItem::OnChar(XTP_REPORTRECORDITEM_ARGS *pItemArgs, UINT nChar)
{
CXTPReportControl* pControl = pItemArgs->pControl;
if ((nChar == VK_SPACE) && IsEditable() && m_bHasCheckbox && (pItemArgs->pColumn == NULL || pItemArgs->pColumn->IsEditable())
&& OnRequestEdit(pItemArgs))
{
if (pControl->IsAutoCheckItems())
{
if (!m_bTristateCheckbox)
SetChecked(!IsChecked());
else
SetCheckedState((GetCheckedState() + 1) % 3);
}
pControl->RedrawControl();
pControl->SendMessageToParent(pItemArgs->pRow, this, pItemArgs->pColumn, XTP_NM_REPORT_CHECKED, NULL);
return TRUE;
}
if (IsAllowEdit(pItemArgs))
{
// ^^ causes CXTPReportRecordItem::OnChar do be called twice
BOOL bSameItem = pItemArgs->pItem == pControl->GetActiveItem();
if (!bSameItem)
{
pControl->EditItem(pItemArgs);
}
CXTPReportInplaceEdit *pEdit = pControl->GetInplaceEdit();
if (pEdit->GetSafeHwnd() && pEdit->GetItem() == this)
{
if (!bSameItem)
{
pEdit->SetFocus();
pEdit->SetSel(0, -1);
}
if (VK_TAB != nChar)
{
pEdit->SendMessage(WM_CHAR, nChar);
}
}
return TRUE;
}
return FALSE;
}
CXTPReportRecordItemEditOptions* CXTPReportRecordItem::GetEditOptions(CXTPReportColumn* pColumn)
{
if (m_pEditOptions)
return m_pEditOptions;
if (pColumn)
return pColumn->GetEditOptions();
return m_pEditOptions = new CXTPReportRecordItemEditOptions();
}
CXTPReportRecordItemControls* CXTPReportRecordItem::GetItemControls()
{
if (!m_pItemControls)
m_pItemControls = new CXTPReportRecordItemControls(this);
return m_pItemControls;
}
void CXTPReportRecordItem::OnInplaceButtonDown(CXTPReportInplaceButton* pButton)
{
CXTPReportControl* pControl = pButton->pControl;
XTP_NM_REPORTINPLACEBUTTON nm;
::ZeroMemory(&nm, sizeof(nm));
nm.pButton = pButton;
nm.pItem = this;
if (pControl->SendNotifyMessage(XTP_NM_REPORT_INPLACEBUTTONDOWN, (NMHDR*)&nm) == TRUE)
return;
if (pButton->GetID() == XTP_ID_REPORT_COMBOBUTTON)
{
CXTPReportInplaceList* pList = pControl->GetInplaceList();
XTP_REPORTRECORDITEM_ARGS itemArgs = *pButton;
if (!itemArgs.pColumn
&& !itemArgs.pControl
&& !itemArgs.pItem
&& !itemArgs.pRow)
return;
ASSERT(itemArgs.pItem == this);
CXTPWindowRect rcButton(pButton);
pControl->ScreenToClient(&rcButton);
itemArgs.rcItem.right = rcButton.right;
itemArgs.rcItem.bottom = rcButton.bottom;
CXTPReportRecordItemEditOptions* pEditOptions = GetEditOptions(itemArgs.pColumn);
pList->m_Items2Show = pButton->m_Items2Show;
if (pEditOptions->GetConstraints()->GetCount() > 0)
pList->Create(&itemArgs, pEditOptions->GetConstraints());
}
else if (pButton->GetID() == XTP_ID_REPORT_SPINBUTTON)
{
XTP_REPORTRECORDITEM_ARGS itemArgs = *pButton;
ASSERT(itemArgs.pItem == this);
CXTPReportInplaceEdit* pEdit = pControl->GetInplaceEdit();
if (itemArgs.pRow && itemArgs.pColumn && pEdit->GetSafeHwnd() && pEdit->GetItem() == this)
{
CString strValue;
pEdit->GetWindowText(strValue);
int nValue = _ttoi(strValue);
int nValue2 = nValue + pButton->m_nSpinIncrement;
nValue2 = max(nValue2, pButton->m_nSpinMin);
nValue2 = min(nValue2, pButton->m_nSpinMax);
if (nValue2 != nValue)
{
strValue.Format(_T("%d"), nValue2);
BOOL bCommit = OnEditChanging(&itemArgs, strValue);
if (bCommit)
pEdit->SetWindowText(strValue);
pControl->RedrawControl();
//pControl->SendMessageToParent(itemArgs.pRow, this, itemArgs.pColumn, XTP_NM_REPORT_VALUECHANGED, 0);
}
}
}
}
CXTPReportHyperlinks* CXTPReportRecordItem::GetHyperlinks()
{
if (!m_pHyperlinks)
m_pHyperlinks = new CXTPReportHyperlinks();
return m_pHyperlinks;
}
void CXTPReportRecordItem::DoPropExchange(CXTPPropExchange* pPX)
{
PX_DWord(pPX, _T("TextColor"), (DWORD&)m_clrText, XTP_REPORT_COLOR_DEFAULT);
PX_DWord(pPX, _T("BackgroundColor"), (DWORD&)m_clrBackground, XTP_REPORT_COLOR_DEFAULT);
PX_Bool(pPX, _T("BoldText"), m_bBoldText, FALSE);
PX_String(pPX, _T("Format"), m_strFormatString, _T("%s"));
PX_Bool(pPX, _T("Editable"), m_bEditable, TRUE);
PX_Int(pPX, _T("IconIndex"), m_nIconIndex, XTP_REPORT_NOICON);
PX_Int(pPX, _T("SortPriority"), m_nSortPriority, -1);
PX_Int(pPX, _T("GroupPriority"), m_nGroupPriority, -1);
PX_String(pPX, _T("GroupCaption"), m_strGroupCaption, _T(""));
PX_Bool(pPX, _T("Focusable"), m_bFocusable, TRUE);
PX_Int(pPX, _T("Checked"), m_checkState, 0);
PX_Bool(pPX, _T("HasCheckbox"), m_bHasCheckbox, FALSE);
PX_Bool(pPX, _T("TristateCheckbox"), m_bTristateCheckbox, FALSE);
ULONGLONG ullData = m_dwData;
PX_UI8(pPX, _T("Data"), ullData, 0);
m_dwData = (DWORD_PTR)ullData;
PX_String(pPX, _T("Tooltip"), m_strTooltip, _T(""));
if (pPX->GetSchema() > _XTP_SCHEMA_98)
{
PX_String(pPX, _T("Caption"), m_strCaption, _T(""));
}
// Hyperlinks
CXTPPropExchangeSection secHyperlinks(pPX->GetSection(_T("Hyperlinks")));
CXTPReportHyperlinks arHyperlinks;
if (pPX->IsStoring() && m_pHyperlinks)
{
arHyperlinks.CopyFrom(m_pHyperlinks);
}
arHyperlinks.DoPropExchange(&secHyperlinks);
if (pPX->IsLoading())
{
if (arHyperlinks.GetSize())
{
if (GetHyperlinks())
GetHyperlinks()->CopyFrom(&arHyperlinks);
}
else if (m_pHyperlinks)
{
m_pHyperlinks->RemoveAll();
}
}
// Item controls
CXTPReportRecordItemControls arItemControls;
if (pPX->IsStoring() && m_pItemControls)
arItemControls.CopyFrom(m_pItemControls);
if (pPX->GetSchema() >= _XTP_SCHEMA_1200)
{
CXTPPropExchangeSection secItemControls(pPX->GetSection(_T("ItemControls")));
arItemControls.DoPropExchange(&secItemControls);
}
if (pPX->IsLoading())
{
if (arItemControls.GetSize())
{
if (GetItemControls())
GetItemControls()->CopyFrom(&arItemControls);
}
else if (m_pItemControls)
{
m_pItemControls->RemoveAll();
}
}
// Update Markup data
if (pPX->IsLoading())
{
XTPMarkupReleaseElement(m_pMarkupUIElement);
CXTPMarkupContext* pMarkupContext = m_pRecord ? m_pRecord->GetMarkupContext() : NULL;
if (pMarkupContext)
{
m_pMarkupUIElement = XTPMarkupParseText(pMarkupContext, m_strCaption);
}
}
}
INT_PTR CXTPReportRecordItem::OnToolHitTest(CPoint /*point*/, TOOLINFO* /*pTI*/)
{
return -1;
}
void CXTPReportRecordItem::Merge(CXTPReportRecordItem *pMergeItem)
{
m_pMergeItem = pMergeItem;
}
CXTPReportRecordItem *CXTPReportRecordItem::GetMergeItem() const
{
return m_pMergeItem;
}
BOOL CXTPReportRecordItem::IsMerged() const
{
return (NULL != m_pMergeItem);
}
int CXTPReportRecordItem::AddHyperlink(CXTPReportHyperlink* pHyperlink)
{
return GetHyperlinks() ? (int)GetHyperlinks()->Add(pHyperlink) : -1;
}
int CXTPReportRecordItem::GetHyperlinksCount() const
{
return m_pHyperlinks ? (int)m_pHyperlinks->GetSize() : 0;
}
CXTPReportHyperlink* CXTPReportRecordItem::GetHyperlinkAt(int nHyperlink) const
{
return m_pHyperlinks ? m_pHyperlinks->GetAt(nHyperlink) : NULL;
}
void CXTPReportRecordItem::RemoveHyperlinkAt(int nHyperlink)
{
if (m_pHyperlinks)
m_pHyperlinks->RemoveAt(nHyperlink);
}
BOOL CXTPReportRecordItem::CreateBorder()
{
if (NULL == m_pBorder)
{
m_pBorder = new CXTPReportBorder();
}
return (NULL != m_pBorder);
}
BOOL CXTPReportRecordItem::DestroyBorder()
{
if (NULL != m_pBorder)
{
delete m_pBorder;
m_pBorder = NULL;
}
return (NULL == m_pBorder);
}
CXTPReportBorder* CXTPReportRecordItem::GetBorder() const
{
return m_pBorder;
}