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.
598 lines
13 KiB
C++
598 lines
13 KiB
C++
// XTPCalendarResource.cpp: implementation of the CXTPCalendarResource class.
|
|
//
|
|
// This file is a part of the XTREME CALENDAR 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 "Common/XTPPropExchange.h"
|
|
#include "Common/XTPNotifyConnection.h"
|
|
#include "Common/XTPSmartPtrInternalT.h"
|
|
|
|
#include "XTPCalendarDefines.h"
|
|
#include "XTPCalendarUtils.h"
|
|
#include "XTPCalendarNotifications.h"
|
|
#include "XTPCalendarPtrCollectionT.h"
|
|
|
|
#include "XTPCalendarEvent.h"
|
|
#include "XTPCalendarEvents.h"
|
|
#include "XTPCalendarData.h"
|
|
#include "XTPCalendarCustomProperties.h"
|
|
#include "XTPCalendarResource.h"
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define XTP_SCHEDULES_DATA_VER 2
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
IMPLEMENT_DYNCREATE(CXTPCalendarResource, CCmdTarget)
|
|
IMPLEMENT_DYNCREATE(CXTPCalendarResources, CCmdTarget)
|
|
|
|
IMPLEMENT_DYNAMIC(CXTPCalendarSchedule, CCmdTarget)
|
|
IMPLEMENT_DYNAMIC(CXTPCalendarSchedules, CCmdTarget)
|
|
|
|
CXTPCalendarSchedule::CXTPCalendarSchedule(UINT uScheduleID, LPCTSTR pcszScheduleName)
|
|
{
|
|
m_uScheduleID = uScheduleID;
|
|
|
|
ASSERT(pcszScheduleName);
|
|
if (pcszScheduleName)
|
|
{
|
|
m_strScheduleName = pcszScheduleName;
|
|
}
|
|
|
|
m_pCustomProperties = new CXTPCalendarCustomProperties();
|
|
|
|
}
|
|
|
|
CXTPCalendarSchedule::~CXTPCalendarSchedule()
|
|
{
|
|
CMDTARGET_RELEASE(m_pCustomProperties)
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
CXTPCalendarSchedules::CXTPCalendarSchedules()
|
|
{
|
|
}
|
|
|
|
CXTPCalendarSchedules::~CXTPCalendarSchedules()
|
|
{
|
|
}
|
|
|
|
BOOL CXTPCalendarSchedules::AddNewSchedule(LPCTSTR pcszScheduleName)
|
|
{
|
|
ASSERT(pcszScheduleName);
|
|
if (!pcszScheduleName)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
UINT uNewID = _GetNextID();
|
|
CXTPCalendarSchedule* pNewSch = new CXTPCalendarSchedule(uNewID, pcszScheduleName);
|
|
if (pNewSch)
|
|
{
|
|
Add(pNewSch, FALSE);
|
|
}
|
|
|
|
return pNewSch != NULL;
|
|
}
|
|
|
|
BOOL CXTPCalendarSchedules::RemoveSchedule(UINT uScheduleID)
|
|
{
|
|
int nFIdx = FindIndex(uScheduleID);
|
|
|
|
if (nFIdx >= 0)
|
|
{
|
|
RemoveAt(nFIdx);
|
|
}
|
|
return nFIdx >= 0;
|
|
}
|
|
|
|
LPCTSTR CXTPCalendarSchedules::GetScheduleName(UINT uScheduleID) const
|
|
{
|
|
int nFIdx = FindIndex(uScheduleID);
|
|
|
|
if (nFIdx >= 0)
|
|
{
|
|
CXTPCalendarSchedule* pSch = GetAt(nFIdx, FALSE);
|
|
if (pSch)
|
|
{
|
|
return pSch->GetName();
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void CXTPCalendarSchedules::SetScheduleName(UINT uScheduleID, LPCTSTR pcszNewName)
|
|
{
|
|
int nFIdx = FindIndex(uScheduleID);
|
|
|
|
if (nFIdx >= 0)
|
|
{
|
|
CXTPCalendarSchedule* pSch = GetAt(nFIdx, FALSE);
|
|
if (pSch)
|
|
{
|
|
pSch->SetName(pcszNewName);
|
|
}
|
|
}
|
|
}
|
|
|
|
int CXTPCalendarSchedules::FindIndex(UINT uScheduleID) const
|
|
{
|
|
int nCount = GetCount();
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
CXTPCalendarSchedule* pSch = GetAt(i, FALSE);
|
|
if (pSch && pSch->GetID() == uScheduleID)
|
|
{
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
UINT CXTPCalendarSchedules::_GetNextID() const
|
|
{
|
|
UINT uMaxID = 0;
|
|
|
|
int nCount = GetCount();
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
CXTPCalendarSchedule* pSch = GetAt(i, FALSE);
|
|
if (pSch && uMaxID < pSch->GetID())
|
|
{
|
|
uMaxID = pSch->GetID();
|
|
}
|
|
}
|
|
return uMaxID + 1;
|
|
}
|
|
|
|
void CXTPCalendarSchedules::DoPropExchange(CXTPPropExchange* pPX)
|
|
{
|
|
if (!pPX)
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
if (pPX->IsLoading())
|
|
{
|
|
_Load(pPX);
|
|
}
|
|
else
|
|
{
|
|
_Save(pPX);
|
|
}
|
|
}
|
|
|
|
void CXTPCalendarSchedules::_Save(CXTPPropExchange* pPX)
|
|
{
|
|
if (!pPX || !pPX->IsStoring())
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
CMDTARGET_ADDREF(pPX);
|
|
CXTPPropExchangeSection secSchedules(pPX); //->GetSection(_T("EventsSchedules")));
|
|
secSchedules->EmptySection();
|
|
|
|
long nVersion = XTP_SCHEDULES_DATA_VER;
|
|
PX_Long(&secSchedules, _T("Version"), nVersion, XTP_SCHEDULES_DATA_VER);
|
|
|
|
int nCount = GetCount();
|
|
CXTPPropExchangeEnumeratorPtr pEnumerator(secSchedules->GetEnumerator(_T("Schedule")));
|
|
POSITION posStorage = pEnumerator->GetPosition(nCount);
|
|
|
|
int nSavedCount = 0;
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
CXTPCalendarSchedule* pSch = GetAt(i, FALSE);
|
|
ASSERT(pSch);
|
|
if (!pSch)
|
|
{
|
|
continue;
|
|
}
|
|
ULONG ulID = pSch->GetID();
|
|
CString strName = pSch->GetName();
|
|
|
|
CXTPPropExchangeSection secSch(pEnumerator->GetNext(posStorage));
|
|
PX_ULong(&secSch, _T("ID"), ulID);
|
|
PX_String(&secSch, _T("Name"), strName);
|
|
|
|
if (pSch->GetCustomProperties())
|
|
pSch->GetCustomProperties()->DoPropExchange(&secSch);
|
|
|
|
nSavedCount++;
|
|
}
|
|
ASSERT(nSavedCount == nCount);
|
|
}
|
|
|
|
void CXTPCalendarSchedules::_Load(CXTPPropExchange* pPX)
|
|
{
|
|
if (!pPX || !pPX->IsLoading())
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
RemoveAll();
|
|
|
|
CMDTARGET_ADDREF(pPX);
|
|
CXTPPropExchangeSection secSchedules(pPX); //->GetSection(_T("EventsSchedules")));
|
|
|
|
long nVersion = 0;
|
|
PX_Long(&secSchedules, _T("Version"), nVersion, XTP_SCHEDULES_DATA_VER);
|
|
|
|
if (nVersion != XTP_SCHEDULES_DATA_VER)
|
|
{
|
|
TRACE(_T("ERROR! XTPCalendarSchedules: Unsupported data file version. (%d) \n"), nVersion);
|
|
return;
|
|
}
|
|
|
|
CXTPPropExchangeEnumeratorPtr pEnumerator(secSchedules->GetEnumerator(_T("Schedule")));
|
|
POSITION posStorage = pEnumerator->GetPosition();
|
|
|
|
while (posStorage)
|
|
{
|
|
ULONG ulID;
|
|
CString strName;
|
|
|
|
CXTPPropExchangeSection secSch(pEnumerator->GetNext(posStorage));
|
|
PX_ULong(&secSch, _T("ID"), ulID, 0);
|
|
PX_String(&secSch, _T("Name"), strName);
|
|
|
|
CXTPCalendarSchedule* pNewSch = new CXTPCalendarSchedule(ulID, strName);
|
|
if (!pNewSch)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (nVersion >= 2)
|
|
{
|
|
XTP_SAFE_CALL2(pNewSch, GetCustomProperties(), DoPropExchange(&secSch));
|
|
}
|
|
|
|
Add(pNewSch, FALSE);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
CXTPCalendarResource::CXTPCalendarResource(CXTPCalendarControl* pCalendarCtrl)
|
|
: m_pCalendarCtrl(pCalendarCtrl)
|
|
{
|
|
m_pDataProvider = NULL;
|
|
m_bCloseDataProviderWhenDestroy = TRUE;
|
|
m_Color = DWORD(-1);
|
|
|
|
}
|
|
|
|
CXTPCalendarResource::~CXTPCalendarResource()
|
|
{
|
|
if (m_pDataProvider)
|
|
{
|
|
if (m_bCloseDataProviderWhenDestroy && m_pDataProvider->IsOpen())
|
|
{
|
|
m_pDataProvider->Close();
|
|
}
|
|
CMDTARGET_RELEASE(m_pDataProvider);
|
|
}
|
|
}
|
|
|
|
void CXTPCalendarResource::SetDataProvider(CXTPCalendarData* pDataProvider,
|
|
BOOL bCloseDataProviderWhenDestroy)
|
|
{
|
|
CMDTARGET_ADDREF(pDataProvider);
|
|
CMDTARGET_RELEASE(m_pDataProvider);
|
|
|
|
m_pDataProvider = pDataProvider;
|
|
m_bCloseDataProviderWhenDestroy = bCloseDataProviderWhenDestroy;
|
|
|
|
}
|
|
|
|
CXTPCalendarEventsPtr CXTPCalendarResource::RetrieveDayEvents(COleDateTime dtDay)
|
|
{
|
|
// get current day date
|
|
dtDay = CXTPCalendarUtils::ResetTime(dtDay);
|
|
|
|
//
|
|
// retrieve all events for this day from the corresponding data provider
|
|
//
|
|
CXTPCalendarEventsPtr ptrEvents = m_pDataProvider ? m_pDataProvider->RetrieveDayEvents(dtDay) :
|
|
new CXTPCalendarEvents();
|
|
|
|
FilterEventsByScheduleID(ptrEvents);
|
|
|
|
return ptrEvents;
|
|
}
|
|
|
|
BOOL CXTPCalendarResource::ExistsScheduleID(UINT uScheduleID,
|
|
BOOL bReturnTrueIfSchedulesSetEmpty)
|
|
{
|
|
const int nScheduleIDCount = (int)m_arScheduleIDs.GetSize();
|
|
|
|
if (nScheduleIDCount == 0)
|
|
{
|
|
return bReturnTrueIfSchedulesSetEmpty;
|
|
}
|
|
|
|
// iterate all ScheduleID's
|
|
for (int i = 0; i < nScheduleIDCount; i++)
|
|
{
|
|
UINT uScheduleID_I = m_arScheduleIDs.GetAt(i);
|
|
|
|
if (uScheduleID_I == uScheduleID)
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void CXTPCalendarResource::FilterEventsByScheduleID(CXTPCalendarEvents* pEvents)
|
|
{
|
|
// filter all events by ScheduleID collection
|
|
//
|
|
const int nScheduleIDCount = (int)m_arScheduleIDs.GetSize();
|
|
|
|
// do not filter by schedule ID if no schedules set
|
|
if (nScheduleIDCount && pEvents)
|
|
{
|
|
const int nEventCount = pEvents->GetCount();
|
|
for (int nEvent = nEventCount - 1; nEvent >= 0; nEvent--)
|
|
{
|
|
BOOL bRemove = TRUE;
|
|
|
|
// get next event from the collection
|
|
CXTPCalendarEvent* pEvent = pEvents->GetAt(nEvent, FALSE);
|
|
ASSERT(pEvent);
|
|
|
|
if (pEvent)
|
|
{
|
|
UINT uScheduleIDEvent = pEvent->GetScheduleID();
|
|
bRemove = !ExistsScheduleID(uScheduleIDEvent, TRUE);
|
|
}
|
|
|
|
if (bRemove)
|
|
{
|
|
pEvents->RemoveAt(nEvent);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Resources collection
|
|
//
|
|
//
|
|
|
|
CXTPCalendarResources::CXTPCalendarResources()
|
|
{
|
|
}
|
|
|
|
CXTPCalendarResources::~CXTPCalendarResources()
|
|
{
|
|
}
|
|
|
|
CXTPCalendarResource* CXTPCalendarResources::Find(CXTPCalendarEvent* pEvent) const
|
|
{
|
|
if (!pEvent || !pEvent->GetDataProvider())
|
|
return NULL;
|
|
|
|
CXTPCalendarData* pDPEvent = pEvent->GetDataProvider();
|
|
UINT uScheduleIDEvent = pEvent->GetScheduleID();
|
|
|
|
int nRCCount = GetCount();
|
|
for (int i = 0; i < nRCCount; i++)
|
|
{
|
|
CXTPCalendarResource* pRC = GetAt(i, FALSE);
|
|
ASSERT(pRC);
|
|
if (pRC && pRC->GetDataProvider() == pDPEvent)
|
|
{
|
|
if (pRC->ExistsScheduleID(uScheduleIDEvent, TRUE))
|
|
return pRC;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
CXTPCalendarEventsPtr CXTPCalendarResources::RetrieveDayEvents(COleDateTime dtDay) const
|
|
{
|
|
CXTPCalendarEventsPtr ptrEvents;
|
|
|
|
int nRCCount = GetCount();
|
|
for (int i = 0; i < nRCCount; i++)
|
|
{
|
|
CXTPCalendarResource* pRC = GetAt(i, FALSE);
|
|
ASSERT(pRC);
|
|
if (pRC)
|
|
{
|
|
CXTPCalendarEventsPtr ptrEvents2;
|
|
ptrEvents2 = pRC->RetrieveDayEvents(dtDay);
|
|
if (!ptrEvents)
|
|
ptrEvents = ptrEvents2;
|
|
else
|
|
ptrEvents->Append(ptrEvents2);
|
|
}
|
|
}
|
|
|
|
return ptrEvents;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
CXTPCalendarResourcesNf::CXTPCalendarResourcesNf()
|
|
{
|
|
m_pConnection = new CXTPNotifyConnection_internal();
|
|
}
|
|
|
|
CXTPCalendarResourcesNf::~CXTPCalendarResourcesNf()
|
|
{
|
|
CXTPNotifySinkBase::UnadviseAll();
|
|
CMDTARGET_RELEASE(m_pConnection);
|
|
}
|
|
|
|
|
|
void CXTPCalendarResourcesNf::ReBuildInternalData()
|
|
{
|
|
UnadviseAll();
|
|
|
|
// rebuild optimized data
|
|
m_arResourcesGroupedByDP.RemoveAll();
|
|
|
|
int nRCCount = GetCount();
|
|
for (int nRCNr = 0; nRCNr < nRCCount; nRCNr++)
|
|
{
|
|
CXTPCalendarResource* pRCorig = GetAt(nRCNr, FALSE);
|
|
|
|
if (!pRCorig || !pRCorig->GetDataProvider() ||
|
|
!pRCorig->GetSchedules())
|
|
{
|
|
ASSERT(FALSE);
|
|
continue;
|
|
}
|
|
CXTPCalendarResource* pRCuniq = FindByDataProvider(&m_arResourcesGroupedByDP, pRCorig->GetDataProvider());
|
|
|
|
if (!pRCuniq)
|
|
{
|
|
pRCuniq = new CXTPCalendarResource();
|
|
if (!pRCuniq)
|
|
{
|
|
return;
|
|
}
|
|
pRCuniq->SetDataProvider(pRCorig->GetDataProvider(), FALSE);
|
|
|
|
m_arResourcesGroupedByDP.Add(pRCuniq, FALSE);
|
|
}
|
|
|
|
int nSchCount = (int)pRCorig->GetSchedules()->GetSize();
|
|
for (int j = 0; j < nSchCount; j++)
|
|
{
|
|
UINT nSchID = pRCorig->GetSchedules()->GetAt(j);
|
|
if (!pRCuniq->ExistsScheduleID(nSchID, FALSE) )
|
|
{
|
|
pRCuniq->GetSchedules()->Add(nSchID);
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------
|
|
if (!m_pConnection)
|
|
{
|
|
return;
|
|
}
|
|
// get notify IDs ---------
|
|
CMap<XTP_NOTIFY_CODE, XTP_NOTIFY_CODE, int, int> mapNfIDs;
|
|
int nConnCount = (int)m_pConnection->m_arrConnections.GetSize();
|
|
for (int nConnNr = 0; nConnNr < nConnCount; nConnNr++)
|
|
{
|
|
CXTPNotifyConnection_internal::CONNECTION_DESCRIPTOR* pConnDesc =
|
|
m_pConnection->m_arrConnections[nConnNr];
|
|
ASSERT(pConnDesc);
|
|
if (!pConnDesc)
|
|
{
|
|
continue;
|
|
}
|
|
mapNfIDs[pConnDesc->dwNotifyCode] = 1;
|
|
}
|
|
|
|
// advice
|
|
POSITION posNfID = mapNfIDs.GetStartPosition();
|
|
while (posNfID)
|
|
{
|
|
XTP_NOTIFY_CODE nfCode = 0;
|
|
int nTmp;
|
|
mapNfIDs.GetNextAssoc(posNfID, nfCode, nTmp);
|
|
|
|
int nDPCount = m_arResourcesGroupedByDP.GetCount();
|
|
for (int i = 0; i < nDPCount; i++)
|
|
{
|
|
CXTPNotifyConnection* pDPconn = XTP_SAFE_GET2(m_arResourcesGroupedByDP.GetAt(i),
|
|
GetDataProvider(), GetConnection(), NULL);
|
|
ASSERT(pDPconn);
|
|
|
|
if (pDPconn)
|
|
{
|
|
CXTPNotifySinkBase::Advise(pDPconn, nfCode);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CXTPCalendarResource* CXTPCalendarResourcesNf::FindByDataProvider(
|
|
const CXTPCalendarResources* pResources,
|
|
CXTPCalendarData* pData)
|
|
{
|
|
if (!pResources || !pData)
|
|
{
|
|
ASSERT(FALSE);
|
|
return NULL;
|
|
}
|
|
|
|
int nCount = pResources->GetCount();
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
CXTPCalendarResource* pRC = pResources->GetAt(i);
|
|
ASSERT(pRC);
|
|
if (pRC && pRC->GetDataProvider() == pData)
|
|
{
|
|
return pRC;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void CXTPCalendarResourcesNf::OnEvent(XTP_NOTIFY_CODE dwNotifyCode, WPARAM wParam,
|
|
LPARAM lParam, DWORD dwFlags)
|
|
|
|
{
|
|
if (dwNotifyCode == XTP_NC_CALENDAREVENTWASADDED ||
|
|
dwNotifyCode == XTP_NC_CALENDAREVENTWASDELETED ||
|
|
dwNotifyCode == XTP_NC_CALENDAREVENTWASCHANGED)
|
|
{
|
|
CXTPCalendarEvent* pEvent = (CXTPCalendarEvent*)lParam;
|
|
ASSERT(pEvent);
|
|
|
|
if (!pEvent)
|
|
{
|
|
return;
|
|
}
|
|
CXTPCalendarResource* pRC = FindByDataProvider(&m_arResourcesGroupedByDP, pEvent->GetDataProvider());
|
|
|
|
UINT uSchID = pEvent->GetScheduleID();
|
|
if (!pRC || !pRC->ExistsScheduleID(uSchID, TRUE))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
ASSERT(GetConnection());
|
|
|
|
if (GetConnection())
|
|
{
|
|
GetConnection()->SendEvent(dwNotifyCode, wParam, lParam, dwFlags);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|