XTPCalendarRecurrencePattern.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:38k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPCalendarRecurrencePattern.cpp: implementation of the CXTPCalendarRecurrencePattern class.
  2. //
  3. // This file is a part of the XTREME CALENDAR MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Common/XTPPropExchange.h"
  22. #include "Common/XTPVC50Helpers.h"
  23. #include "Common/XTPVC80Helpers.h"
  24. #include "XTPCalendarRecurrencePattern.h"
  25. #include "XTPCalendarEvents.h"
  26. #include "XTPCalendarEvent.h"
  27. #include "XTPCalendarUtils.h"
  28. #include "XTPCalendarData.h"
  29. #include "XTPCalendarCustomProperties.h"
  30. #include "XTPCalendarRemindersManager.h"
  31. static LPCTSTR cszRPatt_PatternID = _T("PatternID");
  32. static LPCTSTR cszRPatt_StartTime = _T("StartTime");
  33. static LPCTSTR cszRPatt_DurationMinutes = _T("DurationMinutes");
  34. static LPCTSTR cszRPatt_RecurrenceType = _T("RecurrenceType");
  35. static LPCTSTR cszRPatt_RecurrenceOpt_Data1 = _T("RecurrenceOpt_Data1");
  36. static LPCTSTR cszRPatt_RecurrenceOpt_Data2 = _T("RecurrenceOpt_Data2");
  37. static LPCTSTR cszRPatt_RecurrenceOpt_Data3 = _T("RecurrenceOpt_Data3");
  38. static LPCTSTR cszRPatt_PatternStartDate = _T("PatternStartDate");
  39. static LPCTSTR cszRPatt_UseEndMethod = _T("UseEndMethod");
  40. static LPCTSTR cszRPatt_PatternEndDate = _T("PatternEndDate");
  41. static LPCTSTR cszRPatt_EndAfterOccurrences = _T("EndAfterOccurrences");
  42. static LPCTSTR cszRPatt_MasterEventID = _T("MasterEventID");
  43. //===========================================================================
  44. static const LPCTSTR cszOccRMD_Count        = _T("*xtp*OccRMD_Count");
  45. static const LPCTSTR cszOccRMD_StartTime    = _T("*xtp*OccRMD_Start");
  46. static const LPCTSTR cszOccRMD_EndTime      = _T("*xtp*OccRMD_End");
  47. static const LPCTSTR cszOccRMD_IsReminder                 = _T("*xtp*OccRMD_IsReminder");
  48. static const LPCTSTR cszOccRMD_NextReminderTime_Snoozed = _T("*xtp*OccRMD_NextReminderTime_Snoozed");
  49. //===========================================================================
  50. #ifdef _DEBUG
  51. #define new DEBUG_NEW
  52. #undef THIS_FILE
  53. static char THIS_FILE[] = __FILE__;
  54. #endif
  55. ////////////////////////////////////////////////////////////////////////////
  56. #define XTP_RECPATT_PROP_SET_DATA_VER 1
  57. ////////////////////////////////////////////////////////////////////////////
  58. IMPLEMENT_DYNAMIC(CXTPCalendarRecurrencePattern, CCmdTarget)
  59. /////////////////////////////////////////////////////////////////////////////
  60. CXTPCalendarRecurrencePattern::CXTPCalendarRecurrencePattern(CXTPCalendarData* pDataProvider)
  61. {
  62. ASSERT(pDataProvider);
  63. m_ptrDataProvider = pDataProvider;
  64. CMDTARGET_ADDREF(m_ptrDataProvider);
  65. m_dwPatternID = XTP_CALENDAR_UNKNOWN_RECURRENCE_PATTERN_ID;
  66. m_dwMasterEventID = XTP_CALENDAR_UNKNOWN_EVENT_ID;
  67. m_dtStartTime = (DATE)0; //.SetStatus(COleDateTime::null);
  68. m_nDurationMinutes = 0;
  69. m_Options.m_nRecurrenceType = xtpCalendarRecurrenceUnknown;
  70. m_dtPatternStartDate = (DATE)0; //.SetStatus(COleDateTime::null);
  71. m_pCustomProperties = new CXTPCalendarCustomProperties;
  72. }
  73. CXTPCalendarRecurrencePattern::~CXTPCalendarRecurrencePattern()
  74. {
  75. CMDTARGET_RELEASE(m_ptrDataProvider);
  76. CMDTARGET_RELEASE(m_pCustomProperties);
  77. }
  78. COleDateTime CXTPCalendarRecurrencePattern::GetStartOccurrenceTime(COleDateTime dtOccurrenceStartDate) const
  79. {
  80. COleDateTime dtStartOcc = GetStartTime();
  81. dtStartOcc = CXTPCalendarUtils::UpdateDate(dtStartOcc, dtOccurrenceStartDate);
  82. return dtStartOcc;
  83. }
  84. COleDateTime CXTPCalendarRecurrencePattern::GetEndOccurrenceTime(COleDateTime dtOccurrenceStartDate) const
  85. {
  86. COleDateTimeSpan spDuration = GetDuration();
  87. COleDateTime dtEndOcc = GetStartOccurrenceTime(dtOccurrenceStartDate);
  88. dtEndOcc += spDuration;
  89. return dtEndOcc;
  90. }
  91. void CXTPCalendarRecurrencePattern::_GetOccurrenceStartEnd(const COleDateTime& dtOccStartDate, COleDateTime& rdtOccStart, COleDateTime& rdtOccEnd) const
  92. {
  93. rdtOccStart = GetStartTime();
  94. rdtOccStart = CXTPCalendarUtils::UpdateDate(rdtOccStart, dtOccStartDate);
  95. COleDateTimeSpan spDuration = GetDuration();
  96. rdtOccEnd = rdtOccStart + spDuration;
  97. }
  98. void CXTPCalendarRecurrencePattern::SetPatternStartDate(COleDateTime dtStart)
  99. {
  100. m_dtPatternStartDate = CXTPCalendarUtils::ResetTime(dtStart);
  101. if (m_dtPatternStartDate.GetStatus() == COleDateTime::valid &&
  102. m_PatternEnd.m_dtPatternEndDate.GetStatus() == COleDateTime::valid &&
  103. m_dtPatternStartDate > m_PatternEnd.m_dtPatternEndDate)
  104. {
  105. m_PatternEnd.m_dtPatternEndDate = m_dtPatternStartDate;
  106. }
  107. }
  108. void CXTPCalendarRecurrencePattern::SetPatternEndDate(COleDateTime dtEnd)
  109. {
  110. m_PatternEnd.m_dtPatternEndDate = CXTPCalendarUtils::ResetTime(dtEnd);
  111. m_PatternEnd.m_nUseEnd = xtpCalendarPatternEndDate;
  112. if (m_dtPatternStartDate.GetStatus() == COleDateTime::valid &&
  113. m_PatternEnd.m_dtPatternEndDate.GetStatus() == COleDateTime::valid &&
  114. m_PatternEnd.m_dtPatternEndDate < m_dtPatternStartDate)
  115. {
  116. m_dtPatternStartDate = m_PatternEnd.m_dtPatternEndDate;
  117. }
  118. }
  119. BOOL CXTPCalendarRecurrencePattern::GetOccurrences(CXTPCalendarEvents* pEventsArray,
  120. COleDateTime dtStart, COleDateTime dtEnd,
  121. CXTPCalendarEvent* pMasterEvent)
  122. {
  123. if (!pMasterEvent || !pEventsArray)
  124. {
  125. ASSERT(FALSE);
  126. return FALSE;
  127. }
  128. //------
  129. COleDateTime dtStartOcc, dtEndOcc;
  130. _GetOccurrenceStartEnd(dtStart, dtStartOcc, dtEndOcc);
  131. int nOccDays = CXTPCalendarUtils::GetEventPeriodDays(dtStartOcc, dtEndOcc);
  132. ASSERT(nOccDays > 0);
  133. nOccDays = max(1, nOccDays);
  134. COleDateTime dtStartCheckOcc = dtStart;
  135. if (dtStart == dtEnd)
  136. {
  137. //- check for previous multiday occurrences ---
  138. if (nOccDays > 1)
  139. {
  140. COleDateTimeSpan spCheckMDOcc(nOccDays - 1, 0, 0, 0);
  141. dtStartCheckOcc = dtStart - spCheckMDOcc;
  142. }
  143. }
  144. CXTPCalendarDatesArray arDates;
  145. GetOccurrencesDates(arDates, dtStartCheckOcc, dtEnd);
  146. COleDateTime dtI;
  147. int nCount = (int)arDates.GetSize();
  148. for (int i = 0; i < nCount; i++)
  149. {
  150. dtI = arDates[i];
  151. _GetOccurrenceStartEnd(dtI, dtStartOcc, dtEndOcc);
  152. ASSERT(!(CXTPCalendarUtils::ResetTime(dtEndOcc) < CXTPCalendarUtils::ResetTime(dtStart) ||
  153. CXTPCalendarUtils::ResetTime(dtStartOcc) > CXTPCalendarUtils::ResetTime(dtEnd)));
  154. CXTPCalendarEventPtr ptrOccurrenceEvent(FindException(dtStartOcc, dtEndOcc), TRUE);
  155. if (ptrOccurrenceEvent)
  156. {
  157. continue;
  158. }
  159. else
  160. {
  161. ptrOccurrenceEvent = pMasterEvent->CloneForOccurrence(dtStartOcc, dtEndOcc);
  162. if (ptrOccurrenceEvent && ptrOccurrenceEvent->GetStartTime() <
  163. pMasterEvent->GetLastModificationTime())
  164. {
  165. ptrOccurrenceEvent->SetReminder(FALSE);
  166. }
  167. }
  168. if (ptrOccurrenceEvent)
  169. {
  170. m_arOccReminders.UpdateOccIfNeed(ptrOccurrenceEvent, this);
  171. pEventsArray->Add(ptrOccurrenceEvent);
  172. }
  173. }
  174. FindExceptions(pEventsArray, dtStart, dtEnd);
  175. return TRUE;
  176. }
  177. void CXTPCalendarRecurrencePattern::GetOccurrencesDates(CXTPCalendarDatesArray& rArDates,
  178. COleDateTime dtStart, COleDateTime dtEnd) const
  179. {
  180. COleDateTime dtStart0 = CXTPCalendarUtils::ResetTime(dtStart);
  181. COleDateTime dtEnd0 = CXTPCalendarUtils::SetTime_235959(dtEnd);
  182. int nMaxOccCount = INT_MAX;
  183. int nOccCount = 0;
  184. COleDateTime dtI;
  185. COleDateTime dtE1(9999, 1, 1, 0, 0, 0);
  186. COleDateTime dtS1 = max(dtStart0, m_dtPatternStartDate);
  187. switch (m_PatternEnd.m_nUseEnd)
  188. {
  189. case xtpCalendarPatternEndDate:
  190. dtE1 = min(m_PatternEnd.m_dtPatternEndDate, dtEnd0);
  191. break;
  192. case xtpCalendarPatternEndAfterOccurrences:
  193. nMaxOccCount = m_PatternEnd.m_nEndAfterOccurrences;
  194. dtE1 = dtEnd0;
  195. break;
  196. case xtpCalendarPatternEndNoDate:
  197. dtE1 = dtEnd0;
  198. break;
  199. default:
  200. ASSERT(FALSE);
  201. return;
  202. }
  203. switch (m_Options.m_nRecurrenceType)
  204. {
  205. case xtpCalendarRecurrenceDaily:
  206. {
  207. //------------------------------------------------------
  208. // 1. Every N days:
  209. //      m_nInterval = N,
  210. //      m_nDayOfWeekMask = xtpCalendarDayAllWeek
  211. //------------------------------------------------------
  212. // 2. Every week day (Mo-Fr):
  213. //      m_nInterval = 1,
  214. //      m_nDayOfWeekMask = xtpCalendarDayMo_Fr
  215. //------------------------------------------------------
  216. int nDays = m_Options.m_Daily.nIntervalDays;
  217. if (m_Options.m_Daily.bEveryWeekDayOnly)
  218. {
  219. ASSERT(nDays == 1);
  220. nDays = 1;
  221. }
  222. COleDateTimeSpan spStep(nDays, 0, 0, 0);
  223. if (m_dtPatternStartDate < dtStart0)
  224. {
  225. //--- shift start date --------------
  226. COleDateTimeSpan spDiff = dtStart0 - m_dtPatternStartDate;
  227. int nDiff_Days = (int)GETTOTAL_DAYS_DTS(spDiff);
  228. ASSERT(nDiff_Days >= 1);
  229. int nJump_Days = (nDiff_Days / nDays) * nDays;
  230. spDiff.SetDateTimeSpan(nJump_Days, 0, 0, 0);
  231. dtS1 = m_dtPatternStartDate + spDiff;
  232. if (dtS1 < dtStart0)
  233. {
  234. dtS1 += spStep;
  235. }
  236. //--- calculate occurrences ----------
  237. if (nMaxOccCount != INT_MAX)
  238. {
  239. nOccCount = nDiff_Days / nDays;
  240. if (m_Options.m_Daily.bEveryWeekDayOnly)
  241. {
  242. int nWDstart = m_dtPatternStartDate.GetDayOfWeek();
  243. int nBasis1_days = (nDiff_Days - (7 - nWDstart));
  244. int nSatDays = nBasis1_days / 7 + ((nBasis1_days % 7) ? 1 : 0);
  245. int nBasis6_days = (nDiff_Days - (6 - nWDstart));
  246. int nSunDays = nBasis6_days / 7 + ((nBasis6_days % 7) ? 1 : 0);
  247. nOccCount -= nSatDays + nSunDays;
  248. }
  249. }
  250. }
  251. else
  252. {
  253. dtS1 = m_dtPatternStartDate;
  254. }
  255. for (dtI = dtS1; dtI <= dtE1 && nOccCount < nMaxOccCount; dtI += spStep)
  256. {
  257. if (m_Options.m_Daily.bEveryWeekDayOnly)
  258. {
  259. int nWD = dtI.GetDayOfWeek(); // 1-Sunday, 2 - Monday, ...
  260. if (nWD == 1 || nWD == 7)
  261. {
  262. continue;
  263. }
  264. }
  265. ASSERT(dtI >= dtStart0 && dtI <= dtE1);
  266. rArDates.Add(dtI);
  267. nOccCount++;
  268. }
  269. }
  270. break;
  271. case xtpCalendarRecurrenceWeekly:
  272. {
  273. //------------------------------------------------------
  274. // 1. Every N weeks:
  275. //      m_nInterval = N,
  276. //      m_nDayOfWeekMask = <*MASK*>
  277. //------------------------------------------------------
  278. int nWeeksStep = m_Options.m_Weekly.nIntervalWeeks;
  279. if (nWeeksStep <= 0)
  280. {
  281. ASSERT(FALSE);
  282. nWeeksStep = 1;
  283. }
  284. COleDateTimeSpan spStep(1, 0, 0, 0);
  285. COleDateTimeSpan spStepWeeks((nWeeksStep)*7, 0, 0, 0);
  286. //================================================================
  287. int nFirstDayOfWeekIndex = 2; // Always Monday (as in MS Outlook)
  288. COleDateTimeSpan spWeek(7, 0, 0, 0);
  289. COleDateTime dtPatSW = CXTPCalendarUtils::ShiftDateToWeekBegin(m_dtPatternStartDate, nFirstDayOfWeekIndex);
  290. dtPatSW = CXTPCalendarUtils::ResetTime(dtPatSW);
  291. COleDateTime dtOccFrame1 = dtPatSW;
  292. COleDateTime dtOccFrame2 = dtOccFrame1 + spWeek;
  293. if (m_dtPatternStartDate < dtStart0)
  294. {
  295. COleDateTime dtStart0SW = CXTPCalendarUtils::ShiftDateToWeekBegin(dtStart0, nFirstDayOfWeekIndex);
  296. COleDateTimeSpan spDiff = dtStart0SW - dtPatSW;
  297. int nDiff_Weeks = (int)spDiff.GetTotalDays() / 7;
  298. ASSERT((int)spDiff.GetTotalDays() % 7 == 0);
  299. int nJump_Weeks = (nDiff_Weeks / nWeeksStep) * nWeeksStep;
  300. spDiff.SetDateTimeSpan(nJump_Weeks * 7, 0, 0, 0);
  301. dtOccFrame1 = dtPatSW + spDiff;
  302. dtOccFrame2 = dtOccFrame1 + spWeek;
  303. nOccCount = CXTPCalendarUtils::GetDayOfWeekCount(m_Options.m_Weekly.nDayOfWeekMask);
  304. nOccCount *= nJump_Weeks / nWeeksStep;
  305. //------------------------------------------------------------
  306. int nSkippedMask = CXTPCalendarUtils::MakeDaysOfWeekMask_Mo_(m_dtPatternStartDate.GetDayOfWeek());
  307. nOccCount -= CXTPCalendarUtils::GetDayOfWeekCount(nSkippedMask & m_Options.m_Weekly.nDayOfWeekMask);
  308. //------------------------------------------------------------
  309. int nAddedMask = CXTPCalendarUtils::MakeDaysOfWeekMask_Mo_(dtS1.GetDayOfWeek());
  310. nOccCount += CXTPCalendarUtils::GetDayOfWeekCount(nAddedMask & m_Options.m_Weekly.nDayOfWeekMask);
  311. }
  312. //================================================================
  313. for (dtI = dtS1; dtI <= dtE1 && nOccCount < nMaxOccCount; dtI += spStep)
  314. {
  315. if (nWeeksStep > 1 && !(dtOccFrame1 <= dtI && dtI < dtOccFrame2))
  316. {
  317. dtOccFrame1 += spStepWeeks;
  318. dtOccFrame2 = dtOccFrame1 + spWeek;
  319. dtI = dtOccFrame1 - spStep;
  320. continue;
  321. }
  322. int nWD = dtI.GetDayOfWeek(); // 1-Sunday, 2 - Monday, ...
  323. int nWDMask = CXTPCalendarUtils::GetDayOfWeekMask(nWD);
  324. if (m_Options.m_Weekly.nDayOfWeekMask & nWDMask)
  325. {
  326. ASSERT(dtI >= dtStart0 && dtI <= dtE1);
  327. rArDates.Add(dtI);
  328. nOccCount++;
  329. }
  330. }
  331. }
  332. break;
  333. case xtpCalendarRecurrenceMonthly:
  334. {
  335. //------------------------------------------------------
  336. // 1. Day N of every M month(s):
  337. //      m_nDayOfMonth = N,
  338. //      m_nInterval = M
  339. //------------------------------------------------------
  340. //================================================================
  341. int nMInterval = m_Options.m_Monthly.nIntervalMonths;
  342. if (nMInterval <= 0)
  343. {
  344. ASSERT(FALSE);
  345. nMInterval = 1;
  346. }
  347. COleDateTime dtOccFrame1 = CXTPCalendarUtils::ResetTime(m_dtPatternStartDate);
  348. CXTPCalendarUtils::UpdateMonthDay(dtOccFrame1, 1);
  349. if (m_dtPatternStartDate < dtStart0)
  350. {
  351. int nPS_Year = m_dtPatternStartDate.GetYear();
  352. int nPS_Month = m_dtPatternStartDate.GetMonth();
  353. int nPS_GlobalMonth = nPS_Year * 12 + nPS_Month;
  354. int nS0_Year = dtStart0.GetYear();
  355. int nS0_Month = dtStart0.GetMonth();
  356. int nS0_GlobalMonth = nS0_Year * 12 + nS0_Month;
  357. int nMonthDiff = nS0_GlobalMonth - nPS_GlobalMonth;
  358. int nJump_Month = (nMonthDiff / nMInterval) * nMInterval;
  359. CXTPCalendarUtils::ShiftDate_Month(dtOccFrame1, nJump_Month, 1);
  360. nOccCount = nJump_Month / nMInterval;
  361. //------------------------------------------------------------
  362. if (m_dtPatternStartDate.GetDay() > m_Options.m_Monthly.nDayOfMonth)
  363. {
  364. nOccCount--;
  365. }
  366. //------------------------------------------------------------
  367. if (dtS1.GetDay() > m_Options.m_Monthly.nDayOfMonth)
  368. {
  369. nOccCount++;
  370. }
  371. }
  372. //================================================================
  373. COleDateTime dtOcc(dtOccFrame1);
  374. VERIFY(CXTPCalendarUtils::UpdateMonthDay(dtOcc, m_Options.m_Monthly.nDayOfMonth));
  375. if (dtOcc >= dtS1)
  376. {
  377. dtS1 = dtOcc;
  378. }
  379. else
  380. {
  381. dtS1 = dtOcc;
  382. CXTPCalendarUtils::ShiftDate_Month(dtS1, m_Options.m_Monthly.nIntervalMonths,
  383. m_Options.m_Monthly.nDayOfMonth);
  384. }
  385. for (dtI = dtS1; dtI <= dtE1 && nOccCount < nMaxOccCount;)
  386. {
  387. ASSERT(dtI >= dtStart0 && dtI <= dtE1);
  388. rArDates.Add(dtI);
  389. nOccCount++;
  390. CXTPCalendarUtils::ShiftDate_Month(dtI, m_Options.m_Monthly.nIntervalMonths,
  391. m_Options.m_Monthly.nDayOfMonth);
  392. }
  393. }
  394. break;
  395. case xtpCalendarRecurrenceMonthNth:
  396. {
  397. //------------------------------------------------------
  398. //~ The I:{First, second, ..., Last>
  399. //~         W:{Day, WeekDay, WeekEndDay, Su, Mo, ...}
  400. //~             of every M month(s):
  401. //------------------------------------------------------
  402. //================================================================
  403. int nMInterval = m_Options.m_MonthNth.nIntervalMonths;
  404. if (nMInterval <= 0)
  405. {
  406. ASSERT(FALSE);
  407. nMInterval = 1;
  408. }
  409. COleDateTime dtOccFrame1 = CXTPCalendarUtils::ResetTime(m_dtPatternStartDate);
  410. CXTPCalendarUtils::UpdateMonthDay(dtOccFrame1, 1);
  411. if (m_dtPatternStartDate < dtStart0)
  412. {
  413. int nPS_Year = m_dtPatternStartDate.GetYear();
  414. int nPS_Month = m_dtPatternStartDate.GetMonth();
  415. int nPS_GlobalMonth = nPS_Year * 12 + nPS_Month;
  416. int nS0_Year = dtStart0.GetYear();
  417. int nS0_Month = dtStart0.GetMonth();
  418. int nS0_GlobalMonth = nS0_Year * 12 + nS0_Month;
  419. int nMonthDiff = nS0_GlobalMonth - nPS_GlobalMonth;
  420. int nJump_Month = (nMonthDiff / nMInterval) * nMInterval;
  421. CXTPCalendarUtils::ShiftDate_Month(dtOccFrame1, nJump_Month, 1);
  422. nOccCount = nJump_Month / nMInterval;
  423. //------------------------------------------------------------
  424. COleDateTime dtTestMD(m_dtPatternStartDate);
  425. CXTPCalendarUtils::CalcDayOfMonth(dtTestMD,
  426. m_Options.m_MonthNth.nWhichDay,
  427. m_Options.m_MonthNth.nWhichDayMask);
  428. if (m_dtPatternStartDate.GetDay() > dtTestMD.GetDay())
  429. {
  430. nOccCount--;
  431. }
  432. //------------------------------------------------------------
  433. dtTestMD = dtS1;
  434. CXTPCalendarUtils::CalcDayOfMonth(dtTestMD,
  435. m_Options.m_MonthNth.nWhichDay,
  436. m_Options.m_MonthNth.nWhichDayMask);
  437. if (dtS1.GetDay() > dtTestMD.GetDay())
  438. {
  439. nOccCount++;
  440. }
  441. }
  442. //================================================================
  443. COleDateTime dtOcc(dtOccFrame1);
  444. BOOL bRes = CXTPCalendarUtils::CalcDayOfMonth(dtOcc, m_Options.m_MonthNth.nWhichDay,
  445. m_Options.m_MonthNth.nWhichDayMask);
  446. if (!bRes)
  447. {
  448. return;
  449. }
  450. if (dtOcc >= dtS1)
  451. {
  452. dtS1 = dtOcc;
  453. }
  454. else
  455. {
  456. dtS1 = dtOcc;
  457. CXTPCalendarUtils::ShiftDate_Month(dtS1, nMInterval);
  458. bRes = CXTPCalendarUtils::CalcDayOfMonth(dtS1, m_Options.m_MonthNth.nWhichDay,
  459. m_Options.m_MonthNth.nWhichDayMask);
  460. if (!bRes)
  461. {
  462. return;
  463. }
  464. }
  465. for (dtI = dtS1; dtI <= dtE1 && nOccCount < nMaxOccCount;)
  466. {
  467. ASSERT(dtI >= dtStart0 && dtI <= dtE1);
  468. rArDates.Add(dtI);
  469. nOccCount++;
  470. CXTPCalendarUtils::ShiftDate_Month(dtI, nMInterval);
  471. bRes = CXTPCalendarUtils::CalcDayOfMonth(dtI, m_Options.m_MonthNth.nWhichDay,
  472. m_Options.m_MonthNth.nWhichDayMask);
  473. if (!bRes)
  474. {
  475. ASSERT(FALSE);
  476. break;
  477. }
  478. }
  479. }
  480. break;
  481. case xtpCalendarRecurrenceYearly:
  482. {
  483. //------------------------------------------------------
  484. // Every M:{month} D:{Day}
  485. //      m_nMonthOfYear = M
  486. //      m_nDayOfMonth = D
  487. //------------------------------------------------------
  488. COleDateTime dtOcc(dtS1.GetYear(), m_Options.m_Yearly.nMonthOfYear,
  489.    1, 0, 0, 0);
  490. CXTPCalendarUtils::UpdateMonthDay(dtOcc, m_Options.m_Yearly.nDayOfMonth);
  491. if (dtOcc >= dtS1)
  492. {
  493. dtS1 = dtOcc;
  494. }
  495. else
  496. {
  497. dtS1 = dtOcc;
  498. CXTPCalendarUtils::ShiftDate_Year(dtS1, 1, m_Options.m_Yearly.nDayOfMonth);
  499. }
  500. for (dtI = dtS1; dtI <= dtE1 && nOccCount < nMaxOccCount;
  501.  CXTPCalendarUtils::ShiftDate_Year(dtI, 1, m_Options.m_Yearly.nDayOfMonth))
  502. {
  503. ASSERT(dtI >= dtStart0 && dtI <= dtE1);
  504. rArDates.Add(dtI);
  505. nOccCount++;
  506. }
  507. }
  508. break;
  509. case xtpCalendarRecurrenceYearNth:
  510. {
  511. //------------------------------------------------------
  512. //~ The I:{First, second, ..., Last>
  513. //~         W:{Day, WeekDay, WeekEndDay, Su, Mo, ...}
  514. //~             of M:{month}
  515. //------------------------------------------------------
  516. COleDateTime dtOcc(dtS1.GetYear(), m_Options.m_YearNth.nMonthOfYear,
  517. 1, 0, 0, 0);
  518. BOOL bRes = CXTPCalendarUtils::CalcDayOfMonth(dtOcc,
  519. m_Options.m_YearNth.nWhichDay,
  520. m_Options.m_YearNth.nWhichDayMask);
  521. if (!bRes)
  522. {
  523. return;
  524. }
  525. if (dtOcc >= dtS1)
  526. {
  527. dtS1 = dtOcc;
  528. }
  529. else
  530. {
  531. dtS1 = dtOcc;
  532. CXTPCalendarUtils::ShiftDate_Year(dtS1, 1);
  533. bRes = CXTPCalendarUtils::CalcDayOfMonth(dtS1, m_Options.m_YearNth.nWhichDay,
  534. m_Options.m_YearNth.nWhichDayMask);
  535. if (!bRes)
  536. {
  537. return;
  538. }
  539. }
  540. for (dtI = dtS1; dtI <= dtE1 && nOccCount < nMaxOccCount;)
  541. {
  542. ASSERT(dtI >= dtStart0 && dtI <= dtE1);
  543. rArDates.Add(dtI);
  544. nOccCount++;
  545. CXTPCalendarUtils::ShiftDate_Year(dtI, 1);
  546. bRes = CXTPCalendarUtils::CalcDayOfMonth(dtI, m_Options.m_YearNth.nWhichDay,
  547. m_Options.m_YearNth.nWhichDayMask);
  548. if (!bRes)
  549. {
  550. ASSERT(FALSE);
  551. break;
  552. }
  553. }
  554. }
  555. }
  556. }
  557. void CXTPCalendarRecurrencePattern::SetRecurrenceOptions(const XTP_CALENDAR_RECURRENCE_OPTIONS& Options)
  558. {
  559. m_Options = Options;
  560. if (m_Options.m_nRecurrenceType == xtpCalendarRecurrenceDaily &&
  561. m_Options.m_Daily.bEveryWeekDayOnly)
  562. {
  563. m_Options.m_Daily.nIntervalDays = 1;
  564. }
  565. }
  566. void CXTPCalendarRecurrencePattern::SetPatternEnd(const XTP_CALENDAR_PATTERN_END& patternEnd)
  567. {
  568. m_PatternEnd = patternEnd;
  569. if (m_PatternEnd.m_nUseEnd == xtpCalendarPatternEndDate)
  570. {
  571. m_PatternEnd.m_dtPatternEndDate = CXTPCalendarUtils::ResetTime(m_PatternEnd.m_dtPatternEndDate);
  572. if (m_dtPatternStartDate.GetStatus() == COleDateTime::valid &&
  573. m_PatternEnd.m_dtPatternEndDate.GetStatus() == COleDateTime::valid &&
  574. m_PatternEnd.m_dtPatternEndDate < m_dtPatternStartDate)
  575. {
  576. m_dtPatternStartDate = m_PatternEnd.m_dtPatternEndDate;
  577. }
  578. }
  579. }
  580. CXTPCalendarRecurrencePatternPtr CXTPCalendarRecurrencePattern::ClonePattern()
  581. {
  582. if (!m_ptrDataProvider)
  583. {
  584. ASSERT(FALSE);
  585. return NULL;
  586. }
  587. DWORD dwPatternID = GetPatternID();
  588. DWORD dwMasterID = GetMasterEventID();
  589. CXTPCalendarRecurrencePatternPtr ptrNew = m_ptrDataProvider->CreateNewRecurrencePattern();
  590. if (!ptrNew)
  591. {
  592. ASSERT(FALSE);
  593. return NULL;
  594. }
  595. ptrNew->SetPatternID(dwPatternID);
  596. ptrNew->SetMasterEventID(dwMasterID);
  597. if (!ptrNew->Update(this))
  598. {
  599. ASSERT(FALSE);
  600. return NULL;
  601. }
  602. return ptrNew;
  603. }
  604. BOOL CXTPCalendarRecurrencePattern::Update(CXTPCalendarRecurrencePattern* pNewData)
  605. {
  606. if (pNewData == this)
  607. {
  608. return TRUE;
  609. }
  610. COleDateTime dtTmp = pNewData->GetStartTime();
  611. SetStartTime(dtTmp);
  612. int nTmp = pNewData->GetDurationMinutes();
  613. SetDurationMinutes(nTmp);
  614. const XTP_CALENDAR_RECURRENCE_OPTIONS& rOpt = pNewData->GetRecurrenceOptions();
  615. SetRecurrenceOptions(rOpt);
  616. dtTmp = pNewData->GetPatternStartDate();
  617. SetPatternStartDate(dtTmp);
  618. const XTP_CALENDAR_PATTERN_END& rPatternEnd = pNewData->GetPatternEnd();
  619. SetPatternEnd(rPatternEnd);
  620. RemoveAllExceptions();
  621. CXTPCalendarEventsPtr ptrExceptions = pNewData->GetExceptions();
  622. int nCount = XTP_SAFE_GET1(ptrExceptions, GetCount(), 0);
  623. for (int i = 0; i < nCount; i++)
  624. {
  625. CXTPCalendarEvent* pException = ptrExceptions->GetAt(i, FALSE);
  626. if (pException)
  627. {
  628. if (!SetException(pException))
  629. {
  630. ASSERT(FALSE);
  631. }
  632. }
  633. }
  634. ASSERT(pNewData->GetCustomProperties());
  635. pNewData->GetCustomProperties()->CopyTo(m_pCustomProperties);
  636. m_arOccReminders.RemoveAll();
  637. m_arOccReminders.Append(pNewData->m_arOccReminders);
  638. return TRUE;
  639. }
  640. BOOL CXTPCalendarRecurrencePattern::SetException(CXTPCalendarEvent* pException, CXTPCalendarEvent* pMasterEventToUpdate)
  641. {
  642. if (!pException)
  643. {
  644. ASSERT(FALSE);
  645. return FALSE;
  646. }
  647. DWORD dwExcID = pException->GetEventID();
  648. CXTPCalendarEvent* pExc = m_arExceptionEvents.FindEvent(dwExcID);
  649. if (!pExc)
  650. {
  651. COleDateTime dtStartOcc = pException->GetRException_StartTimeOrig();
  652. COleDateTime dtEndOcc = pException->GetRException_EndTimeOrig();
  653. pExc = FindException(dtStartOcc, dtEndOcc);
  654. }
  655. BOOL bRes = TRUE;
  656. if (pExc)
  657. {
  658. pExc->SetEventID(pException->GetEventID());
  659. bRes = pExc->Update(pException);
  660. ASSERT(bRes);
  661. }
  662. else
  663. {
  664. CXTPCalendarEventPtr ptrExc = pException->CloneEvent();
  665. m_arExceptionEvents.Add(ptrExc);
  666. pExc = ptrExc;
  667. }
  668. pExc->SetRecurrencePatternID(m_dwPatternID);
  669. if (pMasterEventToUpdate)
  670. {
  671. pMasterEventToUpdate->UpdateStartEndDatesFromPatternExceptions();
  672. }
  673. return bRes;
  674. }
  675. BOOL CXTPCalendarRecurrencePattern::RemoveException(CXTPCalendarEvent* pException,
  676. CXTPCalendarEvent* pMasterEventToUpdate)
  677. {
  678. if (!pException)
  679. {
  680. ASSERT(FALSE);
  681. return FALSE;
  682. }
  683. int nRState = pException->GetRecurrenceState();
  684. ASSERT(nRState == xtpCalendarRecurrenceOccurrence || nRState == xtpCalendarRecurrenceException);
  685. COleDateTime dtStartOcc, dtEndOcc;
  686. if (nRState == xtpCalendarRecurrenceOccurrence)
  687. {
  688. dtStartOcc = pException->GetStartTime();
  689. dtEndOcc = pException->GetEndTime();
  690. }
  691. else
  692. {
  693. if (nRState == xtpCalendarRecurrenceException)
  694. {
  695. dtStartOcc = pException->GetRException_StartTimeOrig();
  696. dtEndOcc = pException->GetRException_EndTimeOrig();
  697. }
  698. else
  699. {
  700. return FALSE;
  701. }
  702. }
  703. int nCount = m_arExceptionEvents.GetCount();
  704. int nFExcIdx = FindExceptionIndex(dtStartOcc, dtEndOcc);
  705. if (nFExcIdx >= 0 && nFExcIdx < nCount)
  706. {
  707. m_arExceptionEvents.RemoveAt(nFExcIdx);
  708. if (pMasterEventToUpdate)
  709. {
  710. pMasterEventToUpdate->UpdateStartEndDatesFromPatternExceptions();
  711. }
  712. return TRUE;
  713. }
  714. return FALSE;
  715. }
  716. void CXTPCalendarRecurrencePattern::RemoveAllExceptions()
  717. {
  718. m_arExceptionEvents.RemoveAll();
  719. m_arOccReminders.RemoveAll();
  720. }
  721. CXTPCalendarEvent* CXTPCalendarRecurrencePattern::FindException(COleDateTime dtStartOrig, COleDateTime dtEndOrig) const
  722. {
  723. int nCount = m_arExceptionEvents.GetCount();
  724. int nFExcIdx = FindExceptionIndex(dtStartOrig, dtEndOrig);
  725. if (nFExcIdx >= 0 && nFExcIdx < nCount)
  726. {
  727. CXTPCalendarEvent* pEvent = m_arExceptionEvents.GetAt(nFExcIdx, FALSE);
  728. return pEvent;
  729. }
  730. return NULL;
  731. }
  732. int CXTPCalendarRecurrencePattern::FindExceptionIndex(COleDateTime dtStartOrig, COleDateTime dtEndOrig) const
  733. {
  734. COleDateTime dtTmpS, dtTmpE;
  735. int nCount = m_arExceptionEvents.GetCount();
  736. for (int i = 0; i < nCount; i++)
  737. {
  738. CXTPCalendarEvent* pEvent = m_arExceptionEvents.GetAt(i, FALSE);
  739. ASSERT(pEvent->GetRecurrenceState() == xtpCalendarRecurrenceException);
  740. dtTmpS = pEvent->GetRException_StartTimeOrig();
  741. dtTmpE = pEvent->GetRException_EndTimeOrig();
  742. if (CXTPCalendarUtils::IsEqual(dtTmpS, dtStartOrig) &&
  743. CXTPCalendarUtils::IsEqual(dtTmpE, dtEndOrig))
  744. {
  745. return i;
  746. }
  747. }
  748. return -1;
  749. }
  750. BOOL CXTPCalendarRecurrencePattern::FindExceptions(CXTPCalendarEvents* pEvents,
  751.    COleDateTime dtStart,
  752.    COleDateTime dtEnd) const
  753. {
  754. dtStart = CXTPCalendarUtils::ResetTime(dtStart);
  755. dtEnd = CXTPCalendarUtils::ResetTime(dtEnd);
  756. COleDateTime dtTmpS, dtTmpE;
  757. int nCount = m_arExceptionEvents.GetCount();
  758. for (int i = 0; i < nCount; i++)
  759. {
  760. CXTPCalendarEvent* pEvent = m_arExceptionEvents.GetAt(i, FALSE);
  761. ASSERT(pEvent->GetRecurrenceState() == xtpCalendarRecurrenceException);
  762. dtTmpS = CXTPCalendarUtils::ResetTime(pEvent->GetStartTime());
  763. dtTmpE = CXTPCalendarUtils::ResetTime(pEvent->GetEndTime());
  764. if (dtStart <= dtTmpS && dtTmpS <= dtEnd ||
  765. dtStart <= dtTmpE && dtTmpE <= dtEnd ||
  766. dtTmpS <= dtStart && dtStart <= dtTmpE ||
  767. dtTmpS <= dtEnd && dtEnd <= dtTmpE)
  768. {
  769. if (!pEvent->IsRExceptionDeleted())
  770. {
  771. pEvents->Add(pEvent);
  772. }
  773. }
  774. }
  775. return TRUE;
  776. }
  777. CXTPCalendarEventsPtr CXTPCalendarRecurrencePattern::GetExceptions()
  778. {
  779. CXTPCalendarEventsPtr ptrExceptions = new CXTPCalendarEvents();
  780. if (!ptrExceptions)
  781. {
  782. return NULL;
  783. }
  784. int nCount = m_arExceptionEvents.GetCount();
  785. for (int i = 0; i < nCount; i++)
  786. {
  787. CXTPCalendarEvent* pEvent = m_arExceptionEvents.GetAt(i, FALSE);
  788. ASSERT(pEvent);
  789. CXTPCalendarEventPtr ptrEventCopy = pEvent ? pEvent->CloneEvent() : NULL;
  790. if (ptrEventCopy)
  791. {
  792. ptrExceptions->Add(ptrEventCopy);
  793. }
  794. }
  795. return ptrExceptions;
  796. }
  797. CXTPCalendarEventPtr CXTPCalendarRecurrencePattern::GetMasterEvent() const
  798. {
  799. if (!m_ptrDataProvider)
  800. {
  801. ASSERT(FALSE);
  802. return NULL;
  803. }
  804. CXTPCalendarEventPtr ptrMEvent = m_ptrDataProvider->GetEvent(m_dwMasterEventID);
  805. ASSERT(ptrMEvent);
  806. return ptrMEvent;
  807. }
  808. void CXTPCalendarRecurrencePattern::SetPatternID(DWORD dwID)
  809. {
  810. m_dwPatternID = dwID;
  811. int nCount = m_arExceptionEvents.GetCount();
  812. for (int i = 0; i < nCount; i++)
  813. {
  814. CXTPCalendarEvent* pEvent = m_arExceptionEvents.GetAt(i, FALSE);
  815. ASSERT(pEvent);
  816. if (pEvent)
  817. {
  818. pEvent->SetRecurrencePatternID(m_dwPatternID);
  819. }
  820. }
  821. }
  822. void CXTPCalendarRecurrencePattern::DoPropExchange(CXTPPropExchange* pPX)
  823. {
  824. long nVersion = XTP_RECPATT_PROP_SET_DATA_VER;
  825. PX_Long(pPX, _T("Version"), nVersion, XTP_RECPATT_PROP_SET_DATA_VER);
  826. PX_DWord(pPX, cszRPatt_PatternID, m_dwPatternID, XTP_CALENDAR_UNKNOWN_RECURRENCE_PATTERN_ID);
  827. PX_DateTime(pPX, cszRPatt_StartTime, m_dtStartTime);
  828. PX_Int(pPX, cszRPatt_DurationMinutes, m_nDurationMinutes, 0);
  829. PX_Enum(pPX, cszRPatt_RecurrenceType, m_Options.m_nRecurrenceType, xtpCalendarRecurrenceUnknown);
  830. PX_Int(pPX, cszRPatt_RecurrenceOpt_Data1, m_Options.m_YearNth.nWhichDay, 0);
  831. PX_Int(pPX, cszRPatt_RecurrenceOpt_Data2, m_Options.m_YearNth.nWhichDayMask, 0);
  832. PX_Int(pPX, cszRPatt_RecurrenceOpt_Data3, m_Options.m_YearNth.nMonthOfYear, 0);
  833. PX_DateTime(pPX, cszRPatt_PatternStartDate, m_dtPatternStartDate);
  834. PX_Enum(pPX, cszRPatt_UseEndMethod, m_PatternEnd.m_nUseEnd, xtpCalendarPatternEndNoDate);
  835. if (m_PatternEnd.m_nUseEnd == xtpCalendarPatternEndDate)
  836. {
  837. PX_DateTime(pPX, cszRPatt_PatternEndDate, m_PatternEnd.m_dtPatternEndDate);
  838. }
  839. else if (m_PatternEnd.m_nUseEnd == xtpCalendarPatternEndAfterOccurrences)
  840. {
  841. PX_Int(pPX, cszRPatt_EndAfterOccurrences, m_PatternEnd.m_nEndAfterOccurrences, 1);
  842. }
  843. PX_DWord(pPX, cszRPatt_MasterEventID, m_dwMasterEventID, XTP_CALENDAR_UNKNOWN_EVENT_ID);
  844. //------------------------------------------------------------------------
  845. if (pPX->IsStoring())
  846. {
  847. VERIFY( m_arOccReminders.Save(m_pCustomProperties, this) );
  848. }
  849. //-------------------------------------------
  850. m_pCustomProperties->DoPropExchange(pPX);
  851. //-------------------------------------------
  852. if (pPX->IsLoading())
  853. {
  854. VERIFY( m_arOccReminders.Load(m_pCustomProperties) );
  855. }
  856. m_arOccReminders.ClearProperties(m_pCustomProperties);
  857. }
  858. void CXTPCalendarRecurrencePattern::SetOccReminder(
  859. CXTPCalendarEvent* pOccEvent,
  860. int nbIsReminder,
  861. DATE dtNextReminderTime_Snoozed)
  862. {
  863. ASSERT(pOccEvent);
  864. if (!pOccEvent)
  865. {
  866. return;
  867. }
  868. int nIndex = m_arOccReminders.Find(pOccEvent);
  869. if (nIndex < 0)
  870. {
  871. CXTPCalendarReminderForOccurrence tmpData;
  872. tmpData.m_dtOccurrenceStartTime = pOccEvent->GetStartTime();
  873. tmpData.m_dtOccurrenceEndTime = pOccEvent->GetEndTime();
  874. nIndex = (int)m_arOccReminders.Add(tmpData);
  875. }
  876. CXTPCalendarReminderForOccurrence* pOccRmdData;
  877. pOccRmdData = &m_arOccReminders[nIndex];
  878. if (nbIsReminder != xtpCalendarRmdPrm_DontChange)
  879. {
  880. pOccRmdData->m_nbIsReminder = nbIsReminder;
  881. }
  882. if (dtNextReminderTime_Snoozed != xtpCalendarRmdPrm_DontChange)
  883. {
  884. pOccRmdData->m_dtNextReminderTime_Snoozed = dtNextReminderTime_Snoozed;
  885. }
  886. m_arOccReminders.UpdateOccIfNeedEx(pOccEvent, pOccRmdData, this);
  887. if (pOccRmdData->m_nbIsReminder == xtpCalendarRmdPrm_Default &&
  888. pOccRmdData->m_dtNextReminderTime_Snoozed == xtpCalendarRmdPrm_Default)
  889. {
  890. m_arOccReminders.RemoveAt(nIndex);
  891. }
  892. }
  893. ////////////////////////////////////////////////////////////////////////////
  894. CXTPCalendarReminderForOccurrence::CXTPCalendarReminderForOccurrence()
  895. {
  896. m_dtOccurrenceStartTime = 0;
  897. m_dtOccurrenceEndTime = 0;
  898. m_nbIsReminder = xtpCalendarRmdPrm_Default;
  899. m_dtNextReminderTime_Snoozed = (DATE)xtpCalendarRmdPrm_Default;
  900. }
  901. CXTPCalendarReminderForOccurrence::~CXTPCalendarReminderForOccurrence()
  902. {
  903. }
  904. const CXTPCalendarReminderForOccurrence& CXTPCalendarReminderForOccurrence::operator=(
  905. const CXTPCalendarReminderForOccurrence& rSrc)
  906. {
  907. m_dtOccurrenceStartTime = rSrc.m_dtOccurrenceStartTime;
  908. m_dtOccurrenceEndTime = rSrc.m_dtOccurrenceEndTime;
  909. m_nbIsReminder = rSrc.m_nbIsReminder;
  910. m_dtNextReminderTime_Snoozed = rSrc.m_dtNextReminderTime_Snoozed;
  911. return *this;
  912. }
  913. //===========================================================================
  914. CXTPCalendarReminderForOccurrenceArray::CXTPCalendarReminderForOccurrenceArray()
  915. {
  916. }
  917. CXTPCalendarReminderForOccurrenceArray::~CXTPCalendarReminderForOccurrenceArray()
  918. {
  919. }
  920. int CXTPCalendarReminderForOccurrenceArray::Find(CXTPCalendarEvent* pOccEvent)
  921. {
  922. ASSERT(pOccEvent);
  923. if (!pOccEvent)
  924. {
  925. return -1;
  926. }
  927. ASSERT(pOccEvent->GetRecurrenceState() == xtpCalendarRecurrenceOccurrence);
  928. DATE dtOcctartTime = pOccEvent->GetStartTime();
  929. DATE dtOccEndTime = pOccEvent->GetEndTime();
  930. int nFIndex = Find(dtOcctartTime, dtOccEndTime);
  931. return nFIndex;
  932. }
  933. int CXTPCalendarReminderForOccurrenceArray::Find(DATE dtOccStartTime, DATE dtOccEndTime)
  934. {
  935. int nCount = (int)GetSize();
  936. for (int i = 0; i < nCount; i++)
  937. {
  938. const CXTPCalendarReminderForOccurrence& rData = ElementAt(i);
  939. if (CXTPCalendarUtils::IsEqual(dtOccStartTime, rData.m_dtOccurrenceStartTime) &&
  940. CXTPCalendarUtils::IsEqual(dtOccEndTime, rData.m_dtOccurrenceEndTime))
  941. {
  942. return i;
  943. }
  944. }
  945. return -1;
  946. }
  947. int CXTPCalendarReminderForOccurrenceArray::UpdateOccIfNeed(
  948. CXTPCalendarEvent* pOccEvent,
  949. CXTPCalendarRecurrencePattern* pPattern)
  950. {
  951. if (!pOccEvent || !pPattern)
  952. {
  953. ASSERT(FALSE);
  954. return 0;
  955. }
  956. int nFIndex = Find(pOccEvent);
  957. if (nFIndex < 0)
  958. {
  959. return 0;
  960. }
  961. CXTPCalendarReminderForOccurrence* pOccRmdData;
  962. pOccRmdData = &ElementAt(nFIndex);
  963. int nRes = UpdateOccIfNeedEx(pOccEvent, pOccRmdData, pPattern);
  964. return nRes;
  965. }
  966. int CXTPCalendarReminderForOccurrenceArray::UpdateOccIfNeedEx(
  967. CXTPCalendarEvent* pOccEvent,
  968. const CXTPCalendarReminderForOccurrence* pOccRmdData,
  969. CXTPCalendarRecurrencePattern* pPattern)
  970. {
  971. if (!pOccEvent || !pOccRmdData || !pPattern)
  972. {
  973. ASSERT(FALSE);
  974. return 0;
  975. }
  976. // IsReminder
  977. if (pOccRmdData->m_nbIsReminder == xtpCalendarRmdPrm_Default)
  978. {
  979. CXTPCalendarEventPtr ptrMasterEvent = pPattern->GetMasterEvent();
  980. if (!ptrMasterEvent)
  981. {
  982. ASSERT(FALSE);
  983. return 0;
  984. }
  985. pOccEvent->SetReminder(ptrMasterEvent->IsReminder());
  986. }
  987. else if (pOccRmdData->m_nbIsReminder != xtpCalendarRmdPrm_DontChange)
  988. {
  989. pOccEvent->SetReminder(pOccRmdData->m_nbIsReminder != 0);
  990. }
  991. // MinutesBeforeStart_Snoozed
  992. if (pOccRmdData->m_dtNextReminderTime_Snoozed == xtpCalendarRmdPrm_Default)
  993. {
  994. pOccEvent->GetCustomProperties()->RemoveProperty(cszEventCustProp_NextReminderTime_Snoozed);
  995. }
  996. else if (pOccRmdData->m_dtNextReminderTime_Snoozed != xtpCalendarRmdPrm_DontChange)
  997. {
  998. VERIFY( pOccEvent->GetCustomProperties()->SetProperty(
  999. cszEventCustProp_NextReminderTime_Snoozed,
  1000. pOccRmdData->m_dtNextReminderTime_Snoozed) );
  1001. }
  1002. return 1;
  1003. }
  1004. BOOL CXTPCalendarReminderForOccurrenceArray::Load(CXTPCalendarCustomProperties* pProps)
  1005. {
  1006. ASSERT(pProps);
  1007. if (!pProps)
  1008. {
  1009. return FALSE;
  1010. }
  1011. RemoveAll();
  1012. COleVariant varCount;
  1013. BOOL bExists = pProps->GetProperty(cszOccRMD_Count, varCount);
  1014. if (!bExists)
  1015. {
  1016. return TRUE;
  1017. }
  1018. COleVariant varValue;
  1019. CString strPropNameI;
  1020. int nCount = (int)(long)_variant_t(varCount);
  1021. for (int i = 0; i < nCount; i++)
  1022. {
  1023. CXTPCalendarReminderForOccurrence rmdData;
  1024. _PropName(cszOccRMD_StartTime, i, strPropNameI);
  1025. if (pProps->GetProperty(strPropNameI, varValue))
  1026. {
  1027. rmdData.m_dtOccurrenceStartTime = (DATE)_variant_t(varValue);
  1028. }
  1029. _PropName(cszOccRMD_EndTime, i, strPropNameI);
  1030. if (pProps->GetProperty(strPropNameI, varValue))
  1031. {
  1032. rmdData.m_dtOccurrenceEndTime = (DATE)_variant_t(varValue);
  1033. }
  1034. _PropName(cszOccRMD_IsReminder, i, strPropNameI);
  1035. if (pProps->GetProperty(strPropNameI, varValue))
  1036. {
  1037. rmdData.m_nbIsReminder = (long)_variant_t(varValue);
  1038. }
  1039. _PropName(cszOccRMD_NextReminderTime_Snoozed, i, strPropNameI);
  1040. if (pProps->GetProperty(strPropNameI, varValue))
  1041. {
  1042. rmdData.m_dtNextReminderTime_Snoozed = (DATE)_variant_t(varValue);
  1043. }
  1044. Add(rmdData);
  1045. }
  1046. return TRUE;
  1047. }
  1048. BOOL CXTPCalendarReminderForOccurrenceArray::Save(CXTPCalendarCustomProperties* pProps,
  1049.  CXTPCalendarRecurrencePattern* pPattern)
  1050. {
  1051. ASSERT(pProps);
  1052. if (!pProps)
  1053. {
  1054. return FALSE;
  1055. }
  1056. ClearProperties(pProps);
  1057. CString strPropNameI;
  1058. int nCount = (int)GetSize();
  1059. int i;
  1060. //===========================================================================
  1061. if (pPattern)
  1062. {
  1063. for (i = nCount-1; i >= 0; i--)
  1064. {
  1065. const CXTPCalendarReminderForOccurrence& rData = ElementAt(i);
  1066. int nFExcIdx = pPattern->FindExceptionIndex(rData.m_dtOccurrenceStartTime,
  1067. rData.m_dtOccurrenceEndTime);
  1068. if (nFExcIdx >= 0)
  1069. {
  1070. RemoveAt(i);
  1071. }
  1072. }
  1073. }
  1074. //===========================================================================
  1075. nCount = (int)GetSize();
  1076. for (i = 0; i < nCount; i++)
  1077. {
  1078. const CXTPCalendarReminderForOccurrence& rData = ElementAt(i);
  1079. _PropName(cszOccRMD_StartTime, i, strPropNameI);
  1080. VERIFY( pProps->SetProperty(strPropNameI, COleDateTime(rData.m_dtOccurrenceStartTime)) );
  1081. _PropName(cszOccRMD_EndTime, i, strPropNameI);
  1082. VERIFY( pProps->SetProperty(strPropNameI, COleDateTime(rData.m_dtOccurrenceEndTime)) );
  1083. _PropName(cszOccRMD_IsReminder, i, strPropNameI);
  1084. VERIFY( pProps->SetProperty(strPropNameI, (long)rData.m_nbIsReminder) );
  1085. if (rData.m_dtNextReminderTime_Snoozed != xtpCalendarRmdPrm_Default)
  1086. {
  1087. ASSERT(rData.m_dtNextReminderTime_Snoozed >= xtpCalendarDateTime_min && rData.m_dtNextReminderTime_Snoozed <= xtpCalendarDateTime_max);
  1088. _PropName(cszOccRMD_NextReminderTime_Snoozed, i, strPropNameI);
  1089. VERIFY( pProps->SetProperty(strPropNameI, COleDateTime(rData.m_dtNextReminderTime_Snoozed)) );
  1090. }
  1091. }
  1092. BOOL bRes = pProps->SetProperty(cszOccRMD_Count, (long)nCount);
  1093. ASSERT(bRes);
  1094. return bRes;
  1095. }
  1096. void CXTPCalendarReminderForOccurrenceArray::ClearProperties(CXTPCalendarCustomProperties* pProps)
  1097. {
  1098. ASSERT(pProps);
  1099. if (!pProps)
  1100. {
  1101. return;
  1102. }
  1103. COleVariant varCount;
  1104. BOOL bExists = pProps->GetProperty(cszOccRMD_Count, varCount);
  1105. if (!bExists)
  1106. {
  1107. return;
  1108. }
  1109. CString strPropNameI;
  1110. int nCount = (int)(long)_variant_t(varCount);
  1111. for (int i = 0; i < nCount; i++)
  1112. {
  1113. _PropName(cszOccRMD_StartTime, i, strPropNameI);
  1114. pProps->RemoveProperty(strPropNameI);
  1115. _PropName(cszOccRMD_EndTime, i, strPropNameI);
  1116. pProps->RemoveProperty(strPropNameI);
  1117. _PropName(cszOccRMD_IsReminder, i, strPropNameI);
  1118. pProps->RemoveProperty(strPropNameI);
  1119. _PropName(cszOccRMD_NextReminderTime_Snoozed, i, strPropNameI);
  1120. pProps->RemoveProperty(strPropNameI);
  1121. }
  1122. pProps->RemoveProperty(cszOccRMD_Count);
  1123. }
  1124. void CXTPCalendarReminderForOccurrenceArray::_PropName(LPCTSTR pcszProp, int nIndex, CString& rstrPropNameI)
  1125. {
  1126. TCHAR szIndex[64];
  1127. ITOT_S(nIndex, szIndex, 64, 10);
  1128. rstrPropNameI = pcszProp;
  1129. rstrPropNameI += _T("[");
  1130. rstrPropNameI += szIndex;
  1131. rstrPropNameI += _T("]");
  1132. }