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

对话框与窗口

开发平台:

Visual C++

  1. // XTPCalendarDayView.cpp: implementation of the CXTPCalendarDayView 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 "XTPCalendarData.h"
  22. #include "XTPCalendarDayView.h"
  23. #include "XTPCalendarDayViewTimeScale.h"
  24. #include "XTPCalendarUtils.h"
  25. #include "XTPCalendarPaintManager.h"
  26. #include "XTPCalendarTheme.h"
  27. #include "XTPCalendarThemeOffice2007.h"
  28. #include "XTPCalendarControl.h"
  29. #include "XTPCalendarRecurrencePattern.h"
  30. #include "XTPCalendarNotifications.h"
  31. #include "Common/XTPDrawHelpers.h"
  32. #include "Common/XTPVC50Helpers.h"
  33. #include <math.h>
  34. #ifdef _DEBUG
  35. #undef THIS_FILE
  36. static char THIS_FILE[] = __FILE__;
  37. #define new DEBUG_NEW
  38. #endif
  39. #define XTP_SCROLL_TIMER_RESOLUTION_MS  30
  40. #define XTP_REDRAW_TIMER_RESOLUTION_MS  2000
  41. //////////////////////////////////////////////////////////////////////
  42. // Construction/Destruction
  43. //////////////////////////////////////////////////////////////////////
  44. IMPLEMENT_DYNAMIC(CXTPCalendarDayView, CXTPCalendarView)
  45. CXTPCalendarDayView::CXTPCalendarDayView(CXTPCalendarControl* pCalendarControl) :
  46. TBase(pCalendarControl, xtpCalendarDayView),
  47. m_ptLastMousePos(0, 0)
  48. {
  49. m_pTimeScaleHeader = new CXTPCalendarDayViewTimeScale(this);
  50. m_pTimeScaleHeader2 = new CXTPCalendarDayViewTimeScale(this, FALSE, FALSE);
  51. m_LayoutX.m_nRowCount = 0;
  52. m_LayoutX.m_nVisibleRowCount = 0;
  53. m_LayoutX.m_nTopRow = 0;
  54. m_LayoutX.m_rcAllDayEvents.SetRectEmpty();
  55. m_LayoutX.m_rcDayHeader.SetRectEmpty();
  56. m_LayoutX.m_nAllDayEventsCountMax = 0;
  57. m_LayoutX.m_nAllDayEventHeight = 0;
  58. m_nAllDayEventsCountMin_WhenDrag = 0;
  59. m_spDraggingStartOffset_Time = 0.;
  60. m_nScrollOffsetX = 0;
  61. m_nMinColumnWidth = -1; // 0 - means disabled; -1 use auto for multiresources; -X use for multiresources only; +X used always (in single and multi resources mode).
  62. // add today to the day view by default
  63. COleDateTime dtNow(CXTPCalendarUtils::GetCurrentTime());
  64. m_arDays.Add(new CXTPCalendarDayViewDay(this, dtNow));
  65. // go to the beginning of the work day
  66. int nHour = 0, nMin = 0, nSec = 0;
  67. XTP_SAFE_CALL1(m_pControl, GetWorkDayStartTime(nHour, nMin, nSec));
  68. int nPos = GetCellNumber(nHour, nMin, nSec, FALSE);
  69. _ScrollV(nPos, nPos);
  70. m_dwScrollingEventTimerID = 0;
  71. m_bMouseOutOfDragArea = FALSE;
  72. m_dtDraggingStartPoint = COleDateTime(0, 0, 0, 0, 0, 0);
  73. m_dwRedrawNowLineTimerID = 0;
  74. m_dtLastRedrawTime = CXTPCalendarUtils::GetCurrentTime();
  75. m_ptLBtnDownMousePos = CPoint(0,0);
  76. }
  77. CXTPCalendarDayView::~CXTPCalendarDayView()
  78. {
  79. CMDTARGET_RELEASE(m_pTimeScaleHeader);
  80. CMDTARGET_RELEASE(m_pTimeScaleHeader2);
  81. ClearDays();
  82. }
  83. XTPCalendarViewType CXTPCalendarDayView::GetViewType()
  84. {
  85. int nWWMask = m_pControl ? m_pControl->GetWorkWeekMask() : xtpCalendarDayMo_Fr;
  86. int nDaysCount = GetViewDayCount();
  87. int nWWCount = CXTPCalendarUtils::GetDayOfWeekCount(nWWMask);
  88. if (nDaysCount != nWWCount && nDaysCount != 7)
  89. {
  90. return xtpCalendarDayView;
  91. }
  92. int nFirstDayOfWeek = m_pControl ? m_pControl->GetFirstDayOfWeek() : xtpCalendarDayMonday;
  93. int nNextWWeekIdx = CXTPCalendarUtils::GetDayOfWeekIndex(nFirstDayOfWeek);
  94. BOOL bWDOrderFull = TRUE;
  95. int nViewType = xtpCalendarWorkWeekView;
  96. for (int i = 0; i < nDaysCount; i++)
  97. {
  98. COleDateTime dtDay = GetViewDayDate(i);
  99. int nDayOfWeek = dtDay.GetDayOfWeek();
  100. int nDayMask = CXTPCalendarUtils::GetDayOfWeekMask(nDayOfWeek);
  101. if ((nWWMask & nDayMask) == 0)
  102. {
  103. nViewType = xtpCalendarDayView;
  104. }
  105. if (nNextWWeekIdx != nDayOfWeek)
  106. bWDOrderFull = FALSE;
  107. nNextWWeekIdx = (nNextWWeekIdx % 7) + 1;
  108. }
  109. if (nDaysCount == 7 && bWDOrderFull)
  110. nViewType = xtpCalendarFullWeekView;
  111. return (XTPCalendarViewType)nViewType;
  112. }
  113. void CXTPCalendarDayView::ClearDays()
  114. {
  115. m_arDays.RemoveAll();
  116. }
  117. COleDateTime CXTPCalendarDayView::GetCellTime(int nCell) const
  118. {
  119. double dblTime = (long)nCell * (double)GetCellDuration();
  120. return (DATE)dblTime;
  121. }
  122. COleDateTimeSpan CXTPCalendarDayView::GetCellDuration() const
  123. {
  124. return m_pTimeScaleHeader ? m_pTimeScaleHeader->GetScaleInterval() : (double)0;
  125. }
  126. int CXTPCalendarDayView::GetCellNumber(COleDateTime dtTime, BOOL bForEndTime) const
  127. {
  128. double dblTime = (double)CXTPCalendarUtils::ResetDate(dtTime);
  129. double dblEpsilon = XTP_HALF_SECOND * (bForEndTime ? -1 : 1);
  130. double dblCellDur = (double)GetCellDuration();
  131. if (dblCellDur <= XTP_HALF_SECOND)
  132. {
  133. dblCellDur = XTP_HALF_SECOND * 2 * 60 * 30;
  134. }
  135. int nCell = int(dblTime / dblCellDur + dblEpsilon);
  136. return nCell;
  137. }
  138. int CXTPCalendarDayView::GetCellNumber(int nHour, int nMin, int nSec, BOOL bForEndTime) const
  139. {
  140. COleDateTime dtTime;
  141. dtTime.SetTime(nHour, nMin, nSec);
  142. return GetCellNumber(dtTime, bForEndTime);
  143. }
  144. void CXTPCalendarDayView::ScrollV(int nIndex, int nPos_raw)
  145. {
  146. if (m_bScrollV_Disabled)
  147. {
  148. return;
  149. }
  150. _ScrollV(nIndex, nPos_raw);
  151. }
  152. void CXTPCalendarDayView::_ScrollV(int nIndex, int /*nPos_raw*/)
  153. {
  154. if (nIndex + m_LayoutX.m_nVisibleRowCount >= m_LayoutX.m_nRowCount)
  155. {
  156. nIndex = m_LayoutX.m_nRowCount - m_LayoutX.m_nVisibleRowCount;
  157. }
  158. if (nIndex == m_LayoutX.m_nTopRow)
  159. return;
  160. m_LayoutX.m_nTopRow = nIndex;
  161. }
  162. void CXTPCalendarDayView::ScrollH(int nPos, int nPos_raw)
  163. {
  164. SCROLLINFO si;
  165. if (!GetScrollBarInfoH(&si))
  166. {
  167. m_nScrollOffsetX = 0;
  168. }
  169. int nXmax = si.nMax - si.nPage + 1;
  170. m_nScrollOffsetX = min(max(nPos, si.nMin), nXmax);
  171. if (!m_bScrollH_Disabled)
  172. {
  173. if (nPos_raw < 0)
  174. {
  175. ScrollDaysToPrev();
  176. }
  177. else if (nPos_raw > nXmax)
  178. {
  179. ScrollDaysToNext();
  180. }
  181. }
  182. }
  183. BOOL CXTPCalendarDayView::GetScrollBarInfoV(SCROLLINFO* pSI)
  184. {
  185. ASSERT(pSI);
  186. if (!pSI || m_bScrollV_Disabled)
  187. {
  188. return FALSE;
  189. }
  190. pSI->nPos = m_LayoutX.m_nTopRow;
  191. pSI->nMax = m_LayoutX.m_nRowCount - 1;
  192. pSI->nPage = m_LayoutX.m_nVisibleRowCount;
  193. return m_LayoutX.m_nVisibleRowCount != m_LayoutX.m_nRowCount;
  194. }
  195. BOOL CXTPCalendarDayView::GetScrollBarInfoH(SCROLLINFO* pSI, int* pnScrollStep)
  196. {
  197. ASSERT(pSI);
  198. if (!pSI)
  199. return FALSE;
  200. int nMinColumnWidth = RecalcMinColumnWidth();
  201. if (nMinColumnWidth <= 0)
  202. return FALSE;
  203. int nColumnsCount = GetTotalGroupsCount();
  204. CRect rcClient = _GetScrollRectClient();
  205. int nFullWidth = nColumnsCount * nMinColumnWidth;
  206. if (nFullWidth <= rcClient.Width())
  207. return FALSE;
  208. pSI->nPos = min(m_nScrollOffsetX, nFullWidth);
  209. pSI->nMin = 0;
  210. pSI->nMax = nFullWidth-1;
  211. pSI->nPage = rcClient.Width();
  212. if (pnScrollStep)
  213. *pnScrollStep = 15;
  214. return TRUE;
  215. }
  216. int CXTPCalendarDayView::GetTotalGroupsCount()
  217. {
  218. int nGroupsCount = 0;
  219. int nDays = GetViewDayCount();
  220. for (int i = 0; i < nDays; i++)
  221. {
  222. CXTPCalendarDayViewDay* pDay = GetViewDay(i);
  223. ASSERT(pDay);
  224. if (pDay)
  225. nGroupsCount += pDay->GetViewGroupsCount();
  226. }
  227. return nGroupsCount;
  228. }
  229. int CXTPCalendarDayView::RecalcMinColumnWidth()
  230. {
  231. int nMinColumnWidth = m_nMinColumnWidth;
  232. if (nMinColumnWidth < 0)
  233. {
  234. // automatically use horizontal scrolling for multi-resources mode
  235. if (GetResources() && GetResources()->GetCount() <= 1)
  236. return -1;
  237. if (nMinColumnWidth == -1)
  238. nMinColumnWidth = ::GetSystemMetrics(SM_CXFULLSCREEN) / 6;
  239. else
  240. nMinColumnWidth = abs(nMinColumnWidth);
  241. }
  242. return nMinColumnWidth;
  243. }
  244. int CXTPCalendarDayView::GetAllDayEventsMaxCount()
  245. {
  246. int nAllDayMax = 0;
  247. int nCount = GetViewDayCount();
  248. for (int i = 0; i < nCount; i++)
  249. {
  250. CXTPCalendarDayViewDay* pViewDay = GetViewDay(i);
  251. ASSERT(pViewDay);
  252. if (!pViewDay)
  253. continue;
  254. int nGroupsCount = pViewDay->GetViewGroupsCount();
  255. for (int g = 0; g < nGroupsCount; g++)
  256. {
  257. int nAllDay = 0;
  258. CXTPCalendarDayViewGroup* pViewGroup = pViewDay->GetViewGroup(g);
  259. ASSERT(pViewGroup);
  260. if (!pViewGroup)
  261. {
  262. continue;
  263. }
  264. int nECount = pViewGroup->GetViewEventsCount();
  265. for (int j = 0; j < nECount; j++)
  266. {
  267. CXTPCalendarDayViewEvent* pViewEvent = pViewGroup->GetViewEvent(j);
  268. ASSERT(pViewEvent);
  269. if (pViewEvent && pViewEvent->IsMultidayEvent())
  270. {
  271. nAllDay++;
  272. }
  273. }
  274. nAllDayMax = max(nAllDayMax, nAllDay);
  275. }
  276. }
  277. return nAllDayMax;
  278. }
  279. void CXTPCalendarDayView::AdjustAllDayEvents()
  280. {
  281. if (GetResources() && GetResources()->GetCount() > 1)
  282. {
  283. return;
  284. }
  285. int nDaysCount = GetViewDayCount();
  286. for (int nDayIdx = 0; nDayIdx < nDaysCount; nDayIdx++)
  287. {
  288. CXTPCalendarDayViewDay* pViewDay = GetViewDay(nDayIdx);
  289. if (!pViewDay)
  290. {
  291. ASSERT(FALSE);
  292. continue;
  293. }
  294. // go through all days to look for multiday events
  295. int nGroupsCount = pViewDay->GetViewGroupsCount();
  296. for (int g = 0; g < nGroupsCount; g++)
  297. {
  298. CXTPCalendarDayViewGroup* pViewGroup = pViewDay->GetViewGroup(g);
  299. ASSERT(pViewGroup);
  300. if (!pViewGroup)
  301. {
  302. continue;
  303. }
  304. int nEventsCount = pViewGroup->GetViewEventsCount();
  305. for (int nEvent = 0; nEvent < nEventsCount; nEvent++)
  306. {
  307. CXTPCalendarViewEvent* pViewEvent = pViewGroup->GetViewEvent(nEvent);
  308. if (!pViewEvent)
  309. {
  310. ASSERT(FALSE);
  311. continue;
  312. }
  313. int nMDEFlags = pViewEvent->GetMultiDayEventFlags();
  314. if ((nMDEFlags & xtpCalendarMultiDayMSmask) || !(nMDEFlags & xtpCalendarMultiDayFMLmask))
  315. {
  316. continue; // already marked or not multi day
  317. }
  318. //------------------------
  319. pViewEvent->SetMultiDayEvent_MasterSlave(TRUE, NULL);
  320. int nMasterPlace = pViewEvent->GetEventPlaceNumber();
  321. if ((nMDEFlags & xtpCalendarMultiDayLast) == 0)
  322. {
  323. // find other visible instances and mark them as Slave
  324. for (int i = nDayIdx + 1; i < nDaysCount; i++)
  325. {
  326. CXTPCalendarViewDay* pViewDay2 = GetViewDay(i);
  327. if (XTP_SAFE_GET1(pViewDay2, GetViewGroupsCount(), 0) != 1)
  328. {
  329. ASSERT(FALSE);
  330. break;
  331. }
  332. CXTPCalendarViewEvent* pViewEvent2 = XTP_SAFE_GET2(pViewDay2,
  333. GetViewGroup_(0), GetViewEventByEvent_(pViewEvent->GetEvent()), NULL);
  334. if (!pViewEvent2)
  335. {
  336. break;
  337. }
  338. pViewEvent->AddMultiDayEvent_Slave(pViewEvent2, nMasterPlace);
  339. }
  340. }
  341. }
  342. }
  343. }
  344. }
  345. int CXTPCalendarDayView::CalculateHeaderFormatAndHeight(CDC* pDC, int nCellWidth)
  346. {
  347. ASSERT(pDC);
  348. const int cnMinHeight = 19;
  349. CXTPCalendarViewPart* pPart = XTP_SAFE_GET1(GetPaintManager(), GetDayViewHeaderPart(), NULL);
  350. ASSERT(pPart);
  351. if (!pPart || !pDC)
  352. {
  353. return cnMinHeight;
  354. }
  355. CalculateHeaderFormat(pDC, nCellWidth, &pPart->GetTextFont());
  356. CString strHearderTest = _T("QW(");
  357. int nCount = GetViewDayCount();
  358. for (int i = 0; i < nCount; i++)
  359. {
  360. CXTPCalendarDayViewDay* pDay = GetViewDay(i);
  361. ASSERT(pDay);
  362. if (pDay)
  363. {
  364. strHearderTest += pDay->GetCaption();
  365. }
  366. }
  367. CXTPFontDC fnt(pDC, &pPart->GetTextFont());
  368. CSize sizeH = pDC->GetTextExtent(strHearderTest);
  369. int nHeight = max(cnMinHeight, sizeH.cy + 6);
  370. return nHeight;
  371. }
  372. CXTPCalendarData* CXTPCalendarDayView::_GetDataProviderByConnStr(LPCTSTR pcszConnStr, BOOL bCompareNoCase)
  373. {
  374. UNREFERENCED_PARAMETER(pcszConnStr);
  375. UNREFERENCED_PARAMETER(bCompareNoCase);
  376. return NULL;
  377. }
  378. BOOL CXTPCalendarDayView::IsGroupHeaderVisible()
  379. {
  380. BOOL bHideHeader = XTP_SAFE_GET1(GetResources(), GetCount(), 0) == 1 &&
  381. XTP_SAFE_GET2(GetResources(), GetAt(0), IsSchedulesSetEmpty(), FALSE);
  382. return !bHideHeader;
  383. }
  384. void CXTPCalendarDayView::AdjustLayout(CDC* pDC, const CRect& rcView, BOOL bCallPostAdjustLayout)
  385. {
  386. ASSERT(pDC);
  387. if (!pDC)
  388. {
  389. return;
  390. }
  391. XTP_SAFE_CALL1(m_pTimeScaleHeader, SetCaption(GetScaleText()) );
  392. XTP_SAFE_CALL1(m_pTimeScaleHeader2, SetCaption(GetScale2Text()) );
  393. XTP_SAFE_CALL1(m_pTimeScaleHeader2, SetVisible(IsScale2Visible()) );
  394. TBase::AdjustLayout(pDC, rcView, FALSE);
  395. COleDateTimeSpan spDay(1, 0, 0, 0);
  396. double dRows = spDay / max((double)m_pTimeScaleHeader->GetScaleInterval(), XTP_HALF_SECOND * 2);
  397. m_LayoutX.m_nRowCount = (int)(dRows + XTP_HALF_SECOND); // to prevent loosing 1 :  (int)(47.99999999999) = 47; // need 48 !
  398. //CString str; str.Format(_T("RowsCount[%d] = %.15e (%.15e)"), m_nRowCount, dRows, (dRows + XTP_HALF_SECOND));
  399. //AfxMessageBox(str);
  400. CRect rcView2 = rcView;
  401. // alternative time scale
  402. if (IsScale2Visible())
  403. {
  404. int nTimeScale2Width = XTP_SAFE_GET1(m_pTimeScaleHeader2, CalcWidth(pDC), 0);
  405. m_pTimeScaleHeader2->m_Layout.m_rcHeader.SetRect(rcView2.left, rcView2.top, rcView2.left + nTimeScale2Width, rcView2.bottom);
  406. rcView2.left += nTimeScale2Width;
  407. AdjustScale2TimeZone();
  408. }
  409. // regular time scale
  410. if (m_pTimeScaleHeader)
  411. {
  412. int nTimeScaleWidth = XTP_SAFE_GET1(m_pTimeScaleHeader, CalcWidth(pDC), 0);
  413. m_pTimeScaleHeader->m_Layout.m_rcHeader.SetRect(rcView2.left, rcView2.top, rcView2.left + nTimeScaleWidth, rcView2.bottom);
  414. rcView2.left += nTimeScaleWidth;
  415. }
  416. CXTPCalendarViewPart* pPart = XTP_SAFE_GET1(GetPaintManager(), GetDayViewHeaderPart(), NULL);
  417. int nDaysCount = GetViewDayCount();
  418. if (nDaysCount <= 0 || !pPart)
  419. {
  420. return;
  421. }
  422. int nColumnsCount = GetTotalGroupsCount();
  423. // Adjust Header
  424. int nCellWidth = rcView2.Width() / max(nDaysCount, 1);
  425. int nDayHeaderHeight = CalculateHeaderFormatAndHeight(pDC, nCellWidth);
  426. int nMinRowHeight = nDayHeaderHeight;
  427. m_LayoutX.m_nAllDayEventsCountMax = max(1, GetAllDayEventsMaxCount());
  428. if (m_eDraggingMode == xtpCalendaDragModeResizeBegin || m_eDraggingMode == xtpCalendaDragModeResizeEnd
  429. || _IsDragModeCopyMove(m_eDraggingMode))
  430. {
  431. m_LayoutX.m_nAllDayEventsCountMax = max(m_LayoutX.m_nAllDayEventsCountMax, m_nAllDayEventsCountMin_WhenDrag);
  432. m_nAllDayEventsCountMin_WhenDrag = m_LayoutX.m_nAllDayEventsCountMax;
  433. }
  434. BOOL bGroupHeaderVisible = IsGroupHeaderVisible();
  435. int nDGHeadersHeight = nDayHeaderHeight * (bGroupHeaderVisible ? 2 : 1);
  436. // day view part
  437. int nRowCount = m_LayoutX.m_nRowCount;
  438. int nTotalRows = nRowCount + m_LayoutX.m_nAllDayEventsCountMax + (bGroupHeaderVisible ? 2 : 1);
  439. m_Layout.m_nRowHeight = max(nMinRowHeight, rcView2.Height() / max(nTotalRows, 1));
  440. double dVisibleRowCountMax = (double)(rcView2.Height()) / (double)(max(m_Layout.m_nRowHeight, 1));
  441. double dVisibleRowCount = dVisibleRowCountMax - (0.2 + m_LayoutX.m_nAllDayEventsCountMax) -
  442. (bGroupHeaderVisible ? 2 : 1);
  443. m_LayoutX.m_nVisibleRowCount = max((int)dVisibleRowCount, max(0, (int)dVisibleRowCountMax/2));
  444. m_LayoutX.m_nVisibleRowCount = max(0, min(nRowCount, m_LayoutX.m_nVisibleRowCount));
  445. if (m_LayoutX.m_nTopRow + m_LayoutX.m_nVisibleRowCount >= m_LayoutX.m_nRowCount)
  446. {
  447. m_LayoutX.m_nTopRow = m_LayoutX.m_nRowCount - m_LayoutX.m_nVisibleRowCount;
  448. }
  449. int nAllDayEventsHeight = max(0, rcView2.Height() - (m_LayoutX.m_nVisibleRowCount * m_Layout.m_nRowHeight + nDGHeadersHeight));
  450. m_LayoutX.m_rcDayHeader.SetRect(rcView2.left, rcView2.top, rcView2.right, rcView2.top + nDayHeaderHeight);
  451. m_LayoutX.m_rcAllDayEvents.SetRect(rcView2.left, rcView2.top + nDGHeadersHeight,
  452.  rcView2.right, rcView2.top + nAllDayEventsHeight + nDGHeadersHeight);
  453. int nCols = 0;
  454. for (int i = 0; i < nDaysCount; i++)
  455. {
  456. CXTPCalendarDayViewDay* pDay = GetViewDay(i);
  457. if (!pDay)
  458. {
  459. ASSERT(FALSE);
  460. continue;
  461. }
  462. //int nWidth = (i == nDaysCount - 1) ? rcView2.Width() : rcView2.Width() / (nColumnsCount - nCols);
  463. int nWidth = (rcView2.Width() / (nColumnsCount - nCols)) * pDay->GetViewGroupsCount();
  464. if (i == nDaysCount - 1)
  465. nWidth = rcView2.Width();
  466. CRect rcDay(rcView2.left, rcView2.top, rcView2.left + nWidth, rcView2.bottom);
  467. pDay->AdjustLayout(pDC, rcDay);
  468. rcView2.left += nWidth;
  469. nCols += pDay->GetViewGroupsCount();
  470. }
  471. //----------------------------------------------
  472. if (nDaysCount && XTP_SAFE_GET1(GetViewDay(0), GetViewGroupsCount(), 0) &&
  473. GetViewDay(0)->GetViewGroup(0) )
  474. {
  475. CRect rcAllDayEvents = GetViewDay(0)->GetViewGroup(0)->GetAllDayEventsRect();
  476. ASSERT(rcAllDayEvents.Height() == m_LayoutX.m_rcAllDayEvents.Height());
  477. m_LayoutX.m_rcAllDayEvents.top = rcAllDayEvents.top;
  478. m_LayoutX.m_rcAllDayEvents.bottom = rcAllDayEvents.bottom;
  479. }
  480. AdjustAllDayEvents();
  481. //----------------------------------------------------------
  482. XTP_SAFE_CALL1(m_pTimeScaleHeader, AdjustLayout(pDC) );
  483. XTP_SAFE_CALL1(m_pTimeScaleHeader2, AdjustLayout(pDC) );
  484. //---------------------------------------------------------------------------
  485. int nDVCount = GetViewDayCount();
  486. if (nDVCount)
  487. {
  488. COleDateTime dtFirstDay = GetViewDayDate(0);
  489. COleDateTime dtLastDay = GetViewDayDate(nDVCount-1);
  490. BOOL bSelChanged = FALSE;
  491. if (m_selectedBlock.dtEnd.GetStatus() != COleDateTime::valid ||
  492. m_selectedBlock.dtBegin.GetStatus() != COleDateTime::valid)
  493. {
  494. int nSelRow = GetTopRow() + min(2, GetVisibleRowCount());
  495. m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateTime(dtFirstDay, GetCellTime(nSelRow));
  496. m_selectedBlock.dtEnd = m_selectedBlock.dtBegin + GetCellDuration();
  497. m_selectedBlock.bAllDayEvent = FALSE;
  498. m_selectedBlock.nGroupIndex = 0;
  499. bSelChanged = TRUE;
  500. }
  501. COleDateTime dtSelBeginDay = CXTPCalendarUtils::ResetTime(m_selectedBlock.dtBegin);
  502. COleDateTime dtSelEndDay = CXTPCalendarUtils::ResetTime(m_selectedBlock.dtEnd-COleDateTimeSpan(0, 0, 0, 1));
  503. // compare with the first day
  504. if (dtSelBeginDay < dtFirstDay)
  505. {
  506. m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtBegin, dtFirstDay);
  507. bSelChanged = TRUE;
  508. }
  509. if (dtSelEndDay < dtFirstDay)
  510. {
  511. m_selectedBlock.dtEnd = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtEnd, dtFirstDay);
  512. bSelChanged = TRUE;
  513. }
  514. // compare with the last day
  515. if (dtSelEndDay > dtLastDay)
  516. {
  517. m_selectedBlock.dtEnd = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtEnd, dtLastDay);
  518. bSelChanged = TRUE;
  519. }
  520. if (dtSelBeginDay > dtLastDay)
  521. {
  522. m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtBegin, dtLastDay);
  523. bSelChanged = TRUE;
  524. }
  525. if (bSelChanged)
  526. {
  527. CSelectionChangedContext selChanged(this, xtpCalendarSelectionDays);
  528. }
  529. }
  530. //---------------------------------------------------------------------------
  531. if (bCallPostAdjustLayout)
  532. {
  533. OnPostAdjustLayout();
  534. }
  535. }
  536. /*
  537. AdjustLayout2
  538. <Pre-Theme Adjust Layout step>
  539. Theme->AdjustLayout
  540.    <Adjust Layout for theme step>
  541. <- <call AdjustLayout2 for children>
  542. <After-Theme Adjust Layout step>
  543. OnPostAdjustLayout2
  544. <Pre-Theme Post Adjust Layout step>
  545. Theme->OnPostAdjustLayout
  546. <After-Theme Post Adjust Layout step>
  547. */
  548. void CXTPCalendarDayView::AdjustLayout2(CDC* pDC, const CRect& rcView, BOOL bCallPostAdjustLayout)
  549. {
  550. if (!pDC || !GetTheme())
  551. {
  552. ASSERT(FALSE);
  553. return;
  554. }
  555. TBase::AdjustLayout2(pDC, rcView, bCallPostAdjustLayout);
  556. //*** Pre-Theme Adjust Layout step
  557. XTP_SAFE_CALL1(m_pTimeScaleHeader, SetCaption(GetScaleText()) );
  558. XTP_SAFE_CALL1(m_pTimeScaleHeader2, SetCaption(GetScale2Text()) );
  559. XTP_SAFE_CALL1(m_pTimeScaleHeader2, SetVisible(IsScale2Visible()) );
  560. if (IsScale2Visible())
  561. {
  562. AdjustScale2TimeZone();
  563. }
  564. COleDateTimeSpan spDay(1, 0, 0, 0);
  565. double dRows = spDay / max((double)m_pTimeScaleHeader->GetScaleInterval(), XTP_HALF_SECOND * 2);
  566. m_LayoutX.m_nRowCount = (int)(dRows + XTP_HALF_SECOND); // to prevent loosing 1 :  (int)(47.99999999999) = 47; // need 48 !
  567. m_LayoutX.m_nAllDayEventsCountMax = max(1, GetAllDayEventsMaxCount());
  568. if (m_eDraggingMode == xtpCalendaDragModeResizeBegin || m_eDraggingMode == xtpCalendaDragModeResizeEnd
  569. || _IsDragModeCopyMove(m_eDraggingMode))
  570. {
  571. m_LayoutX.m_nAllDayEventsCountMax = max(m_LayoutX.m_nAllDayEventsCountMax, m_nAllDayEventsCountMin_WhenDrag);
  572. m_nAllDayEventsCountMin_WhenDrag = m_LayoutX.m_nAllDayEventsCountMax;
  573. }
  574. //***
  575. GetTheme()->GetDayViewPart()->AdjustLayout(pDC, rcView);
  576. //*** Post-Theme Adjust Layout step
  577. //---------------------------------------------------------------------------
  578. int nDVCount = GetViewDayCount();
  579. if (nDVCount)
  580. {
  581. COleDateTime dtFirstDay = GetViewDayDate(0);
  582. COleDateTime dtLastDay = GetViewDayDate(nDVCount-1);
  583. BOOL bSelChanged = FALSE;
  584. if (m_selectedBlock.dtEnd.GetStatus() != COleDateTime::valid ||
  585. m_selectedBlock.dtBegin.GetStatus() != COleDateTime::valid)
  586. {
  587. int nSelRow = GetTopRow() + min(2, GetVisibleRowCount());
  588. m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateTime(dtFirstDay, GetCellTime(nSelRow));
  589. m_selectedBlock.dtEnd = m_selectedBlock.dtBegin + GetCellDuration();
  590. m_selectedBlock.bAllDayEvent = FALSE;
  591. m_selectedBlock.nGroupIndex = 0;
  592. bSelChanged = TRUE;
  593. }
  594. COleDateTime dtSelBeginDay = CXTPCalendarUtils::ResetTime(m_selectedBlock.dtBegin);
  595. COleDateTime dtSelEndDay = CXTPCalendarUtils::ResetTime(m_selectedBlock.dtEnd-COleDateTimeSpan(0, 0, 0, 1));
  596. // compare with the first day
  597. if (dtSelBeginDay < dtFirstDay)
  598. {
  599. m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtBegin, dtFirstDay);
  600. bSelChanged = TRUE;
  601. }
  602. if (dtSelEndDay < dtFirstDay)
  603. {
  604. m_selectedBlock.dtEnd = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtEnd, dtFirstDay);
  605. bSelChanged = TRUE;
  606. }
  607. // compare with the last day
  608. if (dtSelEndDay > dtLastDay)
  609. {
  610. m_selectedBlock.dtEnd = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtEnd, dtLastDay);
  611. bSelChanged = TRUE;
  612. }
  613. if (dtSelBeginDay > dtLastDay)
  614. {
  615. m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtBegin, dtLastDay);
  616. bSelChanged = TRUE;
  617. }
  618. if (bSelChanged)
  619. {
  620. CSelectionChangedContext selChanged(this, xtpCalendarSelectionDays);
  621. }
  622. }
  623. //---------------------------------------------------------------------------
  624. if (bCallPostAdjustLayout)
  625. {
  626. OnPostAdjustLayout();
  627. GetTheme()->GetDayViewPart()->OnPostAdjustLayout();
  628. }
  629. }
  630. void CXTPCalendarDayView::Draw2(CDC* pDC)
  631. {
  632. if (!GetTheme())
  633. {
  634. ASSERT(FALSE);
  635. return;
  636. }
  637. GetTheme()->GetDayViewPart()->Draw(pDC);
  638. m_dtLastRedrawTime = CXTPCalendarUtils::GetCurrentTime();
  639. }
  640. void CXTPCalendarDayView::OnDraw(CDC* pDC)
  641. {
  642. SCROLLINFO si;
  643. if (!GetScrollBarInfoH(&si) || pDC->IsPrinting())
  644. {
  645. TBase::OnDraw(pDC);
  646. return;
  647. }
  648. //===================================
  649. CRect rcView = GetViewRect();
  650. CDC memDC;
  651. CBitmap bmpCache;
  652. memDC.CreateCompatibleDC(pDC);
  653. VERIFY( bmpCache.CreateCompatibleBitmap(pDC, rcView.Width(), rcView.Height()) );
  654. CXTPBitmapDC autoDCbmp(&memDC, &bmpCache);
  655. memDC.FillSolidRect(rcView, 0xFF);
  656. memDC.SetViewportOrg(m_nScrollOffsetX, 0);
  657. //------------------------------------------------
  658. if (m_pTimeScaleHeader)
  659. m_pTimeScaleHeader->MoveTo(m_nScrollOffsetX);
  660. if (m_pTimeScaleHeader2 && IsScale2Visible())
  661. m_pTimeScaleHeader2->MoveTo(m_nScrollOffsetX);
  662. //************************************************
  663. TBase::OnDraw(&memDC);
  664. //************************************************
  665. //int nTSWidth = _GetTimeScaleWith();
  666. CXTPClientRect rcClient(GetCalendarControl());
  667. pDC->BitBlt(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(),
  668. &memDC, 0, 0, SRCCOPY);
  669. }
  670. void CXTPCalendarDayView::Draw(CDC* pDC)
  671. {
  672. pDC->SetBkMode(TRANSPARENT);
  673. // days
  674. int nCount = GetViewDayCount();
  675. for (int i = nCount - 1; i >= 0; i--)
  676. {
  677. XTP_SAFE_CALL1(GetViewDay(i), Draw(pDC));
  678. }
  679. // alternative time scale
  680. if (IsScale2Visible() && m_pTimeScaleHeader2)
  681. m_pTimeScaleHeader2->Draw(pDC);
  682. // regular time scale
  683. XTP_SAFE_CALL1(m_pTimeScaleHeader, Draw(pDC));
  684. m_dtLastRedrawTime = CXTPCalendarUtils::GetCurrentTime();
  685. }
  686. BOOL CXTPCalendarDayView::HitTestEx(CPoint pt, XTP_CALENDAR_HITTESTINFO_DAY_VIEW* pHitTest)
  687. {
  688. if (!pHitTest)
  689. {
  690. ASSERT(FALSE);
  691. return FALSE;
  692. }
  693. pHitTest->pt = pt;
  694. if (m_pTimeScaleHeader2 && m_pTimeScaleHeader2->HitTestDateTime(pHitTest))
  695. {
  696. return TRUE;
  697. }
  698. if (m_pTimeScaleHeader && m_pTimeScaleHeader->HitTestDateTime(pHitTest))
  699. {
  700. return TRUE;
  701. }
  702. //----------------------------------------------------
  703. CXTPCalendarThemeOffice2007* pThemeX = DYNAMIC_DOWNCAST(CXTPCalendarThemeOffice2007, GetTheme());
  704. int nHit = XTP_SAFE_GET2(pThemeX, GetPrevNextEventControllerPartX(), HitTest(&pt), 0);
  705. if (nHit)
  706. {
  707. XTP_CALENDAR_HITTESTINFO_DAY_VIEW emptyData;
  708. *pHitTest = emptyData;
  709. pHitTest->uHitCode = nHit;
  710. return TRUE;
  711. }
  712. //----------------------------------------------------
  713. return TBase::HitTestEx(pt, pHitTest);
  714. }
  715. BOOL CXTPCalendarDayView::IsUseCellAlignedDraggingInTimeArea()
  716. {
  717. if (GetTheme() && GetTheme()->GetDayViewPart())
  718. {
  719. return GetTheme()->GetDayViewPart()->IsUseCellAlignedDraggingInTimeArea();
  720. }
  721. return CXTPCalendarView::IsUseCellAlignedDraggingInTimeArea();
  722. }
  723. void CXTPCalendarDayView::OnStartDragging(CPoint point, XTP_CALENDAR_HITTESTINFO* pHitTest)
  724. {
  725. if (!pHitTest || !m_pControl)
  726. {
  727. ASSERT(FALSE);
  728. return;
  729. }
  730. m_dtDraggingStartPoint = pHitTest->dt;
  731. m_spDraggingStartOffset_Time = 0.;
  732. m_nAllDayEventsCountMin_WhenDrag = max(1, GetAllDayEventsMaxCount());
  733. CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateRedraw);
  734. TBase::OnStartDragging(point, pHitTest);
  735. if (double(m_spDraggingStartOffset) != 0.0
  736. && IsUseCellAlignedDraggingInTimeArea())
  737. {
  738. // Align to cell begin time
  739. m_spDraggingStartOffset = pHitTest->dt - pHitTest->pViewEvent->GetEvent()->GetStartTime();
  740. int nTmpCell = GetCellNumber((DATE)(double)m_spDraggingStartOffset, FALSE);
  741. m_spDraggingStartOffset = (double)GetCellTime(nTmpCell);
  742. }
  743. m_selectedBlock.dtEnd = m_selectedBlock.dtBegin;
  744. m_selectedBlock.bAllDayEvent = FALSE;
  745. m_selectedBlock.nGroupIndex = pHitTest->nGroup;
  746. CSelectionChangedContext selChanged(this, xtpCalendarSelectionDays);
  747. }
  748. BOOL CXTPCalendarDayView::OnDragging(CPoint point, XTP_CALENDAR_HITTESTINFO* pHitTest)
  749. {
  750. if (!pHitTest)
  751. {
  752. ASSERT(FALSE);
  753. return FALSE;
  754. }
  755. if (!m_ptrDraggingEventNew || m_eDraggingMode == xtpCalendaDragModeEditSubject ||
  756. !GetCalendarControl())
  757. {
  758. return FALSE;
  759. }
  760. TRACE_DRAGGING(_T("OnDragging - [CXTPCalendarDayView] (point.x =%d, point.y =%d) n"),
  761. point.x, point.y);
  762. XTP_CALENDAR_HITTESTINFO hitInfo2 = *pHitTest;
  763. XTP_CALENDAR_HITTESTINFO* pHitTest2 = &hitInfo2;
  764. BOOL bChanged = FALSE;
  765. XTP_CALENDAR_HITTESTINFO_DAY_VIEW hitTestInfo;
  766.  // TODO:
  767. //if (IsOutOfDraggingRect(point, &hitTestInfo))
  768. //{
  769. //  return FALSE;
  770. //}
  771. if (!HitTestEx(point, &hitTestInfo))
  772. {
  773. return FALSE;
  774. }
  775. //========================================================================
  776. BOOL bScrolled = FALSE;
  777. XTPCalendarDayViewScrollDirection scrollDir = GetNeededScrollDirection(point);
  778. if (scrollDir != xtpCalendarDayViewScrollNotNeeded)
  779. {
  780. if (scrollDir == xtpCalendarDayViewScrollUp)
  781. {
  782. TRACE_DRAGGING(_T("OnDragging::ScrollV upn"));
  783. bScrolled = VertEventScroll(TRUE);//scroll up
  784. SetMouseOutOfDragArea(FALSE);
  785. if (bScrolled)
  786. {
  787. if (HitTestEx(point, &hitTestInfo))
  788. {
  789. pHitTest2->dt = hitTestInfo.dt;
  790. }
  791. }
  792. }
  793. else if (scrollDir == xtpCalendarDayViewScrollDown)
  794. {
  795. TRACE_DRAGGING(_T("OnDragging::ScrollV downn"));
  796. bScrolled = VertEventScroll(FALSE);//scroll down
  797. SetMouseOutOfDragArea(FALSE);
  798. if (bScrolled)
  799. {
  800. if (HitTestEx(point, &hitTestInfo))
  801. {
  802. pHitTest2->dt = hitTestInfo.dt;
  803. }
  804. }
  805. }
  806. }
  807. //  if (IsOutOfDraggingRect(point, &hitTestInfo))
  808. //  {
  809. //      TRACE_DRAGGING("OnDragging::OutOfDragArean");
  810. //          SetMouseOutOfDragArea(TRUE);
  811. //          StopVertEventScroll();
  812. //          bScrolled = TRUE;
  813. //          return TRUE;
  814. //  }
  815. // TODO:
  816. if (IsOutOfClientRect(point, &hitTestInfo))
  817. {
  818. TRACE_DRAGGING(_T("OnDragging::OutOfDragArean"));
  819. SetMouseOutOfDragArea(TRUE);
  820. StopVertEventScroll();
  821. bScrolled = TRUE;
  822. return TRUE;
  823. }
  824. if (!bScrolled)
  825. {
  826. TRACE_DRAGGING(_T("OnDragging::In DragArean"));
  827. SetMouseOutOfDragArea(FALSE);
  828. StopVertEventScroll();
  829. }
  830. // check drag on TimeScale:
  831. TRACE_DRAGGING(_T("OnDragging - [CXTPCalendarDayView] (hour =%d, minute =%d) n"),
  832. pHitTest->dt.GetHour(), pHitTest->dt.GetMinute());
  833. if (_IsDragModeCopyMove(m_eDraggingMode) && (
  834. m_pTimeScaleHeader2 && m_pTimeScaleHeader2->HitTestDateTime(&hitTestInfo) ||
  835. (m_pTimeScaleHeader && m_pTimeScaleHeader->HitTestDateTime(&hitTestInfo))))
  836. {
  837. COleDateTime dtNewTime = pHitTest->dt;
  838. dtNewTime = COleDateTime(m_dtDraggingStartPoint.GetYear(),
  839. m_dtDraggingStartPoint.GetMonth(), m_dtDraggingStartPoint.GetDay(),
  840. dtNewTime.GetHour(), dtNewTime.GetMinute(), dtNewTime.GetSecond());
  841. m_ptrDraggingEventNew->MoveEvent(dtNewTime);
  842. return TRUE;
  843. }
  844. if (!m_ptrDraggingEventOrig)
  845. {
  846. ASSERT(FALSE);
  847. return FALSE;
  848. }
  849. BOOL bAllDayEventArea = 0 != (hitTestInfo.uHitCode & xtpCalendarHitTestDayViewAllDayEvent);
  850. BOOL bAllDayEventNew_prev = m_ptrDraggingEventNew->IsAllDayEvent();
  851. BOOL bAllMultiDayEvent = bAllDayEventNew_prev || m_ptrDraggingEventNew->GetDurationMinutes() > 24 * 60;
  852. BOOL bAllMultiDayEventOrig = m_ptrDraggingEventOrig->IsAllDayEvent();
  853. bAllMultiDayEventOrig |= m_ptrDraggingEventOrig->GetDurationMinutes() > 24 * 60;
  854. bChanged = bAllDayEventArea != bAllMultiDayEvent;
  855. if (bChanged)
  856. {
  857. if (!bAllDayEventArea && bAllMultiDayEventOrig && _IsDragModeCopyMove(m_eDraggingMode))
  858. {
  859. m_ptrDraggingEventNew->SetDuration(GetCellDuration());
  860. }
  861. else if (bAllDayEventArea && !bAllMultiDayEventOrig && _IsDragModeCopyMove(m_eDraggingMode))
  862. {
  863. m_ptrDraggingEventNew->SetStartTime(CXTPCalendarUtils::ResetTime(m_ptrDraggingEventOrig->GetStartTime()));
  864. m_ptrDraggingEventNew->SetEndTime(m_ptrDraggingEventNew->GetStartTime()+COleDateTimeSpan(1, 0, 0, 0));
  865. }
  866. else
  867. {
  868. m_ptrDraggingEventNew->SetStartTime(m_ptrDraggingEventOrig->GetStartTime());
  869. m_ptrDraggingEventNew->SetEndTime(m_ptrDraggingEventOrig->GetEndTime());
  870. }
  871. if (_IsDragModeCopyMove(m_eDraggingMode))
  872. {
  873. if (bAllDayEventArea == bAllMultiDayEventOrig)
  874. {
  875. m_spDraggingStartOffset = m_spDraggingStartOffset_Time;
  876. m_spDraggingStartOffset_Time = 0.;
  877. }
  878. else
  879. {
  880. m_spDraggingStartOffset_Time = m_spDraggingStartOffset;
  881. m_spDraggingStartOffset = 0.;
  882. }
  883. if (bAllDayEventArea)
  884. {
  885. if (GetCalendarControl()->DayView_IsAutoResetBusyFlag())
  886. {
  887. if (!bAllDayEventNew_prev &&
  888. xtpCalendarBusyStatusBusy == m_ptrDraggingEventNew->GetBusyStatus()
  889. &&
  890. !(bAllMultiDayEventOrig &&
  891. xtpCalendarBusyStatusBusy == m_ptrDraggingEventOrig->GetBusyStatus()))
  892. {
  893. m_ptrDraggingEventNew->SetBusyStatus(xtpCalendarBusyStatusFree);
  894. }
  895. }
  896. }
  897. else
  898. {
  899. if (GetCalendarControl()->DayView_IsAutoResetBusyFlag())
  900. {
  901. if (bAllMultiDayEvent &&
  902. xtpCalendarBusyStatusFree == m_ptrDraggingEventNew->GetBusyStatus()
  903. &&
  904. !(!bAllMultiDayEventOrig &&
  905. xtpCalendarBusyStatusFree == m_ptrDraggingEventOrig->GetBusyStatus()))
  906. {
  907. m_ptrDraggingEventNew->SetBusyStatus(xtpCalendarBusyStatusBusy);
  908. }
  909. }
  910. }
  911. }
  912. }
  913. //========================================================================
  914. if (m_eDraggingMode == xtpCalendaDragModeResizeEnd)
  915. {
  916. if (pHitTest2->bTimePartValid)
  917. {
  918. pHitTest2->dt += GetCellDuration();
  919. }
  920. }
  921. BOOL bChangedBase = TBase::OnDragging(point, pHitTest2);
  922. //-------------------------------------------------------------------------
  923. // multi-resources movement
  924. if (_IsDragModeCopyMove(m_eDraggingMode))
  925. {
  926. UINT uScheduleID = XTP_SAFE_GET2(pHitTest2, pViewGroup, GetScheduleID(), 0);
  927. if (uScheduleID != m_ptrDraggingEventNew->GetScheduleID())
  928. {
  929. if (uScheduleID != XTP_CALENDAR_UNKNOWN_SCHEDULE_ID)
  930. {
  931. m_ptrDraggingEventNew->SetScheduleID(uScheduleID);
  932. bChanged = TRUE;
  933. }
  934. else if (m_ptrDraggingEventNew->GetScheduleID() != m_ptrDraggingEventOrig->GetScheduleID())
  935. {
  936. m_ptrDraggingEventNew->SetScheduleID(m_ptrDraggingEventOrig->GetScheduleID());
  937. bChanged = TRUE;
  938. }
  939. }
  940. }
  941. //---
  942. CXTPCalendarData* pHitData = XTP_SAFE_GET2(pHitTest2, pViewGroup, GetDataProvider(), NULL);
  943. if (pHitData && pHitData != m_ptrDraggingEventNew->GetDataProvider())
  944. {
  945. CXTPCalendarEventPtr ptrHitEventNew = pHitData->CreateNewEvent();
  946. if (ptrHitEventNew)
  947. {
  948. if (m_ptrDraggingEventNew->CloneEventTo(ptrHitEventNew))
  949. {
  950. m_ptrDraggingEventNew = ptrHitEventNew;
  951. bChanged = TRUE;
  952. }
  953. }
  954. }
  955. //------------------------------------------------------------------------
  956. //COleDateTimeSpan spDurationNew = m_ptrDraggingEventNew->GetEndTime() -
  957. //                                  m_ptrDraggingEventNew->GetStartTime();
  958. //  TRACE(_T("bAllDayEventArea =%d, Orig->IsAllDayEvent =%d, bAllMultiDayEventOrig =%d, New->GetDurationMinutes=%d [%s - %s]n"),
  959. //      bAllDayEventArea, m_ptrDraggingEventOrig->IsAllDayEvent(),
  960. //bAllMultiDayEventOrig, (int)spDurationNew.GetTotalMinutes(),
  961. //m_ptrDraggingEventNew->GetStartTime().Format(),
  962. //m_ptrDraggingEventNew->GetEndTime().Format());
  963. BOOL bIsResizing = m_eDraggingMode == xtpCalendaDragModeResizeBegin ||
  964. m_eDraggingMode == xtpCalendaDragModeResizeEnd;
  965. BOOL bIsZeroLen = CXTPCalendarUtils::IsEqual(m_ptrDraggingEventNew->GetStartTime(),
  966. m_ptrDraggingEventNew->GetEndTime());
  967. if (bAllDayEventArea && (bIsResizing && !bIsZeroLen || !bIsResizing) &&
  968. (m_ptrDraggingEventOrig->IsAllDayEvent() || !bAllMultiDayEventOrig
  969.  || m_ptrDraggingEventNew->IsAllDayEvent()))
  970. {
  971. m_ptrDraggingEventNew->SetAllDayEvent(TRUE);
  972. }
  973. else
  974. {
  975. m_ptrDraggingEventNew->SetAllDayEvent(FALSE);
  976. }
  977. //------------------------------------------------------------------------
  978. return bChanged || bChangedBase;
  979. }
  980. XTPCalendarDayViewScrollDirection CXTPCalendarDayView::GetNeededScrollDirection(CPoint pnt)
  981. {
  982. static const int nVScrollZone = 20;
  983. CRect rcCtrl;
  984. if (!m_pControl)
  985. {
  986. return xtpCalendarDayViewScrollNotNeeded;
  987. }
  988. m_pControl->GetWindowRect(rcCtrl);
  989. CRect rcAllDayEvents = GetAllDayEventsRectangle();
  990. SCROLLINFO si;
  991. GetScrollBarInfoV(&si);
  992. int nCurPos = si.nPos;
  993. int nLimit = m_pControl->GetScrollLimit(SB_VERT);
  994. BOOL bWidtdhOK = (rcAllDayEvents.left <= pnt.x &&
  995. rcAllDayEvents.right >= pnt.x);
  996. if (!bWidtdhOK)
  997. return xtpCalendarDayViewScrollNotNeeded;
  998. if ((pnt.y >= rcAllDayEvents.bottom) &&
  999. (pnt.y - rcAllDayEvents.bottom <= nVScrollZone) && nCurPos > 0 &&
  1000. m_ptLBtnDownMousePos.y - pnt.y > 2)
  1001. {
  1002. // Scroll up
  1003. return xtpCalendarDayViewScrollUp;
  1004. }
  1005. if ((pnt.y + 3 < rcCtrl.Height()) &&
  1006. (rcCtrl.Height() - (pnt.y + 3) <= nVScrollZone) && nCurPos < nLimit &&
  1007. pnt.y - m_ptLBtnDownMousePos.y > 2)
  1008. {
  1009. return xtpCalendarDayViewScrollDown;
  1010. }
  1011. return xtpCalendarDayViewScrollNotNeeded;
  1012. }
  1013. BOOL CXTPCalendarDayView::IsOutOfClientRect(CPoint pnt, XTP_CALENDAR_HITTESTINFO_DAY_VIEW* pHitInfo)
  1014. {
  1015. if (!m_pControl)
  1016. {
  1017. return FALSE;
  1018. }
  1019. CRect rcCtrl;
  1020. m_pControl->GetWindowRect(rcCtrl);
  1021. if (m_pTimeScaleHeader2 && m_pTimeScaleHeader2->HitTestDateTime(pHitInfo))
  1022. {
  1023. return FALSE;
  1024. }
  1025. if (m_pTimeScaleHeader && m_pTimeScaleHeader->HitTestDateTime(pHitInfo))
  1026. {
  1027. return FALSE;
  1028. }
  1029. //bottom
  1030. if (pnt.y + 3 >= rcCtrl.Height())
  1031. return TRUE;
  1032. //top
  1033. CRect rcAllDayEvents = GetAllDayEventsRectangle();
  1034. if (pnt.y <= rcAllDayEvents.top)
  1035. return TRUE;
  1036. //left
  1037. if (pnt.x < rcAllDayEvents.left)
  1038. return TRUE;
  1039. //right
  1040. if (pnt.x > rcAllDayEvents.right)
  1041. return TRUE;
  1042. if (pHitInfo->uHitCode & xtpCalendarHitTestDayViewTimeScale)
  1043. return TRUE;
  1044. return FALSE;
  1045. }
  1046. void CXTPCalendarDayView::StopVertEventScroll()
  1047. {
  1048. if (m_dwScrollingEventTimerID)
  1049. {
  1050. KillTimer(m_dwScrollingEventTimerID);
  1051. m_dwScrollingEventTimerID = 0;
  1052. }
  1053. }
  1054. void CXTPCalendarDayView::SetMouseOutOfDragArea(BOOL bOutOfArea)
  1055. {
  1056. BOOL bChanged = m_bMouseOutOfDragArea != bOutOfArea;
  1057. m_bMouseOutOfDragArea = bOutOfArea;
  1058. BOOL bNeedUpd = FALSE;
  1059. if (m_bMouseOutOfDragArea)
  1060. {
  1061. if (m_ptrDraggingEventNew)
  1062. {
  1063. m_ptrDraggingEventNew->MoveEvent(m_dtDraggingStartPoint);
  1064. }
  1065. if (m_pControl && m_pControl->m_mouseMode != xtpCalendarMouseEventDraggingOut)
  1066. {
  1067. m_pControl->m_mouseMode = xtpCalendarMouseEventDraggingOut;
  1068. TRACE_DRAGGING(_T("SetMouseOutOfDragArea OUTn"));
  1069. bNeedUpd = TRUE;
  1070. }
  1071. }
  1072. if (bChanged && !m_bMouseOutOfDragArea)
  1073. {
  1074. TRACE_DRAGGING(_T("SetMouseOutOfDragArea INn"));
  1075. XTPCalendarMouseMode mouseMode = xtpCalendarMouseNothing;
  1076. switch (m_eDraggingMode)
  1077. {
  1078. case xtpCalendaDragModeUnknown:
  1079. case xtpCalendaDragModeEditSubject:
  1080. mouseMode = xtpCalendarMouseNothing;
  1081. break;
  1082. case xtpCalendaDragModeCopy:
  1083. mouseMode = xtpCalendarMouseEventDragCopy;
  1084. break;
  1085. case xtpCalendaDragModeMove:
  1086. mouseMode = xtpCalendarMouseEventDragMove;
  1087. break;
  1088. case xtpCalendaDragModeResizeBegin:
  1089. case xtpCalendaDragModeResizeEnd:
  1090. mouseMode = xtpCalendarMouseEventResizingV;
  1091. break;
  1092. }
  1093. XTP_SAFE_SET1(m_pControl, m_mouseMode, mouseMode);
  1094. bNeedUpd = TRUE;
  1095. }
  1096. if (bNeedUpd && m_pControl)
  1097. m_pControl->UpdateMouseCursor();
  1098. }
  1099. BOOL CXTPCalendarDayView::VertEventScroll(BOOL bUp)
  1100. {
  1101. if (!m_pControl)
  1102. {
  1103. ASSERT(FALSE);
  1104. return FALSE;
  1105. }
  1106. SCROLLINFO si;
  1107. if (!GetScrollBarInfoV(&si))
  1108. {
  1109. return FALSE;
  1110. }
  1111. int nCurPos = si.nPos;
  1112. int nCurPos_raw = si.nPos;
  1113. int nLimit = m_pControl->GetScrollLimit(SB_VERT);
  1114. if (bUp && nCurPos > 0)
  1115. {
  1116. //scroll up
  1117. nCurPos = max(nCurPos - 1, 0);
  1118. nCurPos_raw--;
  1119. m_bScrollingEventUp = TRUE;
  1120. }
  1121. else if (!bUp && nCurPos < nLimit)
  1122. {
  1123. //scroll down
  1124. nCurPos = min(nCurPos + 1, nLimit);
  1125. nCurPos_raw++;
  1126. m_bScrollingEventUp = FALSE;
  1127. }
  1128. else
  1129. {
  1130. //limit is reached
  1131. StopVertEventScroll();
  1132. return FALSE;//not handled
  1133. }
  1134. ScrollV(nCurPos, nCurPos_raw);
  1135. m_pControl->SetScrollPos(SB_VERT, nCurPos, FALSE);
  1136. m_pControl->AdjustScrollBar();
  1137. if (!m_dwScrollingEventTimerID)
  1138. {
  1139. //Start timer
  1140. m_dwScrollingEventTimerID = SetTimer(XTP_SCROLL_TIMER_RESOLUTION_MS);
  1141. DBG_TRACE_TIMER(_T("SET Timer: ID =%d, m_dwScrollingEventTimerID, CXTPCalendarDayView::VertEventScroll() n"), m_dwScrollingEventTimerID);
  1142. }
  1143. return TRUE;
  1144. }
  1145. void CXTPCalendarDayView::OnActivateView(BOOL bActivate, CXTPCalendarView* pActivateView,
  1146. CXTPCalendarView* pInactiveView)
  1147. {
  1148. TBase::OnActivateView(bActivate, pActivateView, pInactiveView);
  1149. if (!bActivate)
  1150. {
  1151. if (m_dwRedrawNowLineTimerID)
  1152. {
  1153. KillTimer(m_dwRedrawNowLineTimerID);
  1154. m_dwRedrawNowLineTimerID = 0;
  1155. //TRACE(_T("DayView: Auto redraw timer was KILLED. n"));
  1156. }
  1157. if (m_dwScrollingEventTimerID)
  1158. {
  1159. KillTimer(m_dwScrollingEventTimerID);
  1160. m_dwScrollingEventTimerID = 0;
  1161. }
  1162. }
  1163. if (bActivate && m_dwRedrawNowLineTimerID == 0)
  1164. {
  1165. m_dwRedrawNowLineTimerID = SetTimer(XTP_REDRAW_TIMER_RESOLUTION_MS);
  1166. DBG_TRACE_TIMER(_T("SET Timer: ID =%d, m_dwRedrawNowLineTimerID, CXTPCalendarDayView::OnActivateView() n"), m_dwRedrawNowLineTimerID);
  1167. //TRACE(_T("DayView: Auto redraw timer was SET. n"));
  1168. }
  1169. }
  1170. BOOL CXTPCalendarDayView::OnTimer(UINT_PTR uTimerID)
  1171. {
  1172. if (uTimerID == m_dwScrollingEventTimerID)
  1173. {
  1174. OnMouseMove(MK_LBUTTON, m_ptLastMousePos);
  1175. return TRUE;
  1176. }
  1177. else if (uTimerID == m_dwRedrawNowLineTimerID)
  1178. {
  1179. COleDateTime dtNow = CXTPCalendarUtils::GetCurrentTime();
  1180. //COleDateTimeSpan spDiff = dtNow - m_dtLastRedrawTime;
  1181. //if ((spDiff.GetTotalSeconds() >= 15 || dtNow.GetSecond()%15 == 0) &&
  1182. //  dtNow.GetSecond() != m_dtLastRedrawTime.GetSecond())
  1183. if (dtNow.GetMinute() != m_dtLastRedrawTime.GetMinute())
  1184. {
  1185. CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateRedraw);
  1186. //TRACE(_T("DayView: Auto REDRAW (%d:%d:%d). n"), (int)dtNow.GetHour(),
  1187. //  (int)dtNow.GetMinute(), (int)dtNow.GetSecond());
  1188. }
  1189. return TRUE;
  1190. }
  1191. return TBase::OnTimer(uTimerID);
  1192. }
  1193. BOOL CXTPCalendarDayView::OnEndDragging(CPoint point, XTP_CALENDAR_HITTESTINFO* pHitInfo)
  1194. {
  1195. if (!m_pControl || !pHitInfo)
  1196. {
  1197. ASSERT(FALSE);
  1198. return FALSE;
  1199. }
  1200. CRect rcCtrl;
  1201. m_pControl->GetWindowRect(rcCtrl);
  1202. BOOL bReturnBack = point.y + 3 >= rcCtrl.Height();
  1203. if (m_dwScrollingEventTimerID)
  1204. {
  1205. if (bReturnBack)
  1206. {
  1207. pHitInfo->dt = m_dtDraggingStartPoint;
  1208. OnDragging(point, pHitInfo);
  1209. }
  1210. else
  1211. {
  1212. OnDragging(point, pHitInfo);
  1213. }
  1214. }
  1215. StopVertEventScroll();
  1216. m_dtDraggingStartPoint = COleDateTime(0, 0, 0, 0, 0, 0);
  1217. if (_IsDragModeCopyMove(m_eDraggingMode) && m_ptrDraggingEventNew && m_ptrDraggingEventOrig)
  1218. {
  1219. if (!m_ptrDraggingEventNew->IsEqualStartEnd(m_ptrDraggingEventOrig))
  1220. {
  1221. COleDateTime dtS = m_ptrDraggingEventNew->GetStartTime();
  1222. COleDateTime dtE = m_ptrDraggingEventNew->GetEndTime();
  1223. COleDateTime dtS0 = CXTPCalendarUtils::ResetDate(dtS);
  1224. COleDateTime dtE0 = CXTPCalendarUtils::ResetDate(dtE);
  1225. m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateTime(dtS, GetCellTime(GetCellNumber(dtS0, FALSE)));
  1226. m_selectedBlock.dtEnd = GetCellTime(GetCellNumber(dtE0, dtS0 == dtE0 ? FALSE : TRUE)) + GetCellDuration();
  1227. m_selectedBlock.dtEnd = CXTPCalendarUtils::UpdateTime(dtE, m_selectedBlock.dtEnd);
  1228. if (m_ptrDraggingEventNew->IsAllDayEvent() ||
  1229. m_ptrDraggingEventNew->GetDurationMinutes() > 24 * 60)
  1230. {
  1231. m_selectedBlock.bAllDayEvent = TRUE;
  1232. }
  1233. m_selectedBlock.nGroupIndex = pHitInfo->nGroup;
  1234. CSelectionChangedContext selChanged(this, xtpCalendarSelectionDays);
  1235. }
  1236. }
  1237. m_nAllDayEventsCountMin_WhenDrag = 0;
  1238. {
  1239. CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateScrollBar);
  1240. }
  1241. return TBase::OnEndDragging(point, pHitInfo);
  1242. }
  1243. BOOL CXTPCalendarDayView::OnLButtonUp(UINT nFlags, CPoint point)
  1244. {
  1245. m_ptLBtnDownMousePos = CPoint(0, 0);
  1246. return TBase::OnLButtonUp(nFlags, point);
  1247. }
  1248. BOOL CXTPCalendarDayView::OnLButtonDown(UINT nFlags, CPoint point)
  1249. {
  1250. CSelectionChangedContext selChanged(this);
  1251. TBase::OnLButtonDown(nFlags, point);
  1252. m_ptLBtnDownMousePos = point;
  1253. if (m_eDraggingMode != xtpCalendaDragModeUnknown)
  1254. {
  1255. return FALSE;
  1256. }
  1257. XTP_CALENDAR_HITTESTINFO_DAY_VIEW hitTestInfo;
  1258. if (HitTestEx(point, &hitTestInfo))
  1259. {
  1260. if (hitTestInfo.dt.GetStatus() != COleDateTime::valid)
  1261. return FALSE;
  1262. ASSERT(hitTestInfo.dt.GetStatus() == COleDateTime::valid);
  1263. BOOL bEvent = (hitTestInfo.uHitCode & xtpCalendarHitTestEvent_Mask) != 0;
  1264. if (bEvent)
  1265. {
  1266. CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateRedraw);
  1267. m_selectedBlock.dtEnd = m_selectedBlock.dtBegin = hitTestInfo.dt;
  1268. m_dtSelectionStart = hitTestInfo.dt;
  1269. m_selectedBlock.bAllDayEvent = FALSE;
  1270. m_selectedBlock.nGroupIndex = hitTestInfo.nGroup;
  1271. CSelectionChangedContext selChanged1(this, xtpCalendarSelectionDays);
  1272. }
  1273. else
  1274. {
  1275. BOOL bFixBegin = (nFlags & MK_SHIFT);
  1276. BOOL bAllDay = 0 != (hitTestInfo.uHitCode & xtpCalendarHitTestDayViewAllDayEvent);
  1277. COleDateTime dtNewEnd = m_selectedBlock.dtEnd;
  1278. if (hitTestInfo.uHitCode & xtpCalendarHitTestDayViewTimeScale)
  1279. {
  1280. dtNewEnd = CXTPCalendarUtils::UpdateTime(dtNewEnd, hitTestInfo.dt + GetCellDuration());
  1281. hitTestInfo.nGroup = max(0, m_selectedBlock.nGroupIndex);
  1282. }
  1283. else if (hitTestInfo.uHitCode & xtpCalendarHitTestDayViewCell)
  1284. {
  1285. dtNewEnd = hitTestInfo.dt + GetCellDuration();
  1286. }
  1287. else if (bAllDay)
  1288. {
  1289. dtNewEnd = hitTestInfo.dt + COleDateTimeSpan(1, 0, 0, 0);
  1290. }
  1291. else {
  1292. return TRUE;
  1293. }
  1294. ProcessCellSelection(dtNewEnd, bFixBegin, bAllDay, hitTestInfo.nGroup);
  1295. }
  1296. return TRUE;
  1297. }
  1298. return FALSE;
  1299. }
  1300. void CXTPCalendarDayView::OnMouseMove(UINT nFlags, CPoint point)
  1301. {
  1302. CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateRedrawIfNeed);
  1303. CSelectionChangedContext selChanged(this);
  1304. m_ptLastMousePos = point;
  1305. TBase::OnMouseMove(nFlags, point);
  1306. if (m_eDraggingMode != xtpCalendaDragModeUnknown)
  1307. {
  1308. return;
  1309. }
  1310. // process selection mode
  1311. if ((nFlags & MK_LBUTTON) == 0)
  1312. {
  1313. return;
  1314. }
  1315. else if (!m_bStartedClickInside)
  1316. {
  1317. return;
  1318. }
  1319. XTP_CALENDAR_HITTESTINFO_DAY_VIEW hitTestInfo;
  1320. if (HitTestEx(point, &hitTestInfo))
  1321. {
  1322. COleDateTime dtEnd = m_selectedBlock.dtEnd;
  1323. BOOL bAllDayEvent = m_selectedBlock.bAllDayEvent;
  1324. BOOL bScrolled = FALSE;
  1325. XTPCalendarDayViewScrollDirection direction = GetNeededScrollDirection(point);
  1326. if (direction != xtpCalendarDayViewScrollNotNeeded &&
  1327. hitTestInfo.dt.GetStatus() == COleDateTime::valid)
  1328. {
  1329. if (direction == xtpCalendarDayViewScrollUp)
  1330. {
  1331. bScrolled = VertEventScroll(TRUE);//scroll up
  1332. hitTestInfo.dt -= GetCellDuration();
  1333. }
  1334. else if (direction == xtpCalendarDayViewScrollDown)
  1335. {
  1336. bScrolled = VertEventScroll(FALSE);
  1337. hitTestInfo.dt += GetCellDuration();
  1338. }
  1339. }
  1340. if (!bScrolled)
  1341. {
  1342. StopVertEventScroll();
  1343. }
  1344. //-------------------------------------------------------------------
  1345. // selection processing
  1346. if (hitTestInfo.uHitCode & xtpCalendarHitTestDayViewTimeScale)
  1347. {
  1348. m_selectedBlock.bAllDayEvent = FALSE;
  1349. if (bAllDayEvent)
  1350. {
  1351. m_selectedBlock.dtBegin = m_dtSelectionStart;
  1352. }
  1353. m_selectedBlock.dtEnd = CXTPCalendarUtils::UpdateTime(m_selectedBlock.dtEnd, hitTestInfo.dt);
  1354. if (m_selectedBlock.dtEnd >= m_selectedBlock.dtBegin)
  1355. {
  1356. m_selectedBlock.dtEnd += GetCellDuration();
  1357. }
  1358. }
  1359. else if (hitTestInfo.uHitCode & xtpCalendarHitTestDayViewCell)
  1360. {
  1361. m_selectedBlock.bAllDayEvent = FALSE;
  1362. if (bAllDayEvent)
  1363. {
  1364. m_selectedBlock.dtBegin = m_dtSelectionStart;
  1365. }
  1366. m_selectedBlock.dtEnd = hitTestInfo.dt;
  1367. if (m_selectedBlock.dtEnd >= m_selectedBlock.dtBegin)
  1368. {
  1369. m_selectedBlock.dtEnd += GetCellDuration();
  1370. }
  1371. }
  1372. else if (hitTestInfo.uHitCode & xtpCalendarHitTestDayViewAllDayEvent)
  1373. {
  1374. if (!bAllDayEvent)
  1375. {
  1376. m_dtSelectionStart = m_selectedBlock.dtBegin;
  1377. m_selectedBlock.dtBegin = CXTPCalendarUtils::ResetTime(m_selectedBlock.dtBegin);
  1378. }
  1379. m_selectedBlock.dtEnd = hitTestInfo.dt;
  1380. if (m_selectedBlock.dtEnd >= m_selectedBlock.dtBegin)
  1381. {
  1382. m_selectedBlock.dtEnd += COleDateTimeSpan(1, 0, 0, 0);
  1383. }
  1384. m_selectedBlock.bAllDayEvent = TRUE;
  1385. }
  1386. //---------------------------------------------------------------------------
  1387. if (m_selectedBlock.dtEnd != dtEnd || m_selectedBlock.bAllDayEvent != bAllDayEvent)
  1388. {
  1389. CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateRedraw);
  1390. CSelectionChangedContext selChanged1(this, xtpCalendarSelectionDays);
  1391. }
  1392. }
  1393. }
  1394. BOOL CXTPCalendarDayView::GetSelection(COleDateTime* pBegin, COleDateTime* pEnd,
  1395.    BOOL* pbAllDayEvent, int* pnGroupIndex,
  1396.    COleDateTimeSpan* pspSelectionResolution)
  1397. {
  1398. if (!m_selectedBlock.IsValid())
  1399. return FALSE;
  1400. COleDateTime dtBegin = m_selectedBlock.dtBegin, dtEnd = m_selectedBlock.dtEnd;
  1401. BOOL bAllDayEvent = m_selectedBlock.bAllDayEvent;
  1402. if (pbAllDayEvent)
  1403. {
  1404. *pbAllDayEvent = bAllDayEvent;
  1405. }
  1406. if (bAllDayEvent)
  1407. {
  1408. if (dtBegin > dtEnd)
  1409. {
  1410. COleDateTime dt = dtEnd;
  1411. dtEnd = dtBegin + COleDateTimeSpan(1, 0, 0, 0);
  1412. dtBegin = dt;
  1413. }
  1414. dtBegin = CXTPCalendarUtils::ResetTime(dtBegin);
  1415. if (!CXTPCalendarUtils::IsZeroTime(dtEnd))
  1416. {
  1417. dtEnd += COleDateTimeSpan(1, 0, 0, 0);
  1418. }
  1419. dtEnd = CXTPCalendarUtils::ResetTime(dtEnd);
  1420. }
  1421. else
  1422. {
  1423. if (dtBegin >= dtEnd)
  1424. {
  1425. COleDateTime dt = dtEnd;
  1426. dtEnd = dtBegin + GetCellDuration();
  1427. dtBegin = dt;
  1428. }
  1429. bAllDayEvent = CXTPCalendarUtils::IsZeroTime(dtBegin) &&
  1430.    CXTPCalendarUtils::IsZeroTime(dtEnd);
  1431. }
  1432. if (pBegin)
  1433. *pBegin = dtBegin;
  1434. if (pEnd)
  1435. *pEnd = dtEnd;
  1436. if (pnGroupIndex)
  1437. {
  1438. *pnGroupIndex = m_selectedBlock.nGroupIndex;
  1439. }
  1440. if (pspSelectionResolution)
  1441. {
  1442. if (bAllDayEvent)
  1443. {
  1444. *pspSelectionResolution = COleDateTimeSpan(1, 0, 0, 0);
  1445. }
  1446. else
  1447. {
  1448. *pspSelectionResolution = GetCellDuration();
  1449. }
  1450. }
  1451. return TRUE;
  1452. }
  1453. void CXTPCalendarDayView::ShowDay(const COleDateTime& date, BOOL bSelect)
  1454. {
  1455. CXTPCalendarControl::CUpdateContext updateContext(m_pControl);
  1456. ClearDays();
  1457. AddDay(date);
  1458. if (bSelect)
  1459. {
  1460. CXTPCalendarDayViewDay* pDay = m_arDays.GetCount() > 0 ? m_arDays.GetAt(0) : NULL;
  1461. if (pDay)
  1462. SelectDay(pDay);
  1463. }
  1464. }
  1465. void CXTPCalendarDayView::AddDay(const COleDateTime& date)
  1466. {
  1467. CXTPCalendarControl::CViewChangedContext viewChanged(this);
  1468. _AddDay(date);
  1469. }
  1470. void CXTPCalendarDayView::_AddDay(const COleDateTime& date)
  1471. {
  1472. CXTPCalendarControl::CUpdateContext updateContext(m_pControl);
  1473. CXTPCalendarDayViewDay* pDay = new CXTPCalendarDayViewDay(this, date);
  1474. if (pDay)
  1475. {
  1476. m_arDays.Add(pDay);
  1477. pDay->Populate(date);
  1478. }
  1479. }
  1480. void CXTPCalendarDayView::ShowDays(const COleDateTime& dtBegin, const COleDateTime& dtEnd)
  1481. {
  1482. CXTPCalendarControl::CUpdateContext updateContext(m_pControl);
  1483. CXTPCalendarControl::CViewChangedContext viewChanged(this);
  1484. ClearDays();
  1485. COleDateTimeSpan spDay(1, 0, 0, 0);
  1486. COleDateTimeSpan spDaysRange = CXTPCalendarUtils::ResetTime(dtEnd) - CXTPCalendarUtils::ResetTime(dtBegin);
  1487. int nDays = GETTOTAL_DAYS_DTS(spDaysRange) + 1;
  1488. COleDateTime dtDay = CXTPCalendarUtils::ResetTime(dtBegin);
  1489. nDays = max(1, nDays); // to be sure that at leas one day will be added
  1490. for (int i = 0; i < nDays; i++)
  1491. {
  1492. _AddDay(dtDay);
  1493. dtDay += spDay;
  1494. }
  1495. }
  1496. void CXTPCalendarDayView::ShowWorkingDays(const COleDateTime& dtDay)
  1497. {
  1498. if (!m_pControl)
  1499. {
  1500. ASSERT(FALSE);
  1501. return;
  1502. }
  1503. CXTPCalendarControl::CUpdateContext updateContext(m_pControl);
  1504. CXTPCalendarControl::CViewChangedContext viewChanged(this);
  1505. COleDateTime dtWeekDay(dtDay);
  1506. int nFirstWeekDay = m_pControl->GetFirstDayOfWeek();
  1507. // adjust beginning of the week iteration period to the FirstDayOfWeek
  1508. while (dtWeekDay.GetDayOfWeek() != nFirstWeekDay)
  1509. {
  1510. dtWeekDay -= COleDateTimeSpan(1);
  1511. }
  1512. // add all working days during the week to the collection
  1513. ClearDays();
  1514. for (int nWeekDay = 0; nWeekDay < 7; nWeekDay++)
  1515. {
  1516. int nWWMask = m_pControl->GetWorkWeekMask();
  1517. int nDayOfWeek = dtWeekDay.GetDayOfWeek();
  1518. int nDayMask = CXTPCalendarUtils::GetDayOfWeekMask(nDayOfWeek);
  1519. if (nWWMask & nDayMask)
  1520. {
  1521. _AddDay(dtWeekDay);
  1522. }
  1523. dtWeekDay += COleDateTimeSpan(1);
  1524. }
  1525. if (GetViewDayCount() == 0)
  1526. {
  1527. _AddDay(CXTPCalendarUtils::ResetTime(COleDateTime::GetCurrentTime()));
  1528. }
  1529. }
  1530. COleDateTimeSpan CXTPCalendarDayView::GetScaleInterval() const
  1531. {
  1532. int nSI_min = XTP_SAFE_GET2(m_pControl, GetCalendarOptions(), nDayView_ScaleInterval, 30);
  1533. return COleDateTimeSpan(0, 0, nSI_min, 0);
  1534. }
  1535. void CXTPCalendarDayView::SetScaleInterval(const COleDateTimeSpan spScaleInterval)
  1536. {
  1537. BOOL bValidSVal = GETTOTAL_MINUTES_DTS(spScaleInterval) >= 1;
  1538. ASSERT(bValidSVal);
  1539. if (m_pTimeScaleHeader && bValidSVal)
  1540. {
  1541. int nOldScaleInterval = XTP_SAFE_GET2(m_pControl, GetCalendarOptions(), nDayView_ScaleInterval, 30);
  1542. int nScaleInterval = (int)GETTOTAL_MINUTES_DTS(spScaleInterval);
  1543. if (nScaleInterval != nOldScaleInterval)
  1544. {
  1545. XTP_SAFE_SET2(m_pControl, GetCalendarOptions(), nDayView_ScaleInterval, nScaleInterval);
  1546. CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateAll);
  1547. SendNotification(XTP_NC_CALENDAROPTIONSWASCHANGED, xtpCalendarDayView, 0);
  1548. SendNotification(XTP_NC_CALENDARVIEWTIMESCALEWASCHANGED, 0, 0);
  1549. }
  1550. }
  1551. }
  1552. void CXTPCalendarDayView::SetScaleText(LPCTSTR strText)
  1553. {
  1554. XTP_SAFE_CALL1(m_pTimeScaleHeader, SetCaption(strText));
  1555. XTP_SAFE_SET2(m_pControl, GetCalendarOptions(), strDayView_ScaleLabel, strText);
  1556. SendNotification(XTP_NC_CALENDAROPTIONSWASCHANGED, xtpCalendarDayView, 0);
  1557. SendNotification(XTP_NC_CALENDARVIEWTIMESCALEWASCHANGED, 0, 0);
  1558. }
  1559. CString CXTPCalendarDayView::GetScaleText()
  1560. {
  1561. return XTP_SAFE_GET2(m_pControl, GetCalendarOptions(), strDayView_ScaleLabel, _T(""));
  1562. }
  1563. void CXTPCalendarDayView::SetScale2Text(LPCTSTR strText)
  1564. {
  1565. XTP_SAFE_CALL1(m_pTimeScaleHeader2, SetCaption(strText));
  1566. XTP_SAFE_SET2(m_pControl, GetCalendarOptions(), strDayView_Scale2Label, strText);
  1567. SendNotification(XTP_NC_CALENDAROPTIONSWASCHANGED, xtpCalendarDayView, 0);
  1568. SendNotification(XTP_NC_CALENDARVIEWTIMESCALEWASCHANGED, 0, 0);
  1569. }
  1570. CString CXTPCalendarDayView::GetScale2Text()
  1571. {
  1572. return XTP_SAFE_GET2(m_pControl, GetCalendarOptions(), strDayView_Scale2Label, _T(""));
  1573. }
  1574. void CXTPCalendarDayView::SetScale2TimeZone(const TIME_ZONE_INFORMATION* pTzInfo)
  1575. {
  1576. if (!pTzInfo || !m_pControl || !m_pControl->GetCalendarOptions())
  1577. {
  1578. ASSERT(FALSE);
  1579. return;
  1580. }
  1581. m_pControl->GetCalendarOptions()->tziDayView_Scale2TimeZone = *pTzInfo;
  1582. AdjustScale2TimeZone();
  1583. SendNotification(XTP_NC_CALENDAROPTIONSWASCHANGED, xtpCalendarDayView, 0);
  1584. SendNotification(XTP_NC_CALENDARVIEWTIMESCALEWASCHANGED, 0, 0);
  1585. }
  1586. void CXTPCalendarDayView::AdjustScale2TimeZone()
  1587. {
  1588. TIME_ZONE_INFORMATION tziCurrent;
  1589. ::ZeroMemory(&tziCurrent, sizeof(tziCurrent));
  1590. if (::GetTimeZoneInformation(&tziCurrent) == TIME_ZONE_ID_INVALID)
  1591. {
  1592. ASSERT(FALSE);
  1593. return;
  1594. }
  1595. TIME_ZONE_INFORMATION tziScale2 = GetScale2TimeZone();
  1596. SYSTEMTIME systm00, systmScale1, systmScale2;
  1597. ZeroMemory(&systm00, sizeof(systm00));
  1598. ZeroMemory(&systmScale1, sizeof(systmScale1));
  1599. ZeroMemory(&systmScale2, sizeof(systmScale2));
  1600. ::GetLocalTime(&systm00);
  1601. systm00.wHour = systm00.wMinute = systm00.wSecond = 0;
  1602. if (!CXTPCalendarUtils::SystemTimeToTzSpecificLocalTime(&tziCurrent,
  1603. &systm00, &systmScale1))
  1604. {
  1605. ASSERT(FALSE);
  1606. return;
  1607. }
  1608. if (!CXTPCalendarUtils::SystemTimeToTzSpecificLocalTime(&tziScale2,
  1609. &systm00, &systmScale2))
  1610. {
  1611. ASSERT(FALSE);
  1612. return;
  1613. }
  1614. COleDateTime dtScale1(systmScale1), dtScale2(systmScale2);
  1615. COleDateTimeSpan spScale2Offset = dtScale2 - dtScale1;
  1616. ASSERT((GETTOTAL_SECONDS_DTS(spScale2Offset) % 60) == 0);
  1617. int nTimeShift2_min = GETTOTAL_MINUTES_DTS(spScale2Offset);
  1618. XTP_SAFE_CALL1(m_pTimeScaleHeader2, SetTimeshift(nTimeShift2_min));
  1619. }
  1620. const TIME_ZONE_INFORMATION& CXTPCalendarDayView::GetScale2TimeZone()
  1621. {
  1622. static TIME_ZONE_INFORMATION s_tzEmty = {0};
  1623. return XTP_SAFE_GET2(m_pControl, GetCalendarOptions(), tziDayView_Scale2TimeZone, s_tzEmty);
  1624. }
  1625. void CXTPCalendarDayView::ShowScale2(BOOL bShow)
  1626. {
  1627. if (!m_pTimeScaleHeader2 || !m_pControl)
  1628. {
  1629. ASSERT(FALSE);
  1630. return;
  1631. }
  1632. m_pTimeScaleHeader2->SetVisible(bShow);
  1633. m_pControl->GetCalendarOptions()->bDayView_Scale2Visible = bShow;
  1634. m_pControl->AdjustLayout();
  1635. SendNotification(XTP_NC_CALENDAROPTIONSWASCHANGED, xtpCalendarDayView, 0);
  1636. SendNotification(XTP_NC_CALENDARVIEWTIMESCALEWASCHANGED, 0, 0);
  1637. }
  1638. BOOL CXTPCalendarDayView::IsScale2Visible()
  1639. {
  1640. return XTP_SAFE_GET2(m_pControl, GetCalendarOptions(), bDayView_Scale2Visible, FALSE);
  1641. }
  1642. COleDateTime CXTPCalendarDayView::GetViewDayDate(int nIndex)
  1643. {
  1644. CXTPCalendarDayViewDay* pViewDay = GetViewDay(nIndex);
  1645. ASSERT(pViewDay);
  1646. return pViewDay ? pViewDay->m_dtDate :
  1647. CXTPCalendarUtils::ResetTime(CXTPCalendarUtils::GetCurrentTime());
  1648. }
  1649. void CXTPCalendarDayView::_ScrollDays(int nScrollDaysCount, BOOL bPrev)
  1650. {
  1651. ASSERT(nScrollDaysCount >= 1 && nScrollDaysCount <= 14);
  1652. nScrollDaysCount = min(14, max(1, nScrollDaysCount));
  1653. int nCount = GetViewDayCount();
  1654. if (!nCount)
  1655. {
  1656. ASSERT(FALSE);
  1657. return;
  1658. }
  1659. CXTPCalendarControl::CUpdateContext updateContext(m_pControl);
  1660. CXTPCalendarControl::CViewChangedContext viewChanged(this);
  1661. COleDateTimeSpan spDay(bPrev ? -1 : 1, 0, 0, 0);
  1662. COleDateTime dtNewDay = GetViewDayDate(bPrev ? 0 : nCount-1);
  1663. for (int i = 0; i < nScrollDaysCount; i++)
  1664. {
  1665. dtNewDay += spDay;
  1666. CXTPCalendarDayViewDay* pDay = new CXTPCalendarDayViewDay(this, dtNewDay);
  1667. if (pDay)
  1668. {
  1669. m_arDays.RemoveAt(bPrev ? nCount-1 : 0);
  1670. m_arDays.InsertAt(bPrev ? 0 : nCount-1, pDay);
  1671. pDay->Populate(dtNewDay);
  1672. }
  1673. }
  1674. }
  1675. void CXTPCalendarDayView::ScrollDaysToPrev(int nScrollDaysCount)
  1676. {
  1677. _ScrollDays(nScrollDaysCount, TRUE);
  1678. }
  1679. void CXTPCalendarDayView::ScrollDaysToNext(int nScrollDaysCount)
  1680. {
  1681. _ScrollDays(nScrollDaysCount, FALSE);
  1682. }
  1683. BOOL CXTPCalendarDayView::IsExpandDown()
  1684. {
  1685. int nDays = GetViewDayCount();
  1686. for (int nDay = 0; nDay < nDays; nDay++)
  1687. {
  1688. CXTPCalendarDayViewDay* pDay = GetViewDay(nDay);
  1689. ASSERT(pDay);
  1690. if (!pDay)
  1691. continue;
  1692. int nGroupsCount = pDay->GetViewGroupsCount();
  1693. for (int i = 0; i < nGroupsCount; i++)
  1694. {
  1695. if (pDay->GetViewGroup(i) && pDay->GetViewGroup(i)->IsExpandDown())
  1696. return TRUE;
  1697. }
  1698. }
  1699. return FALSE;
  1700. }
  1701. BOOL CXTPCalendarDayView::IsExpandUp()
  1702. {
  1703. int nDays = GetViewDayCount();
  1704. for (int nDay = 0; nDay < nDays; nDay++)
  1705. {
  1706. CXTPCalendarDayViewDay* pDay = GetViewDay(nDay);
  1707. ASSERT(pDay);
  1708. if (!pDay)
  1709. continue;
  1710. int nGroupsCount = pDay->GetViewGroupsCount();
  1711. for (int i = 0; i < nGroupsCount; i++)
  1712. {
  1713. if (pDay->GetViewGroup(i) && pDay->GetViewGroup(i)->IsExpandUp())
  1714. return TRUE;
  1715. }
  1716. }
  1717. return FALSE;
  1718. }
  1719. CXTPCalendarDayViewDay* CXTPCalendarDayView::GetDay(COleDateTime dtDay)
  1720. {
  1721. dtDay = CXTPCalendarUtils::ResetTime(dtDay);
  1722. int nDays = GetViewDayCount();
  1723. for (int i = 0; i < nDays; i++)
  1724. {
  1725. COleDateTime dtDay_I = GetViewDayDate(i);
  1726. if (CXTPCalendarUtils::IsEqual(dtDay, dtDay_I))
  1727. {
  1728. return GetViewDay(i);
  1729. }
  1730. }
  1731. return NULL;
  1732. }
  1733. void CXTPCalendarDayView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  1734. {
  1735. CSelectionChangedContext selChanged(this);
  1736. TBase::OnKeyDown(nChar, nRepCnt, nFlags);
  1737. if (nChar == VK_LEFT || nChar == VK_RIGHT || nChar == VK_UP || nChar == VK_DOWN ||
  1738. nChar == VK_PRIOR || nChar == VK_NEXT)
  1739. {
  1740. CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateRedraw);
  1741. UnselectAllEvents();
  1742. BOOL bVKShift = !!(GetKeyState(VK_SHIFT) & 0x8000);
  1743. COleDateTimeSpan spCell = GetCellDuration();
  1744. COleDateTimeSpan spDay(1, 0, 0, 0);
  1745. COleDateTime dtNewSelEnd = m_selectedBlock.dtEnd;
  1746. BOOL bEndIsEnd = m_selectedBlock.dtEnd > m_selectedBlock.dtBegin || !bVKShift;
  1747. int nSelCell = GetCellNumber(CXTPCalendarUtils::ResetDate(m_selectedBlock.dtEnd -
  1748. COleDateTimeSpan(0, 0, 0, bEndIsEnd ? 1 : 0)), bEndIsEnd);
  1749. CXTPDrawHelpers::KeyToLayout(m_pControl, nChar);
  1750. int nDVCount = GetViewDayCount();
  1751. COleDateTime dtFirstDay = GetViewDayDate(0);
  1752. COleDateTime dtLastDay = GetViewDayDate(nDVCount-1);
  1753. if (nChar == VK_LEFT)
  1754. {
  1755. if (!m_bScrollH_Disabled || CXTPCalendarUtils::ResetTime(dtNewSelEnd) > dtFirstDay)
  1756. {
  1757. if (!bVKShift && m_selectedBlock.nGroupIndex > 0)
  1758. {
  1759. m_selectedBlock.nGroupIndex--;
  1760. }
  1761. else
  1762. {
  1763. dtNewSelEnd -= spDay;
  1764. CXTPCalendarDayViewDay* pDay = GetDay(dtNewSelEnd);
  1765. if (!bVKShift && pDay)
  1766. {
  1767. m_selectedBlock.nGroupIndex = pDay->GetViewGroupsCount() - 1;
  1768. }
  1769. }
  1770. }
  1771. }
  1772. else
  1773. if (nChar == VK_RIGHT)
  1774. {
  1775. if (!m_bScrollH_Disabled || CXTPCalendarUtils::ResetTime(dtNewSelEnd) < dtLastDay)
  1776. {
  1777. CXTPCalendarDayViewDay* pDay = GetDay(dtNewSelEnd);
  1778. if (!bVKShift && pDay && m_selectedBlock.nGroupIndex < pDay->GetViewGroupsCount() - 1)
  1779. {
  1780. m_selectedBlock.nGroupIndex++;
  1781. }
  1782. else
  1783. {
  1784. dtNewSelEnd += spDay;
  1785. m_selectedBlock.nGroupIndex = 0;
  1786. }
  1787. }
  1788. }
  1789. else
  1790. if (nChar == VK_UP)
  1791. {
  1792. BOOL bRange = !m_bScrollV_Disabled || nSelCell > m_LayoutX.m_nTopRow;
  1793. if (nSelCell > 0 && bRange)
  1794. {
  1795. dtNewSelEnd = CXTPCalendarUtils::UpdateTime(dtNewSelEnd, GetCellTime(nSelCell));
  1796. }
  1797. if (m_selectedBlock.bAllDayEvent)
  1798. {
  1799. m_selectedBlock.bAllDayEvent = FALSE;
  1800. dtNewSelEnd -= spDay;
  1801. }
  1802. }
  1803. else
  1804. if (nChar == VK_DOWN)
  1805. {
  1806. BOOL bRange = !m_bScrollV_Disabled || nSelCell < m_LayoutX.m_nTopRow + m_LayoutX.m_nVisibleRowCount - 1;
  1807. if (nSelCell + 1 < GetRowCount() && bRange)
  1808. {
  1809. dtNewSelEnd = CXTPCalendarUtils::UpdateTime(dtNewSelEnd, GetCellTime(nSelCell+1)) + spCell;
  1810. if (nSelCell == GetRowCount()-2)
  1811. {
  1812. dtNewSelEnd -= COleDateTimeSpan(0, 0, 0, 1);
  1813. }
  1814. }
  1815. }
  1816. else
  1817. if (nChar == VK_PRIOR)
  1818. {
  1819. if (!m_bScrollV_Disabled)
  1820. {
  1821. nSelCell = max(1, nSelCell - m_LayoutX.m_nVisibleRowCount + 1);
  1822. m_LayoutX.m_nTopRow = max(0, m_LayoutX.m_nTopRow - m_LayoutX.m_nVisibleRowCount);
  1823. dtNewSelEnd = CXTPCalendarUtils::UpdateTime(dtNewSelEnd, GetCellTime(nSelCell));
  1824. CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateScrollBar);
  1825. }
  1826. }
  1827. else
  1828. if (nChar == VK_NEXT)
  1829. {
  1830. if (!m_bScrollV_Disabled)
  1831. {
  1832. nSelCell = min(max(0, GetRowCount()-1), nSelCell + m_LayoutX.m_nVisibleRowCount);
  1833. m_LayoutX.m_nTopRow += m_LayoutX.m_nVisibleRowCount;
  1834. dtNewSelEnd = CXTPCalendarUtils::UpdateTime(dtNewSelEnd, GetCellTime(nSelCell)) + spCell;
  1835. if (nSelCell == GetRowCount()-1)
  1836. {
  1837. dtNewSelEnd -= COleDateTimeSpan(0, 0, 0, 1);
  1838. }
  1839. CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateScrollBar);
  1840. }
  1841. }
  1842. ProcessCellSelection(dtNewSelEnd, bVKShift, m_selectedBlock.bAllDayEvent,
  1843.  m_selectedBlock.nGroupIndex);
  1844. }
  1845. }
  1846. void CXTPCalendarDayView::ProcessCellSelection(COleDateTime dtNewSelEnd,
  1847. BOOL bFixSelBegin, BOOL bAllDayEventSel, int nGroupIndex)
  1848. {
  1849. int nCount = GetViewDayCount();
  1850. if (!nCount)
  1851. {
  1852. ASSERT(FALSE);
  1853. return;
  1854. }
  1855. CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateRedraw);
  1856. COleDateTimeSpan spDay(1, 0, 0, 0);
  1857. COleDateTimeSpan spCell = GetCellDuration();
  1858. COleDateTimeSpan spSelStep = bAllDayEventSel ? spDay : spCell;
  1859. COleDateTime dtFirstDay = GetViewDayDate(0);
  1860. COleDateTime dtSelBegin_prev = m_selectedBlock.dtBegin;
  1861. COleDateTime dtSelEnd_prev = m_selectedBlock.dtEnd;
  1862. if (CXTPCalendarUtils::IsEqual(m_selectedBlock.dtEnd, m_selectedBlock.dtBegin))
  1863. {
  1864. int nSelRow = GetTopRow() + min(2, GetVisibleRowCount());
  1865. m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateTime(dtFirstDay, GetCellTime(nSelRow));
  1866. m_dtSelectionStart = m_selectedBlock.dtBegin;
  1867. m_selectedBlock.dtEnd = m_selectedBlock.dtBegin + spCell;
  1868. }
  1869. m_selectedBlock.dtEnd = dtNewSelEnd;
  1870. if (!bFixSelBegin)
  1871. {
  1872. m_selectedBlock.dtBegin = m_selectedBlock.dtEnd - spSelStep;
  1873. m_dtSelectionStart = m_selectedBlock.dtBegin;
  1874. }
  1875. else
  1876. if (CXTPCalendarUtils::IsEqual(m_selectedBlock.dtEnd, m_selectedBlock.dtBegin) ||
  1877. (!bAllDayEventSel && m_selectedBlock.dtEnd < m_selectedBlock.dtBegin &&
  1878.  dtSelEnd_prev > dtSelBegin_prev)
  1879.    )
  1880. {
  1881. m_selectedBlock.dtEnd -= spSelStep;
  1882. }
  1883. m_selectedBlock.bAllDayEvent = bAllDayEventSel;
  1884. m_selectedBlock.nGroupIndex = nGroupIndex;
  1885. //===========================================================================
  1886. int nDVCount = GetViewDayCount();
  1887. COleDateTime dtLastDay = GetViewDayDate(nDVCount-1);
  1888. COleDateTime& rdtSel1 = m_selectedBlock.dtEnd < m_selectedBlock.dtBegin ?
  1889. m_selectedBlock.dtEnd : m_selectedBlock.dtBegin;
  1890. COleDateTime& rdtSel2 = m_selectedBlock.dtEnd > m_selectedBlock.dtBegin ?
  1891. m_selectedBlock.dtEnd : m_selectedBlock.dtBegin;
  1892. COleDateTime dtSelDay1 = CXTPCalendarUtils::ResetTime(rdtSel1);
  1893. COleDateTime dtSelDay2 = CXTPCalendarUtils::ResetTime(rdtSel2-COleDateTimeSpan(0, 0, 0, 1));
  1894. //---------------------------------------------------------------------------
  1895. if (!m_bScrollH_Disabled)
  1896. {
  1897. if (dtSelDay1 < dtFirstDay)
  1898. {
  1899. ScrollDaysToPrev();
  1900. }
  1901. else if (dtSelDay2 > dtLastDay)
  1902. {
  1903. ScrollDaysToNext();
  1904. }
  1905. }
  1906. //---------------------------------------------------------------------------
  1907. // update variables after scrolling
  1908. nDVCount = GetViewDayCount();
  1909. dtFirstDay = GetViewDayDate(0);
  1910. dtLastDay = GetViewDayDate(nDVCount-1);
  1911. if (dtSelDay1 < dtFirstDay || (!bFixSelBegin && dtSelDay2 >= dtLastDay))
  1912. {
  1913. if (bFixSelBegin)
  1914. {
  1915. rdtSel1 = CXTPCalendarUtils::UpdateTime(dtFirstDay, rdtSel1);
  1916. rdtSel2 = rdtSel1 + spSelStep;
  1917. }
  1918. }
  1919. //---------------------------------------------------------------------------
  1920. if (dtSelDay2 > dtLastDay || (!bFixSelBegin && dtSelDay1 <= dtFirstDay))
  1921. {
  1922. rdtSel2 = rdtSel1 + spSelStep;
  1923. }
  1924. //---------------------------------------------------------------------------
  1925. BOOL bEndIsEnd = m_selectedBlock.dtEnd > m_selectedBlock.dtBegin;
  1926. int nSelEndCell = GetCellNumber(CXTPCalendarUtils::ResetDate(m_selectedBlock.dtEnd -
  1927. COleDateTimeSpan(0, 0, 0, bEndIsEnd ? 1 : 0)), bEndIsEnd);
  1928. if (nSelEndCell < m_LayoutX.m_nTopRow && !bAllDayEventSel)
  1929. {
  1930. if (!m_bScrollV_Disabled)
  1931. {
  1932. m_LayoutX.m_nTopRow = min(max(0, nSelEndCell), max(0, GetRowCount()-1));
  1933. CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateScrollBar);
  1934. }
  1935. }
  1936. else if (nSelEndCell >= m_LayoutX.m_nTopRow + m_LayoutX.m_nVisibleRowCount && !bAllDayEventSel)
  1937. {
  1938. if (!m_bScrollV_Disabled)
  1939. {
  1940. m_LayoutX.m_nTopRow = nSelEndCell - m_LayoutX.m_nVisibleRowCount + 1;
  1941. m_LayoutX.m_nTopRow = min(max(0, m_LayoutX.m_nTopRow), max(0, GetRowCount() - 1));
  1942. CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateScrollBar);
  1943. }
  1944. }
  1945. if (_EnsureVisibleSelectionH())
  1946. {
  1947. GetCalendarControl()->AdjustLayout();
  1948. CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateScrollBar);
  1949. }
  1950. CSelectionChangedContext selChanged(this, xtpCalendarSelectionDays);
  1951. }
  1952. BOOL CXTPCalendarDayView::_EnsureVisibleSelectionH()
  1953. {
  1954. if (!m_selectedBlock.IsValid())
  1955. return FALSE;
  1956. CXTPCalendarViewDay* pVDay = _GetViewDay(CXTPCalendarUtils::ResetTime(m_selectedBlock.dtEnd));
  1957. ASSERT(pVDay);
  1958. if (!pVDay)
  1959. return FALSE;
  1960. CRect rcGroup = pVDay->GetDayRect();
  1961. {
  1962. CXTPCalendarViewGroup* pVGroup = pVDay->GetViewGroup_(m_selectedBlock.nGroupIndex);
  1963. ASSERT(pVGroup);
  1964. if (pVGroup)
  1965. rcGroup = pVGroup->GetRect();
  1966. }
  1967. CRect rcVisible = _GetScrollRectClient();
  1968. int nNewScrollPos = m_nScrollOffsetX;
  1969. if (rcGroup.left < rcVisible.left)
  1970. {
  1971. nNewScrollPos -= rcVisible.left - rcGroup.left;
  1972. if (nNewScrollPos <= 2) nNewScrollPos = 0;
  1973. }
  1974. else if (rcGroup.right > rcVisible.right)
  1975. {
  1976. nNewScrollPos += rcGroup.right - rcVisible.right + 1;
  1977. }
  1978. if (nNewScrollPos != m_nScrollOffsetX)
  1979. {
  1980. ScrollH(nNewScrollPos, nNewScrollPos);
  1981. return TRUE;
  1982. }
  1983. return FALSE;
  1984. }
  1985. BOOL CXTPCalendarDayView::EnsureVisibleH(CXTPCalendarViewGroup* pViewGroup)
  1986. {
  1987. ASSERT(pViewGroup);
  1988. if (!pViewGroup)
  1989. return FALSE;
  1990. SCROLLINFO si;
  1991. if (!GetScrollBarInfoH(&si))
  1992. return FALSE;
  1993. CRect rcVisible = _GetScrollRectClient();
  1994. CRect rcGroup = pViewGroup->GetRect();
  1995. int nNewScrollPos = m_nScrollOffsetX;
  1996. if (rcGroup.left < rcVisible.left)
  1997. {
  1998. nNewScrollPos -= rcVisible.left - rcGroup.left;
  1999. }
  2000. else if (rcGroup.right > rcVisible.right)
  2001. {
  2002. nNewScrollPos += rcGroup.right - rcVisible.right + 1;
  2003. }
  2004. if (nNewScrollPos != m_nScrollOffsetX)
  2005. {
  2006. ScrollH(nNewScrollPos, nNewScrollPos);
  2007. GetCalendarControl()->AdjustLayout();
  2008. CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateScrollBar);
  2009. return TRUE;
  2010. }
  2011. return FALSE;
  2012. }
  2013. BOOL CXTPCalendarDayView::_EnsureVisibleH(CXTPCalendarViewEvent* pViewEvent)
  2014. {
  2015. ASSERT(pViewEvent);
  2016. CXTPCalendarViewGroup* pVGroup = pViewEvent ? pViewEvent->GetViewGroup_() : NULL;
  2017. ASSERT(pVGroup);
  2018. if (!pVGroup)
  2019. return FALSE;
  2020. SCROLLINFO si;
  2021. if (!GetScrollBarInfoH(&si))
  2022. return FALSE;
  2023. CRect rcVisible = _GetScrollRectClient();
  2024. CRect rcObj = pViewEvent->GetEventRect();
  2025. CRect rcGroup = pVGroup->GetRect();
  2026. if (pViewEvent->IsMultidayEvent() && (pViewEvent->GetMultiDayEventFlags() & xtpCalendarMultiDayMaster))
  2027. {
  2028. rcObj.left = max(rcObj.left, rcVisible.left);
  2029. rcObj.right = min(rcObj.right, rcVisible.right);
  2030. rcGroup.right = rcGroup.left + rcVisible.Width();
  2031. }
  2032. int nNewScrollPos = m_nScrollOffsetX;
  2033. if (rcObj.left < rcVisible.left)
  2034. {
  2035. nNewScrollPos -= rcVisible.left - rcGroup.left;
  2036. }
  2037. else if (rcObj.right > rcVisible.right)
  2038. {
  2039. nNewScrollPos += rcGroup.right - rcVisible.right + 1;
  2040. }
  2041. if (nNewScrollPos != m_nScrollOffsetX)
  2042. {
  2043. ScrollH(nNewScrollPos, nNewScrollPos);
  2044. return TRUE;
  2045. }
  2046. return FALSE;
  2047. }
  2048. BOOL CXTPCalendarDayView::_EnsureVisibleV(CXTPCalendarViewEvent* pViewEvent)
  2049. {
  2050. if (!pViewEvent || !pViewEvent->GetEvent() || !GetCalendarControl() ||
  2051. !XTP_SAFE_GET2(pViewEvent, GetViewGroup_(), GetViewDay_(), NULL) )
  2052. {
  2053. ASSERT(FALSE);
  2054. return FALSE;
  2055. }
  2056. //---------------------------------------------------------------------------
  2057. if (pViewEvent->IsMultidayEvent())
  2058. {
  2059. //return pViewEvent->IsVisible();
  2060. return FALSE;
  2061. }
  2062. //---------------------------------------------------------------------------
  2063. COleDateTime dtDay = XTP_SAFE_GET3(pViewEvent, GetViewGroup_(), GetViewDay_(), GetDayDate(), (DATE)0);
  2064. dtDay = CXTPCalendarUtils::ResetTime(dtDay);
  2065. COleDateTime dtStart = pViewEvent->GetEvent()->GetStartTime();
  2066. COleDateTime dtEnd = pViewEvent->GetEvent()->GetEndTime();
  2067. COleDateTime stSTime = CXTPCalendarUtils::ResetDate(dtStart);
  2068. COleDateTime stETime = CXTPCalendarUtils::ResetDate(dtEnd);
  2069. if (CXTPCalendarUtils::IsZeroTime(stETime))
  2070. stETime = CXTPCalendarUtils::SetTime_235959(stETime);
  2071. int nSCell = 0;
  2072. int nECell = max(0, GetRowCount() - 1);
  2073. if (CXTPCalendarUtils::ResetTime(dtStart) == dtDay)
  2074. nSCell =  GetCellNumber(stSTime, FALSE);
  2075. if (CXTPCalendarUtils::ResetTime(dtEnd) == dtDay)
  2076. nECell = GetCellNumber(stETime, TRUE);
  2077. if (nSCell < m_LayoutX.m_nTopRow)
  2078. {
  2079. m_LayoutX.m_nTopRow = min(max(0, nSCell-1), max(0, GetRowCount()-1));
  2080. return TRUE;
  2081. }
  2082. else if (nECell >= m_LayoutX.m_nTopRow + m_LayoutX.m_nVisibleRowCount)
  2083. {
  2084. int nTopRowPrev = m_LayoutX.m_nTopRow;
  2085. m_LayoutX.m_nTopRow = nECell - m_LayoutX.m_nVisibleRowCount + 1;
  2086. m_LayoutX.m_nTopRow = min(max(0, m_LayoutX.m_nTopRow), max(0, GetRowCount()-1));
  2087. m_LayoutX.m_nTopRow = min(max(0, nSCell-1), m_LayoutX.m_nTopRow);
  2088. if (nTopRowPrev != m_LayoutX.m_nTopRow)
  2089. {
  2090. return TRUE;
  2091. }
  2092. }
  2093. return FALSE;
  2094. }
  2095. BOOL CXTPCalendarDayView::EnsureVisible(CXTPCalendarViewEvent* pViewEvent)
  2096. {
  2097. ASSERT(pViewEvent);
  2098. if (!pViewEvent)
  2099. return FALSE;
  2100. BOOL bChanged1 = _EnsureVisibleH(pViewEvent);
  2101. BOOL bChanged2 = _EnsureVisibleV(pViewEvent);
  2102. if (bChanged1 || bChanged2)
  2103. {
  2104. GetCalendarControl()->AdjustLayout();
  2105. CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateScrollBar);
  2106. }
  2107. ASSERT(pViewEvent->IsVisible());
  2108. return TRUE;
  2109. }
  2110. BOOL CXTPCalendarDayView::EnsureVisibleH(CXTPCalendarViewEvent* pViewEvent)
  2111. {
  2112. ASSERT(pViewEvent);
  2113. if (!pViewEvent)
  2114. return FALSE;
  2115. BOOL bChanged1 = _EnsureVisibleH(pViewEvent);
  2116. if (bChanged1)
  2117. {
  2118. GetCalendarControl()->AdjustLayout();
  2119. CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateScrollBar);
  2120. }
  2121. ASSERT(pViewEvent->IsVisible());
  2122. return TRUE;
  2123. }
  2124. CXTPCalendarViewEvent* CXTPCalendarDayView::FindEventToEditByTAB(COleDateTime dtMinStart,
  2125. BOOL bReverse, CXTPCalendarEvent* pAfterEvent)
  2126. {
  2127. CXTPCalendarViewEvent* pViewEvent = TBase::FindEventToEditByTAB(dtMinStart, bReverse, pAfterEvent);
  2128. if (pViewEvent)
  2129. {
  2130. if (EnsureVisible(pViewEvent))
  2131. {
  2132. return pViewEvent;
  2133. }
  2134. }
  2135. return NULL;
  2136. }
  2137. COleDateTime CXTPCalendarDayView::GetNextTimeEditByTAB()
  2138. {
  2139. COleDateTime dtSel1 = min(m_selectedBlock.dtBegin, m_selectedBlock.dtEnd);
  2140. COleDateTime dtSel2 = max(m_selectedBlock.dtBegin, m_selectedBlock.dtEnd);
  2141. COleDateTime dtSel1Day = CXTPCalendarUtils::ResetTime(dtSel1);
  2142. COleDateTime dtSel2Day = CXTPCalendarUtils::ResetTime(dtSel2);
  2143. int nDVCount = GetViewDayCount();
  2144. COleDateTime dtFirstDay = GetViewDayDate(0);
  2145. COleDateTime dtLastDay = GetViewDayDate(nDVCount-1);
  2146. if (dtSel1Day >= dtFirstDay && dtSel1Day <= dtLastDay)
  2147. {
  2148. return dtSel1;
  2149. }
  2150. else
  2151. if (dtSel2Day >= dtFirstDay && dtSel2Day <= dtLastDay)
  2152. {
  2153. return dtSel2;
  2154. }
  2155. return TBase::GetNextTimeEditByTAB();
  2156. }
  2157. void CXTPCalendarDayView::UpdateNextTimeEditByTAB(COleDateTime dtNext, BOOL bReverse, BOOL bReset)
  2158. {
  2159. m_selectedBlock.dtBegin = m_selectedBlock.dtEnd = GetNextTimeEditByTAB();
  2160. m_dtSelectionStart = m_selectedBlock.dtBegin;
  2161. COleDateTime dtNextDay = CXTPCalendarUtils::ResetTime(dtNext);
  2162. COleDateTime dtCurrDay = CXTPCalendarUtils::ResetTime(GetNextTimeEditByTAB());
  2163. if (dtNextDay != dtCurrDay || bReset)
  2164. {
  2165. m_selectedBlock.dtBegin = m_selectedBlock.dtEnd = dtNextDay;
  2166. m_dtSelectionStart = m_selectedBlock.dtBegin;
  2167. COleDateTime dtFirstDay = GetViewDayDate(bReverse ? GetViewDayCount()-1 : 0);
  2168. if (dtNextDay == dtFirstDay || bReset)
  2169. {
  2170. if (bReverse)
  2171. {
  2172. m_selectedBlock.dtBegin = m_selectedBlock.dtEnd = dtNextDay + COleDateTimeSpan(1, 0, 0, 0);
  2173. m_selectedBlock.dtBegin = m_selectedBlock.dtEnd - GetCellDuration();
  2174. }
  2175. else
  2176. {
  2177. m_selectedBlock.dtEnd = m_selectedBlock.dtBegin + GetCellDuration();
  2178. }
  2179. ProcessCellSelection(m_selectedBlock.dtEnd, FALSE, FALSE, 0);
  2180. }
  2181. }
  2182. }
  2183. COleDateTimeSpan CXTPCalendarDayView::GetEventDurationMin() const
  2184. {
  2185. return GetCellDuration();
  2186. }
  2187. CXTPCalendarTimeZonePtr CXTPCalendarDayView::GetCurrentTimeZoneInfo()
  2188. {
  2189. TIME_ZONE_INFORMATION tziCurrent;
  2190. ::ZeroMemory(&tziCurrent, sizeof(tziCurrent));
  2191. if (::GetTimeZoneInformation(&tziCurrent) == TIME_ZONE_ID_INVALID)
  2192. {
  2193. ASSERT(FALSE);
  2194. return NULL;
  2195. }
  2196. return CXTPCalendarTimeZone::GetTimeZoneInfo(&tziCurrent);
  2197. }
  2198. CXTPCalendarTimeZonePtr CXTPCalendarDayView::GetScale2TimeZoneInfo()
  2199. {
  2200. return CXTPCalendarTimeZone::GetTimeZoneInfo(&GetScale2TimeZone());
  2201. }
  2202. void CXTPCalendarDayView::ScrollToWorkDayBegin()
  2203. {
  2204. if (!m_pControl || !m_pControl->GetCalendarOptions())
  2205. {
  2206. ASSERT(FALSE);
  2207. return;
  2208. }
  2209. COleDateTime dtStartDate = GetViewDayDate(0);
  2210. COleDateTime dtSelBegin = CXTPCalendarUtils::UpdateTime(dtStartDate, m_pControl->GetCalendarOptions()->dtWorkDayStartTime);
  2211. COleDateTime dtSelEnd = dtSelBegin + GetCellDuration();
  2212. SetSelection(dtSelBegin, dtSelEnd, FALSE);
  2213. int nWDStartCell = GetCellNumber(m_pControl->GetCalendarOptions()->dtWorkDayStartTime, FALSE);
  2214. _ScrollV(nWDStartCell, nWDStartCell);
  2215. }
  2216. int CXTPCalendarDayView::_GetTimeScaleWith()
  2217. {
  2218. int nWidth = XTP_SAFE_GET1(GetTimeScale(), GetWidth(), 0);
  2219. if (IsScale2Visible())
  2220. nWidth += XTP_SAFE_GET1(GetTimeScale(2), GetWidth(), 0);
  2221. return nWidth;
  2222. }
  2223. CRect CXTPCalendarDayView::_GetScrollRectClient()
  2224. {
  2225. CXTPClientRect rcClient(GetCalendarControl());
  2226. rcClient.left += _GetTimeScaleWith();
  2227. rcClient.left = min(rcClient.left, rcClient.right);
  2228. return rcClient;
  2229. }
  2230. /////////////////////////////////////////////////////////////////////////////