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.

971 lines
25 KiB
C++

// XTPCalendarEvent.cpp: implementation of the CXTPCalendarEvent 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/XTPColorManager.h"
#include "Common/XTPSmartPtrInternalT.h"
#include "XTPCalendarDefines.h"
#include "XTPCalendarUtils.h"
#include "XTPCalendarPtrCollectionT.h"
#include "XTPCalendarEventLabel.h"
#include "XTPCalendarCustomProperties.h"
#include "XTPCalendarTimeZoneHelper.h"
#include "XTPCalendarNotifications.h"
#include "XTPCalendarRecurrencePattern.h"
#include "XTPCalendarEvent.h"
#include "XTPCalendarEvents.h"
#include "XTPCalendarData.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
static LPCTSTR cszEventProp_EventID = _T("EventID");
static LPCTSTR cszEventProp_ScheduleID= _T("ScheduleID");
static LPCTSTR cszEventProp_StartTime = _T("StartTime");
static LPCTSTR cszEventProp_EndTime = _T("EndTime");
static LPCTSTR cszEventProp_Subject = _T("Subject");
static LPCTSTR cszEventProp_Location = _T("Location");
static LPCTSTR cszEventProp_Body = _T("Body");
static LPCTSTR cszEventProp_MultipleSchedules= _T("MultipleSchedules");
// OLD. used to read old data files
static LPCTSTR cszEventPropOld_Description = _T("Description");
static LPCTSTR cszEventProp_AllDayEvent = _T("AllDayEvent");
static LPCTSTR cszEventProp_LabelID = _T("LabelID");
static LPCTSTR cszEventProp_BusyStatus = _T("BusyStatus");
static LPCTSTR cszEventProp_Importance = _T("Importance");
static LPCTSTR cszEventProp_ReminderMinutesBeforeStart = _T("ReminderMinutesBeforeStart");
static LPCTSTR cszEventProp_ReminderSoundFile = _T("ReminderSoundFile");
static LPCTSTR cszEventProp_CreationTime = _T("CreationTime");
static LPCTSTR cszEventProp_LastModificationTime = _T("LastModificationTime");
static LPCTSTR cszEventProp_RecurrenceState = _T("RecurrenceState");
static LPCTSTR cszEventProp_IsMeeting = _T("IsMeeting");
static LPCTSTR cszEventProp_IsPrivate = _T("IsPrivate");
static LPCTSTR cszEventProp_IsReminder = _T("IsReminder");
//## Recurrence Event properties
static LPCTSTR cszEventProp_RecurrencePatternID = _T("RecurrencePatternID");
//## Recurrence Event Exception properties
static LPCTSTR cszEventProp_RExceptionDeleted = _T("RExceptionDeleted");
static LPCTSTR cszEventProp_RException_StartTimeOrig= _T("RException_StartTimeOrig");
static LPCTSTR cszEventProp_RException_EndTimeOrig = _T("RException_EndTimeOrig");
/////////////////////////////////////////////////////////////////////////////
#define XTP_EVENT_PROP_SET_DATA_VER_1 1
#define XTP_EVENT_PROP_SET_DATA_VER_2 2
#define XTP_EVENT_PROP_SET_DATA_VER_3 3
#define XTP_EVENT_PROP_SET_DATA_VER 4
IMPLEMENT_DYNAMIC(CXTPCalendarEvent, CCmdTarget)
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
CXTPCalendarEvent::CXTPCalendarEvent(CXTPCalendarData* pDataProvider)
{
ASSERT(pDataProvider);
m_pDataProvider = pDataProvider;
if (m_pDataProvider)
{
m_pDataProvider->InternalAddRef();
}
m_dwEventID = XTP_CALENDAR_UNKNOWN_EVENT_ID;
m_nLabelID = XTP_CALENDAR_DEFAULT_LABEL_ID;
m_uScheduleID = XTP_CALENDAR_UNKNOWN_SCHEDULE_ID;
m_nBusyStatus = xtpCalendarBusyStatusFree;
m_nImportance = xtpCalendarImportanceNormal;
m_dwRecurrencePatternID = XTP_CALENDAR_UNKNOWN_RECURRENCE_PATTERN_ID;
m_nRecurrenceState = xtpCalendarRecurrenceNotRecurring;
m_bRExceptionDeleted = FALSE;
//<<EventVisible>>
m_bEventVisible = TRUE;
//<<EventVisible>>
m_bAllDayEvent = FALSE;
m_dtStartTime = (DATE)0; //.SetStatus(COleDateTime::null);
m_dtEndTime = (DATE)0; //.SetStatus(COleDateTime::null);
m_dtCreationTime = m_dtLastModificationTime = CXTPCalendarUtils::GetCurrentTime();
m_bReminder = FALSE;
m_nReminderMinutesBeforeStart = XTP_CALENDAR_DEFAULT_REMINDER_MINUTES;
m_dtRException_StartTimeOrig = (DATE)0; // .SetStatus(COleDateTime::null);
m_dtRException_EndTimeOrig = (DATE)0; // .SetStatus(COleDateTime::null);
m_bMeeting = FALSE;
m_bPrivate = FALSE;
m_dwRecurrencePatternID_ToUse = XTP_CALENDAR_UNKNOWN_RECURRENCE_PATTERN_ID;
m_pCustomProperties = new CXTPCalendarCustomProperties;
m_pCustomIconsIDs = new CXTPCalendarCustomIconIDs;
m_pEventCategoryIDs = new CXTPCalendarEventCategoryIDs;
m_sMultipleSchedules.Empty();
}
CXTPCalendarEvent::~CXTPCalendarEvent()
{
CMDTARGET_RELEASE(m_pDataProvider);
CMDTARGET_RELEASE(m_pCustomProperties);
CMDTARGET_RELEASE(m_pCustomIconsIDs);
CMDTARGET_RELEASE(m_pEventCategoryIDs);
}
int CXTPCalendarEvent::GetCategoriesCount() const
{
return XTP_SAFE_GET1(GetCategories(), GetSize(), 0);
}
CXTPCalendarEventLabel* CXTPCalendarEvent::GetLabel() const
{
CXTPCalendarEventLabel* pResultLab = NULL;
if (m_pDataProvider && m_pDataProvider->GetLabelList())
{
pResultLab = m_pDataProvider->GetLabelList()->Find(m_nLabelID);
}
return pResultLab;
}
void CXTPCalendarEvent::SetStartTime(COleDateTime dtStart)
{
if (m_nRecurrenceState == xtpCalendarRecurrenceOccurrence ||
m_nRecurrenceState == xtpCalendarRecurrenceMaster)
{
ASSERT(FALSE);
return;
}
m_dtStartTime = dtStart;
if (m_dtStartTime.GetStatus() == COleDateTime::valid &&
m_dtEndTime.GetStatus() == COleDateTime::valid &&
(m_dtStartTime > m_dtEndTime ||
CXTPCalendarUtils::IsEqual(m_dtEndTime, m_dtStartTime)))
{
m_dtEndTime = m_dtStartTime;
}
}
void CXTPCalendarEvent::SetEndTime(COleDateTime dtEnd)
{
if (m_nRecurrenceState == xtpCalendarRecurrenceOccurrence ||
m_nRecurrenceState == xtpCalendarRecurrenceMaster)
{
ASSERT(FALSE);
return;
}
m_dtEndTime = dtEnd;
if (m_dtStartTime.GetStatus() == COleDateTime::valid &&
m_dtEndTime.GetStatus() == COleDateTime::valid &&
(m_dtEndTime < m_dtStartTime ||
CXTPCalendarUtils::IsEqual(m_dtEndTime, m_dtStartTime)))
{
m_dtStartTime = m_dtEndTime;
}
}
void CXTPCalendarEvent::SetDuration(COleDateTimeSpan spDuration, BOOL bKeepStart)
{
if (bKeepStart)
{
SetEndTime(m_dtStartTime + spDuration);
}
else
{
SetStartTime(m_dtEndTime - spDuration);
}
}
void CXTPCalendarEvent::MoveEvent(COleDateTime dtNewStartTime)
{
COleDateTimeSpan spDuration = m_dtEndTime - m_dtStartTime;
SetStartTime(dtNewStartTime);
SetEndTime(dtNewStartTime + spDuration);
//CXTPCalendarRecurrencePatternPtr CalendarRecurrencePatternPtr = GetRecurrencePattern();
//if (CalendarRecurrencePatternPtr)
//{
// CalendarRecurrencePatternPtr->SetStartTime(dtNewStartTime);
// CalendarRecurrencePatternPtr->SetDurationMinutes((int) spDuration.GetTotalMinutes());
//}
}
int CXTPCalendarEvent::GetDurationMinutes() const
{
return CXTPCalendarUtils::GetDurationMinutes(m_dtStartTime, m_dtEndTime, m_bAllDayEvent);
}
COleDateTimeSpan CXTPCalendarEvent::GetDuration() const
{
COleDateTimeSpan spDuration;
if (m_bAllDayEvent)
{
spDuration = CXTPCalendarUtils::ResetTime(m_dtEndTime) - CXTPCalendarUtils::ResetTime(m_dtStartTime);
}
else
{
spDuration = m_dtEndTime - m_dtStartTime;
}
return spDuration;
}
CXTPCalendarRecurrencePatternPtr CXTPCalendarEvent::GetRecurrencePattern() const
{
if (m_ptrRPattern)
{
ASSERT(m_nRecurrenceState == xtpCalendarRecurrenceMaster);
CXTPCalendarRecurrencePatternPtr ptrPattern = m_ptrRPattern->ClonePattern();
return ptrPattern;
}
if (!m_pDataProvider)
{
ASSERT(FALSE);
return NULL;
}
CXTPCalendarRecurrencePatternPtr ptrPattern = m_pDataProvider->GetRecurrencePattern(m_dwRecurrencePatternID);
return ptrPattern;
}
BOOL CXTPCalendarEvent::SetRecurrenceState_Master(CXTPCalendarRecurrencePattern* pPattern)
{
if (!pPattern || m_nRecurrenceState != xtpCalendarRecurrenceNotRecurring)
{
ASSERT(FALSE);
return FALSE;
}
ASSERT(!m_ptrRPattern);
m_nRecurrenceState = xtpCalendarRecurrenceMaster;
m_ptrRPattern = pPattern;
m_ptrRPattern->InternalAddRef();
m_dwRecurrencePatternID = m_ptrRPattern->GetPatternID();
m_ptrRPattern->SetMasterEventID(m_dwEventID);
BOOL bRes = CalcStartEndDatesFromPattern();
ASSERT(bRes);
return bRes;
}
BOOL CXTPCalendarEvent::SetRecurrenceState_ExceptionOccurrence(XTPCalendarEventRecurrenceState nState, DWORD dwNewPatternID)
{
ASSERT(nState == xtpCalendarRecurrenceOccurrence || nState == xtpCalendarRecurrenceException);
if (m_ptrRPattern || m_nRecurrenceState == xtpCalendarRecurrenceMaster)
{
ASSERT(FALSE); //set new recur. state to master event. strange! why ???
return FALSE;
}
// update original Start/End times for exception event
if (nState == xtpCalendarRecurrenceException)
{
// You should change state to exception only for occurrence or new event (event copy).
// !!! Otherwise this may not work correctly !!!
//ASSERT(m_nRecurrenceState == xtpCalendarRecurrenceOccurrence);
ASSERT(m_nRecurrenceState == xtpCalendarRecurrenceNotRecurring ||
m_nRecurrenceState == xtpCalendarRecurrenceOccurrence ||
m_nRecurrenceState == xtpCalendarRecurrenceException);
COleDateTime dtTmpOrig = GetStartTime();
SetRException_StartTimeOrig(dtTmpOrig);
dtTmpOrig = GetEndTime();
SetRException_EndTimeOrig(dtTmpOrig);
}
m_nRecurrenceState = nState;
if (dwNewPatternID != XTP_CALENDAR_UNKNOWN_RECURRENCE_PATTERN_ID)
{
m_dwRecurrencePatternID = dwNewPatternID;
}
//ASSERT(m_dwRecurrencePatternID != XTP_CALENDAR_UNKNOWN_RECURRENCE_PATTERN_ID);
return TRUE;
}
BOOL CXTPCalendarEvent::SetRecurrenceState_NotRecurring()
{
if (m_ptrRPattern)
{
m_ptrRPattern->SetMasterEventID(XTP_CALENDAR_UNKNOWN_EVENT_ID);
}
m_dwRecurrencePatternID_ToUse = m_dwRecurrencePatternID;
m_nRecurrenceState = xtpCalendarRecurrenceNotRecurring;
m_ptrRPattern = NULL;
m_dwRecurrencePatternID = XTP_CALENDAR_UNKNOWN_RECURRENCE_PATTERN_ID;
return TRUE;
}
BOOL CXTPCalendarEvent::CalcStartEndDatesFromPattern()
{
if (m_nRecurrenceState != xtpCalendarRecurrenceMaster || !m_ptrRPattern)
{
ASSERT(FALSE);
return FALSE;
}
COleDateTime dtS = m_ptrRPattern->GetPatternStartDate();
COleDateTime dtE(9999, 1, 1, 0, 0, 0);
if (m_ptrRPattern->GetUseEndMethod() == xtpCalendarPatternEndDate ||
m_ptrRPattern->GetUseEndMethod() == xtpCalendarPatternEndAfterOccurrences &&
m_ptrRPattern->GetEndAfterOccurrences() < 4000)
{
CXTPCalendarDatesArray arDates;
m_ptrRPattern->GetOccurrencesDates(arDates, dtS, dtE);
int nCount = (int) arDates.GetSize();
if (nCount)
{
dtS = arDates[0];
dtE = arDates[nCount - 1];
m_dtStartTime = m_ptrRPattern->GetStartOccurrenceTime(dtS);
m_dtEndTime = m_ptrRPattern->GetEndOccurrenceTime(dtS);
ASSERT(GetEventPeriodDays() > 0);
int nDays = max(1, GetEventPeriodDays());
dtE += COleDateTimeSpan(nDays - 1, 0, 0, 0);
}
else
{
dtE = dtS;
}
}
m_dtStartTime = dtS;
m_dtEndTime = dtE;
UpdateStartEndDatesFromPatternExceptions();
return TRUE;
}
BOOL CXTPCalendarEvent::UpdateStartEndDatesFromPatternExceptions()
{
COleDateTime dtS = GetStartTime();
COleDateTime dtE = GetEndTime();
BOOL bRes = FALSE;
CXTPCalendarEventsPtr ptrExceptions = m_ptrRPattern->GetExceptions();
int nCount = ptrExceptions ? ptrExceptions->GetCount() : 0;
for (int i = 0; i < nCount; i++)
{
CXTPCalendarEvent* pExcept = ptrExceptions->GetAt(i);
if (pExcept->GetStartTime() < dtS)
{
dtS = pExcept->GetStartTime();
bRes = TRUE;
}
if (pExcept->GetEndTime() > dtE)
{
dtE = pExcept->GetEndTime();
bRes = TRUE;
}
}
if (bRes)
{
m_dtStartTime = dtS;
m_dtEndTime = dtE;
}
return bRes;
}
CXTPCalendarEventPtr CXTPCalendarEvent::CloneEvent()
{
if (!m_pDataProvider)
{
ASSERT(FALSE);
return NULL;
}
CXTPCalendarEventPtr ptrNewEvent = m_pDataProvider->CreateNewEvent(GetEventID());
if (!ptrNewEvent)
{
ASSERT(FALSE);
return NULL;
}
if (CloneEventTo(ptrNewEvent))
return ptrNewEvent;
ASSERT(FALSE);
return NULL;
}
BOOL CXTPCalendarEvent::CloneEventTo(CXTPCalendarEvent* pEventDest)
{
if (!m_pDataProvider || !pEventDest)
{
ASSERT(FALSE);
return FALSE;
}
pEventDest->Clear();
BOOL bRes = pEventDest->Update(this);
if (!bRes)
{
ASSERT(FALSE);
return FALSE;
}
XTPCalendarEventRecurrenceState nRState = GetRecurrenceState();
if (nRState == xtpCalendarRecurrenceMaster)
{
CXTPCalendarRecurrencePatternPtr ptrRPattern = GetRecurrencePattern();
bRes = pEventDest->SetRecurrenceState_Master(ptrRPattern);
}
else if (nRState != xtpCalendarRecurrenceNotRecurring)
{
ASSERT(nRState == xtpCalendarRecurrenceException || nRState == xtpCalendarRecurrenceOccurrence);
DWORD dwPatternID = GetRecurrencePatternID();
bRes = pEventDest->SetRecurrenceState_ExceptionOccurrence(nRState, dwPatternID);
}
if (nRState == xtpCalendarRecurrenceException)
{
COleDateTime dtTmpOrig = GetRException_StartTimeOrig();
pEventDest->SetRException_StartTimeOrig(dtTmpOrig);
dtTmpOrig = GetRException_EndTimeOrig();
pEventDest->SetRException_EndTimeOrig(dtTmpOrig);
}
pEventDest->m_dwRecurrencePatternID_ToUse = m_dwRecurrencePatternID_ToUse;
ASSERT(bRes);
return bRes;
}
BOOL CXTPCalendarEvent::Update(CXTPCalendarEvent* pNewData)
{
if (pNewData == this)
{
return TRUE;
}
UINT uScheduleID = pNewData->GetScheduleID();
SetScheduleID(uScheduleID);
SetScheduleSet(pNewData->GetScheduleSet());
CString strTmp = pNewData->GetSubject();
SetSubject(strTmp);
strTmp = pNewData->GetLocation();
SetLocation(strTmp);
int nTmp = pNewData->GetLabelID();
SetLabelID(nTmp);
BOOL bTmp = pNewData->IsAllDayEvent();
SetAllDayEvent(bTmp);
//<<EventVisible>>
bTmp = pNewData->IsEventVisible();
SetEventVisible(bTmp);
//<<EventVisible>>
COleDateTime dtTmp = pNewData->GetStartTime();
m_dtStartTime = dtTmp;
dtTmp = pNewData->GetEndTime();
m_dtEndTime = dtTmp;
bTmp = pNewData->IsReminder();
SetReminder(bTmp);
nTmp = pNewData->GetReminderMinutesBeforeStart();
SetReminderMinutesBeforeStart(nTmp);
strTmp = pNewData->GetReminderSoundFile();
SetReminderSoundFile(strTmp);
strTmp = pNewData->GetBody();
SetBody(strTmp);
nTmp = pNewData->GetBusyStatus();
SetBusyStatus(nTmp);
nTmp = pNewData->GetImportance();
SetImportance(nTmp);
dtTmp = pNewData->GetCreationTime();
SetCreationTime(dtTmp);
dtTmp = pNewData->GetLastModificationTime();
SetLastModificationTime(dtTmp);
nTmp = pNewData->IsMeeting();
SetMeeting(nTmp);
nTmp = pNewData->IsPrivate();
SetPrivate(nTmp);
bTmp = pNewData->IsRExceptionDeleted();
SetRExceptionDeleted(bTmp);
dtTmp = pNewData->GetRException_StartTimeOrig();
SetRException_StartTimeOrig(dtTmp);
dtTmp = pNewData->GetRException_EndTimeOrig();
SetRException_EndTimeOrig(dtTmp);
// Custom properties
ASSERT(pNewData->GetCustomProperties());
if (pNewData->GetCustomProperties())
{
pNewData->GetCustomProperties()->CopyTo(m_pCustomProperties);
}
// Custom Icons
if (GetCustomIcons() && pNewData->GetCustomIcons())
{
GetCustomIcons()->Copy(*pNewData->GetCustomIcons());
}
else
{
XTP_SAFE_CALL1(GetCustomIcons(), RemoveAll());
}
// Event categories
if (GetCategories() && pNewData->GetCategories())
{
GetCategories()->Copy(*pNewData->GetCategories());
}
else
{
XTP_SAFE_CALL1(GetCategories(), RemoveAll());
}
return TRUE;
}
CXTPCalendarEventPtr CXTPCalendarEvent::CloneForOccurrence(COleDateTime dtStart,
COleDateTime dtEnd, DWORD dwNewEventID)
{
int eRecurrenceState = GetRecurrenceState();
if (eRecurrenceState != xtpCalendarRecurrenceMaster || !m_pDataProvider)
{
ASSERT(FALSE);
return NULL;
}
CXTPCalendarEventPtr ptrNewEvent = m_pDataProvider->CreateNewEvent(dwNewEventID);
if (!ptrNewEvent)
{
ASSERT(FALSE);
return FALSE;
}
BOOL bRes = ptrNewEvent->Update(this);
if (!bRes)
{
ASSERT(FALSE);
return NULL;
}
ptrNewEvent->SetStartTime(dtStart);
ptrNewEvent->SetEndTime(dtEnd);
ptrNewEvent->SetRecurrenceState_ExceptionOccurrence(xtpCalendarRecurrenceOccurrence, m_dwRecurrencePatternID);
ptrNewEvent->SetRExceptionDeleted(FALSE);
return ptrNewEvent;
}
BOOL CXTPCalendarEvent::MakeEventAsRecurrence()
{
if (m_nRecurrenceState != xtpCalendarRecurrenceNotRecurring || !m_pDataProvider)
{
ASSERT(FALSE);
return FALSE;
}
ASSERT(m_ptrRPattern == NULL);
CXTPCalendarRecurrencePatternPtr ptrPattern;
ptrPattern = m_pDataProvider->CreateNewRecurrencePattern(m_dwRecurrencePatternID_ToUse);
if (!SetRecurrenceState_Master(ptrPattern))
{
ASSERT(FALSE);
return FALSE;
}
return TRUE;
}
BOOL CXTPCalendarEvent::UpdateRecurrence(CXTPCalendarRecurrencePattern* pRPattern)
{
if (m_nRecurrenceState != xtpCalendarRecurrenceMaster ||
!m_pDataProvider || !m_ptrRPattern || !pRPattern)
{
ASSERT(FALSE);
return FALSE;
}
//ASSERT(m_dwRecurrencePatternID == m_ptrRPattern->GetPatternID());
//ASSERT(m_dwEventID == m_ptrRPattern->GetMasterEventID());
//DWORD dwPatternID2 = pRPattern->GetPatternID();
//DWORD dwMasterID2 = pRPattern->GetMasterEventID();
//if (m_dwRecurrencePatternID != dwPatternID2 || m_dwEventID != dwMasterID2)
//{
// ASSERT(FALSE);
// return FALSE;
//}
//------------------------------------------------
BOOL bRes = m_ptrRPattern->Update(pRPattern);
if (!bRes)
{
ASSERT(FALSE);
return FALSE;
}
m_dwRecurrencePatternID = m_ptrRPattern->GetPatternID();
m_ptrRPattern->SetMasterEventID(m_dwEventID);
bRes = CalcStartEndDatesFromPattern();
ASSERT(bRes);
return bRes;
}
BOOL CXTPCalendarEvent::RemoveRecurrence()
{
COleDateTime dtStart, dtEnd;
BOOL bIsMaster = GetRecurrenceState() == xtpCalendarRecurrenceMaster;
if (bIsMaster && m_ptrRPattern)
{
dtStart = CXTPCalendarUtils::UpdateTime(m_ptrRPattern->GetPatternStartDate(),
m_ptrRPattern->GetStartTime());
dtEnd = dtStart + m_ptrRPattern->GetDuration();
}
else
{
bIsMaster = FALSE;
}
if (!SetRecurrenceState_NotRecurring())
{
ASSERT(FALSE);
return FALSE;
}
if (bIsMaster)
{
SetStartTime(dtStart);
SetEndTime(dtEnd);
}
return TRUE;
}
CXTPCalendarRecurrencePattern* CXTPCalendarEvent::GetRPatternRef() const
{
ASSERT(GetRecurrenceState() == xtpCalendarRecurrenceMaster);
return m_ptrRPattern;
}
int CXTPCalendarEvent::GetEventPeriodDays() const
{
return CXTPCalendarUtils::GetEventPeriodDays(GetStartTime(), GetEndTime());
}
BOOL CXTPCalendarEvent::IsEqualStartEnd(const CXTPCalendarEvent* pEvent) const
{
COleDateTime dtStart2 = pEvent->GetStartTime();
COleDateTime dtEnd2 = pEvent->GetEndTime();
BOOL bRes = CXTPCalendarUtils::IsEqual(m_dtStartTime, dtStart2, TRUE) &&
CXTPCalendarUtils::IsEqual(m_dtEndTime, dtEnd2, TRUE);
return bRes;
}
BOOL CXTPCalendarEvent::IsEqualIDs(const CXTPCalendarEvent* pEvent) const
{
if (!pEvent)
{
ASSERT(FALSE);
return FALSE;
}
int nRState2 = pEvent->GetRecurrenceState();
BOOL bRes = FALSE;
if (m_nRecurrenceState == xtpCalendarRecurrenceNotRecurring &&
nRState2 == xtpCalendarRecurrenceNotRecurring)
{
DWORD dwEventID2 = pEvent->GetEventID();
bRes = (m_dwEventID == dwEventID2);
}
else
{
DWORD dwPatternID2 = pEvent->GetRecurrencePatternID();
// for xtpCalendarRecurrenceMaster & xtpCalendarRecurrenceOccurrence
COleDateTime dtStart = m_dtStartTime;
COleDateTime dtEnd = m_dtEndTime;
COleDateTime dtStart2 = pEvent->GetStartTime();
COleDateTime dtEnd2 = pEvent->GetEndTime();
if (m_nRecurrenceState == xtpCalendarRecurrenceException)
{
dtStart = GetRException_StartTimeOrig();
dtEnd = GetRException_EndTimeOrig();
}
if (pEvent->GetRecurrenceState() == xtpCalendarRecurrenceException)
{
dtStart2 = pEvent->GetRException_StartTimeOrig();
dtEnd2 = pEvent->GetRException_EndTimeOrig();
}
bRes = m_dwRecurrencePatternID == dwPatternID2 &&
CXTPCalendarUtils::IsEqual(dtStart, dtStart2, TRUE) &&
CXTPCalendarUtils::IsEqual(dtEnd, dtEnd2, TRUE);
}
return bRes;
}
void CXTPCalendarEvent::Clear()
{
CXTPCalendarEventPtr ptrEmptyEvent = m_pDataProvider->CreateNewEvent(GetEventID());
if (!ptrEmptyEvent)
{
ASSERT(FALSE);
return;
}
SetRecurrenceState_NotRecurring();
Update(ptrEmptyEvent);
}
void CXTPCalendarEvent::DoPropExchange(CXTPPropExchange* pPX)
{
long nVersion = XTP_EVENT_PROP_SET_DATA_VER;
PX_Long(pPX, _T("Version"), nVersion, XTP_EVENT_PROP_SET_DATA_VER);
// TODO:
PX_DWord(pPX, cszEventProp_ScheduleID, (DWORD&)m_uScheduleID, 0);
PX_DWord(pPX, cszEventProp_EventID, m_dwEventID, XTP_CALENDAR_UNKNOWN_EVENT_ID);
PX_DateTime(pPX, cszEventProp_StartTime, m_dtStartTime);
PX_DateTime(pPX, cszEventProp_EndTime, m_dtEndTime);
PX_String(pPX, cszEventProp_Subject, m_strSubject, _T(""));
PX_String(pPX, cszEventProp_Location, m_strLocation, _T(""));
if (nVersion > XTP_EVENT_PROP_SET_DATA_VER_3)
{
if (pPX->IsStoring())
{
if (m_sMultipleSchedules.IsEmpty())
m_sMultipleSchedules.Format(_T("|%d|"), m_uScheduleID);
}
PX_String(pPX, cszEventProp_MultipleSchedules, m_sMultipleSchedules, _T(""));
if (!pPX->IsStoring())
{
if (m_sMultipleSchedules.IsEmpty())
m_sMultipleSchedules.Format(_T("|%d|"), m_uScheduleID);
}
}
if (nVersion > XTP_EVENT_PROP_SET_DATA_VER_1)
{
PX_String(pPX, cszEventProp_Body, m_strBody, _T(""));
}
else
{
PX_String(pPX, cszEventPropOld_Description, m_strBody, _T(""));
}
PX_Bool(pPX, cszEventProp_AllDayEvent, m_bAllDayEvent, FALSE);
PX_Int(pPX, cszEventProp_LabelID, m_nLabelID, XTP_CALENDAR_DEFAULT_LABEL_ID);
PX_Int(pPX, cszEventProp_BusyStatus, m_nBusyStatus, xtpCalendarBusyStatusFree);
PX_Int(pPX, cszEventProp_Importance, m_nImportance, xtpCalendarImportanceNormal);
if (nVersion > XTP_EVENT_PROP_SET_DATA_VER_1)
{
PX_Bool(pPX, cszEventProp_IsReminder, m_bReminder, FALSE);
}
PX_Int(pPX, cszEventProp_ReminderMinutesBeforeStart, m_nReminderMinutesBeforeStart, 15);
PX_String(pPX, cszEventProp_ReminderSoundFile, m_strReminderSoundFile, _T(""));
PX_DateTime(pPX, cszEventProp_CreationTime, m_dtCreationTime);
PX_DateTime(pPX, cszEventProp_LastModificationTime, m_dtLastModificationTime);
PX_Bool(pPX, cszEventProp_IsMeeting, m_bMeeting, FALSE);
PX_Bool(pPX, cszEventProp_IsPrivate, m_bPrivate, FALSE);
if (pPX->IsStoring())
{
PX_Enum(pPX, cszEventProp_RecurrenceState, m_nRecurrenceState, xtpCalendarRecurrenceNotRecurring);
PX_DWord(pPX, cszEventProp_RecurrencePatternID, m_dwRecurrencePatternID, XTP_CALENDAR_UNKNOWN_RECURRENCE_PATTERN_ID);
if (m_nRecurrenceState == xtpCalendarRecurrenceException)
{
PX_Bool(pPX, cszEventProp_RExceptionDeleted, m_bRExceptionDeleted, FALSE);
PX_DateTime(pPX, cszEventProp_RException_StartTimeOrig, m_dtRException_StartTimeOrig);
PX_DateTime(pPX, cszEventProp_RException_EndTimeOrig, m_dtRException_EndTimeOrig);
}
}
else
{
//===========================================================================
XTPCalendarEventRecurrenceState nRecurrenceState = m_nRecurrenceState = xtpCalendarRecurrenceNotRecurring;
PX_Enum(pPX, cszEventProp_RecurrenceState, nRecurrenceState, xtpCalendarRecurrenceNotRecurring);
DWORD dwRecurrencePatternID = XTP_CALENDAR_UNKNOWN_RECURRENCE_PATTERN_ID;
PX_DWord(pPX, cszEventProp_RecurrencePatternID, dwRecurrencePatternID, XTP_CALENDAR_UNKNOWN_RECURRENCE_PATTERN_ID);
if (nRecurrenceState == xtpCalendarRecurrenceMaster)
{
if (!MakeEventAsRecurrence())
{
ASSERT(FALSE);
return;
}
}
else if (nRecurrenceState == xtpCalendarRecurrenceException || nRecurrenceState == xtpCalendarRecurrenceOccurrence)
{
SetRecurrenceState_ExceptionOccurrence(nRecurrenceState, dwRecurrencePatternID);
if (nRecurrenceState == xtpCalendarRecurrenceException)
{
PX_Bool(pPX, cszEventProp_RExceptionDeleted, m_bRExceptionDeleted, FALSE);
PX_DateTime(pPX, cszEventProp_RException_StartTimeOrig, m_dtRException_StartTimeOrig);
PX_DateTime(pPX, cszEventProp_RException_EndTimeOrig, m_dtRException_EndTimeOrig);
}
}
}
//------------------------------------------------------------------------
if (m_pCustomProperties)
m_pCustomProperties->DoPropExchange(pPX);
if (m_pCustomIconsIDs)
m_pCustomIconsIDs->DoPropExchange(pPX);
if (m_pEventCategoryIDs && nVersion > XTP_EVENT_PROP_SET_DATA_VER_2)
m_pEventCategoryIDs->DoPropExchange(pPX);
}
void CXTPCalendarEvent::ClearIntermediateData()
{
m_dwRecurrencePatternID_ToUse = XTP_CALENDAR_UNKNOWN_RECURRENCE_PATTERN_ID;
if (!IsReminder() && m_pCustomProperties)
{
// clear this property if reminder disabled
m_pCustomProperties->RemoveProperty(cszEventCustProp_NextReminderTime_Snoozed);
}
if (!IsReminder() && m_ptrRPattern)
{
ASSERT(m_nRecurrenceState == xtpCalendarRecurrenceMaster);
// clear reminders info for occurrences
// if reminder disabled for whole series.
m_ptrRPattern->GetOccReminders()->RemoveAll();
}
}
void CXTPCalendarEvent::SetRecurrencePatternID(DWORD dwRecurrencePatternID)
{
m_dwRecurrencePatternID = dwRecurrencePatternID;
if (m_ptrRPattern)
{
ASSERT(m_nRecurrenceState == xtpCalendarRecurrenceMaster);
m_ptrRPattern->SetPatternID(dwRecurrencePatternID);
}
}
void CXTPCalendarEvent::SetEventID(DWORD dwEventID)
{
m_dwEventID = dwEventID;
if (m_nRecurrenceState == xtpCalendarRecurrenceMaster)
{
ASSERT(m_ptrRPattern);
if (m_ptrRPattern)
{
m_ptrRPattern->SetMasterEventID(m_dwEventID);
}
}
}
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////