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.

310 lines
6.3 KiB
C++

// XTPReportRecordItemRange.cpp
//
// 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 "XTPReportRecordItemRange.h"
CXTPReportRecordItemId::CXTPReportRecordItemId()
: m_nColumn(-1)
, m_nRecord(-1)
{
// Nothing
}
CXTPReportRecordItemId::CXTPReportRecordItemId(int nColumn, int nRecord)
: m_nColumn(nColumn)
, m_nRecord(nRecord)
{
// Nothing
}
void CXTPReportRecordItemId::Set(int nColumn, int nRecord)
{
m_nColumn = nColumn;
m_nRecord = nRecord;
}
int CXTPReportRecordItemId::GetColumn() const
{
return m_nColumn;
}
int CXTPReportRecordItemId::GetRecord() const
{
return m_nRecord;
}
bool CXTPReportRecordItemId::operator == (
const CXTPReportRecordItemId &otherId) const
{
return (this->m_nColumn == otherId.m_nColumn)
&& (this->m_nRecord == otherId.m_nRecord);
}
CXTPReportRecordMergeItemId::CXTPReportRecordMergeItemId()
: CXTPReportRecordItemId()
, m_nColumnPos(-1)
{
}
CXTPReportRecordMergeItemId::CXTPReportRecordMergeItemId(int nColumnPos, int nColumn, int nRecord)
: CXTPReportRecordItemId(nColumn, nRecord)
, m_nColumnPos(nColumnPos)
{
}
/////////////////////////////////////////////////////////////////////////////
CXTPReportRecordItemRange::CXTPReportRecordItemRange()
: m_nColumnFrom(-1)
, m_nColumnTo (-1)
, m_nRecordFrom(-1)
, m_nRecordTo (-1)
{
// Nothing
}
CXTPReportRecordItemRange::CXTPReportRecordItemRange(
int nColumnFrom,
int nColumnTo,
int nRecordFrom,
int nRecordTo)
: m_nColumnFrom(nColumnFrom)
, m_nColumnTo (nColumnTo)
, m_nRecordFrom(nRecordFrom)
, m_nRecordTo (nRecordTo)
{
// Nothing
}
void CXTPReportRecordItemRange::Invalidate()
{
m_nColumnFrom = -1;
m_nColumnTo = -1;
m_nRecordFrom = -1;
m_nRecordTo = -1;
}
bool CXTPReportRecordItemRange::IsValid() const
{
return (m_nColumnFrom >= 0)
&& (m_nColumnTo >= 0)
&& (m_nRecordFrom >= 0)
&& (m_nRecordTo >= 0);
}
bool CXTPReportRecordItemRange::IsInRange(
const int nColumn,
const int nRecord) const
{
return (nColumn >= m_nColumnFrom) && (nColumn <= m_nColumnTo)
&& (nRecord >= m_nRecordFrom) && (nRecord <= m_nRecordTo);
}
bool CXTPReportRecordItemRange::IsNeighbour(
const int nColumn,
const int nRecord) const
{
bool bNeighbour = false;
if (IsValid())
{
if (abs(m_nColumnFrom - nColumn) <= 1 &&
abs(m_nColumnTo - nColumn) <= 1 &&
abs(m_nRecordFrom - nRecord) <= 1 &&
abs(m_nRecordTo - nRecord) <= 1)
{
bNeighbour = true;
}
}
return bNeighbour;
}
bool CXTPReportRecordItemRange::IsConnected(
const int nColumn,
const int nRecord) const
{
bool bConnected = false;
/*
Surrounding items marked as '+' are considered connected,
items marked as '-' not.
[-][+][+][-]
[+][ ][ ][+]
[+][ ][ ][+]
[-][+][+][-]
*/
if (IsValid())
{
if (nColumn >= m_nColumnFrom && nColumn <= m_nColumnTo)
{
if (nRecord == m_nRecordFrom-1 || nRecord == m_nRecordTo+1)
{
bConnected = true;
}
}
if (nRecord >= m_nRecordFrom && nRecord <= m_nRecordTo)
{
if (nColumn == m_nColumnFrom-1 || nColumn == m_nColumnTo+1)
{
bConnected = true;
}
}
}
return bConnected;
}
void CXTPReportRecordItemRange::ExpandTo(int nColumn, int nRecord)
{
if (IsValid())
{
m_nColumnFrom = min(m_nColumnFrom, nColumn);
m_nColumnTo = max(m_nColumnTo, nColumn);
m_nRecordFrom = min(m_nRecordFrom, nRecord);
m_nRecordTo = max(m_nRecordTo, nRecord);
}
}
void CXTPReportRecordItemRange::ExpandTo(
const CXTPReportRecordItemId expand)
{
ExpandTo(expand.m_nColumn, expand.m_nRecord);
}
/////////////////////////////////////////////////////////////////////////////
CXTPReportRecordMergeItem::CXTPReportRecordMergeItem()
{
// Nothing
}
CXTPReportRecordMergeItem::CXTPReportRecordMergeItem(
const CXTPReportRecordMergeItem &other)
{
CopyFrom(other);
}
CXTPReportRecordMergeItem& CXTPReportRecordMergeItem::operator = (
const CXTPReportRecordMergeItem &other)
{
if (this != &other)
{
m_items.RemoveAll();
CopyFrom(other);
}
return *this;
}
void CXTPReportRecordMergeItem::AddItem(CXTPReportRecordMergeItemId itemId, CRect rcItem)
{
Item item;
item.m_itemId = itemId;
item.m_rcItem = rcItem;
m_items.AddTail(item);
}
bool CXTPReportRecordMergeItem::FindRange(CXTPReportRecordItemRange &range, CRect &rcItem)
{
CXTPReportRecordItemRange internal;
range.Invalidate();
Item item;
POSITION pos = m_items.GetHeadPosition();
while (pos)
{
POSITION posOld = pos;
item = m_items.GetNext(pos);
if (!internal.IsValid())
{
m_items.RemoveAt(posOld);
rcItem = item.m_rcItem;
internal.m_nColumnFrom = item.m_itemId.m_nColumnPos;
internal.m_nColumnTo = item.m_itemId.m_nColumnPos;
internal.m_nRecordFrom = item.m_itemId.m_nRecord;
internal.m_nRecordTo = item.m_itemId.m_nRecord;
range.m_nColumnFrom = item.m_itemId.m_nColumn;
range.m_nColumnTo = item.m_itemId.m_nColumn;
range.m_nRecordFrom = item.m_itemId.m_nRecord;
range.m_nRecordTo = item.m_itemId.m_nRecord;
}
else
{
if (internal.IsInRange (item.m_itemId.m_nColumnPos, item.m_itemId.m_nRecord)
|| internal.IsConnected(item.m_itemId.m_nColumnPos, item.m_itemId.m_nRecord))
{
m_items.RemoveAt(posOld);
internal.ExpandTo(item.m_itemId.m_nColumnPos, item.m_itemId.m_nRecord);
range.ExpandTo(item.m_itemId);
rcItem.left = min(rcItem.left, item.m_rcItem.left);
rcItem.right = max(rcItem.right, item.m_rcItem.right);
rcItem.top = min(rcItem.top, item.m_rcItem.top);
rcItem.bottom = max(rcItem.bottom, item.m_rcItem.bottom);
}
}
}
return range.IsValid();
}
void CXTPReportRecordMergeItem::CopyFrom(
const CXTPReportRecordMergeItem &other)
{
POSITION pos = other.m_items.GetHeadPosition();
while (pos)
{
m_items.AddTail(other.m_items.GetAt(pos));
other.m_items.GetNext(pos);
}
}