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

对话框与窗口

开发平台:

Visual C++

  1. // XTPCalendarController.cpp : implementation file
  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/XTPVC50Helpers.h"
  22. #include "Common/XTPMacros.h"
  23. #include "Common/XTPNotifyConnection.h"
  24. #include "XTPCalendarControl.h"
  25. #include "XTPCalendarView.h"
  26. #include "XTPCalendarWeekView.h"
  27. #include "XTPCalendarMonthView.h"
  28. #include "XTPCalendarDayView.h"
  29. #include "XTPCalendarData.h"
  30. #include "XTPCalendarResource.h"
  31. #include "XTPCalendarNotifications.h"
  32. #include "XTPDatePickerItemMonth.h"
  33. #include "XTPDatePickerItemDay.h"
  34. #include "XTPDatePickerControl.h"
  35. #include "XTPDatePickerPaintManager.h"
  36. #include "XTPDatePickerNotifications.h"
  37. #include "XTPCalendarController.h"
  38. #ifdef _DEBUG
  39. #define new DEBUG_NEW
  40. #undef THIS_FILE
  41. static char THIS_FILE[] = __FILE__;
  42. #endif
  43. // DBG
  44. #define DBG_TRACE_DP_NF
  45. #define DBG_TRACE_DP_TIMER
  46. //#define DBG_TRACE_DP_NF  TRACE
  47. //#define DBG_TRACE_DP_TIMER     TRACE
  48. // DBG
  49. /////////////////////////////////////////////////////////////////////////////
  50. #define XTP_CC_DONT_SCROLL_DP 1234567890
  51. #define XTP_CC_REFRESH_DAYS_STEP_TIMER_MS 120
  52. #define XTP_CC_REFRESH_DAYS_STEP_DAYS     3
  53. /////////////////////////////////////////////////////////////////////////////
  54. // CXTPCalendarController
  55. const int nXTPMaxDayViewDays = 6;
  56. ////////////////////////////////////////////////////////////////////////////
  57. CXTPCalendarController::CXTPDayInfoCache::CXTPMapTimers CXTPCalendarController::CXTPDayInfoCache::m_mapTimers;
  58. IMPLEMENT_DYNCREATE(CXTPCalendarController, CCmdTarget)
  59. //////////////////////////////////////////////////////////////////////////
  60. CXTPCalendarController::CXTPDayInfoCache::CXTPDayInfoCache()
  61. {
  62. // 37, 53, 79 , 101, 127, 199, 503, 1021, 1511, 2003, 3001, 4001, 5003, 6007, 8009, 12007, 16001
  63. m_mapDaysInfo.InitHashTable(503, FALSE);
  64. m_mapDaysToRefresh.InitHashTable(503, FALSE);
  65. m_pOwner = NULL;
  66. m_uTimerID = 0;
  67. m_dwLastRedrawTime = 0;
  68. m_dwLastSelfClearTime = 0;
  69. m_dwWaitingDataTime = 0;
  70. m_uActivePriority = 1;
  71. }
  72. CXTPCalendarController::CXTPDayInfoCache::~CXTPDayInfoCache()
  73. {
  74. KillTimer();
  75. }
  76. void CXTPCalendarController::CXTPDayInfoCache::KillTimer()
  77. {
  78. if (m_uTimerID)
  79. {
  80. ::KillTimer(NULL, m_uTimerID);
  81. m_mapTimers.RemoveKey(m_uTimerID);
  82. m_uTimerID = 0;
  83. }
  84. }
  85. BOOL CXTPCalendarController::CXTPDayInfoCache::HasEvents(DATE dtDay)
  86. {
  87. XTPDayInfo tmpDI;
  88. if (m_mapDaysInfo.Lookup((long)dtDay, tmpDI))
  89. {
  90. UpdateDayInfo(dtDay, tmpDI.bHasEvents);
  91. return tmpDI.bHasEvents;
  92. }
  93. else
  94. {
  95. _RequestToRefreshDays(dtDay, dtDay, m_uActivePriority);
  96. }
  97. return FALSE;
  98. }
  99. void CXTPCalendarController::CXTPDayInfoCache::Init(CXTPCalendarController* pOwner)
  100. {
  101. ASSERT(pOwner);
  102. m_pOwner = pOwner;
  103. }
  104. void CXTPCalendarController::CXTPDayInfoCache::Clear()
  105. {
  106. m_mapDaysInfo.RemoveAll();
  107. m_mapDaysToRefresh.RemoveAll();
  108. m_uActivePriority = 1;
  109. DBG_TRACE_DP_TIMER(_T("XTPCalendarController::DayInfoCache - CLEAR n"));
  110. }
  111. UINT CXTPCalendarController::CXTPDayInfoCache::UpActivePriority()
  112. {
  113. return ++m_uActivePriority;
  114. }
  115. void CXTPCalendarController::CXTPDayInfoCache::UpdateDayInfo(DATE dtDay, BOOL bHasEvents)
  116. {
  117. XTPDayInfo tmpDI = {bHasEvents, (DATE)CXTPCalendarUtils::GetCurrentTime()};
  118. m_mapDaysInfo[(long)dtDay] = tmpDI;
  119. }
  120. void CXTPCalendarController::CXTPDayInfoCache::ClearDays(COleDateTime dtDayFrom, COleDateTime dtDayTo)
  121. {
  122. long nDay = min((long)dtDayFrom, (long)dtDayTo);
  123. long nDay2 = max((long)dtDayFrom, (long)dtDayTo);
  124. for (; nDay <= nDay2; nDay++)
  125. {
  126. m_mapDaysInfo.RemoveKey(nDay);
  127. }
  128. DBG_TRACE_DP_TIMER(_T("XTPCalendarController::DayInfoCache - Clear days (%s - %s) n"), (LPCTSTR)dtDayFrom.Format(), (LPCTSTR)dtDayTo.Format());
  129. }
  130. void CXTPCalendarController::CXTPDayInfoCache::RequestToRefreshDays(COleDateTime dtDayFrom, COleDateTime dtDayTo)
  131. {
  132. m_uActivePriority++;
  133. DBG_TRACE_DP_TIMER(_T("XTPCalendarController::DayInfoCache - RequestToRefreshDays (%s - %s). ActivePriority = %d n"),
  134.    (LPCTSTR)dtDayFrom.Format(), (LPCTSTR)dtDayTo.Format(), m_uActivePriority);
  135. _RequestToRefreshDays(dtDayFrom, dtDayTo, m_uActivePriority);
  136. }
  137. void CXTPCalendarController::CXTPDayInfoCache::_RequestToRefreshDays(COleDateTime dtDayFrom, COleDateTime dtDayTo, UINT uPriority)
  138. {
  139. ASSERT(m_pOwner);
  140. if (!m_pOwner)
  141. {
  142. return;
  143. }
  144. long nDay = min((long)dtDayFrom, (long)dtDayTo);
  145. long nDay2 = max((long)dtDayFrom, (long)dtDayTo);
  146. // WARNING! - Ooo... The days range is too large!
  147. ASSERT(nDay2 - nDay < 10*1000);
  148. for (; nDay <= nDay2; nDay++)
  149. {
  150. m_mapDaysToRefresh[nDay] = uPriority;
  151. }
  152. if (m_mapDaysToRefresh.GetCount() && m_uTimerID == 0)
  153. {
  154. UINT uTimeOut = (UINT)m_pOwner->m_nBoldDaysIdleStepTime_ms;
  155. m_uTimerID = ::SetTimer(NULL, 0, uTimeOut, OnTimerCallback);
  156. m_mapTimers[m_uTimerID] = this;
  157. DBG_TRACE_DP_TIMER(_T("XTPCalendarController::DayInfoCache - _RequestToRefreshDays, SetTimer (ID = %d) n"), m_uTimerID);
  158. }
  159. }
  160. void CXTPCalendarController::CXTPDayInfoCache::OnRefreshDays(int nDaysCountToRefresh)
  161. {
  162. ASSERT(m_pOwner);
  163. if (!XTP_SAFE_GET1(m_pOwner, m_pResourcesNf, NULL))
  164. {
  165. if (!m_dwWaitingDataTime)
  166. {
  167. m_dwWaitingDataTime = GetTickCount();
  168. DBG_TRACE_DP_TIMER(_T("XTPCalendarController::DayInfoCache - OnRefreshDays, Start Wait for datan"));
  169. }
  170. if (abs((long)(GetTickCount() - m_dwWaitingDataTime)) >= 5000)
  171. {
  172. m_dwWaitingDataTime = 0;
  173. if (m_uTimerID)
  174. {
  175. DBG_TRACE_DP_TIMER(_T("XTPCalendarController::DayInfoCache - OnRefreshDays, KillTimer (ID = %d) n"), m_uTimerID);
  176. DBG_TRACE_DP_TIMER(_T("XTPCalendarController::DayInfoCache - OnRefreshDays, end Wait for datan"));
  177. KillTimer();
  178. OnSelfClearOld();
  179. }
  180. }
  181. return;
  182. }
  183. else
  184. {
  185. if (m_dwWaitingDataTime)
  186. {
  187. DBG_TRACE_DP_TIMER(_T("XTPCalendarController::DayInfoCache - OnRefreshDays, end Wait for datan"));
  188. }
  189. m_dwWaitingDataTime = 0;
  190. }
  191. //***************************************************
  192. for (int i = 0; i < nDaysCountToRefresh; i++)
  193. {
  194. long nDay_min = LONG_MAX;
  195. UINT uPriority_max = 0;
  196. POSITION pos = m_mapDaysToRefresh.GetStartPosition();
  197. while (pos)
  198. {
  199. long nDay = 0;
  200. UINT uPriority = 0;
  201. m_mapDaysToRefresh.GetNextAssoc(pos, nDay, uPriority);
  202. if (uPriority == uPriority_max && nDay < nDay_min ||
  203. uPriority > uPriority_max)
  204. {
  205. uPriority_max = uPriority;
  206. nDay_min = nDay;
  207. }
  208. }
  209. if (nDay_min < LONG_MAX)
  210. {
  211. m_mapDaysToRefresh.RemoveKey(nDay_min);
  212. COleDateTime dtDay((DATE)nDay_min);
  213. BOOL bHasEvents = XTP_SAFE_GET1(m_pOwner, _HasEvents(dtDay), FALSE);
  214. UpdateDayInfo(dtDay, bHasEvents);
  215. }
  216. }
  217. //***************************************************
  218. if (m_mapDaysToRefresh.GetCount() == 0 && m_uTimerID)
  219. {
  220. DBG_TRACE_DP_TIMER(_T("XTPCalendarController::DayInfoCache - OnRefreshDays, KillTimer (ID = %d) n"), m_uTimerID);
  221. DBG_TRACE_DP_TIMER(_T("XTPCalendarController::DayInfoCache - Days In Cache %d n"), m_mapDaysInfo.GetCount());
  222. KillTimer();
  223. OnSelfClearOld();
  224. }
  225. if (abs((long)(GetTickCount() - m_dwLastRedrawTime)) >= 500 || m_uTimerID == 0)
  226. {
  227. XTP_SAFE_CALL2(m_pOwner, m_pDatePickerCtrl, RedrawControl());
  228. m_dwLastRedrawTime = GetTickCount();
  229. }
  230. }
  231. void CXTPCalendarController::CXTPDayInfoCache::OnSelfClearOld()
  232. {
  233. #ifdef _DEBUG
  234. int nUpdateTime_ms = 20 * 1000;
  235. COleDateTimeSpan spCachePeriod(0, 0, 1, 0); // 1 min
  236. #else
  237. int nUpdateTime_ms = 5 * 60 * 1000; // 5 min
  238. COleDateTimeSpan spCachePeriod(0, 1, 0, 0); // 1 hour
  239. #endif
  240. if (abs((long)(GetTickCount() - m_dwLastSelfClearTime)) < nUpdateTime_ms)
  241. {
  242. return;
  243. }
  244. m_dwLastSelfClearTime = ::GetTickCount();
  245. COleDateTime dtOldTime = CXTPCalendarUtils::GetCurrentTime();
  246. dtOldTime -= spCachePeriod;
  247. DBG_TRACE_DP_TIMER(_T("XTPCalendarController::DayInfoCache - OnSelfClear, Start. Days In Cache %d n"), m_mapDaysInfo.GetCount());
  248. POSITION pos = m_mapDaysInfo.GetStartPosition();
  249. while (pos)
  250. {
  251. long nDay = 0;
  252. XTPDayInfo tmpDI;
  253. m_mapDaysInfo.GetNextAssoc(pos, nDay, tmpDI);
  254. if (tmpDI.dtLastAccessTime < dtOldTime)
  255. {
  256. m_mapDaysInfo.RemoveKey(nDay);
  257. }
  258. }
  259. DBG_TRACE_DP_TIMER(_T("XTPCalendarController::DayInfoCache - OnSelfClear, End. Days In Cache %d n"), m_mapDaysInfo.GetCount());
  260. }
  261. VOID CALLBACK CXTPCalendarController::CXTPDayInfoCache::OnTimerCallback(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
  262. {
  263. UNREFERENCED_PARAMETER(hwnd);
  264. UNREFERENCED_PARAMETER(uMsg);
  265. UNREFERENCED_PARAMETER(dwTime);
  266.  CXTPDayInfoCache* pThis = m_mapTimers[idEvent];
  267.  ASSERT(pThis && pThis->m_pOwner);
  268.  if (pThis && pThis->m_pOwner)
  269.  {
  270. //***********************
  271. SAFE_MANAGE_STATE(pThis->m_pOwner->m_pModuleState);
  272. //***********************
  273.  pThis->OnRefreshDays(pThis->m_pOwner->m_nBoldDaysPerIdleStep);
  274.  }
  275. }
  276. //////////////////////////////////////////////////////////////////////////
  277. CXTPCalendarController::CXTPCalendarController()
  278. {
  279. m_pCalendarCtrl = NULL;
  280. m_pDatePickerCtrl = NULL;
  281. m_bAdjustingView = FALSE;
  282. m_bBoldDaysWithEvents = TRUE;
  283. m_bBoldDaysOnIdle = TRUE;
  284. m_nBoldDaysPerIdleStep = XTP_CC_REFRESH_DAYS_STEP_DAYS;
  285. m_nBoldDaysIdleStepTime_ms = XTP_CC_REFRESH_DAYS_STEP_TIMER_MS;
  286. m_bUseActiveViewResoucesForBold = FALSE;
  287. m_pResourcesNf = NULL;
  288. m_eLastActiveView = -1;
  289. m_cnidEventAdded = 0;
  290. m_cnidEventChanged = 0;
  291. m_cnidEventDeleted = 0;
  292. m_DayInfoCache.Init(this);
  293. }
  294. CXTPCalendarController::~CXTPCalendarController()
  295. {
  296. CMDTARGET_RELEASE(m_pCalendarCtrl);
  297. CMDTARGET_RELEASE(m_pDatePickerCtrl);
  298. CMDTARGET_RELEASE(m_pResourcesNf);
  299. }
  300. /////////////////////////////////////////////////////////////////////////////
  301. // CXTPCalendarController message handlers
  302. void CXTPCalendarController::AdviseToNotifications()
  303. {
  304. m_Sink.UnadviseAll();
  305. m_cnidEventAdded = 0;
  306. m_cnidEventChanged = 0;
  307. m_cnidEventDeleted = 0;
  308. CMDTARGET_RELEASE(m_pResourcesNf);
  309. // Advise to Calendar notifications
  310. if (m_pCalendarCtrl)
  311. {
  312. CXTPNotifyConnection* ptrDPConn = m_pCalendarCtrl ? m_pCalendarCtrl->GetConnection() : NULL;
  313. ASSERT(ptrDPConn);
  314. if (!ptrDPConn)
  315. {
  316. return;
  317. }
  318. m_Sink.Advise(ptrDPConn, XTP_NC_CALENDARVIEWWASCHANGED, &CXTPCalendarController::OnEvent_CalendarView);
  319. m_Sink.Advise(ptrDPConn, XTP_NC_CALENDAROPTIONSWASCHANGED, &CXTPCalendarController::OnEvent_CalendarOptionsChanged);
  320. m_Sink.Advise(ptrDPConn, XTP_NC_CALENDAR_RESOURCES_WHERE_CHANGED, &CXTPCalendarController::OnEvent_CalendarResourcesChanged);
  321. m_Sink.Advise(ptrDPConn, XTP_NC_CALENDAR_THEME_CHANGED, &CXTPCalendarController::OnEvent_CalendarThemeChanged);
  322. }
  323. // Advise to Date Picker notifications
  324. if (m_pDatePickerCtrl)
  325. {
  326. CXTPNotifyConnection* ptrDPConn = m_pDatePickerCtrl ? m_pDatePickerCtrl->GetConnection() : NULL;
  327. ASSERT(ptrDPConn);
  328. if (!ptrDPConn)
  329. {
  330. return;
  331. }
  332. m_Sink.Advise(ptrDPConn, XTP_NC_DATEPICKERBUTTONCLICKED, &CXTPCalendarController::OnEvent_DatePicker);
  333. m_Sink.Advise(ptrDPConn, XTP_NC_DATEPICKERSELECTIONCHANGED, &CXTPCalendarController::OnEvent_DatePicker);
  334. m_Sink.Advise(ptrDPConn, XTP_NC_DATEPICKERBEFOREGOMODAL, &CXTPCalendarController::OnEvent_DatePicker);
  335. m_Sink.Advise(ptrDPConn, XTP_NC_DATEPICKERMONTHCHANGED, &CXTPCalendarController::OnEvent_DatePicker);
  336. m_Sink.Advise(ptrDPConn, XTP_NC_DATEPICKERGETDAYMETRICS, &CXTPCalendarController::OnEvent_DtPickGetItemMetrics);
  337. }
  338. }
  339. void CXTPCalendarController::_AdviseToDataChanged()
  340. {
  341. ASSERT(m_pResourcesNf);
  342. if (!m_pResourcesNf)
  343. {
  344. return;
  345. }
  346. CXTPNotifyConnection* ptrDPConn = m_pResourcesNf->GetConnection();
  347. ASSERT(ptrDPConn);
  348. if (!ptrDPConn)
  349. {
  350. return;
  351. }
  352. m_cnidEventAdded = m_Sink.Advise(ptrDPConn, XTP_NC_CALENDAREVENTWASADDED, &CXTPCalendarController::OnEvent_CalendarDataChanged);
  353. m_cnidEventChanged = m_Sink.Advise(ptrDPConn, XTP_NC_CALENDAREVENTWASCHANGED, &CXTPCalendarController::OnEvent_CalendarDataChanged);
  354. m_cnidEventDeleted = m_Sink.Advise(ptrDPConn, XTP_NC_CALENDAREVENTWASDELETED, &CXTPCalendarController::OnEvent_CalendarDataChanged);
  355. }
  356. void CXTPCalendarController::_UnadviseFromDataChanged()
  357. {
  358. if (m_cnidEventAdded)
  359. {
  360. m_Sink.Unadvise(m_cnidEventAdded);
  361. }
  362. if (m_cnidEventChanged)
  363. {
  364. m_Sink.Unadvise(m_cnidEventChanged);
  365. }
  366. if (m_cnidEventDeleted)
  367. {
  368. m_Sink.Unadvise(m_cnidEventDeleted);
  369. }
  370. m_cnidEventAdded = 0;
  371. m_cnidEventChanged = 0;
  372. m_cnidEventDeleted = 0;
  373. }
  374. BOOL CXTPCalendarController::IsFirstDayOfWeekShifted_FromSun2Mon()
  375. {
  376. if (!m_pCalendarCtrl || !m_pCalendarCtrl->GetActiveView())
  377. {
  378. return FALSE;
  379. }
  380. int nViewType = m_pCalendarCtrl->GetActiveView()->GetViewType();
  381. if (nViewType == xtpCalendarMonthView || nViewType == xtpCalendarWeekView)
  382. {
  383. int nFirstDayOfWeekIndex = m_pCalendarCtrl->GetFirstDayOfWeek();
  384. int bCompress = (nViewType == xtpCalendarWeekView) ||
  385. m_pCalendarCtrl->MonthView_IsCompressWeekendDays();
  386. if (bCompress && nFirstDayOfWeekIndex == 1)
  387. {
  388. return TRUE;
  389. }
  390. }
  391. return FALSE;
  392. }
  393. void CXTPCalendarController::OnEvent_CalendarView(XTP_NOTIFY_CODE Event, WPARAM /*wParam*/, LPARAM lParam)
  394. {
  395. if (!XTP_NC_CALENDARVIEWWASCHANGED == Event)
  396. {
  397. ASSERT(FALSE);
  398. return;
  399. }
  400. if (m_bAdjustingView)
  401. {
  402. return;
  403. }
  404. if (m_pDatePickerCtrl && m_pCalendarCtrl)
  405. {
  406. CXTPCalendarView* pView = m_pCalendarCtrl->GetActiveView();
  407. if (!pView)
  408. return;
  409. //--------------------------------------------------------
  410. int nViewTypeX = pView->GetViewType();
  411. if (nViewTypeX == xtpCalendarWorkWeekView)
  412. {
  413. nViewTypeX = xtpCalendarDayView;
  414. }
  415. if (m_eLastActiveView != nViewTypeX)
  416. {
  417. m_eLastActiveView = nViewTypeX;
  418. CMDTARGET_RELEASE(m_pResourcesNf);
  419. _UnadviseFromDataChanged();
  420. if (m_bBoldDaysOnIdle)
  421. {
  422. COleDateTime dtFirstVisibleDay, dtLastVisibleDay;
  423. if (m_pDatePickerCtrl->GetVisibleRange(dtFirstVisibleDay, dtLastVisibleDay))
  424. {
  425. m_DayInfoCache.RequestToRefreshDays(dtFirstVisibleDay, dtLastVisibleDay);
  426. }
  427. }
  428. }
  429. //--------------------------------------------------------
  430. COleDateTimeSpan spCompressCorrector(0 , 0, 0, 0);
  431. if (IsFirstDayOfWeekShifted_FromSun2Mon())
  432. {
  433. spCompressCorrector.SetDateTimeSpan(-1, 0, 0, 0);
  434. }
  435. int nCount = pView->GetViewDayCount();
  436. if (nCount > 0)
  437. {
  438. COleDateTime dtDay = m_pCalendarCtrl->GetActiveView()->GetViewDayDate(0);
  439. dtDay += spCompressCorrector;
  440. m_pDatePickerCtrl->SetSelRange(dtDay, dtDay);
  441. }
  442. for (int i = 1; i < nCount; i++)
  443. {
  444. COleDateTime dtDay = m_pCalendarCtrl->GetActiveView()->GetViewDayDate(i);
  445. dtDay += spCompressCorrector;
  446. m_pDatePickerCtrl->Select(dtDay);
  447. }
  448. if (lParam != XTP_CC_DONT_SCROLL_DP)
  449. m_pDatePickerCtrl->EnsureVisibleSelection();
  450. if (::IsWindow(m_pDatePickerCtrl->GetSafeHwnd()))
  451. {
  452. m_pDatePickerCtrl->RedrawControl();
  453. m_pDatePickerCtrl->UpdateWindow();
  454. }
  455. }
  456. }
  457. void CXTPCalendarController::OnEvent_DatePicker(XTP_NOTIFY_CODE Event, WPARAM wParam, LPARAM /*lParam*/)
  458. {
  459. wParam;
  460. switch (Event)
  461. {
  462. case XTP_NC_DATEPICKERBEFOREGOMODAL:
  463. if (m_pDatePickerCtrl && m_pCalendarCtrl)
  464. {
  465. OnEvent_CalendarView(XTP_NC_CALENDARVIEWWASCHANGED, 0, 0);
  466. }
  467. break;
  468. case XTP_NC_DATEPICKERBUTTONCLICKED:
  469. DBG_TRACE_DP_NF(_T("OnEvent: DatePickerButtonClicked - ID = %u.     {CalendarController}. n"), wParam);
  470. break;
  471. case XTP_NC_DATEPICKERMONTHCHANGED:
  472. m_DayInfoCache.UpActivePriority();
  473. break;
  474. case XTP_NC_DATEPICKERSELECTIONCHANGED:
  475. DBG_TRACE_DP_NF(_T("OnEvent: XTP_NC_DATEPICKERSELECTIONCHANGED.     {CalendarController}. n"));
  476. if (m_pDatePickerCtrl && m_pCalendarCtrl && m_pCalendarCtrl->GetActiveView())
  477. {
  478. BOOL bChanged = FALSE;
  479. COleDateTime dtFrom;
  480. COleDateTime dtTo;
  481. if (m_pDatePickerCtrl->GetSelRange(dtFrom, dtTo))
  482. {
  483. int nFirstDayOfWeekIndex = m_pDatePickerCtrl->GetFirstDayOfWeek();
  484. CXTPCalendarControl::CUpdateContext updateContext(m_pCalendarCtrl);
  485. int nSelRangeDays = GETTOTAL_DAYS_DTS(dtTo - dtFrom)+1;
  486. // count selected days
  487. int nSelDays = 0;
  488. COleDateTimeSpan spDay(1, 0, 0, 0);
  489. for (COleDateTime dtDay = dtFrom; dtDay <= dtTo; dtDay += spDay)
  490. {
  491. if (m_pDatePickerCtrl->IsSelected(dtDay))
  492. {
  493. nSelDays++;
  494. }
  495. }
  496. // Day view
  497. if (nSelRangeDays <= nXTPMaxDayViewDays || nSelRangeDays != nSelDays ||
  498. dtFrom.GetDayOfWeek() != nFirstDayOfWeekIndex && nSelRangeDays <= 8
  499.  )
  500. {
  501. m_bAdjustingView = TRUE;
  502. // to save WorkWeek view mode
  503. int eViewMode = XTP_SAFE_GET2(m_pCalendarCtrl, GetActiveView(), GetViewType(), xtpCalendarDayView);
  504. if (eViewMode != xtpCalendarWorkWeekView || nSelDays != 1)
  505. {
  506. eViewMode = xtpCalendarDayView;
  507. }
  508. // WorkWeekView - set visible days
  509. if (eViewMode == xtpCalendarWorkWeekView)
  510. {
  511. CXTPCalendarDayView* pDayView = DYNAMIC_DOWNCAST(CXTPCalendarDayView, m_pCalendarCtrl->GetActiveView());
  512. if (pDayView)
  513. {
  514. pDayView->UnselectAllEvents();
  515. COleDateTime dtWWStart;
  516. m_pCalendarCtrl->GetWorkDayStartTime(dtWWStart);
  517. dtWWStart = CXTPCalendarUtils::UpdateDate(dtWWStart, dtFrom);
  518. pDayView->SetSelection(dtWWStart, dtWWStart + pDayView->GetCellDuration());
  519. }
  520. }
  521. //*** switch calendar view
  522. m_pCalendarCtrl->SwitchActiveView((XTPCalendarViewType)eViewMode);
  523. //***
  524. CXTPCalendarDayView* pDayView = DYNAMIC_DOWNCAST(CXTPCalendarDayView, m_pCalendarCtrl->GetActiveView());
  525. // DayView - set visible days
  526. if (pDayView && eViewMode == xtpCalendarDayView)
  527. {
  528. COleDateTime dtSelStart, dtSelEnd;
  529. BOOL bAllDay = FALSE;
  530. BOOL bSel = pDayView->GetSelection(&dtSelStart, &dtSelEnd, &bAllDay);
  531. if (bSel)
  532. {
  533. COleDateTimeSpan spSel = dtSelEnd - dtSelStart;
  534. COleDateTimeSpan spSelMin = pDayView->GetCellDuration();
  535. if (spSel < spSelMin)
  536. {
  537. bSel = FALSE;
  538. }
  539. }
  540. if (!bSel)
  541. {
  542. m_pCalendarCtrl->GetWorkDayStartTime(dtSelStart);
  543. dtSelEnd = dtSelStart + pDayView->GetCellDuration();
  544. bAllDay = FALSE;
  545. }
  546. dtSelStart = CXTPCalendarUtils::UpdateDate(dtSelStart, dtFrom);
  547. dtSelEnd = CXTPCalendarUtils::UpdateDate(dtSelEnd, dtFrom);
  548. pDayView->ShowDay(dtFrom);
  549. pDayView->SetSelection(dtSelStart, dtSelEnd, bAllDay);
  550. // add other selected days to calendar view
  551. for (COleDateTime dtDay(dtFrom + spDay); dtDay <= dtTo; dtDay += spDay)
  552. {
  553. if (m_pDatePickerCtrl->IsSelected(dtDay))
  554. {
  555. // add it to Calendar View
  556. pDayView->AddDay(dtDay);
  557. }
  558. }
  559. m_pCalendarCtrl->Populate();
  560. }
  561. m_bAdjustingView = FALSE;
  562. bChanged = TRUE;
  563. }
  564. // Week view
  565. else if (nSelRangeDays == 7 && nSelRangeDays == nSelDays)
  566. {
  567. COleDateTime dtBegin = dtFrom;
  568. if (IsFirstDayOfWeekShifted_FromSun2Mon())
  569. {
  570. dtBegin += spDay;
  571. }
  572. m_bAdjustingView = TRUE;
  573. m_pCalendarCtrl->SwitchActiveView(xtpCalendarWeekView);
  574. CXTPCalendarWeekView* pWeekView = DYNAMIC_DOWNCAST(CXTPCalendarWeekView, m_pCalendarCtrl->GetActiveView());
  575. if (pWeekView)
  576. {
  577. pWeekView->SetBeginDate(dtBegin);
  578. m_pCalendarCtrl->Populate();
  579. }
  580. m_bAdjustingView = FALSE;
  581. bChanged = TRUE;
  582. }
  583. // Month view
  584. else
  585. {
  586. ASSERT(nSelRangeDays == nSelDays && nSelRangeDays > 7);
  587. m_bAdjustingView = TRUE;
  588. m_pCalendarCtrl->SwitchActiveView(xtpCalendarMonthView);
  589. CXTPCalendarMonthView* pMonthView = DYNAMIC_DOWNCAST(CXTPCalendarMonthView, m_pCalendarCtrl->GetActiveView());
  590. if (pMonthView)
  591. {
  592. CXTPCalendarControl::CViewChangedContext viewChanged(m_pCalendarCtrl, xtpCalendarViewChangedLock);
  593. COleDateTime dtBegin = dtFrom;
  594. if (IsFirstDayOfWeekShifted_FromSun2Mon())
  595. {
  596. dtBegin += spDay;
  597. }
  598. // Calculate weeks count
  599. COleDateTime dtWeekFromBegin = pMonthView->GetGrid()->ShiftDateToCell_00(dtFrom);
  600. COleDateTime dtWeekToEnd = pMonthView->GetGrid()->ShiftDateToCell_00(dtTo);
  601. dtWeekToEnd += COleDateTimeSpan(7, 0, 0, 0);
  602. int nSelectedWeeksRange = GETTOTAL_DAYS_DTS(dtWeekToEnd - dtWeekFromBegin);
  603. int nWeeks = nSelectedWeeksRange / 7;
  604. nWeeks = max(XTP_CALENDAR_MONTHVIEW_SHOW_WEEKS_MIN, nWeeks);
  605. nWeeks = min(XTP_CALENDAR_MONTHVIEW_SHOW_WEEKS_MAX, nWeeks);
  606. pMonthView->GetGrid()->SetBeginDate(dtBegin);
  607. pMonthView->GetGrid()->SetWeeksCount(nWeeks);
  608. m_pCalendarCtrl->Populate();
  609. }
  610. m_bAdjustingView = FALSE;
  611. bChanged = TRUE;
  612. }
  613. if (bChanged)
  614. {
  615. OnEvent_CalendarView(XTP_NC_CALENDARVIEWWASCHANGED, 0, XTP_CC_DONT_SCROLL_DP);
  616. if (m_pDatePickerCtrl->IsModal())
  617. {
  618. m_pCalendarCtrl->Invalidate(FALSE);
  619. m_pCalendarCtrl->RedrawControl();
  620. }
  621. }
  622. }
  623. }
  624. break;
  625. default:
  626. ASSERT(FALSE);
  627. }
  628. }
  629. void CXTPCalendarController::OnEvent_CalendarOptionsChanged(XTP_NOTIFY_CODE Event, WPARAM wParam, LPARAM /*lParam*/)
  630. {
  631. if (Event != XTP_NC_CALENDAROPTIONSWASCHANGED)
  632. {
  633. ASSERT(FALSE);
  634. return;
  635. }
  636. if ((int)wParam < 0)
  637. {
  638. SetFirstDayOfWeekToDatePicker();
  639. }
  640. }
  641. void CXTPCalendarController::OnEvent_CalendarResourcesChanged(XTP_NOTIFY_CODE Event, WPARAM /*wParam*/, LPARAM /*lParam*/)
  642. {
  643. if (Event != XTP_NC_CALENDARDATAPROVIDERWASCHANGED)
  644. {
  645. ASSERT(FALSE);
  646. return;
  647. }
  648. CMDTARGET_RELEASE(m_pResourcesNf);
  649. _UnadviseFromDataChanged();
  650. m_DayInfoCache.Clear();
  651. }
  652. void CXTPCalendarController::OnEvent_CalendarThemeChanged(XTP_NOTIFY_CODE Event, WPARAM /*wParam*/, LPARAM /*lParam*/)
  653. {
  654. if (Event != XTP_NC_CALENDAR_THEME_CHANGED)
  655. {
  656. ASSERT(FALSE);
  657. return;
  658. }
  659. if (m_pCalendarCtrl && m_pDatePickerCtrl)
  660. {
  661. if (m_pDatePickerCtrl->GetPaintTheme() != m_pCalendarCtrl->GetPaintTheme())
  662. {
  663. m_pDatePickerCtrl->SetPaintTheme(m_pCalendarCtrl->GetPaintTheme());
  664. }
  665. }
  666. }
  667. void CXTPCalendarController::OnEvent_CalendarDataChanged(XTP_NOTIFY_CODE Event, WPARAM /*wParam*/, LPARAM lParam)
  668. {
  669. if (!m_pDatePickerCtrl)
  670. {
  671. return;
  672. }
  673. if (Event != XTP_NC_CALENDAREVENTWASADDED &&
  674. Event != XTP_NC_CALENDAREVENTWASCHANGED&&
  675. Event != XTP_NC_CALENDAREVENTWASDELETED)
  676. {
  677. ASSERT(FALSE);
  678. return;
  679. }
  680. //-------------------------------------
  681. COleDateTime dtFirstVisibleDay, dtLastVisibleDay;
  682. BOOL bRes = m_pDatePickerCtrl->GetVisibleRange(dtFirstVisibleDay, dtLastVisibleDay);
  683. if (!bRes)
  684. {
  685. return;
  686. }
  687. CXTPCalendarEvent* pEvent = (CXTPCalendarEvent*)lParam;
  688. if (!pEvent)
  689. {
  690. return;
  691. }
  692. if (Event == XTP_NC_CALENDAREVENTWASADDED ||
  693. Event == XTP_NC_CALENDAREVENTWASDELETED)
  694. {
  695. if (CXTPCalendarUtils::ResetTime(pEvent->GetStartTime()) > dtLastVisibleDay ||
  696. CXTPCalendarUtils::ResetTime(pEvent->GetEndTime()) < dtFirstVisibleDay )
  697. {
  698. return; // xtpCalendar_Skip;
  699. }
  700. if (m_bBoldDaysOnIdle)
  701. {
  702. m_DayInfoCache.ClearDays(pEvent->GetStartTime(), pEvent->GetEndTime());
  703. }
  704. }
  705. else
  706. {
  707. if (m_bBoldDaysOnIdle)
  708. {
  709. m_DayInfoCache.RequestToRefreshDays(dtFirstVisibleDay, dtLastVisibleDay);
  710. COleDateTime dtFom = max(dtFirstVisibleDay, pEvent->GetStartTime());
  711. COleDateTime dtTo = min(dtLastVisibleDay, pEvent->GetEndTime());
  712. m_DayInfoCache.RequestToRefreshDays(dtFom, dtTo);
  713. }
  714. }
  715. m_pDatePickerCtrl->_RedrawControl(FALSE);
  716. }
  717. void CXTPCalendarController::SetFirstDayOfWeekToDatePicker()
  718. {
  719. if (m_pDatePickerCtrl && m_pCalendarCtrl)
  720. {
  721. int nFirstDayOfWeekIndex = m_pCalendarCtrl->GetFirstDayOfWeek();
  722. m_pDatePickerCtrl->SetFirstDayOfWeek(nFirstDayOfWeekIndex);
  723. }
  724. }
  725. void CXTPCalendarController::OnEvent_DtPickGetItemMetrics(XTP_NOTIFY_CODE Event, WPARAM wParam, LPARAM lParam)
  726. {
  727. if (Event != XTP_NC_DATEPICKERGETDAYMETRICS)
  728. {
  729. ASSERT(FALSE);
  730. return;
  731. }
  732. if (!m_bBoldDaysWithEvents)
  733. {
  734. return;
  735. }
  736. const COleDateTime dtDay = (DATE)(XTP_DATE_VALUE)wParam;
  737. XTP_DAYITEM_METRICS* pDayItemMetrics = (XTP_DAYITEM_METRICS*)lParam;
  738. ASSERT(pDayItemMetrics);
  739. if (!pDayItemMetrics || !m_pCalendarCtrl || !m_pDatePickerCtrl)
  740. {
  741. return;
  742. }
  743. //--------------------------------------------------------------------
  744. if (!m_pResourcesNf)
  745. {
  746. m_pResourcesNf = new CXTPCalendarResourcesNf();
  747. if (!m_pResourcesNf)
  748. {
  749. return;
  750. }
  751. CXTPCalendarResources* pRC0 = m_pCalendarCtrl->GetResources();
  752. if (m_bUseActiveViewResoucesForBold)
  753. {
  754. pRC0 = m_pCalendarCtrl->GetActiveView()->GetResources();
  755. }
  756. m_pResourcesNf->Append(pRC0);
  757. _AdviseToDataChanged();
  758. m_pResourcesNf->ReBuildInternalData();
  759. }
  760. //--------------------------------------------------------------------
  761. BOOL bHasEvents = FALSE;
  762. if (m_bBoldDaysOnIdle)
  763. {
  764. bHasEvents = m_DayInfoCache.HasEvents(dtDay);
  765. }
  766. else
  767. {
  768. // check whether specified day has events
  769. bHasEvents = _HasEvents(dtDay);
  770. }
  771. // make the day with events as bold
  772. if (bHasEvents)
  773. {
  774. // set bold to day metrics
  775. pDayItemMetrics->SetFont(m_pDatePickerCtrl->GetPaintManager()->GetDayTextFontBold());
  776. }
  777. }
  778. BOOL CXTPCalendarController::_HasEvents(COleDateTime dtDay)
  779. {
  780. ASSERT(m_pResourcesNf);
  781. if (!m_pResourcesNf)
  782. {
  783. return FALSE;
  784. }
  785. CXTPCalendarResources* pRCx = m_pResourcesNf->GetResourcesGroupedByDP();
  786. int nRCCount = pRCx ? pRCx->GetCount() : 0;
  787. for (int i = 0; i < nRCCount; i++)
  788. {
  789. CXTPCalendarResource* pRC = pRCx->GetAt(i);
  790. ASSERT(pRC);
  791. CXTPCalendarEventsPtr ptrEvents = pRC ? pRC->RetrieveDayEvents(dtDay) : NULL;
  792. if (ptrEvents && ptrEvents->GetCount() > 0)
  793. {
  794. return TRUE;
  795. }
  796. }
  797. return FALSE;
  798. }
  799. void CXTPCalendarController::SetCalendar(CXTPCalendarControl* pCalendarCtrl)
  800. {
  801. m_Sink.UnadviseAll();
  802. if (m_pCalendarCtrl)
  803. {
  804. m_pCalendarCtrl->InternalRelease();
  805. }
  806. m_pCalendarCtrl = pCalendarCtrl;
  807. if (m_pCalendarCtrl)
  808. {
  809. m_pCalendarCtrl->InternalAddRef();
  810. AdviseToNotifications();
  811. SetFirstDayOfWeekToDatePicker();
  812. OnEvent_CalendarThemeChanged(XTP_NC_CALENDAR_THEME_CHANGED, 0, 0);
  813. }
  814. if (m_pCalendarCtrl && m_pDatePickerCtrl)
  815. {
  816. m_eLastActiveView = -1; // to ensure update
  817. OnEvent_CalendarView(XTP_NC_CALENDARVIEWWASCHANGED, 0, 0);
  818. }
  819. }
  820. void CXTPCalendarController::SetDatePicker(CXTPDatePickerControl* pDatePickerCtrl)
  821. {
  822. m_Sink.UnadviseAll();
  823. if (m_pDatePickerCtrl)
  824. {
  825. m_pDatePickerCtrl->InternalRelease();
  826. }
  827. m_pDatePickerCtrl = pDatePickerCtrl;
  828. if (m_pDatePickerCtrl)
  829. {
  830. m_pDatePickerCtrl->InternalAddRef();
  831. m_pDatePickerCtrl->SetMaxSelCount(XTP_CALENDAR_MONTHVIEW_SHOW_WEEKS_MAX * 7);
  832. AdviseToNotifications();
  833. SetFirstDayOfWeekToDatePicker();
  834. OnEvent_CalendarThemeChanged(XTP_NC_CALENDAR_THEME_CHANGED, 0, 0);
  835. }
  836. if (m_pCalendarCtrl && m_pDatePickerCtrl)
  837. {
  838. m_eLastActiveView = -1; // to ensure update
  839. OnEvent_CalendarView(XTP_NC_CALENDARVIEWWASCHANGED, 0, 0);
  840. }
  841. }
  842. CXTPCalendarControl* CXTPCalendarController::GetCalendar() const
  843. {
  844. return m_pCalendarCtrl;
  845. }
  846. CXTPDatePickerControl* CXTPCalendarController::GetDatePicker() const
  847. {
  848. return m_pDatePickerCtrl;
  849. }
  850. void CXTPCalendarController::SetBoldDaysWithEvents(BOOL bBold)
  851. {
  852. m_bBoldDaysWithEvents = bBold;
  853. if (m_pResourcesNf && !m_bBoldDaysWithEvents)
  854. {
  855. CMDTARGET_RELEASE(m_pResourcesNf);
  856. m_eLastActiveView = -1;
  857. _UnadviseFromDataChanged();
  858. m_DayInfoCache.Clear();
  859. }
  860. }