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

对话框与窗口

开发平台:

Visual C++

  1. // XTPCalendarRemindersManager.cpp: implementation of the
  2. // CXTPCalendarRemindersManager class.
  3. //
  4. // This file is a part of the XTREME CALENDAR MFC class library.
  5. // (c)1998-2008 Codejock Software, All Rights Reserved.
  6. //
  7. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  8. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  9. // CONSENT OF CODEJOCK SOFTWARE.
  10. //
  11. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  12. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  13. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  14. // SINGLE COMPUTER.
  15. //
  16. // CONTACT INFORMATION:
  17. // support@codejock.com
  18. // http://www.codejock.com
  19. //
  20. /////////////////////////////////////////////////////////////////////////////
  21. #include "stdafx.h"
  22. #include "Common/XTPVC50Helpers.h"
  23. #include "Common/XTPPropExchange.h"
  24. #include "XTPCalendarRemindersManager.h"
  25. #include "XTPCalendarData.h"
  26. #include "XTPCalendarNotifications.h"
  27. #include "XTPCalendarCustomProperties.h"
  28. #include "XTPCalendarResource.h"
  29. #ifdef _DEBUG
  30. #define new DEBUG_NEW
  31. #undef THIS_FILE
  32. static char THIS_FILE[] = __FILE__;
  33. #endif
  34. #ifdef _DEBUG
  35. //  #define DBG_REMINDERS_TRACE TRACE
  36. #endif
  37. #ifndef DBG_REMINDERS_TRACE
  38. #define DBG_REMINDERS_TRACE
  39. #endif
  40. #define TIMERID_RMD_REFRESH 1
  41. #define XTP_CALENDAR_RMD_REFRESH_TIMEOUT 3*1000
  42. #define TIMERID_RMD_NOTIFY_CHANGED 2
  43. #define XTP_CALENDAR_RMD_NOTIFY_CHANGED_TIMEOUT 500
  44. static LPCTSTR XTP_CALENDAR_REMINDERS_MANAGER_WND_NAME = _T("XTPCalendarRemindersManagerWnd");
  45. ////////////////////////////////////////////////////////////////////////////
  46. IMPLEMENT_DYNAMIC(CXTPCalendarReminder, CCmdTarget)
  47. IMPLEMENT_DYNAMIC(CXTPCalendarRemindersManager, CCmdTarget)
  48. CXTPCalendarReminder::CXTPCalendarReminder(CXTPCalendarRemindersManager* pOwnerMan)
  49. {
  50. m_pOwnerMan = pOwnerMan;
  51. m_pEventDataProvider = NULL;
  52. m_dtEventStartTime = (DATE)0;
  53. m_dtNextReminderTime = (DATE)0;
  54. m_nMinutesBeforeStart = 0;
  55. m_eEventType = evtNormal;
  56. ::ZeroMemory(&m_RecurrenceEventInfo, sizeof(m_RecurrenceEventInfo));
  57. m_dwNormalEventID = XTP_CALENDAR_UNKNOWN_EVENT_ID;
  58. }
  59. CXTPCalendarReminder::~CXTPCalendarReminder()
  60. {
  61. CMDTARGET_RELEASE(m_pEventDataProvider);
  62. }
  63. CXTPCalendarEventPtr CXTPCalendarReminder::GetEvent()
  64. {
  65. if (!m_pOwnerMan || !m_pEventDataProvider)
  66. {
  67. ASSERT(FALSE);
  68. return NULL;
  69. }
  70. if (m_eEventType == evtNormal)
  71. {
  72. return m_pEventDataProvider->GetEvent(m_dwNormalEventID);
  73. }
  74. if (m_eEventType != evtRecurrence)
  75. {
  76. ASSERT(FALSE);
  77. return NULL;
  78. }
  79. CXTPCalendarEventPtr ptrMaster = m_pEventDataProvider->GetEvent(m_RecurrenceEventInfo.m_dwMasterEventID);
  80. CXTPCalendarRecurrencePatternPtr ptrPattern = ptrMaster ? ptrMaster->GetRecurrencePattern() : NULL;
  81. if (!ptrMaster || !ptrPattern)
  82. {
  83. ASSERT(FALSE);
  84. return NULL;
  85. }
  86. CXTPCalendarEvent* pExc = ptrPattern->FindException(m_RecurrenceEventInfo.m_dtOccurrenceStartTime,
  87. m_RecurrenceEventInfo.m_dtOccurrenceEndTime);
  88. if (pExc)
  89. {
  90. return pExc->CloneEvent();
  91. }
  92. return ptrMaster->CloneForOccurrence(m_RecurrenceEventInfo.m_dtOccurrenceStartTime,
  93.  m_RecurrenceEventInfo.m_dtOccurrenceEndTime);
  94. }
  95. void CXTPCalendarReminder::SetEvent(CXTPCalendarEvent* pEvent)
  96. {
  97. if (!pEvent || !pEvent->GetDataProvider())
  98. {
  99. ASSERT(FALSE);
  100. return;
  101. }
  102. // data provider
  103. CMDTARGET_RELEASE(m_pEventDataProvider);
  104. m_pEventDataProvider = pEvent->GetDataProvider();
  105. CMDTARGET_ADDREF(m_pEventDataProvider);
  106. //-----
  107. m_dtEventStartTime = pEvent->GetStartTime();
  108. int nRState = pEvent->GetRecurrenceState();
  109. if (nRState == xtpCalendarRecurrenceNotRecurring)
  110. {
  111. m_eEventType = evtNormal;
  112. m_dwNormalEventID = pEvent->GetEventID();
  113. return;
  114. }
  115. CXTPCalendarRecurrencePatternPtr ptrPattern = pEvent->GetRecurrencePattern();
  116. if (nRState != xtpCalendarRecurrenceOccurrence &&
  117. nRState != xtpCalendarRecurrenceException || !ptrPattern)
  118. {
  119. ASSERT(FALSE);
  120. return;
  121. }
  122. m_eEventType = evtRecurrence;
  123. m_RecurrenceEventInfo.m_dwMasterEventID = ptrPattern->GetMasterEventID();
  124. if (nRState == xtpCalendarRecurrenceOccurrence)
  125. {
  126. m_RecurrenceEventInfo.m_dtOccurrenceStartTime = pEvent->GetStartTime();
  127. m_RecurrenceEventInfo.m_dtOccurrenceEndTime = pEvent->GetEndTime();
  128. }
  129. else if (nRState == xtpCalendarRecurrenceException)
  130. {
  131. m_RecurrenceEventInfo.m_dtOccurrenceStartTime = pEvent->GetRException_StartTimeOrig();
  132. m_RecurrenceEventInfo.m_dtOccurrenceEndTime = pEvent->GetRException_EndTimeOrig();
  133. }
  134. else
  135. {
  136. ASSERT(FALSE);
  137. }
  138. }
  139. BOOL CXTPCalendarReminder::IsEqualID(const CXTPCalendarReminder* pR2) const
  140. {
  141. ASSERT(pR2);
  142. if (!pR2)
  143. {
  144. return FALSE;
  145. }
  146. if (m_pEventDataProvider != pR2->m_pEventDataProvider)
  147. {
  148. return FALSE;
  149. }
  150. if (m_eEventType != pR2->m_eEventType)
  151. {
  152. return FALSE;
  153. }
  154. if (m_eEventType == evtNormal)
  155. {
  156. return m_dwNormalEventID == pR2->m_dwNormalEventID;
  157. }
  158. if (m_eEventType != evtRecurrence)
  159. {
  160. ASSERT(FALSE);
  161. return FALSE;
  162. }
  163. if (m_RecurrenceEventInfo.m_dwMasterEventID != pR2->m_RecurrenceEventInfo.m_dwMasterEventID)
  164. {
  165. return FALSE;
  166. }
  167. if (!CXTPCalendarUtils::IsEqual(m_RecurrenceEventInfo.m_dtOccurrenceStartTime,
  168. pR2->m_RecurrenceEventInfo.m_dtOccurrenceStartTime) )
  169. {
  170. return FALSE;
  171. }
  172. if (!CXTPCalendarUtils::IsEqual(m_RecurrenceEventInfo.m_dtOccurrenceEndTime,
  173. pR2->m_RecurrenceEventInfo.m_dtOccurrenceEndTime) )
  174. {
  175. return FALSE;
  176. }
  177. return TRUE;
  178. }
  179. ////////////////////////////////////////////////////////////////////////////
  180. int CXTPCalendarReminders::Find(const CXTPCalendarReminder* pReminder) const
  181. {
  182. if (!pReminder)
  183. {
  184. ASSERT(FALSE);
  185. return -1;
  186. }
  187. int nCount = GetCount();
  188. for (int i = 0; i < nCount; i++)
  189. {
  190. CXTPCalendarReminder* pRmdI = GetAt(i, FALSE);
  191. ASSERT(pRmdI);
  192. if (pRmdI && pRmdI->IsEqualID(pReminder))
  193. {
  194. return i;
  195. }
  196. }
  197. return -1;
  198. }
  199. int CXTPCalendarReminders::Find(CXTPCalendarEvent* pEvent) const
  200. {
  201. if (!pEvent)
  202. {
  203. ASSERT(FALSE);
  204. return -1;
  205. }
  206. CXTPCalendarReminder eventRmd;
  207. eventRmd.SetEvent(pEvent);
  208. int nCount = GetCount();
  209. for (int i = 0; i < nCount; i++)
  210. {
  211. CXTPCalendarReminder* pRmdI = GetAt(i, FALSE);
  212. ASSERT(pRmdI);
  213. if (pRmdI && eventRmd.IsEqualID(pRmdI))
  214. {
  215. return i;
  216. }
  217. }
  218. return -1;
  219. }
  220. int CXTPCalendarReminders::Find(DWORD dwEventID, CXTPCalendarData* pDP) const
  221. {
  222. // DEBUG
  223. // ASSERT(pDP);
  224. int nCount = GetCount();
  225. for (int i = 0; i < nCount; i++)
  226. {
  227. CXTPCalendarReminder* pRmdI = GetAt(i, FALSE);
  228. ASSERT(pRmdI);
  229. if (!pRmdI)
  230. {
  231. continue;
  232. }
  233. if (pDP && pDP != pRmdI->m_pEventDataProvider)
  234. continue;
  235. if (pRmdI->m_eEventType == CXTPCalendarReminder::evtNormal &&
  236. pRmdI->m_dwNormalEventID == dwEventID
  237. ||
  238. pRmdI->m_eEventType == CXTPCalendarReminder::evtRecurrence &&
  239. pRmdI->m_RecurrenceEventInfo.m_dwMasterEventID == dwEventID)
  240. {
  241. return i;
  242. }
  243. }
  244. return -1;
  245. }
  246. BOOL CXTPCalendarReminders::RemoveDataForEvent(CXTPCalendarEvent* pEvent)
  247. {
  248. ASSERT(pEvent);
  249. if (!pEvent)
  250. {
  251. ASSERT(FALSE);
  252. return FALSE;
  253. }
  254. BOOL bChanged = FALSE;
  255. if (pEvent->GetRecurrenceState() == xtpCalendarRecurrenceMaster)
  256. {
  257. bChanged = _RemoveDataForMasterEvent(pEvent);
  258. }
  259. else
  260. {
  261. int nFIdx = Find(pEvent);
  262. if (nFIdx >= 0)
  263. {
  264. RemoveAt(nFIdx);
  265. bChanged = TRUE;
  266. ASSERT(Find(pEvent) < 0);
  267. }
  268. }
  269. //---------------------------------
  270. int nFIdx = Find(pEvent->GetEventID(), pEvent->GetDataProvider());
  271. if (nFIdx >= 0)
  272. {
  273. RemoveAt(nFIdx);
  274. bChanged = TRUE;
  275. }
  276. return bChanged;
  277. }
  278. void CXTPCalendarReminders::Sort()
  279. {
  280. int nCount = GetCount();
  281. for (int i = 0; i < nCount; i++)
  282. {
  283. for (int j = i+1; j < nCount; j++)
  284. {
  285. TObjectPtr ptrE1 = GetAt(i, TRUE);
  286. TObjectPtr ptrE2 = GetAt(j, TRUE);
  287. if (ptrE1->m_dtEventStartTime > ptrE2->m_dtEventStartTime)
  288. {
  289. SetAt(j, ptrE1.Detach());
  290. SetAt(i, ptrE2.Detach());
  291. }
  292. }
  293. }
  294. }
  295. BOOL CXTPCalendarReminders::_RemoveDataForMasterEvent(CXTPCalendarEvent* pEvent)
  296. {
  297. if (!pEvent || pEvent->GetRecurrenceState() != xtpCalendarRecurrenceMaster)
  298. {
  299. ASSERT(FALSE);
  300. return FALSE;
  301. }
  302. BOOL bChanged = FALSE;
  303. DWORD dwMasterEventID = pEvent->GetEventID();
  304. CXTPCalendarData* pEvDP = pEvent->GetDataProvider();
  305. int nCount = GetCount();
  306. for (int i = nCount-1; i >= 0 ; i--)
  307. {
  308. CXTPCalendarReminder* pRmdI = GetAt(i, FALSE);
  309. ASSERT(pRmdI);
  310. if (!pRmdI)
  311. {
  312. continue;
  313. }
  314. if (pRmdI->m_eEventType == CXTPCalendarReminder::evtRecurrence &&
  315. pRmdI->m_RecurrenceEventInfo.m_dwMasterEventID == dwMasterEventID &&
  316. pRmdI->m_pEventDataProvider == pEvDP)
  317. {
  318. RemoveAt(i);
  319. bChanged = TRUE;
  320. }
  321. }
  322. return bChanged;
  323. }
  324. ////////////////////////////////////////////////////////////////////////////
  325. CXTPCalendarRemindersManager::CXTPCalendarRemindersManager()
  326. {
  327. m_dtLastUpdateTime = (DATE)0;
  328. m_pConnection = new CXTPNotifyConnection();
  329. m_pResourcesNf = new CXTPCalendarResourcesNf();
  330. m_bSkipOnEventChanged = FALSE;
  331. m_bMonitoringRunning = FALSE;
  332. }
  333. CXTPCalendarRemindersManager::~CXTPCalendarRemindersManager()
  334. {
  335. //RemoveAll();
  336. CMDTARGET_RELEASE(m_pConnection);
  337. CMDTARGET_RELEASE(m_pResourcesNf);
  338. }
  339. BEGIN_MESSAGE_MAP(CXTPCalendarRemindersManager, CWnd)
  340. ON_WM_TIMER()
  341. ON_WM_TIMECHANGE()
  342. END_MESSAGE_MAP()
  343. void CXTPCalendarRemindersManager::OnFinalRelease()
  344. {
  345. StopMonitoring();
  346. CWnd::OnFinalRelease();
  347. CCmdTarget::OnFinalRelease();
  348. }
  349. BOOL CXTPCalendarRemindersManager::_CreateWnd()
  350. {
  351. LPCTSTR pcszSimpleWndClass = AfxRegisterWndClass(0);
  352. CRect rcEmpty(0,0,0,0);
  353. BOOL bCreated = CreateEx(0, pcszSimpleWndClass,
  354. XTP_CALENDAR_REMINDERS_MANAGER_WND_NAME,
  355. WS_POPUP, rcEmpty, NULL, 0);
  356. return bCreated;
  357. }
  358. BOOL CXTPCalendarRemindersManager::StartMonitoring(CXTPCalendarResources* pResources,
  359.    COleDateTimeSpan spPeriod2Cache)
  360. {
  361. if (!GetSafeHwnd())
  362. {
  363. if (!_CreateWnd())
  364. {
  365. ASSERT(FALSE);
  366. return FALSE;
  367. }
  368. }
  369. //***********************************
  370. if (IsMonitoringRunning())
  371. {
  372. StopMonitoring();
  373. }
  374. //***********************************
  375. RemoveAll();
  376. XTP_SAFE_CALL1(m_pResourcesNf, RemoveAll());
  377. m_Sink.UnadviseAll();
  378. //-----------------------------------
  379. ASSERT(pResources);
  380. ASSERT(GETTOTAL_SECONDS_DTS(spPeriod2Cache) > 0);
  381. if (!pResources || !m_pResourcesNf)
  382. {
  383. return FALSE;
  384. }
  385. DBG_REMINDERS_TRACE(_T("%s - CXTPCalendarRemindersManager::StartMonitoring(). period = %d min n"),
  386. (LPCTSTR)CXTPCalendarUtils::GetCurrentTime().Format(),
  387. (int)spPeriod2Cache.GetTotalMinutes());
  388. m_pResourcesNf->Append(pResources);
  389. m_spPeriod2Cache = spPeriod2Cache;
  390. //------------------------------------
  391. // Advise to Data Provider notifications
  392. CXTPNotifyConnection* pConnRC = m_pResourcesNf->GetConnection();
  393. ASSERT(pConnRC);
  394. if (pConnRC)
  395. {
  396. m_Sink.Advise(pConnRC, XTP_NC_CALENDAREVENTWASADDED, &CXTPCalendarRemindersManager::OnEventChanged);
  397. m_Sink.Advise(pConnRC, XTP_NC_CALENDAREVENTWASDELETED, &CXTPCalendarRemindersManager::OnEventChanged);
  398. m_Sink.Advise(pConnRC, XTP_NC_CALENDAREVENTWASCHANGED, &CXTPCalendarRemindersManager::OnEventChanged);
  399. }
  400. m_pResourcesNf->ReBuildInternalData();
  401. //------------------------------------
  402. COleDateTime dtNow = CXTPCalendarUtils::GetCurrentTime();
  403. UpdateDataFromDP(dtNow, m_spPeriod2Cache);
  404. SetTimer(TIMERID_RMD_REFRESH, XTP_CALENDAR_RMD_REFRESH_TIMEOUT, NULL);
  405. //--------------------------------------------------------
  406. m_bMonitoringRunning = TRUE;
  407. NotifyReminders(xtpCalendarRemindersMonitoringStarted);
  408. return TRUE;
  409. }
  410. BOOL CXTPCalendarRemindersManager::StopMonitoring()
  411. {
  412. if (IsWindow(m_hWnd))
  413. {
  414. KillTimer(TIMERID_RMD_REFRESH);
  415. }
  416. m_Sink.UnadviseAll();
  417. RemoveAll();
  418. m_bMonitoringRunning = FALSE;
  419. NotifyReminders(xtpCalendarRemindersMonitoringStopped);
  420. DBG_REMINDERS_TRACE(_T("%s - CXTPCalendarRemindersManager::STOP Monitoring().  n"),
  421. CXTPCalendarUtils::GetCurrentTime().Format());
  422. return TRUE;
  423. }
  424. void CXTPCalendarRemindersManager::RemoveAll()
  425. {
  426. m_arWaitingReminders.RemoveAll();
  427. m_arActiveReminders.RemoveAll();
  428. }
  429. BOOL CXTPCalendarRemindersManager::UpdateDataFromDP(COleDateTime dtFrom,
  430. COleDateTimeSpan spPeriod)
  431. {
  432. ASSERT(m_pResourcesNf);
  433. if (!m_pResourcesNf || 0 == m_pResourcesNf->GetCount())
  434. {
  435. m_dtLastUpdateTime = (DATE)0;
  436. return FALSE;
  437. }
  438. DWORD dwTime0 = ::GetTickCount();
  439. DBG_REMINDERS_TRACE(_T("%s - CXTPCalendarRemindersManager::start retrieve UpcomingEvents().  n"),
  440. CXTPCalendarUtils::GetCurrentTime().Format());
  441. CWaitCursor _WC;
  442. int nWaitingCount = m_arWaitingReminders.GetCount();
  443. int nActiveCount = m_arActiveReminders.GetCount();
  444. // ???
  445. m_arWaitingReminders.RemoveAll();
  446. m_arActiveReminders.RemoveAll();
  447. CXTPCalendarEventsPtr ptrEvents;
  448. BOOL bDataAvailable = GetUpcomingEventsAll(dtFrom, spPeriod, ptrEvents);
  449. if (bDataAvailable)
  450. {
  451. int nCount = ptrEvents ? ptrEvents->GetCount() : 0;
  452. for (int i = 0; i < nCount; i++)
  453. {
  454. CXTPCalendarEvent* pEvent = ptrEvents->GetAt(i, FALSE);
  455. ASSERT(pEvent);
  456. ProcessNewEvent(pEvent, dtFrom, spPeriod);
  457. }
  458. m_arActiveReminders.Sort();
  459. m_dtLastUpdateTime = dtFrom;
  460. int nWaitingCount2 = m_arWaitingReminders.GetCount();
  461. //------------------------------------
  462. DWORD dwTime1 = ::GetTickCount();
  463. DBG_REMINDERS_TRACE(_T("%s - CXTPCalendarRemindersManager::STOP retrieve UpcomingEvents(). time=%d ms, count = %d n"),
  464. CXTPCalendarUtils::GetCurrentTime().Format(), (dwTime1 - dwTime0), nWaitingCount2);
  465. //------------------------------------------------------------
  466. return (nWaitingCount != 0 || nWaitingCount2 != 0 || nActiveCount != 0);
  467. }
  468. //===================================================
  469. DBG_REMINDERS_TRACE(_T("%s - CXTPCalendarRemindersManager::SKIP  retrieve UpcomingEvents(). *** Some Data Closed. *** n"),
  470. CXTPCalendarUtils::GetCurrentTime().Format());
  471. m_dtLastUpdateTime = (DATE)0;
  472. return FALSE;
  473. }
  474. void CXTPCalendarRemindersManager::OnEventChanged(XTP_NOTIFY_CODE Event,
  475.   WPARAM /*wParam*/, LPARAM lParam)
  476. {
  477. if (m_bSkipOnEventChanged)
  478. {
  479. return;
  480. }
  481. CXTPCalendarEvent* pEvent = (CXTPCalendarEvent*)lParam;
  482. if (!m_pResourcesNf || 0 == m_pResourcesNf->GetCount() || !pEvent)
  483. {
  484. ASSERT(FALSE);
  485. return;
  486. }
  487. if (lParam && (Event == XTP_NC_CALENDAREVENTWASADDED || 
  488. Event == XTP_NC_CALENDAREVENTWASDELETED || Event == XTP_NC_CALENDAREVENTWASCHANGED))
  489. {
  490. CXTPCalendarResource* pRC = m_pResourcesNf->FindByDataProvider(pEvent->GetDataProvider());
  491. ASSERT(pRC);
  492. if (!pRC)
  493. return;
  494. UINT uScheduleIDEvent = pEvent->GetScheduleID();
  495. if (!pRC->ExistsScheduleID(uScheduleIDEvent, TRUE))
  496. return;
  497. }
  498. COleDateTime dtNow = CXTPCalendarUtils::GetCurrentTime();
  499. BOOL bChanged = FALSE;
  500. BOOL bChanged2 = FALSE;
  501. if (Event == XTP_NC_CALENDAREVENTWASADDED)
  502. {
  503. //CXTPCalendarEvent* pEvent = (CXTPCalendarEvent*)lParam;
  504. ProcessNewEvent(pEvent, m_dtLastUpdateTime, m_spPeriod2Cache);
  505. bChanged = ProcessActiveReminders(dtNow);
  506. }
  507. else if (Event == XTP_NC_CALENDAREVENTWASDELETED)
  508. {
  509. //CXTPCalendarEvent* pEvent = (CXTPCalendarEvent*)lParam;
  510. m_arWaitingReminders.RemoveDataForEvent(pEvent);
  511. bChanged = m_arActiveReminders.RemoveDataForEvent(pEvent);
  512. }
  513. else if (Event == XTP_NC_CALENDAREVENTWASCHANGED)
  514. {
  515. //CXTPCalendarEvent* pEvent = (CXTPCalendarEvent*)lParam;
  516. bChanged = ProcessChangedEvent(pEvent);
  517. bChanged2 = ProcessActiveReminders(dtNow);
  518. }
  519. else
  520. {
  521. ASSERT(FALSE);
  522. }
  523. if (bChanged || bChanged2)
  524. {
  525. PostNotify_RemindersFire();
  526. DBG_REMINDERS_TRACE(_T("%s - CXTPCalendarRemindersManager::OnEventChanged(). data updated. n"),
  527. CXTPCalendarUtils::GetCurrentTime().Format());
  528. }
  529. }
  530. BOOL CXTPCalendarRemindersManager::ProcessNewEvent(CXTPCalendarEvent* pEvent,
  531.    COleDateTime dtFrom, COleDateTimeSpan spPeriod)
  532. {
  533. if (!pEvent)
  534. {
  535. ASSERT(FALSE);
  536. return FALSE;
  537. }
  538. if (pEvent->GetRecurrenceState() == xtpCalendarRecurrenceMaster)
  539. {
  540. return _ProcessNewMasterEvent(pEvent, dtFrom, spPeriod);
  541. }
  542. return _ProcessNewSingleEvent(pEvent, dtFrom, spPeriod);
  543. }
  544. BOOL CXTPCalendarRemindersManager::_ProcessNewSingleEvent(CXTPCalendarEvent* pEvent,
  545.   COleDateTime dtFrom, COleDateTimeSpan spPeriod)
  546. {
  547. if (pEvent->GetRecurrenceState() == xtpCalendarRecurrenceMaster)
  548. {
  549. ASSERT(FALSE);
  550. return FALSE;
  551. }
  552. if (!pEvent->IsReminder())
  553. {
  554. return FALSE;
  555. }
  556. int nMinBeforeStart = pEvent->GetReminderMinutesBeforeStart();
  557. COleDateTimeSpan spRem = CXTPCalendarUtils::Minutes2Span(nMinBeforeStart);
  558. COleDateTime dtNextReminderTime = pEvent->GetStartTime() - spRem;
  559. //---------------------------------
  560. COleVariant varNextReminderTime_Snoozed;
  561. BOOL bSnoozed = pEvent->GetCustomProperties()->GetProperty(
  562. cszEventCustProp_NextReminderTime_Snoozed, varNextReminderTime_Snoozed);
  563. if (bSnoozed)
  564. {
  565. dtNextReminderTime = (DATE)_variant_t(varNextReminderTime_Snoozed);
  566. }
  567. //---------------------------------
  568. COleDateTime dtEndMonitoringPeriod = dtFrom + spPeriod;
  569. if (dtNextReminderTime > dtEndMonitoringPeriod)
  570. {
  571. return FALSE;
  572. }
  573. //=======================================================================
  574. CXTPCalendarReminder* pRmdData = new CXTPCalendarReminder(this);
  575. if (!pRmdData)
  576. {
  577. return FALSE;
  578. }
  579. pRmdData->SetEvent(pEvent);
  580. pRmdData->m_nMinutesBeforeStart = nMinBeforeStart;
  581. pRmdData->m_dtNextReminderTime = dtNextReminderTime;
  582. m_arWaitingReminders.Add(pRmdData, FALSE);
  583. return TRUE;
  584. }
  585. BOOL CXTPCalendarRemindersManager::ProcessChangedEvent(CXTPCalendarEvent* pEvent)
  586. {
  587. ASSERT(pEvent);
  588. if (!pEvent)
  589. {
  590. return FALSE;
  591. }
  592. m_arWaitingReminders.RemoveDataForEvent(pEvent);
  593. BOOL bActiveChanged = m_arActiveReminders.RemoveDataForEvent(pEvent);
  594. ////BOOL bChanged2 =
  595. ProcessNewEvent(pEvent, m_dtLastUpdateTime, m_spPeriod2Cache);
  596. return bActiveChanged;// || bChanged2;
  597. }
  598. BOOL CXTPCalendarRemindersManager::_ProcessNewMasterEvent(CXTPCalendarEvent* pEvent,
  599.  COleDateTime dtFrom,
  600.  COleDateTimeSpan spPeriod)
  601. {
  602. if (!pEvent || !pEvent->GetCustomProperties())
  603. {
  604. ASSERT(FALSE);
  605. return FALSE;
  606. }
  607. if (pEvent->GetRecurrenceState() != xtpCalendarRecurrenceMaster)
  608. {
  609. ASSERT(FALSE);
  610. return FALSE;
  611. }
  612. CXTPCalendarEvents arOccurrences;
  613. CXTPCalendarRecurrencePatternPtr ptrPattern = pEvent->GetRecurrencePattern();
  614. if (!ptrPattern)
  615. {
  616. ASSERT(FALSE);
  617. return FALSE;
  618. }
  619. int nMaxMinutesBefore = 0;
  620. BOOL bReminderExists = _GetMaxExceptionReminder(ptrPattern, nMaxMinutesBefore);
  621. if (pEvent->IsReminder())
  622. {
  623. nMaxMinutesBefore = max(nMaxMinutesBefore, pEvent->GetReminderMinutesBeforeStart());
  624. bReminderExists = TRUE;
  625. }
  626. if (!bReminderExists)
  627. {
  628. return FALSE;
  629. }
  630. COleDateTimeSpan spMaxBeforePeriod = CXTPCalendarUtils::Minutes2Span(nMaxMinutesBefore);
  631. COleDateTime dtOccFrom = ptrPattern->GetPatternStartDate();
  632. COleDateTime dtOccTo = dtFrom + spPeriod + spMaxBeforePeriod;
  633. ptrPattern->GetOccurrences(&arOccurrences, dtOccFrom, dtOccTo, pEvent);
  634. int nCount = arOccurrences.GetCount();
  635. for (int i = 0; i < nCount; i++)
  636. {
  637. CXTPCalendarEvent* pOccExc = arOccurrences.GetAt(i, FALSE);
  638. _ProcessNewSingleEvent(pOccExc, dtFrom, spPeriod);
  639. }
  640. return TRUE;
  641. }
  642. BOOL CXTPCalendarRemindersManager::_GetMaxExceptionReminder(
  643. CXTPCalendarRecurrencePattern* pPattern,
  644. int& rnMinutes)
  645. {
  646. ASSERT(pPattern);
  647. if (!pPattern)
  648. {
  649. return FALSE;
  650. }
  651. CXTPCalendarEventsPtr ptrExcAr = pPattern->GetExceptions();
  652. if (!ptrExcAr)
  653. {
  654. return FALSE;
  655. }
  656. BOOL bExists = FALSE;
  657. rnMinutes = 0;
  658. int nCount = ptrExcAr->GetCount();
  659. for (int i = 0; i < nCount; i++)
  660. {
  661. CXTPCalendarEvent* pExc = ptrExcAr->GetAt(i, FALSE);
  662. if (pExc && pExc->IsReminder())
  663. {
  664. rnMinutes = max(rnMinutes, pExc->GetReminderMinutesBeforeStart());
  665. bExists = TRUE;
  666. }
  667. }
  668. return bExists;
  669. }
  670. void CXTPCalendarRemindersManager::OnTimer(UINT_PTR uTimerID)
  671. {
  672. if (!m_pResourcesNf || 0 == m_pResourcesNf->GetCount())
  673. {
  674. ASSERT(FALSE);
  675. return;
  676. }
  677. if (uTimerID == TIMERID_RMD_NOTIFY_CHANGED)
  678. {
  679. KillTimer(TIMERID_RMD_NOTIFY_CHANGED);
  680. NotifyReminders(xtpCalendarRemindersFire);
  681. DBG_REMINDERS_TRACE(_T("%s - CXTPCalendarRemindersManager::POST NotifyReminders(fier). n"),
  682. CXTPCalendarUtils::GetCurrentTime().Format());
  683. return;
  684. }
  685. //===========================================================================
  686. if (uTimerID != TIMERID_RMD_REFRESH)
  687. {
  688. ASSERT(FALSE);
  689. return;
  690. }
  691. //===========================================================================
  692. COleDateTime dtNow = CXTPCalendarUtils::GetCurrentTime();
  693. //-(1) Update cached data if need
  694. COleDateTime dtNextUpdateTime = m_dtLastUpdateTime + m_spPeriod2Cache;
  695. BOOL bUpdated = FALSE;
  696. if (dtNextUpdateTime <= dtNow || 0 == (DATE)m_dtLastUpdateTime)
  697. {
  698. DBG_REMINDERS_TRACE(_T("%s - CXTPCalendarRemindersManager::Update from timer ==>>. n"),
  699. CXTPCalendarUtils::GetCurrentTime().Format());
  700. bUpdated = UpdateDataFromDP(dtNow, m_spPeriod2Cache);
  701. }
  702. //---------------------------------------------------------------------------
  703. //-(2) Notify reminders
  704. BOOL bUpdated2 = ProcessActiveReminders(dtNow);
  705. if (bUpdated || bUpdated2)
  706. {
  707. DBG_REMINDERS_TRACE(_T("%s - CXTPCalendarRemindersManager::NotifyReminders(fier). n"),
  708. CXTPCalendarUtils::GetCurrentTime().Format());
  709. NotifyReminders(xtpCalendarRemindersFire);
  710. }
  711. //---------------------------------------------------------------------------
  712. }
  713. void CXTPCalendarRemindersManager::OnTimeChange()
  714. {
  715. DBG_REMINDERS_TRACE(_T("%s - CXTPCalendarRemindersManager::OnTimeChange(update will soon). n"),
  716. CXTPCalendarUtils::GetCurrentTime().Format());
  717. m_dtLastUpdateTime = (DATE)0;
  718. SetTimer(TIMERID_RMD_REFRESH, XTP_CALENDAR_RMD_REFRESH_TIMEOUT, NULL);
  719. }
  720. BOOL CXTPCalendarRemindersManager::ProcessActiveReminders(COleDateTime dtTime)
  721. {
  722. CXTPAutoResetValue<BOOL> autoReset(m_bSkipOnEventChanged, FALSE);
  723. m_bSkipOnEventChanged = TRUE;
  724. BOOL bChanged = FALSE;
  725. int nCount = m_arWaitingReminders.GetCount();
  726. for (int i = nCount-1; i >= 0 ; i--)
  727. {
  728. CXTPCalendarReminder* pRmdI = m_arWaitingReminders.GetAt(i, FALSE);
  729. if (pRmdI->m_dtNextReminderTime <= dtTime)
  730. {
  731. m_arActiveReminders.Add(pRmdI, TRUE);
  732. m_arWaitingReminders.RemoveAt(i);
  733. bChanged = TRUE;
  734. _RemoveSnoozeData(pRmdI);
  735. }
  736. }
  737. if (bChanged)
  738. m_arActiveReminders.Sort();
  739. return bChanged;
  740. }
  741. BOOL CXTPCalendarRemindersManager::_RemoveSnoozeData(CXTPCalendarReminder* pRmd)
  742. {
  743. CXTPCalendarEventPtr ptrEvent = pRmd->GetEvent();
  744. if (ptrEvent && ptrEvent->GetCustomProperties())
  745. {
  746. COleVariant varTmp;
  747. BOOL bSnoozed = ptrEvent->GetCustomProperties()->GetProperty(
  748. cszEventCustProp_NextReminderTime_Snoozed, varTmp);
  749. if (bSnoozed)
  750. {
  751. if (ptrEvent->GetRecurrenceState() == xtpCalendarRecurrenceOccurrence)
  752. {
  753. CXTPCalendarRecurrencePatternPtr ptrPattern = ptrEvent->GetRecurrencePattern();
  754. CXTPCalendarEventPtr ptrMaster = ptrPattern ? ptrPattern->GetMasterEvent() : NULL;
  755. if (ptrMaster)
  756. {
  757. ptrPattern->SetOccReminder(ptrEvent, xtpCalendarRmdPrm_Default, (DATE)xtpCalendarRmdPrm_Default);
  758. VERIFY( ptrMaster->UpdateRecurrence(ptrPattern) );
  759. VERIFY( XTP_SAFE_GET1(ptrMaster->GetDataProvider(), ChangeEvent(ptrMaster), FALSE) );
  760. }
  761. }
  762. else
  763. {
  764. ptrEvent->GetCustomProperties()->RemoveProperty(cszEventCustProp_NextReminderTime_Snoozed);
  765. VERIFY( XTP_SAFE_GET1(ptrEvent->GetDataProvider(), ChangeEvent(ptrEvent), FALSE) );
  766. }
  767. return TRUE;
  768. }
  769. }
  770. return FALSE;
  771. }
  772. void CXTPCalendarRemindersManager::NotifyReminders(int eAction, LPARAM lParam)
  773. {
  774. if (m_pConnection)
  775. {
  776. m_pConnection->SendEvent(XTP_NC_CALENDAR_ON_REMINDERS, (WPARAM)eAction, lParam);
  777. }
  778. }
  779. void CXTPCalendarRemindersManager::PostNotify_RemindersFire()
  780. {
  781. SetTimer(TIMERID_RMD_NOTIFY_CHANGED, XTP_CALENDAR_RMD_NOTIFY_CHANGED_TIMEOUT, NULL);
  782. }
  783. int CXTPCalendarRemindersManager::GetActiveRemindersCount()
  784. {
  785. return m_arActiveReminders.GetCount();
  786. }
  787. void CXTPCalendarRemindersManager::GetActiveReminders(CXTPCalendarReminders& rarActiveReminders)
  788. {
  789. rarActiveReminders.RemoveAll();
  790. rarActiveReminders.Append(&m_arActiveReminders);
  791. }
  792. BOOL CXTPCalendarRemindersManager::Snooze(CXTPCalendarReminder* pReminder,
  793.   int nMinutesAfterNow)
  794. {
  795. const int cnMaxSnoozeMinutes = (60*24*365) * 1000; // 1000 years
  796. // WARNING. no sense to snooze before now.
  797. ASSERT(nMinutesAfterNow >= 1);
  798. // WARNING. do you really need to snooze so far.
  799. ASSERT(nMinutesAfterNow <= cnMaxSnoozeMinutes);
  800. nMinutesAfterNow = max(1, min(nMinutesAfterNow, cnMaxSnoozeMinutes));
  801. CXTPCalendarEventPtr ptrEvent = pReminder ? pReminder->GetEvent() : NULL;
  802. if (!pReminder || !ptrEvent)
  803. {
  804. ASSERT(FALSE);
  805. return FALSE;
  806. }
  807. pReminder->m_dtNextReminderTime = CXTPCalendarUtils::GetCurrentTime();
  808. pReminder->m_dtNextReminderTime += CXTPCalendarUtils::Minutes2Span(nMinutesAfterNow);
  809. m_arWaitingReminders.Add(pReminder, TRUE);
  810. int nIdx = m_arActiveReminders.Find(pReminder);
  811. if (nIdx >= 0)
  812. {
  813. m_arActiveReminders.RemoveAt(nIdx);
  814. }
  815. CXTPAutoResetValue<BOOL> autoReset(m_bSkipOnEventChanged, FALSE);
  816. m_bSkipOnEventChanged = TRUE;
  817. if (ptrEvent->GetRecurrenceState() == xtpCalendarRecurrenceOccurrence)
  818. {
  819. CXTPCalendarRecurrencePatternPtr ptrPattern = ptrEvent->GetRecurrencePattern();
  820. CXTPCalendarEventPtr ptrMaster = ptrPattern ? ptrPattern->GetMasterEvent() : NULL;
  821. if (ptrMaster)
  822. {
  823. ptrPattern->SetOccReminder(ptrEvent, xtpCalendarRmdPrm_DontChange,
  824. (DATE)pReminder->m_dtNextReminderTime);
  825. VERIFY( ptrMaster->UpdateRecurrence(ptrPattern) );
  826. VERIFY( XTP_SAFE_GET1(ptrMaster->GetDataProvider(), ChangeEvent(ptrMaster), FALSE) );
  827. }
  828. }
  829. else
  830. {
  831. VERIFY( ptrEvent->GetCustomProperties()->SetProperty(
  832. cszEventCustProp_NextReminderTime_Snoozed,
  833. (DATE)pReminder->m_dtNextReminderTime) );
  834. VERIFY( XTP_SAFE_GET1(ptrEvent->GetDataProvider(), ChangeEvent(ptrEvent), FALSE) );
  835. }
  836. NotifyReminders(xtpCalendarReminderSnoozed, (LPARAM)pReminder);
  837. return TRUE;
  838. }
  839. BOOL CXTPCalendarRemindersManager::Dismiss(CXTPCalendarReminder* pReminder)
  840. {
  841. if (!pReminder)
  842. {
  843. ASSERT(FALSE);
  844. return FALSE;
  845. }
  846. int nIdx = m_arActiveReminders.Find(pReminder);
  847. if (nIdx >= 0)
  848. {
  849. m_arActiveReminders.RemoveAt(nIdx);
  850. }
  851. BOOL bRes = _Dismiss(pReminder);
  852. if (bRes)
  853. {
  854. NotifyReminders(xtpCalendarReminderDismissed, (LPARAM)pReminder);
  855. }
  856. return bRes;
  857. }
  858. BOOL CXTPCalendarRemindersManager::DismissAll()
  859. {
  860. int nCount = m_arActiveReminders.GetCount();
  861. for (int i = 0; i < nCount; i++)
  862. {
  863. CXTPCalendarReminder* pReminder = m_arActiveReminders.GetAt(i, FALSE);
  864. ASSERT(pReminder);
  865. if (pReminder)
  866. {
  867. _Dismiss(pReminder);
  868. }
  869. }
  870. m_arActiveReminders.RemoveAll();
  871. if (nCount)
  872. {
  873. NotifyReminders(xtpCalendarReminderDismissedAll);
  874. }
  875. return nCount > 0;
  876. }
  877. BOOL CXTPCalendarRemindersManager::_Dismiss(CXTPCalendarReminder* pReminder)
  878. {
  879. CXTPCalendarEventPtr ptrEvent = pReminder ? pReminder->GetEvent() : NULL;
  880. if (!pReminder || !ptrEvent)
  881. {
  882. ASSERT(FALSE);
  883. return FALSE;
  884. }
  885. CXTPAutoResetValue<BOOL> autoReset(m_bSkipOnEventChanged, FALSE);
  886. m_bSkipOnEventChanged = TRUE;
  887. if (ptrEvent->GetRecurrenceState() == xtpCalendarRecurrenceOccurrence)
  888. {
  889. CXTPCalendarRecurrencePatternPtr ptrPattern = ptrEvent->GetRecurrencePattern();
  890. CXTPCalendarEventPtr ptrMaster = ptrPattern ? ptrPattern->GetMasterEvent() : NULL;
  891. if (ptrMaster)
  892. {
  893. ptrPattern->SetOccReminder(ptrEvent, FALSE);
  894. VERIFY( ptrMaster->UpdateRecurrence(ptrPattern) );
  895. VERIFY( XTP_SAFE_GET1(ptrMaster->GetDataProvider(), ChangeEvent(ptrMaster), FALSE) );
  896. }
  897. }
  898. else
  899. {
  900. ptrEvent->SetReminder(FALSE);
  901. //ptrEvent->GetCustomProperties()->RemoveProperty(cszEventCustProp_NextReminderTime_Snoozed);
  902. VERIFY( XTP_SAFE_GET1(ptrEvent->GetDataProvider(), ChangeEvent(ptrEvent), FALSE) );
  903. }
  904. return TRUE;
  905. }
  906. BOOL CXTPCalendarRemindersManager::GetUpcomingEventsAll(COleDateTime dtFrom,
  907. COleDateTimeSpan spPeriod, CXTPCalendarEventsPtr& rptrEvents)
  908. {
  909. rptrEvents = NULL;
  910. if (!m_pResourcesNf || !m_pResourcesNf->GetResourcesGroupedByDP())
  911. {
  912. ASSERT(FALSE);
  913. return FALSE;
  914. }
  915. CXTPCalendarResources* pRCgroups = m_pResourcesNf->GetResourcesGroupedByDP();
  916. int i;
  917. int nCount = pRCgroups->GetCount();
  918. //-- check is all data providers opened -------------
  919. for (i = 0; i < nCount; i++)
  920. {
  921. CXTPCalendarResource* pRC = pRCgroups->GetAt(i);
  922. ASSERT(pRC);
  923. CXTPCalendarData* pData = pRC ? pRC->GetDataProvider() : NULL;
  924. ASSERT(pData);
  925. if (!pData || !pData->IsOpen())
  926. {
  927. return FALSE;
  928. }
  929. }
  930. //-- read data ----------------
  931. for (i = 0; i < nCount; i++)
  932. {
  933. CXTPCalendarResource* pRC = pRCgroups->GetAt(i);
  934. ASSERT(pRC);
  935. CXTPCalendarData* pData = pRC ? pRC->GetDataProvider() : NULL;
  936. if (!pData || !pData->IsOpen())
  937. {
  938. ASSERT(FALSE);
  939. continue;
  940. }
  941. CXTPCalendarEventsPtr ptrEv = pData->GetUpcomingEvents(dtFrom, spPeriod);
  942. if (rptrEvents)
  943. {
  944. rptrEvents->Append(ptrEv);
  945. }
  946. else
  947. {
  948. rptrEvents = ptrEv;
  949. }
  950. pRC->FilterEventsByScheduleID(rptrEvents);
  951. }
  952. return TRUE;
  953. }
  954. /////////////////////////////////////////////////////////////////////////////