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

对话框与窗口

开发平台:

Visual C++

  1. // XTPCalendarMonthView.cpp: implementation of the CXTPCalendarMonthView 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/XTPVC50Helpers.h"
  22. #include "XTPCalendarMonthView.h"
  23. #include "XTPCalendarControl.h"
  24. #include "XTPCalendarTheme.h"
  25. #include "XTPCalendarNotifications.h"
  26. #include "XTPCalendarOptions.h"
  27. #ifdef _DEBUG
  28. #define new DEBUG_NEW
  29. #undef THIS_FILE
  30. static char THIS_FILE[] = __FILE__;
  31. #endif
  32. #define XTP_CAL_MIDDLE_SCROLL_POS 49
  33. //////////////////////////////////////////////////////////////////////
  34. // Construction/Destruction
  35. //////////////////////////////////////////////////////////////////////
  36. IMPLEMENT_DYNAMIC(CXTPCalendarMonthView, CXTPCalendarView)
  37. CXTPCalendarMonthView::CXTPCalendarMonthView(CXTPCalendarControl* pCalendarControl) :
  38. TBase(pCalendarControl, xtpCalendarMonthView)
  39. {
  40. m_strLongDateFormat = _T("MMMM d");
  41. m_strSmallDateFormat = _T("d");
  42. m_nEventCaptionFormat = xtpCalendarCaptionFormatSubject;
  43. m_nEventTimeWidth = 0;
  44. COleDateTime dtNow = CXTPCalendarUtils::GetCurrentTime();
  45. COleDateTime dtFirst(dtNow.GetYear(), dtNow.GetMonth(), 1, 0, 0, 0);
  46. m_pGrid = new CMonthViewGrid(this);
  47. if (m_pGrid)
  48. {
  49. m_pGrid->SetWeeksCount(5);
  50. m_pGrid->SetBeginDate(dtFirst);
  51. m_pGrid->AdjustFirstDayOfWeek();
  52. m_pGrid->SetBeginDate(dtFirst);
  53. }
  54. }
  55. void CXTPCalendarMonthView::ShowDay(const COleDateTime& date, BOOL bSelect)
  56. {
  57. if (!m_pGrid)
  58. {
  59. return;
  60. }
  61. CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateAll);
  62. m_pGrid->SetBeginDate(date);
  63. Populate();
  64. UnselectAllEvents();
  65. if (bSelect)
  66. SelectDay(CXTPCalendarUtils::ResetTime(date));
  67. }
  68. CXTPCalendarMonthView::~CXTPCalendarMonthView()
  69. {
  70. if (m_pGrid)
  71. {
  72. delete m_pGrid;
  73. m_pGrid = NULL;
  74. }
  75. }
  76. void CXTPCalendarMonthView::Populate()
  77. {
  78. ASSERT(m_pGrid);
  79. if (m_pGrid)
  80. {
  81. m_pGrid->AdjustFirstDayOfWeek();
  82. TBase::Populate();
  83. }
  84. }
  85. void CXTPCalendarMonthView::AdjustLayout(CDC* pDC, const CRect& rcView, BOOL bCallPostAdjustLayout)
  86. {
  87. ASSERT(pDC);
  88. if (!m_pGrid || !pDC)
  89. {
  90. return;
  91. }
  92. TBase::AdjustLayout(pDC, rcView, FALSE);
  93. _CalculateDateFormats(pDC);
  94. _CalculateEventCaptionFormat(pDC);
  95. m_pGrid->AdjustLayout(pDC);
  96. //---------------------------------------------------------------------------
  97. if (bCallPostAdjustLayout)
  98. {
  99. OnPostAdjustLayout();
  100. }
  101. }
  102. void CXTPCalendarMonthView::AdjustLayout2(CDC* pDC, const CRect& rcView, BOOL bCallPostAdjustLayout)
  103. {
  104. if (!GetTheme())
  105. {
  106. ASSERT(FALSE);
  107. return;
  108. }
  109. TBase::AdjustLayout2(pDC, rcView, bCallPostAdjustLayout);
  110. GetTheme()->GetMonthViewPart()->AdjustLayout(pDC, rcView, bCallPostAdjustLayout);
  111. }
  112. void CXTPCalendarMonthView::ScrollV(int /*nPos*/, int nPos_raw)
  113. {
  114. if (!m_pGrid || m_bScrollV_Disabled)
  115. {
  116. return;
  117. }
  118. if (IsEditingSubject())
  119. {
  120. EndEditSubject(xtpCalendarEditSubjectCommit, FALSE);
  121. }
  122. COleDateTime dtFirst0 = m_pGrid->GetBeginDate();
  123. m_pGrid->ScrollV(nPos_raw);
  124. COleDateTime dtFirst1 = m_pGrid->GetBeginDate();
  125. if (GetSelection())
  126. {
  127. COleDateTimeSpan spShift = dtFirst1 - dtFirst0;
  128. m_selectedBlock.dtBegin += spShift;
  129. m_selectedBlock.dtEnd += spShift;
  130. CSelectionChangedContext selChanged(this, xtpCalendarSelectionDays);
  131. }
  132. UnselectAllEvents();
  133. Populate();
  134. }
  135. void CXTPCalendarMonthView::Draw2(CDC* pDC)
  136. {
  137. if (!GetTheme())
  138. {
  139. ASSERT(FALSE);
  140. return;
  141. }
  142. GetTheme()->GetMonthViewPart()->Draw(pDC);
  143. }
  144. void CXTPCalendarMonthView::Draw(CDC* pDC)
  145. {
  146. ASSERT(pDC);
  147. if (!pDC || !m_pGrid)
  148. {
  149. return;
  150. }
  151. pDC->SetBkMode(TRANSPARENT);
  152. pDC->FillSolidRect(GetViewRect(), GetSysColor(COLOR_3DFACE));
  153. m_pGrid->Draw(pDC);
  154. //-- Draw Days ------------------------------
  155. int nCount = GetViewDayCount();
  156. for (int i = 0; i < nCount; i++)
  157. {
  158. CXTPCalendarMonthViewDay* pViewDay = GetViewDay(i);
  159. ASSERT(pViewDay);
  160. if (pViewDay)
  161. {
  162. pViewDay->Draw(pDC);
  163. }
  164. }
  165. }
  166. void CXTPCalendarMonthView::_SplitDateFormat(const CString& strDateFormat, CStringArray& rarTokens)
  167. {
  168. CString strSeparators = _T(" dDmMyYgG");
  169. CString strToken;
  170. CString strCHprev;
  171. BOOL bIsPrevSeparator = FALSE;
  172. int nLength = strDateFormat.GetLength();
  173. for (int i = 0; i < nLength; i++)
  174. {
  175. CString strCH(strDateFormat[i]);
  176. if (strCH == _T("'"))
  177. {
  178. strToken += strCH;
  179. for (i++; i < nLength; i++)
  180. {
  181. strCH = strDateFormat[i];
  182. CString strCH2((i + 1 < nLength) ? strDateFormat[i+1] : _T(''));
  183. strToken += strCH;
  184. if (strCH == _T("'") && strCH2 == _T("'"))
  185. {
  186. strToken += strCH2;
  187. i++;
  188. continue;
  189. }
  190. if (strCH == _T("'"))
  191. {
  192. break;
  193. }
  194. }
  195. rarTokens.Add(strToken);
  196. strToken.Empty();
  197. strCHprev.Empty();
  198. continue;
  199. }
  200. BOOL bIsSeparator = (strSeparators.Find(strCH) >= 0);
  201. if (bIsPrevSeparator != bIsSeparator ||
  202. bIsPrevSeparator && bIsSeparator && strCH.CompareNoCase(strCHprev)
  203.   )
  204. {
  205. if (!strToken.IsEmpty())
  206. {
  207. rarTokens.Add(strToken);
  208. }
  209. strToken.Empty();
  210. }
  211. strToken += strCH;
  212. strCHprev = strCH;
  213. bIsPrevSeparator = bIsSeparator;
  214. }
  215. if (!strToken.IsEmpty())
  216. {
  217. rarTokens.Add(strToken);
  218. }
  219. }
  220. void CXTPCalendarMonthView::_ReadDefaultDateFormats()
  221. {
  222. const CString strSpecials(_T(" ,.-_=+|?/<>~`!@#$%^&*()"));
  223. CString strLongDateFormat;
  224. CString strSmallDateFormat;
  225. CString strLocaleFormat = CXTPCalendarUtils::GetLocaleString(LOCALE_SLONGDATE, 81);
  226. CStringArray arTokens;
  227. _SplitDateFormat(strLocaleFormat, arTokens);
  228. BOOL bDayAdded = FALSE;
  229. BOOL bMonthAdded = FALSE;
  230. BOOL bDateFormatTokenWas = FALSE;
  231. int nCount = (int)arTokens.GetSize();
  232. for (int i = 0; i < nCount; i++)
  233. {
  234. CString strToken = arTokens[i];
  235. if (!bDayAdded && (strToken == _T("d") || strToken == _T("dd")))
  236. {
  237. strLongDateFormat += _T("d");
  238. strSmallDateFormat += _T("d");
  239. bDayAdded = TRUE;
  240. if (i + 1 < nCount)
  241. {
  242. strLongDateFormat += arTokens[i + 1];
  243. strSmallDateFormat += arTokens[i + 1];
  244. }
  245. }
  246. if (!bMonthAdded && (strToken == _T("M") || strToken == _T("MM") ||
  247. strToken == _T("MMM") || strToken == _T("MMMM")))
  248. {
  249. strLongDateFormat += strToken;
  250. bMonthAdded = TRUE;
  251. if (i + 1 < nCount)
  252. {
  253. strLongDateFormat += arTokens[i + 1];
  254. }
  255. }
  256. if (!bDateFormatTokenWas)
  257. {
  258. if (strToken == _T("ddd") || strToken == _T("dddd") || strToken == _T("gg") ||
  259. strToken == _T("y") || strToken == _T("yy") || strToken == _T("yyyy"))
  260. {
  261. bDateFormatTokenWas = TRUE;
  262. if (!bDayAdded && !bMonthAdded)
  263. {
  264. strLongDateFormat.Empty();
  265. }
  266. if (!bDayAdded)
  267. {
  268. strSmallDateFormat.Empty();
  269. }
  270. }
  271. }
  272. if (!bDateFormatTokenWas && !bDayAdded && !bMonthAdded)
  273. {
  274. strLongDateFormat += strToken;
  275. strSmallDateFormat += strToken;
  276. }
  277. }
  278. TRIMRIGHT_S(strLongDateFormat, strSpecials);
  279. TRIMRIGHT_S(strSmallDateFormat, strSpecials);
  280. if (!bDayAdded && !bMonthAdded)
  281. {
  282. strLongDateFormat = _T("M-d");
  283. strSmallDateFormat = _T("d");
  284. }
  285. else if (!bDayAdded || !bMonthAdded)
  286. {
  287. int nLen = strLongDateFormat.GetLength();
  288. CString strCHlast = nLen ? strLongDateFormat.Right(1) : _T("");
  289. if (strCHlast.FindOneOf(strSpecials) < 0)
  290. {
  291. strLongDateFormat += _T("-");
  292. }
  293. if (!bDayAdded)
  294. {
  295. strLongDateFormat += _T("d");
  296. strSmallDateFormat = _T("d");
  297. }
  298. else
  299. {
  300. strLongDateFormat += _T("M");
  301. }
  302. }
  303. m_strDayHeaderFormatDefaultLong = strLongDateFormat;
  304. m_strDayHeaderFormatDefaultMiddle = m_strDayHeaderFormatDefaultLong;
  305. REPLACE_S(m_strDayHeaderFormatDefaultMiddle, _T("MMMM"), _T("MMM"));
  306. m_strDayHeaderFormatDefaultShort = m_strDayHeaderFormatDefaultMiddle;
  307. REPLACE_S(m_strDayHeaderFormatDefaultShort, _T("MMM"), _T("MM"));
  308. m_strDayHeaderFormatDefaultShortest = strSmallDateFormat;
  309. }
  310. void CXTPCalendarMonthView::_CalculateDateFormats(CDC* pDC)
  311. {
  312. if (!m_pGrid || !m_pControl || !GetPaintManager() || !pDC)
  313. {
  314. ASSERT(FALSE);
  315. return;
  316. }
  317. _ReadDefaultDateFormats();
  318. m_strLongDateFormat = _GetDayHeaderFormat(0);
  319. m_strSmallDateFormat = _GetDayHeaderFormat(3);
  320. CXTPCalendarViewPart* pPart = GetPaintManager()->GetMonthViewEventPart();
  321. if (!pPart)
  322. {
  323. return;
  324. }
  325. CXTPFontDC fnt(pDC, &pPart->GetTextFont());
  326. int nBorderX = pDC->GetTextExtent(_T("WW"), 2).cx;
  327. int arBorder[] = {nBorderX*3/2, nBorderX, nBorderX/2, 0};
  328. int nColsCount = max(1, m_pGrid->GetColsCount());
  329. int nCellWidth = GetViewRect().Width() / nColsCount;
  330. for (int i = 0; i <= 2; i++)
  331. {
  332. m_strLongDateFormat = _GetDayHeaderFormat(i);
  333. int nLen = _GetMaxWidth(pDC, m_strLongDateFormat);
  334. if (nLen < nCellWidth - arBorder[i])
  335. {
  336. return;
  337. }
  338. }
  339. }
  340. CString CXTPCalendarMonthView::_FormatDayDate(COleDateTime dtDay, BOOL bLong)
  341. {
  342. SYSTEMTIME st;
  343. ZeroMemory(&st, sizeof(st));
  344. CString strDate;
  345. int nDay = dtDay.GetDay();
  346. CString strFormat = (bLong || nDay == 1) ? m_strLongDateFormat : m_strSmallDateFormat;
  347. if (GETASSYSTEMTIME_DT(dtDay, st))
  348. {
  349. strDate = CXTPCalendarUtils::GetDateFormat(&st, strFormat);
  350. }
  351. if (strDate.IsEmpty())
  352. {
  353. ASSERT(FALSE);
  354. strDate.Format(_T("%d-%d"), dtDay.GetMonth(), dtDay.GetDay());
  355. }
  356. return strDate;
  357. }
  358. BOOL CXTPCalendarMonthView::GetScrollBarInfoV(SCROLLINFO* pSI)
  359. {
  360. ASSERT(pSI);
  361. if (!pSI || m_bScrollV_Disabled)
  362. {
  363. return FALSE;
  364. }
  365. pSI->nPos = m_pGrid->GetScrollPos();
  366. pSI->nMax = 105;
  367. pSI->nPage = m_pGrid->GetWeeksCount();
  368. return TRUE;
  369. }
  370. CXTPCalendarMonthViewDay* CXTPCalendarMonthView::GetViewDay(int nIndex)
  371. {
  372. if (!m_pGrid)
  373. {
  374. return NULL;
  375. }
  376. int nWeeksCount = m_pGrid->GetWeeksCount();
  377. int nCount = m_arDays.GetCount();
  378. ASSERT(nCount == nWeeksCount * 7);
  379. if (nIndex >= nWeeksCount * 7 || nIndex >= nCount)
  380. {
  381. ASSERT(FALSE);
  382. return NULL;
  383. }
  384. CXTPCalendarMonthViewDay* pDView = m_arDays.GetAt(nIndex);
  385. if (!pDView)
  386. {
  387. int nWeekIndex = nIndex / 7;
  388. int nWeekDayIndex = nIndex % 7;
  389. pDView = new CXTPCalendarMonthViewDay(this, nWeekIndex, nWeekDayIndex);
  390. m_arDays.SetAt(nIndex, pDView);
  391. }
  392. return pDView;
  393. }
  394. COleDateTime CXTPCalendarMonthView::GetViewDayDate(int nIndex)
  395. {
  396. int nWeekIndex = nIndex / 7;
  397. int nWeekDayIndex = nIndex % 7;
  398. return XTP_SAFE_GET1(m_pGrid, GetDayDate(nWeekIndex, nWeekDayIndex), (DATE)0);
  399. }
  400. void CXTPCalendarMonthView::_CalculateEventCaptionFormat(CDC* pDC)
  401. {
  402. if (!m_pGrid || !m_pControl || !GetPaintManager() || !pDC)
  403. {
  404. ASSERT(FALSE);
  405. return;
  406. }
  407. BOOL bShowEnd = m_pControl->MonthView_IsShowEndDate();
  408. BOOL bShowAsClocks = m_pControl->MonthView_IsShowTimeAsClocks();
  409. CXTPCalendarViewPart* pPart = GetPaintManager()->GetMonthViewEventPart();
  410. if (!pPart)
  411. {
  412. return;
  413. }
  414. CXTPFontDC fnt(pDC, &pPart->GetTextFont());
  415. //--------------------
  416. CSize szW = pDC->GetTextExtent(_T(" "), 1);
  417. int nColsCount = max(1, m_pGrid->GetColsCount());
  418. int nCellWidth = GetViewRect().Width() / nColsCount;
  419. int nTimeWithMax = (nCellWidth - szW.cx * 2)/2;
  420. //--------------------
  421. m_nEventCaptionFormat = bShowEnd ? xtpCalendarCaptionFormatStartEndSubject : xtpCalendarCaptionFormatStartSubject;
  422. m_nEventTimeWidth = (GetPaintManager()->GetClockSize().cx + szW.cx);
  423. if (!bShowAsClocks)
  424. {
  425. CString strTime = GetItemTextEventTimeMax();
  426. m_nEventTimeWidth = pDC->GetTextExtent(strTime).cx + szW.cx;
  427. m_nEventTimeWidth = min(m_nEventTimeWidth, max(0, nCellWidth - 5));
  428. }
  429. if (bShowEnd)
  430. {
  431. m_nEventTimeWidth *= 2;
  432. }
  433. if (m_nEventTimeWidth > nTimeWithMax && m_nEventCaptionFormat == xtpCalendarCaptionFormatStartEndSubject)
  434. {
  435. m_nEventCaptionFormat = xtpCalendarCaptionFormatStartSubject;
  436. m_nEventTimeWidth /= 2;
  437. }
  438. if (m_nEventTimeWidth > nTimeWithMax)
  439. {
  440. m_nEventCaptionFormat = xtpCalendarCaptionFormatSubject;
  441. m_nEventTimeWidth = 0;
  442. }
  443. DWORD dwOpt = XTP_SAFE_GET2(GetCalendarControl(), GetCalendarOptions(), dwAdditionalOptions, 0);
  444. if (dwOpt & xtpCalendarOptMonthViewShowStartTimeAlways)
  445. m_nEventCaptionFormat = xtpCalendarCaptionFormatStartSubject;
  446. if (bShowEnd && (dwOpt & xtpCalendarOptMonthViewShowEndTimeAlways))
  447. m_nEventCaptionFormat = xtpCalendarCaptionFormatStartEndSubject;
  448. }
  449. BOOL CXTPCalendarMonthView::OnLButtonDown(UINT nFlags, CPoint point)
  450. {
  451. if (GetTheme() && GetTheme()->GetMonthViewPart())
  452. if (GetTheme()->GetMonthViewPart()->OnLButtonDown(this, nFlags, point))
  453. return TRUE;
  454. return TBase::OnLButtonDown(nFlags, point);
  455. }
  456. void CXTPCalendarMonthView::OnMouseMove(UINT nFlags, CPoint point)
  457. {
  458. if (GetTheme() && GetTheme()->GetMonthViewPart())
  459. GetTheme()->GetMonthViewPart()->OnMouseMove(this, nFlags, point);
  460. TBase::OnMouseMove(nFlags, point);
  461. }
  462. void CXTPCalendarMonthView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  463. {
  464. CSelectionChangedContext selChanged(this);
  465. TBase::OnKeyDown(nChar, nRepCnt, nFlags);
  466. if (nChar == VK_LEFT || nChar == VK_RIGHT || nChar == VK_UP || nChar == VK_DOWN ||
  467. nChar == VK_PRIOR || nChar == VK_NEXT)
  468. {
  469. CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateRedraw);
  470. BOOL bVKShift = !!(GetKeyState(VK_SHIFT) & 0x8000);
  471. COleDateTimeSpan spDay(1, 0, 0, 0);
  472. COleDateTimeSpan spWeek(7, 0, 0, 0);
  473. COleDateTimeSpan spPage(GetViewDayCount(), 0, 0, 0);
  474. int nDVCount = GetViewDayCount();
  475. BOOL bSelReseted = m_selectedBlock.dtEnd.GetStatus() != COleDateTime::valid;
  476. COleDateTime dtLastSelDay = GetLastSelectedDate();
  477. COleDateTime dtNewSelDay = dtLastSelDay;
  478. CXTPDrawHelpers::KeyToLayout(m_pControl, nChar);
  479. if (nChar == VK_LEFT)
  480. {
  481. dtNewSelDay -= spDay;
  482. }
  483. else
  484. if (nChar == VK_RIGHT)
  485. {
  486. dtNewSelDay += spDay;
  487. }
  488. else
  489. if (nChar == VK_UP)
  490. {
  491. dtNewSelDay -= spWeek;
  492. }
  493. else
  494. if (nChar == VK_DOWN)
  495. {
  496. dtNewSelDay += spWeek;
  497. }
  498. else
  499. if (nChar == VK_PRIOR)
  500. {
  501. dtNewSelDay -= spPage;
  502. }
  503. else
  504. if (nChar == VK_NEXT)
  505. {
  506. dtNewSelDay += spPage;
  507. }
  508. //---------------------------------------------------------------------------
  509. COleDateTime dtFirstDay = GetViewDayDate(0);
  510. COleDateTime dtLastDay = GetViewDayDate(nDVCount-1);
  511. BOOL bNeedScroll = dtNewSelDay < dtFirstDay || dtNewSelDay > dtLastDay;
  512. if (bNeedScroll && !m_bScrollV_Disabled)
  513. {
  514. CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateAll);
  515. if (m_pGrid)
  516. {
  517. m_pGrid->SetBeginDate(dtNewSelDay);
  518. Populate();
  519. bSelReseted = TRUE;
  520. }
  521. }
  522. //---------------------------------------------------------------------------
  523. if (!bNeedScroll || !m_bScrollV_Disabled)
  524. {
  525. if (bVKShift && !bSelReseted)
  526. {
  527. SelectDays(dtNewSelDay);
  528. }
  529. else
  530. {
  531. UnselectAllEvents();
  532. SelectDay(dtNewSelDay);
  533. }
  534. }
  535. }
  536. }
  537. /////////////////////////////////////////////////////////////////////////////
  538. //class CXTPCalendarMonthView::CMonthViewGrid
  539. CXTPCalendarMonthView::CMonthViewGrid::CMonthViewGrid(CXTPCalendarMonthView* pView)
  540. {
  541. m_pView = pView;
  542. m_dtBeginDate.SetStatus(COleDateTime::null);
  543. m_nWeeksCount = 0;
  544. SetWeeksCount(5);
  545. m_nColHeaderHeight = 18;
  546. m_nFirstDayOfWeekIndex = 2;     // 1 = Sunday, 2 = Monday ...
  547. }
  548. CXTPCalendarMonthView::CMonthViewGrid::~CMonthViewGrid()
  549. {
  550. }
  551. COleDateTime CXTPCalendarMonthView::CMonthViewGrid::GetMiddleScrollBeginDate()
  552. {
  553. COleDateTime dtNow = CXTPCalendarUtils::GetCurrentTime();
  554. COleDateTime dtFirst(dtNow.GetYear(), dtNow.GetMonth(), 1, 0, 0, 0);
  555. COleDateTime dtMiddle = ShiftDateToCell_00(dtFirst);
  556. return dtMiddle;
  557. }
  558. int CXTPCalendarMonthView::CMonthViewGrid::GetScrollPos()
  559. {
  560. COleDateTime dtMiddle = GetMiddleScrollBeginDate();
  561. COleDateTime dtBegin = GetBeginDate();
  562. COleDateTimeSpan spPos = dtBegin - dtMiddle;
  563. int nDays = (int)spPos.GetTotalDays();
  564. ASSERT(nDays % 7 == 0);
  565. int nPos = nDays/7 + XTP_CAL_MIDDLE_SCROLL_POS;
  566. return nPos;
  567. }
  568. void CXTPCalendarMonthView::CMonthViewGrid::ScrollV(int nPos)
  569. {
  570. COleDateTimeSpan    spScroll((nPos - XTP_CAL_MIDDLE_SCROLL_POS)*7, 0, 0, 0);
  571. COleDateTime dtMiddle = GetMiddleScrollBeginDate();
  572. COleDateTime dtScrolled_00 = dtMiddle + spScroll;
  573. SetBeginDate(dtScrolled_00);
  574. }
  575. COleDateTime CXTPCalendarMonthView::CMonthViewGrid::ShiftDateToCell_00(COleDateTime dtDate)
  576. {
  577. dtDate = CXTPCalendarUtils::ResetTime(dtDate);
  578. int nShift = (dtDate.GetDayOfWeek() - m_nFirstDayOfWeekIndex + 7) % 7;
  579. if (nShift)
  580. {
  581. COleDateTimeSpan spShift(nShift, 0, 0, 0);
  582. dtDate -= spShift;
  583. }
  584. return dtDate;
  585. }
  586. void CXTPCalendarMonthView::CMonthViewGrid::SetWeeksCount(int nWeeks)
  587. {
  588. ASSERT(nWeeks >= XTP_CALENDAR_MONTHVIEW_SHOW_WEEKS_MIN);
  589. ASSERT(nWeeks <= XTP_CALENDAR_MONTHVIEW_SHOW_WEEKS_MAX);
  590. ASSERT(m_pView);
  591. if (!m_pView)
  592. {
  593. return;
  594. }
  595. if (m_nWeeksCount != nWeeks)
  596. {
  597. if (m_pView->IsEditingSubject())
  598. {
  599. m_pView->EndEditSubject(xtpCalendarEditSubjectCommit, FALSE);
  600. }
  601. }
  602. m_nWeeksCount = max(nWeeks, XTP_CALENDAR_MONTHVIEW_SHOW_WEEKS_MIN);
  603. m_nWeeksCount = min(m_nWeeksCount, XTP_CALENDAR_MONTHVIEW_SHOW_WEEKS_MAX);
  604. int nDaysCount = m_nWeeksCount * 7;
  605. int nCount = (int)m_pView->m_arDays.GetCount();
  606. if (nDaysCount != nCount)
  607. {
  608. m_pView->m_arDays.SetSize(nDaysCount);
  609. CXTPCalendarControl::CViewChangedContext viewChanged(m_pView);
  610. }
  611. }
  612. COleDateTime CXTPCalendarMonthView::CMonthViewGrid::GetDayDate(int nWeekIndex, int nWeekDayIndex) const
  613. {
  614. ASSERT(nWeekIndex >= 0 && nWeekIndex < m_nWeeksCount);
  615. ASSERT(nWeekDayIndex >= 0 && nWeekDayIndex < 7);
  616. int nDayIndex = nWeekIndex * 7 + nWeekDayIndex;
  617. COleDateTimeSpan spShift(nDayIndex, 0, 0, 0);
  618. COleDateTime dtDay = m_dtBeginDate + spShift;
  619. return dtDay;
  620. }
  621. CRect CXTPCalendarMonthView::CMonthViewGrid::GetDayRect(int nWeekIndex, int nWeekDayIndex, BOOL bIncludeBorders) const
  622. {
  623. BOOL bCompressWeD = XTP_SAFE_GET2(m_pView, GetCalendarControl(), MonthView_IsCompressWeekendDays(), FALSE);
  624. COleDateTime dtDate = GetDayDate(nWeekIndex, nWeekDayIndex);
  625. int nWDay = dtDate.GetDayOfWeek();
  626. int nColIdx = nWeekDayIndex;
  627. int nCompressedColIdx = 7 - m_nFirstDayOfWeekIndex;
  628. if (bCompressWeD && nColIdx > nCompressedColIdx)
  629. {
  630. nColIdx--;
  631. }
  632. CRect rcDay(0, 0, 0, 0);
  633. rcDay.left = m_arColsLeftX[nColIdx];
  634. rcDay.right = m_arColsLeftX[nColIdx + 1];
  635. int nHalfHeight = (m_arRowsTopY[nWeekIndex + 1] - m_arRowsTopY[nWeekIndex]) / 2;
  636. if (bCompressWeD && nWDay == 7)
  637. {
  638. rcDay.top = m_arRowsTopY[nWeekIndex];
  639. rcDay.bottom = rcDay.top + nHalfHeight;
  640. }
  641. else
  642. if (bCompressWeD && nWDay == 1)
  643. {
  644. rcDay.top = m_arRowsTopY[nWeekIndex] + nHalfHeight;
  645. rcDay.bottom = m_arRowsTopY[nWeekIndex + 1];
  646. }
  647. else
  648. {
  649. rcDay.top = m_arRowsTopY[nWeekIndex];
  650. rcDay.bottom = m_arRowsTopY[nWeekIndex + 1];
  651. }
  652. if (!bIncludeBorders)
  653. {
  654. rcDay.DeflateRect(1, 1, 0, 0);
  655. }
  656. return rcDay;
  657. }
  658. CRect CXTPCalendarMonthView::CMonthViewGrid::GetCelRect(int nWeekIndex, int nColIndex, BOOL bIncludeBorders) const
  659. {
  660. CRect rcCell(0, 0, 0, 0);
  661. rcCell.left = m_arColsLeftX[nColIndex];
  662. rcCell.right = m_arColsLeftX[nColIndex + 1];
  663. rcCell.top = m_arRowsTopY[nWeekIndex];
  664. rcCell.bottom = m_arRowsTopY[nWeekIndex + 1];
  665. if (!bIncludeBorders)
  666. {
  667. rcCell.DeflateRect(1, 1, 0, 0);
  668. }
  669. return rcCell;
  670. }
  671. int CXTPCalendarMonthView::CMonthViewGrid::GetColsCount() const
  672. {
  673. BOOL bCompressWeD = XTP_SAFE_GET2(m_pView, GetCalendarControl(), MonthView_IsCompressWeekendDays(), FALSE);
  674. int nColsCount = bCompressWeD ? 6 : 7;
  675. return nColsCount;
  676. }
  677. int CXTPCalendarMonthView::CMonthViewGrid::GetWeekDayCol(int nWeekDayIndex) const
  678. {
  679. BOOL bCompressWeD = XTP_SAFE_GET2(m_pView, GetCalendarControl(), MonthView_IsCompressWeekendDays(), FALSE);
  680. int nCompressedColIdx = 7 - m_nFirstDayOfWeekIndex;
  681. int nColIdx = (nWeekDayIndex - m_nFirstDayOfWeekIndex + 7) % 7;
  682. if (bCompressWeD && nColIdx > nCompressedColIdx)
  683. {
  684. nColIdx--;
  685. }
  686. return nColIdx;
  687. }
  688. int CXTPCalendarMonthView::CMonthViewGrid::GetWeekDayForColIndex(int nColIdx) const
  689. {
  690. BOOL bCompressWeD = XTP_SAFE_GET2(m_pView, GetCalendarControl(), MonthView_IsCompressWeekendDays(), FALSE);
  691. int nCompressedColIdx = 7 - m_nFirstDayOfWeekIndex;
  692. if (bCompressWeD && nColIdx == nCompressedColIdx)
  693. {
  694. return 7;
  695. }
  696. if (bCompressWeD && nColIdx > nCompressedColIdx)
  697. {
  698. nColIdx++;
  699. }
  700. int nWeekDayIndex = (m_nFirstDayOfWeekIndex - 1 + nColIdx) % 7 + 1;
  701. return nWeekDayIndex;
  702. }
  703. int CXTPCalendarMonthView::CMonthViewGrid::GetColHeaderHeight() const
  704. {
  705. return m_nColHeaderHeight;
  706. }
  707. void CXTPCalendarMonthView::CMonthViewGrid::SetColHeaderHeight(int nHeight)
  708. {
  709. m_nColHeaderHeight = nHeight;
  710. }
  711. CXTPCalendarMonthViewDay* CXTPCalendarMonthView::CMonthViewGrid::GetViewDay(int nWeekIndex, int nWeekDayIndex)
  712. {
  713. int nIdx = nWeekIndex * 7 + nWeekDayIndex;
  714. return XTP_SAFE_GET1(m_pView, GetViewDay(nIdx), NULL);
  715. }
  716. void CXTPCalendarMonthView::CMonthViewGrid::AdjustFirstDayOfWeek()
  717. {
  718. BOOL bCompressWeD = XTP_SAFE_GET2(m_pView, GetCalendarControl(), MonthView_IsCompressWeekendDays(), FALSE);
  719. int nFDPrev = m_nFirstDayOfWeekIndex;
  720. //- Adjust First day of Week ------------------------------------------
  721. m_nFirstDayOfWeekIndex = XTP_SAFE_GET2(m_pView, GetCalendarControl(), GetFirstDayOfWeek(), 2);
  722. if (bCompressWeD && m_nFirstDayOfWeekIndex == 1)
  723. {
  724. m_nFirstDayOfWeekIndex = 2;
  725. }
  726. int nDShift = m_nFirstDayOfWeekIndex - nFDPrev;
  727. COleDateTime dtBeginDate = GetDayDate(0, 0);
  728. dtBeginDate += COleDateTimeSpan(nDShift);
  729. SetBeginDate(dtBeginDate);
  730. }
  731. void CXTPCalendarMonthView::CMonthViewGrid::SetBeginDate(COleDateTime dtBeginDate)
  732. {
  733. CXTPCalendarControl::CViewChangedContext viewChanged(m_pView);
  734. m_dtBeginDate = ShiftDateToCell_00(dtBeginDate);
  735. }
  736. void CXTPCalendarMonthView::GetWeekDayTextIfNeed(CString* pstrText, int nWeekDay)
  737. {
  738. ASSERT(nWeekDay >= 1 && nWeekDay <= 7);
  739. if (!pstrText)
  740. {
  741. ASSERT(FALSE);
  742. return;
  743. }
  744. DWORD dwFlags = XTP_SAFE_GET1(GetCalendarControl(), GetAskItemTextFlags(), 0);
  745. if (dwFlags & xtpCalendarItemText_MonthViewWeekDayHeader)
  746. {
  747. XTP_CALENDAR_GETITEMTEXT_PARAMS objRequest;
  748. ::ZeroMemory(&objRequest, sizeof(objRequest));
  749. objRequest.nItem = xtpCalendarItemText_MonthViewWeekDayHeader;
  750. objRequest.pstrText = pstrText;
  751. objRequest.nWeekDay = nWeekDay;
  752. XTP_SAFE_CALL1(GetCalendarControl(), SendNotificationAlways(XTP_NC_CALENDAR_GETITEMTEXT, (WPARAM)&objRequest, 0));
  753. }
  754. }
  755. void CXTPCalendarMonthView::CMonthViewGrid::AdjustHeader(CDC* pDC)
  756. {
  757. CXTPCalendarViewPart* pPart = XTP_SAFE_GET2(m_pView, GetPaintManager(), GetMonthViewHeaderPart(), NULL);
  758. if (!m_pView || !m_pView->GetCalendarControl() || !pPart || !pDC)
  759. {
  760. ASSERT(FALSE);
  761. return;
  762. }
  763. CXTPFontDC fnt(pDC, &pPart->GetTextFont());
  764. int nColsCount = max(1, GetColsCount());
  765. int nCellWidth = m_pView->GetViewRect().Width() / nColsCount;
  766. //-- Calc header settings -----------------------------------------
  767. LCTYPE LC_WeekDAYNAME1 = LOCALE_SDAYNAME1;
  768. int nHWithMax = 0;
  769. int i;
  770. for (i = 0; i < 7; i++)
  771. {
  772. CString sWD = CXTPCalendarUtils::GetLocaleString(LC_WeekDAYNAME1 + i, 100);
  773. nHWithMax = max(nHWithMax, pDC->GetTextExtent(sWD).cx);
  774. }
  775. int nSpace = pDC->GetTextExtent(_T("Ww"), 2).cx * 2;
  776. if (nHWithMax + nSpace > nCellWidth)
  777. {
  778. LC_WeekDAYNAME1 = LOCALE_SABBREVDAYNAME1;
  779. }
  780. //---------------------------------------------------------------------------
  781. m_arColHeaderText.RemoveAll();
  782. m_arColHeaderText.SetSize(7);
  783. CString strHearderTest = _T("/");
  784. for (i = 0; i < 7; i++)
  785. {
  786. CString sWD = CXTPCalendarUtils::GetLocaleString(LC_WeekDAYNAME1 + i, 100);
  787. int nCol = GetWeekDayCol((i + 2) % 7);
  788. CString sVal = m_arColHeaderText[nCol];
  789. if (!sVal.IsEmpty())
  790. {
  791. // compressed col - always Sat/Sun
  792. CString sSat = CXTPCalendarUtils::GetLocaleString(LOCALE_SABBREVDAYNAME6, 100);
  793. CString sSun = CXTPCalendarUtils::GetLocaleString(LOCALE_SABBREVDAYNAME7, 100);
  794. m_arColHeaderText[nCol] = sSat + _T("/") + sSun;
  795. strHearderTest += sWD;
  796. }
  797. else
  798. {
  799. m_arColHeaderText[nCol] += sWD;
  800. strHearderTest += sWD;
  801. }
  802. }
  803. //-------------------------------------------
  804. CSize sizeH = pDC->GetTextExtent(strHearderTest);
  805. m_nColHeaderHeight = max(18, sizeH.cy + 6);
  806. m_pView->m_Layout.m_nRowHeight = m_nColHeaderHeight;
  807. }
  808. void CXTPCalendarMonthView::CMonthViewGrid::AdjustDays(CDC* pDC)
  809. {
  810. ASSERT(pDC);
  811. if (!pDC)
  812. {
  813. return;
  814. }
  815. int nWeeksCount = m_nWeeksCount;
  816. for (int nWeek = 0; nWeek < nWeeksCount; nWeek++)
  817. {
  818. for (int nDayIdx = 0; nDayIdx < 7; nDayIdx++)
  819. {
  820. CRect rcDay = GetDayRect(nWeek, nDayIdx, TRUE);
  821. CXTPCalendarMonthViewDay* pViewDay = GetViewDay(nWeek, nDayIdx);
  822. //----------------------------------------
  823. if (pViewDay)
  824. pViewDay->AdjustLayout(pDC, rcDay);
  825. }
  826. }
  827. }
  828. void CXTPCalendarMonthView::CMonthViewGrid::AdjustEvents(CDC* pDC)
  829. {
  830. ASSERT(pDC);
  831. if (!pDC)
  832. {
  833. return;
  834. }
  835. BOOL bCompressWeD = XTP_SAFE_GET2(m_pView, GetCalendarControl(), MonthView_IsCompressWeekendDays(), FALSE);
  836. int nSundayIdx = (7 - m_nFirstDayOfWeekIndex + 1) % 7;
  837. CXTPCalendarMonthViewDay* pViewDay;
  838. int nWeeksCount = m_nWeeksCount;
  839. for (int nWeek = 0; nWeek < nWeeksCount; nWeek++)
  840. {
  841. int nDayIdx;
  842. // Adjust Begin/End for multiday events
  843. for (nDayIdx = 0; nDayIdx < 7; nDayIdx++)
  844. {
  845. // go through all days to look for multiday events
  846. pViewDay = GetViewDay(nWeek, nDayIdx);
  847. ASSERT(pViewDay);
  848. if (!pViewDay)
  849. {
  850. continue;
  851. }
  852. ASSERT(pViewDay->GetViewGroupsCount() == 1);
  853. int nEventsCount = 0; //pViewDay->GetViewEventsCount();
  854. if (pViewDay->GetViewGroupsCount())
  855. {
  856. nEventsCount = XTP_SAFE_GET2(pViewDay, GetViewGroup_(0), GetViewEventsCount(), 0);
  857. }
  858. for (int nEvent = 0; nEvent < nEventsCount; nEvent++)
  859. {
  860. CXTPCalendarMonthViewEvent* pViewEvent = XTP_SAFE_GET2(pViewDay, GetViewGroup(0), GetViewEvent(nEvent), NULL );//pViewDay->GetViewEvent(nEvent);
  861. ASSERT(pViewEvent);
  862. if (!pViewEvent)
  863. {
  864. continue;
  865. }
  866. int nMDEFlags = pViewEvent->GetMultiDayEventFlags();
  867. if ((nMDEFlags & xtpCalendarMultiDayMSmask) || !(nMDEFlags & xtpCalendarMultiDayFMLmask))
  868. {
  869. continue; // already marked or not multiday
  870. }
  871. //------------------------
  872. BOOL bLast = (nMDEFlags & xtpCalendarMultiDayLast) != 0;
  873. pViewEvent->SetMultiDayEvent_MasterSlave(TRUE, NULL);
  874. int nMasterPlace = pViewEvent->GetEventPlaceNumber();
  875. if (!bLast && (nDayIdx != nSundayIdx || !bCompressWeD))
  876. {
  877. // find other visible instances and mark them as Slave
  878. for (int i = nDayIdx + 1; i < 7; i++)
  879. {
  880. if (i == nSundayIdx && bCompressWeD)
  881. {
  882. break; //continue; // skip compressed sunday
  883. }
  884. CXTPCalendarMonthViewDay* pViewDay2 = GetViewDay(nWeek, i);
  885. CXTPCalendarViewEvent* pViewEvent2 = NULL;
  886. ASSERT(XTP_SAFE_GET1(pViewDay2, GetViewGroupsCount(), 0) == 1);
  887. if (XTP_SAFE_GET1(pViewDay2, GetViewGroupsCount(), 0))
  888. {
  889. pViewEvent2 = XTP_SAFE_GET2(pViewDay2, GetViewGroup_(0),
  890. GetViewEventByEvent_(pViewEvent->GetEvent()), NULL);
  891. }
  892. if (!pViewEvent2)
  893. {
  894. break;
  895. }
  896. pViewEvent->AddMultiDayEvent_Slave(pViewEvent2, nMasterPlace);
  897. if (!pViewEvent2->IsVisible())
  898. {
  899. break;
  900. }
  901. }
  902. }
  903. }
  904. }
  905. }
  906. }
  907. void CXTPCalendarMonthView::CMonthViewGrid::AdjustGrid(const CRect& rcRect)
  908. {
  909. //-------------------------------------------
  910. int nColsCount = GetColsCount();
  911. int nWidth = rcRect.Width(); // m_pView->GetViewRect().Width();
  912. int nHeight = rcRect.Height(); //max(0, m_pView->GetViewRect().Height() - m_nColHeaderHeight);
  913. m_arRowsTopY.SetSize(m_nWeeksCount + 1);
  914. m_arColsLeftX.SetSize(nColsCount + 1);
  915. int nCurrPos = rcRect.top; //m_nColHeaderHeight;
  916. for (int nWeek = 0; nWeek < m_nWeeksCount; nWeek++)
  917. {
  918. m_arRowsTopY[nWeek] = nCurrPos;
  919. int nHeightRow = nHeight / (m_nWeeksCount - nWeek);
  920. nCurrPos += nHeightRow;
  921. nHeight -= nHeightRow;
  922. }
  923. m_arRowsTopY[m_nWeeksCount] = nCurrPos;
  924. nCurrPos = rcRect.left; //0;
  925. for (int nDayColl = 0; nDayColl < nColsCount; nDayColl++)
  926. {
  927. m_arColsLeftX[nDayColl] = nCurrPos;
  928. int nWidthRow = nWidth / (nColsCount - nDayColl);
  929. nCurrPos += nWidthRow;
  930. nWidth -= nWidthRow;
  931. }
  932. m_arColsLeftX[nColsCount] = nCurrPos;
  933. }
  934. void CXTPCalendarMonthView::CMonthViewGrid::AdjustLayout(CDC* pDC)
  935. {
  936. ASSERT(pDC);
  937. ASSERT(m_pView);
  938. if (!m_pView || !pDC)
  939. {
  940. return;
  941. }
  942. AdjustHeader(pDC);
  943. //------------------------------------------------------------------
  944. CRect rcGrid = m_pView->GetViewRect();
  945. rcGrid.top = min(rcGrid.top + m_nColHeaderHeight, rcGrid.bottom);
  946. AdjustGrid(rcGrid);
  947. //------------------------------------------------------------------
  948. //------------------------------------------------------
  949. AdjustDays(pDC);
  950. AdjustEvents(pDC);
  951. }
  952. void CXTPCalendarMonthView::CMonthViewGrid::Draw(CDC* pDC)
  953. {
  954. //-- Draw Header -------------------------------
  955. int nColsCount = GetColsCount();
  956. for (int nCol = 0; nCol < nColsCount; nCol++)
  957. {
  958. CRect rcCell = GetCelRect(0, nCol, TRUE);
  959. rcCell.top = m_pView->m_rcView.top;
  960. rcCell.bottom = rcCell.top + m_nColHeaderHeight;
  961. CString strWD = m_arColHeaderText[nCol];
  962. int nWeekDay = GetWeekDayForColIndex(nCol);
  963. m_pView->GetWeekDayTextIfNeed(&strWD, nWeekDay);
  964. XTP_SAFE_CALL3(m_pView, GetPaintManager(), GetMonthViewHeaderPart(),
  965. OnDraw(pDC, m_pView, rcCell, nCol, strWD));
  966. }
  967. //-- Draw Grid Lines and fill background -------
  968. XTP_SAFE_CALL3(m_pView, GetPaintManager(), GetMonthViewGridPart(),
  969. OnDrawGrid(pDC, m_pView));
  970. }