2722 lines
71 KiB
C++
2722 lines
71 KiB
C++
// XTPCalendarDayView.cpp: implementation of the CXTPCalendarDayView class.
|
|
//
|
|
// This file is a part of the XTREME CALENDAR MFC class library.
|
|
// (c)1998-2008 Codejock Software, All Rights Reserved.
|
|
//
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
|
//
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
|
// SINGLE COMPUTER.
|
|
//
|
|
// CONTACT INFORMATION:
|
|
// support@codejock.com
|
|
// http://www.codejock.com
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "XTPCalendarData.h"
|
|
#include "XTPCalendarDayView.h"
|
|
#include "XTPCalendarDayViewTimeScale.h"
|
|
#include "XTPCalendarUtils.h"
|
|
|
|
#include "XTPCalendarPaintManager.h"
|
|
#include "XTPCalendarTheme.h"
|
|
#include "XTPCalendarThemeOffice2007.h"
|
|
|
|
#include "XTPCalendarControl.h"
|
|
#include "XTPCalendarRecurrencePattern.h"
|
|
#include "XTPCalendarNotifications.h"
|
|
|
|
#include "Common/XTPDrawHelpers.h"
|
|
#include "Common/XTPVC50Helpers.h"
|
|
|
|
#include <math.h>
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
#define XTP_SCROLL_TIMER_RESOLUTION_MS 30
|
|
#define XTP_REDRAW_TIMER_RESOLUTION_MS 2000
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
IMPLEMENT_DYNAMIC(CXTPCalendarDayView, CXTPCalendarView)
|
|
|
|
CXTPCalendarDayView::CXTPCalendarDayView(CXTPCalendarControl* pCalendarControl) :
|
|
TBase(pCalendarControl, xtpCalendarDayView),
|
|
m_ptLastMousePos(0, 0)
|
|
{
|
|
m_pTimeScaleHeader = new CXTPCalendarDayViewTimeScale(this);
|
|
m_pTimeScaleHeader2 = new CXTPCalendarDayViewTimeScale(this, FALSE, FALSE);
|
|
|
|
m_LayoutX.m_nRowCount = 0;
|
|
m_LayoutX.m_nVisibleRowCount = 0;
|
|
m_LayoutX.m_nTopRow = 0;
|
|
|
|
m_LayoutX.m_rcAllDayEvents.SetRectEmpty();
|
|
m_LayoutX.m_rcDayHeader.SetRectEmpty();
|
|
|
|
m_LayoutX.m_nAllDayEventsCountMax = 0;
|
|
m_LayoutX.m_nAllDayEventHeight = 0;
|
|
|
|
m_nAllDayEventsCountMin_WhenDrag = 0;
|
|
|
|
m_spDraggingStartOffset_Time = 0.;
|
|
|
|
m_nScrollOffsetX = 0;
|
|
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).
|
|
|
|
// add today to the day view by default
|
|
COleDateTime dtNow(CXTPCalendarUtils::GetCurrentTime());
|
|
m_arDays.Add(new CXTPCalendarDayViewDay(this, dtNow));
|
|
|
|
// go to the beginning of the work day
|
|
int nHour = 0, nMin = 0, nSec = 0;
|
|
XTP_SAFE_CALL1(m_pControl, GetWorkDayStartTime(nHour, nMin, nSec));
|
|
int nPos = GetCellNumber(nHour, nMin, nSec, FALSE);
|
|
_ScrollV(nPos, nPos);
|
|
|
|
m_dwScrollingEventTimerID = 0;
|
|
m_bMouseOutOfDragArea = FALSE;
|
|
m_dtDraggingStartPoint = COleDateTime(0, 0, 0, 0, 0, 0);
|
|
|
|
m_dwRedrawNowLineTimerID = 0;
|
|
m_dtLastRedrawTime = CXTPCalendarUtils::GetCurrentTime();
|
|
|
|
m_ptLBtnDownMousePos = CPoint(0,0);
|
|
}
|
|
|
|
CXTPCalendarDayView::~CXTPCalendarDayView()
|
|
{
|
|
CMDTARGET_RELEASE(m_pTimeScaleHeader);
|
|
CMDTARGET_RELEASE(m_pTimeScaleHeader2);
|
|
|
|
ClearDays();
|
|
}
|
|
|
|
XTPCalendarViewType CXTPCalendarDayView::GetViewType()
|
|
{
|
|
int nWWMask = m_pControl ? m_pControl->GetWorkWeekMask() : xtpCalendarDayMo_Fr;
|
|
|
|
int nDaysCount = GetViewDayCount();
|
|
|
|
int nWWCount = CXTPCalendarUtils::GetDayOfWeekCount(nWWMask);
|
|
if (nDaysCount != nWWCount && nDaysCount != 7)
|
|
{
|
|
return xtpCalendarDayView;
|
|
}
|
|
|
|
int nFirstDayOfWeek = m_pControl ? m_pControl->GetFirstDayOfWeek() : xtpCalendarDayMonday;
|
|
int nNextWWeekIdx = CXTPCalendarUtils::GetDayOfWeekIndex(nFirstDayOfWeek);
|
|
BOOL bWDOrderFull = TRUE;
|
|
int nViewType = xtpCalendarWorkWeekView;
|
|
|
|
for (int i = 0; i < nDaysCount; i++)
|
|
{
|
|
COleDateTime dtDay = GetViewDayDate(i);
|
|
int nDayOfWeek = dtDay.GetDayOfWeek();
|
|
int nDayMask = CXTPCalendarUtils::GetDayOfWeekMask(nDayOfWeek);
|
|
|
|
if ((nWWMask & nDayMask) == 0)
|
|
{
|
|
nViewType = xtpCalendarDayView;
|
|
}
|
|
|
|
if (nNextWWeekIdx != nDayOfWeek)
|
|
bWDOrderFull = FALSE;
|
|
|
|
nNextWWeekIdx = (nNextWWeekIdx % 7) + 1;
|
|
}
|
|
|
|
if (nDaysCount == 7 && bWDOrderFull)
|
|
nViewType = xtpCalendarFullWeekView;
|
|
|
|
return (XTPCalendarViewType)nViewType;
|
|
}
|
|
|
|
void CXTPCalendarDayView::ClearDays()
|
|
{
|
|
m_arDays.RemoveAll();
|
|
}
|
|
|
|
COleDateTime CXTPCalendarDayView::GetCellTime(int nCell) const
|
|
{
|
|
double dblTime = (long)nCell * (double)GetCellDuration();
|
|
|
|
return (DATE)dblTime;
|
|
}
|
|
|
|
COleDateTimeSpan CXTPCalendarDayView::GetCellDuration() const
|
|
{
|
|
return m_pTimeScaleHeader ? m_pTimeScaleHeader->GetScaleInterval() : (double)0;
|
|
}
|
|
|
|
int CXTPCalendarDayView::GetCellNumber(COleDateTime dtTime, BOOL bForEndTime) const
|
|
{
|
|
double dblTime = (double)CXTPCalendarUtils::ResetDate(dtTime);
|
|
|
|
double dblEpsilon = XTP_HALF_SECOND * (bForEndTime ? -1 : 1);
|
|
double dblCellDur = (double)GetCellDuration();
|
|
if (dblCellDur <= XTP_HALF_SECOND)
|
|
{
|
|
dblCellDur = XTP_HALF_SECOND * 2 * 60 * 30;
|
|
}
|
|
int nCell = int(dblTime / dblCellDur + dblEpsilon);
|
|
return nCell;
|
|
}
|
|
|
|
int CXTPCalendarDayView::GetCellNumber(int nHour, int nMin, int nSec, BOOL bForEndTime) const
|
|
{
|
|
COleDateTime dtTime;
|
|
dtTime.SetTime(nHour, nMin, nSec);
|
|
return GetCellNumber(dtTime, bForEndTime);
|
|
}
|
|
|
|
void CXTPCalendarDayView::ScrollV(int nIndex, int nPos_raw)
|
|
{
|
|
if (m_bScrollV_Disabled)
|
|
{
|
|
return;
|
|
}
|
|
_ScrollV(nIndex, nPos_raw);
|
|
}
|
|
|
|
void CXTPCalendarDayView::_ScrollV(int nIndex, int /*nPos_raw*/)
|
|
{
|
|
if (nIndex + m_LayoutX.m_nVisibleRowCount >= m_LayoutX.m_nRowCount)
|
|
{
|
|
nIndex = m_LayoutX.m_nRowCount - m_LayoutX.m_nVisibleRowCount;
|
|
}
|
|
|
|
if (nIndex == m_LayoutX.m_nTopRow)
|
|
return;
|
|
|
|
m_LayoutX.m_nTopRow = nIndex;
|
|
}
|
|
|
|
void CXTPCalendarDayView::ScrollH(int nPos, int nPos_raw)
|
|
{
|
|
SCROLLINFO si;
|
|
if (!GetScrollBarInfoH(&si))
|
|
{
|
|
m_nScrollOffsetX = 0;
|
|
}
|
|
|
|
int nXmax = si.nMax - si.nPage + 1;
|
|
|
|
m_nScrollOffsetX = min(max(nPos, si.nMin), nXmax);
|
|
|
|
if (!m_bScrollH_Disabled)
|
|
{
|
|
if (nPos_raw < 0)
|
|
{
|
|
ScrollDaysToPrev();
|
|
}
|
|
else if (nPos_raw > nXmax)
|
|
{
|
|
ScrollDaysToNext();
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::GetScrollBarInfoV(SCROLLINFO* pSI)
|
|
{
|
|
ASSERT(pSI);
|
|
if (!pSI || m_bScrollV_Disabled)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
pSI->nPos = m_LayoutX.m_nTopRow;
|
|
pSI->nMax = m_LayoutX.m_nRowCount - 1;
|
|
pSI->nPage = m_LayoutX.m_nVisibleRowCount;
|
|
|
|
return m_LayoutX.m_nVisibleRowCount != m_LayoutX.m_nRowCount;
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::GetScrollBarInfoH(SCROLLINFO* pSI, int* pnScrollStep)
|
|
{
|
|
ASSERT(pSI);
|
|
if (!pSI)
|
|
return FALSE;
|
|
|
|
int nMinColumnWidth = RecalcMinColumnWidth();
|
|
if (nMinColumnWidth <= 0)
|
|
return FALSE;
|
|
int nColumnsCount = GetTotalGroupsCount();
|
|
|
|
CRect rcClient = _GetScrollRectClient();
|
|
|
|
int nFullWidth = nColumnsCount * nMinColumnWidth;
|
|
|
|
if (nFullWidth <= rcClient.Width())
|
|
return FALSE;
|
|
|
|
pSI->nPos = min(m_nScrollOffsetX, nFullWidth);
|
|
pSI->nMin = 0;
|
|
pSI->nMax = nFullWidth-1;
|
|
pSI->nPage = rcClient.Width();
|
|
|
|
if (pnScrollStep)
|
|
*pnScrollStep = 15;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int CXTPCalendarDayView::GetTotalGroupsCount()
|
|
{
|
|
int nGroupsCount = 0;
|
|
|
|
int nDays = GetViewDayCount();
|
|
for (int i = 0; i < nDays; i++)
|
|
{
|
|
CXTPCalendarDayViewDay* pDay = GetViewDay(i);
|
|
ASSERT(pDay);
|
|
if (pDay)
|
|
nGroupsCount += pDay->GetViewGroupsCount();
|
|
}
|
|
return nGroupsCount;
|
|
}
|
|
|
|
int CXTPCalendarDayView::RecalcMinColumnWidth()
|
|
{
|
|
int nMinColumnWidth = m_nMinColumnWidth;
|
|
if (nMinColumnWidth < 0)
|
|
{
|
|
// automatically use horizontal scrolling for multi-resources mode
|
|
if (GetResources() && GetResources()->GetCount() <= 1)
|
|
return -1;
|
|
|
|
if (nMinColumnWidth == -1)
|
|
nMinColumnWidth = ::GetSystemMetrics(SM_CXFULLSCREEN) / 6;
|
|
else
|
|
nMinColumnWidth = abs(nMinColumnWidth);
|
|
}
|
|
return nMinColumnWidth;
|
|
}
|
|
|
|
int CXTPCalendarDayView::GetAllDayEventsMaxCount()
|
|
{
|
|
int nAllDayMax = 0;
|
|
int nCount = GetViewDayCount();
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
CXTPCalendarDayViewDay* pViewDay = GetViewDay(i);
|
|
ASSERT(pViewDay);
|
|
if (!pViewDay)
|
|
continue;
|
|
int nGroupsCount = pViewDay->GetViewGroupsCount();
|
|
for (int g = 0; g < nGroupsCount; g++)
|
|
{
|
|
int nAllDay = 0;
|
|
|
|
CXTPCalendarDayViewGroup* pViewGroup = pViewDay->GetViewGroup(g);
|
|
ASSERT(pViewGroup);
|
|
if (!pViewGroup)
|
|
{
|
|
continue;
|
|
}
|
|
int nECount = pViewGroup->GetViewEventsCount();
|
|
for (int j = 0; j < nECount; j++)
|
|
{
|
|
CXTPCalendarDayViewEvent* pViewEvent = pViewGroup->GetViewEvent(j);
|
|
ASSERT(pViewEvent);
|
|
if (pViewEvent && pViewEvent->IsMultidayEvent())
|
|
{
|
|
nAllDay++;
|
|
}
|
|
}
|
|
|
|
nAllDayMax = max(nAllDayMax, nAllDay);
|
|
}
|
|
}
|
|
return nAllDayMax;
|
|
}
|
|
|
|
void CXTPCalendarDayView::AdjustAllDayEvents()
|
|
{
|
|
if (GetResources() && GetResources()->GetCount() > 1)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int nDaysCount = GetViewDayCount();
|
|
for (int nDayIdx = 0; nDayIdx < nDaysCount; nDayIdx++)
|
|
{
|
|
CXTPCalendarDayViewDay* pViewDay = GetViewDay(nDayIdx);
|
|
if (!pViewDay)
|
|
{
|
|
ASSERT(FALSE);
|
|
continue;
|
|
}
|
|
// go through all days to look for multiday events
|
|
int nGroupsCount = pViewDay->GetViewGroupsCount();
|
|
for (int g = 0; g < nGroupsCount; g++)
|
|
{
|
|
CXTPCalendarDayViewGroup* pViewGroup = pViewDay->GetViewGroup(g);
|
|
ASSERT(pViewGroup);
|
|
if (!pViewGroup)
|
|
{
|
|
continue;
|
|
}
|
|
int nEventsCount = pViewGroup->GetViewEventsCount();
|
|
for (int nEvent = 0; nEvent < nEventsCount; nEvent++)
|
|
{
|
|
CXTPCalendarViewEvent* pViewEvent = pViewGroup->GetViewEvent(nEvent);
|
|
if (!pViewEvent)
|
|
{
|
|
ASSERT(FALSE);
|
|
continue;
|
|
}
|
|
|
|
int nMDEFlags = pViewEvent->GetMultiDayEventFlags();
|
|
|
|
if ((nMDEFlags & xtpCalendarMultiDayMSmask) || !(nMDEFlags & xtpCalendarMultiDayFMLmask))
|
|
{
|
|
continue; // already marked or not multi day
|
|
}
|
|
//------------------------
|
|
|
|
pViewEvent->SetMultiDayEvent_MasterSlave(TRUE, NULL);
|
|
int nMasterPlace = pViewEvent->GetEventPlaceNumber();
|
|
|
|
if ((nMDEFlags & xtpCalendarMultiDayLast) == 0)
|
|
{
|
|
// find other visible instances and mark them as Slave
|
|
for (int i = nDayIdx + 1; i < nDaysCount; i++)
|
|
{
|
|
CXTPCalendarViewDay* pViewDay2 = GetViewDay(i);
|
|
if (XTP_SAFE_GET1(pViewDay2, GetViewGroupsCount(), 0) != 1)
|
|
{
|
|
ASSERT(FALSE);
|
|
break;
|
|
}
|
|
CXTPCalendarViewEvent* pViewEvent2 = XTP_SAFE_GET2(pViewDay2,
|
|
GetViewGroup_(0), GetViewEventByEvent_(pViewEvent->GetEvent()), NULL);
|
|
|
|
if (!pViewEvent2)
|
|
{
|
|
break;
|
|
}
|
|
pViewEvent->AddMultiDayEvent_Slave(pViewEvent2, nMasterPlace);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
int CXTPCalendarDayView::CalculateHeaderFormatAndHeight(CDC* pDC, int nCellWidth)
|
|
{
|
|
ASSERT(pDC);
|
|
|
|
const int cnMinHeight = 19;
|
|
|
|
CXTPCalendarViewPart* pPart = XTP_SAFE_GET1(GetPaintManager(), GetDayViewHeaderPart(), NULL);
|
|
ASSERT(pPart);
|
|
if (!pPart || !pDC)
|
|
{
|
|
return cnMinHeight;
|
|
}
|
|
|
|
CalculateHeaderFormat(pDC, nCellWidth, &pPart->GetTextFont());
|
|
|
|
CString strHearderTest = _T("QW(");
|
|
|
|
int nCount = GetViewDayCount();
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
CXTPCalendarDayViewDay* pDay = GetViewDay(i);
|
|
ASSERT(pDay);
|
|
if (pDay)
|
|
{
|
|
strHearderTest += pDay->GetCaption();
|
|
}
|
|
}
|
|
|
|
CXTPFontDC fnt(pDC, &pPart->GetTextFont());
|
|
|
|
CSize sizeH = pDC->GetTextExtent(strHearderTest);
|
|
int nHeight = max(cnMinHeight, sizeH.cy + 6);
|
|
|
|
return nHeight;
|
|
}
|
|
|
|
CXTPCalendarData* CXTPCalendarDayView::_GetDataProviderByConnStr(LPCTSTR pcszConnStr, BOOL bCompareNoCase)
|
|
{
|
|
UNREFERENCED_PARAMETER(pcszConnStr);
|
|
UNREFERENCED_PARAMETER(bCompareNoCase);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::IsGroupHeaderVisible()
|
|
{
|
|
BOOL bHideHeader = XTP_SAFE_GET1(GetResources(), GetCount(), 0) == 1 &&
|
|
XTP_SAFE_GET2(GetResources(), GetAt(0), IsSchedulesSetEmpty(), FALSE);
|
|
return !bHideHeader;
|
|
}
|
|
|
|
void CXTPCalendarDayView::AdjustLayout(CDC* pDC, const CRect& rcView, BOOL bCallPostAdjustLayout)
|
|
{
|
|
ASSERT(pDC);
|
|
if (!pDC)
|
|
{
|
|
return;
|
|
}
|
|
|
|
XTP_SAFE_CALL1(m_pTimeScaleHeader, SetCaption(GetScaleText()) );
|
|
XTP_SAFE_CALL1(m_pTimeScaleHeader2, SetCaption(GetScale2Text()) );
|
|
XTP_SAFE_CALL1(m_pTimeScaleHeader2, SetVisible(IsScale2Visible()) );
|
|
|
|
TBase::AdjustLayout(pDC, rcView, FALSE);
|
|
|
|
COleDateTimeSpan spDay(1, 0, 0, 0);
|
|
|
|
double dRows = spDay / max((double)m_pTimeScaleHeader->GetScaleInterval(), XTP_HALF_SECOND * 2);
|
|
m_LayoutX.m_nRowCount = (int)(dRows + XTP_HALF_SECOND); // to prevent loosing 1 : (int)(47.99999999999) = 47; // need 48 !
|
|
|
|
//CString str; str.Format(_T("RowsCount[%d] = %.15e (%.15e)"), m_nRowCount, dRows, (dRows + XTP_HALF_SECOND));
|
|
//AfxMessageBox(str);
|
|
|
|
CRect rcView2 = rcView;
|
|
// alternative time scale
|
|
if (IsScale2Visible())
|
|
{
|
|
int nTimeScale2Width = XTP_SAFE_GET1(m_pTimeScaleHeader2, CalcWidth(pDC), 0);
|
|
|
|
m_pTimeScaleHeader2->m_Layout.m_rcHeader.SetRect(rcView2.left, rcView2.top, rcView2.left + nTimeScale2Width, rcView2.bottom);
|
|
rcView2.left += nTimeScale2Width;
|
|
|
|
AdjustScale2TimeZone();
|
|
}
|
|
|
|
// regular time scale
|
|
if (m_pTimeScaleHeader)
|
|
{
|
|
int nTimeScaleWidth = XTP_SAFE_GET1(m_pTimeScaleHeader, CalcWidth(pDC), 0);
|
|
m_pTimeScaleHeader->m_Layout.m_rcHeader.SetRect(rcView2.left, rcView2.top, rcView2.left + nTimeScaleWidth, rcView2.bottom);
|
|
rcView2.left += nTimeScaleWidth;
|
|
}
|
|
|
|
CXTPCalendarViewPart* pPart = XTP_SAFE_GET1(GetPaintManager(), GetDayViewHeaderPart(), NULL);
|
|
int nDaysCount = GetViewDayCount();
|
|
if (nDaysCount <= 0 || !pPart)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int nColumnsCount = GetTotalGroupsCount();
|
|
|
|
// Adjust Header
|
|
int nCellWidth = rcView2.Width() / max(nDaysCount, 1);
|
|
int nDayHeaderHeight = CalculateHeaderFormatAndHeight(pDC, nCellWidth);
|
|
|
|
int nMinRowHeight = nDayHeaderHeight;
|
|
m_LayoutX.m_nAllDayEventsCountMax = max(1, GetAllDayEventsMaxCount());
|
|
|
|
if (m_eDraggingMode == xtpCalendaDragModeResizeBegin || m_eDraggingMode == xtpCalendaDragModeResizeEnd
|
|
|| _IsDragModeCopyMove(m_eDraggingMode))
|
|
{
|
|
m_LayoutX.m_nAllDayEventsCountMax = max(m_LayoutX.m_nAllDayEventsCountMax, m_nAllDayEventsCountMin_WhenDrag);
|
|
m_nAllDayEventsCountMin_WhenDrag = m_LayoutX.m_nAllDayEventsCountMax;
|
|
}
|
|
|
|
BOOL bGroupHeaderVisible = IsGroupHeaderVisible();
|
|
int nDGHeadersHeight = nDayHeaderHeight * (bGroupHeaderVisible ? 2 : 1);
|
|
|
|
// day view part
|
|
int nRowCount = m_LayoutX.m_nRowCount;
|
|
int nTotalRows = nRowCount + m_LayoutX.m_nAllDayEventsCountMax + (bGroupHeaderVisible ? 2 : 1);
|
|
|
|
m_Layout.m_nRowHeight = max(nMinRowHeight, rcView2.Height() / max(nTotalRows, 1));
|
|
|
|
double dVisibleRowCountMax = (double)(rcView2.Height()) / (double)(max(m_Layout.m_nRowHeight, 1));
|
|
double dVisibleRowCount = dVisibleRowCountMax - (0.2 + m_LayoutX.m_nAllDayEventsCountMax) -
|
|
(bGroupHeaderVisible ? 2 : 1);
|
|
|
|
m_LayoutX.m_nVisibleRowCount = max((int)dVisibleRowCount, max(0, (int)dVisibleRowCountMax/2));
|
|
m_LayoutX.m_nVisibleRowCount = max(0, min(nRowCount, m_LayoutX.m_nVisibleRowCount));
|
|
|
|
if (m_LayoutX.m_nTopRow + m_LayoutX.m_nVisibleRowCount >= m_LayoutX.m_nRowCount)
|
|
{
|
|
m_LayoutX.m_nTopRow = m_LayoutX.m_nRowCount - m_LayoutX.m_nVisibleRowCount;
|
|
}
|
|
|
|
int nAllDayEventsHeight = max(0, rcView2.Height() - (m_LayoutX.m_nVisibleRowCount * m_Layout.m_nRowHeight + nDGHeadersHeight));
|
|
|
|
m_LayoutX.m_rcDayHeader.SetRect(rcView2.left, rcView2.top, rcView2.right, rcView2.top + nDayHeaderHeight);
|
|
|
|
m_LayoutX.m_rcAllDayEvents.SetRect(rcView2.left, rcView2.top + nDGHeadersHeight,
|
|
rcView2.right, rcView2.top + nAllDayEventsHeight + nDGHeadersHeight);
|
|
|
|
int nCols = 0;
|
|
for (int i = 0; i < nDaysCount; i++)
|
|
{
|
|
CXTPCalendarDayViewDay* pDay = GetViewDay(i);
|
|
if (!pDay)
|
|
{
|
|
ASSERT(FALSE);
|
|
continue;
|
|
}
|
|
|
|
//int nWidth = (i == nDaysCount - 1) ? rcView2.Width() : rcView2.Width() / (nColumnsCount - nCols);
|
|
int nWidth = (rcView2.Width() / (nColumnsCount - nCols)) * pDay->GetViewGroupsCount();
|
|
if (i == nDaysCount - 1)
|
|
nWidth = rcView2.Width();
|
|
|
|
|
|
CRect rcDay(rcView2.left, rcView2.top, rcView2.left + nWidth, rcView2.bottom);
|
|
pDay->AdjustLayout(pDC, rcDay);
|
|
|
|
rcView2.left += nWidth;
|
|
nCols += pDay->GetViewGroupsCount();
|
|
}
|
|
|
|
//----------------------------------------------
|
|
if (nDaysCount && XTP_SAFE_GET1(GetViewDay(0), GetViewGroupsCount(), 0) &&
|
|
GetViewDay(0)->GetViewGroup(0) )
|
|
{
|
|
CRect rcAllDayEvents = GetViewDay(0)->GetViewGroup(0)->GetAllDayEventsRect();
|
|
ASSERT(rcAllDayEvents.Height() == m_LayoutX.m_rcAllDayEvents.Height());
|
|
|
|
m_LayoutX.m_rcAllDayEvents.top = rcAllDayEvents.top;
|
|
m_LayoutX.m_rcAllDayEvents.bottom = rcAllDayEvents.bottom;
|
|
}
|
|
|
|
AdjustAllDayEvents();
|
|
|
|
//----------------------------------------------------------
|
|
XTP_SAFE_CALL1(m_pTimeScaleHeader, AdjustLayout(pDC) );
|
|
XTP_SAFE_CALL1(m_pTimeScaleHeader2, AdjustLayout(pDC) );
|
|
|
|
//---------------------------------------------------------------------------
|
|
int nDVCount = GetViewDayCount();
|
|
if (nDVCount)
|
|
{
|
|
COleDateTime dtFirstDay = GetViewDayDate(0);
|
|
COleDateTime dtLastDay = GetViewDayDate(nDVCount-1);
|
|
BOOL bSelChanged = FALSE;
|
|
|
|
if (m_selectedBlock.dtEnd.GetStatus() != COleDateTime::valid ||
|
|
m_selectedBlock.dtBegin.GetStatus() != COleDateTime::valid)
|
|
{
|
|
int nSelRow = GetTopRow() + min(2, GetVisibleRowCount());
|
|
|
|
m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateTime(dtFirstDay, GetCellTime(nSelRow));
|
|
m_selectedBlock.dtEnd = m_selectedBlock.dtBegin + GetCellDuration();
|
|
m_selectedBlock.bAllDayEvent = FALSE;
|
|
m_selectedBlock.nGroupIndex = 0;
|
|
|
|
bSelChanged = TRUE;
|
|
}
|
|
|
|
COleDateTime dtSelBeginDay = CXTPCalendarUtils::ResetTime(m_selectedBlock.dtBegin);
|
|
COleDateTime dtSelEndDay = CXTPCalendarUtils::ResetTime(m_selectedBlock.dtEnd-COleDateTimeSpan(0, 0, 0, 1));
|
|
|
|
// compare with the first day
|
|
if (dtSelBeginDay < dtFirstDay)
|
|
{
|
|
m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtBegin, dtFirstDay);
|
|
bSelChanged = TRUE;
|
|
}
|
|
if (dtSelEndDay < dtFirstDay)
|
|
{
|
|
m_selectedBlock.dtEnd = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtEnd, dtFirstDay);
|
|
bSelChanged = TRUE;
|
|
}
|
|
// compare with the last day
|
|
if (dtSelEndDay > dtLastDay)
|
|
{
|
|
m_selectedBlock.dtEnd = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtEnd, dtLastDay);
|
|
bSelChanged = TRUE;
|
|
}
|
|
if (dtSelBeginDay > dtLastDay)
|
|
{
|
|
m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtBegin, dtLastDay);
|
|
bSelChanged = TRUE;
|
|
}
|
|
|
|
if (bSelChanged)
|
|
{
|
|
CSelectionChangedContext selChanged(this, xtpCalendarSelectionDays);
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
if (bCallPostAdjustLayout)
|
|
{
|
|
OnPostAdjustLayout();
|
|
}
|
|
}
|
|
|
|
/*
|
|
AdjustLayout2
|
|
<Pre-Theme Adjust Layout step>
|
|
Theme->AdjustLayout
|
|
<Adjust Layout for theme step>
|
|
<- <call AdjustLayout2 for children>
|
|
|
|
<After-Theme Adjust Layout step>
|
|
|
|
OnPostAdjustLayout2
|
|
<Pre-Theme Post Adjust Layout step>
|
|
Theme->OnPostAdjustLayout
|
|
|
|
<After-Theme Post Adjust Layout step>
|
|
*/
|
|
|
|
void CXTPCalendarDayView::AdjustLayout2(CDC* pDC, const CRect& rcView, BOOL bCallPostAdjustLayout)
|
|
{
|
|
if (!pDC || !GetTheme())
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
TBase::AdjustLayout2(pDC, rcView, bCallPostAdjustLayout);
|
|
|
|
//*** Pre-Theme Adjust Layout step
|
|
XTP_SAFE_CALL1(m_pTimeScaleHeader, SetCaption(GetScaleText()) );
|
|
XTP_SAFE_CALL1(m_pTimeScaleHeader2, SetCaption(GetScale2Text()) );
|
|
XTP_SAFE_CALL1(m_pTimeScaleHeader2, SetVisible(IsScale2Visible()) );
|
|
|
|
if (IsScale2Visible())
|
|
{
|
|
AdjustScale2TimeZone();
|
|
}
|
|
|
|
COleDateTimeSpan spDay(1, 0, 0, 0);
|
|
|
|
double dRows = spDay / max((double)m_pTimeScaleHeader->GetScaleInterval(), XTP_HALF_SECOND * 2);
|
|
m_LayoutX.m_nRowCount = (int)(dRows + XTP_HALF_SECOND); // to prevent loosing 1 : (int)(47.99999999999) = 47; // need 48 !
|
|
|
|
m_LayoutX.m_nAllDayEventsCountMax = max(1, GetAllDayEventsMaxCount());
|
|
|
|
if (m_eDraggingMode == xtpCalendaDragModeResizeBegin || m_eDraggingMode == xtpCalendaDragModeResizeEnd
|
|
|| _IsDragModeCopyMove(m_eDraggingMode))
|
|
{
|
|
m_LayoutX.m_nAllDayEventsCountMax = max(m_LayoutX.m_nAllDayEventsCountMax, m_nAllDayEventsCountMin_WhenDrag);
|
|
m_nAllDayEventsCountMin_WhenDrag = m_LayoutX.m_nAllDayEventsCountMax;
|
|
}
|
|
|
|
|
|
//***
|
|
GetTheme()->GetDayViewPart()->AdjustLayout(pDC, rcView);
|
|
|
|
//*** Post-Theme Adjust Layout step
|
|
//---------------------------------------------------------------------------
|
|
int nDVCount = GetViewDayCount();
|
|
if (nDVCount)
|
|
{
|
|
COleDateTime dtFirstDay = GetViewDayDate(0);
|
|
COleDateTime dtLastDay = GetViewDayDate(nDVCount-1);
|
|
BOOL bSelChanged = FALSE;
|
|
|
|
if (m_selectedBlock.dtEnd.GetStatus() != COleDateTime::valid ||
|
|
m_selectedBlock.dtBegin.GetStatus() != COleDateTime::valid)
|
|
{
|
|
int nSelRow = GetTopRow() + min(2, GetVisibleRowCount());
|
|
|
|
m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateTime(dtFirstDay, GetCellTime(nSelRow));
|
|
m_selectedBlock.dtEnd = m_selectedBlock.dtBegin + GetCellDuration();
|
|
m_selectedBlock.bAllDayEvent = FALSE;
|
|
m_selectedBlock.nGroupIndex = 0;
|
|
|
|
bSelChanged = TRUE;
|
|
}
|
|
|
|
COleDateTime dtSelBeginDay = CXTPCalendarUtils::ResetTime(m_selectedBlock.dtBegin);
|
|
COleDateTime dtSelEndDay = CXTPCalendarUtils::ResetTime(m_selectedBlock.dtEnd-COleDateTimeSpan(0, 0, 0, 1));
|
|
|
|
// compare with the first day
|
|
if (dtSelBeginDay < dtFirstDay)
|
|
{
|
|
m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtBegin, dtFirstDay);
|
|
bSelChanged = TRUE;
|
|
}
|
|
if (dtSelEndDay < dtFirstDay)
|
|
{
|
|
m_selectedBlock.dtEnd = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtEnd, dtFirstDay);
|
|
bSelChanged = TRUE;
|
|
}
|
|
// compare with the last day
|
|
if (dtSelEndDay > dtLastDay)
|
|
{
|
|
m_selectedBlock.dtEnd = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtEnd, dtLastDay);
|
|
bSelChanged = TRUE;
|
|
}
|
|
if (dtSelBeginDay > dtLastDay)
|
|
{
|
|
m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateDate(m_selectedBlock.dtBegin, dtLastDay);
|
|
bSelChanged = TRUE;
|
|
}
|
|
|
|
if (bSelChanged)
|
|
{
|
|
CSelectionChangedContext selChanged(this, xtpCalendarSelectionDays);
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
if (bCallPostAdjustLayout)
|
|
{
|
|
OnPostAdjustLayout();
|
|
|
|
GetTheme()->GetDayViewPart()->OnPostAdjustLayout();
|
|
}
|
|
}
|
|
|
|
void CXTPCalendarDayView::Draw2(CDC* pDC)
|
|
{
|
|
if (!GetTheme())
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
GetTheme()->GetDayViewPart()->Draw(pDC);
|
|
|
|
m_dtLastRedrawTime = CXTPCalendarUtils::GetCurrentTime();
|
|
}
|
|
|
|
void CXTPCalendarDayView::OnDraw(CDC* pDC)
|
|
{
|
|
SCROLLINFO si;
|
|
if (!GetScrollBarInfoH(&si) || pDC->IsPrinting())
|
|
{
|
|
TBase::OnDraw(pDC);
|
|
return;
|
|
}
|
|
|
|
//===================================
|
|
CRect rcView = GetViewRect();
|
|
|
|
CDC memDC;
|
|
CBitmap bmpCache;
|
|
memDC.CreateCompatibleDC(pDC);
|
|
|
|
VERIFY( bmpCache.CreateCompatibleBitmap(pDC, rcView.Width(), rcView.Height()) );
|
|
|
|
CXTPBitmapDC autoDCbmp(&memDC, &bmpCache);
|
|
memDC.FillSolidRect(rcView, 0xFF);
|
|
|
|
memDC.SetViewportOrg(m_nScrollOffsetX, 0);
|
|
|
|
//------------------------------------------------
|
|
if (m_pTimeScaleHeader)
|
|
m_pTimeScaleHeader->MoveTo(m_nScrollOffsetX);
|
|
|
|
if (m_pTimeScaleHeader2 && IsScale2Visible())
|
|
m_pTimeScaleHeader2->MoveTo(m_nScrollOffsetX);
|
|
|
|
//************************************************
|
|
TBase::OnDraw(&memDC);
|
|
//************************************************
|
|
|
|
//int nTSWidth = _GetTimeScaleWith();
|
|
CXTPClientRect rcClient(GetCalendarControl());
|
|
|
|
pDC->BitBlt(rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(),
|
|
&memDC, 0, 0, SRCCOPY);
|
|
|
|
}
|
|
|
|
void CXTPCalendarDayView::Draw(CDC* pDC)
|
|
{
|
|
pDC->SetBkMode(TRANSPARENT);
|
|
|
|
// days
|
|
int nCount = GetViewDayCount();
|
|
for (int i = nCount - 1; i >= 0; i--)
|
|
{
|
|
XTP_SAFE_CALL1(GetViewDay(i), Draw(pDC));
|
|
}
|
|
|
|
// alternative time scale
|
|
if (IsScale2Visible() && m_pTimeScaleHeader2)
|
|
m_pTimeScaleHeader2->Draw(pDC);
|
|
|
|
// regular time scale
|
|
XTP_SAFE_CALL1(m_pTimeScaleHeader, Draw(pDC));
|
|
|
|
m_dtLastRedrawTime = CXTPCalendarUtils::GetCurrentTime();
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::HitTestEx(CPoint pt, XTP_CALENDAR_HITTESTINFO_DAY_VIEW* pHitTest)
|
|
{
|
|
if (!pHitTest)
|
|
{
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
pHitTest->pt = pt;
|
|
|
|
if (m_pTimeScaleHeader2 && m_pTimeScaleHeader2->HitTestDateTime(pHitTest))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
if (m_pTimeScaleHeader && m_pTimeScaleHeader->HitTestDateTime(pHitTest))
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
//----------------------------------------------------
|
|
CXTPCalendarThemeOffice2007* pThemeX = DYNAMIC_DOWNCAST(CXTPCalendarThemeOffice2007, GetTheme());
|
|
|
|
int nHit = XTP_SAFE_GET2(pThemeX, GetPrevNextEventControllerPartX(), HitTest(&pt), 0);
|
|
|
|
if (nHit)
|
|
{
|
|
XTP_CALENDAR_HITTESTINFO_DAY_VIEW emptyData;
|
|
*pHitTest = emptyData;
|
|
pHitTest->uHitCode = nHit;
|
|
return TRUE;
|
|
}
|
|
//----------------------------------------------------
|
|
|
|
return TBase::HitTestEx(pt, pHitTest);
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::IsUseCellAlignedDraggingInTimeArea()
|
|
{
|
|
if (GetTheme() && GetTheme()->GetDayViewPart())
|
|
{
|
|
return GetTheme()->GetDayViewPart()->IsUseCellAlignedDraggingInTimeArea();
|
|
}
|
|
return CXTPCalendarView::IsUseCellAlignedDraggingInTimeArea();
|
|
}
|
|
|
|
void CXTPCalendarDayView::OnStartDragging(CPoint point, XTP_CALENDAR_HITTESTINFO* pHitTest)
|
|
{
|
|
if (!pHitTest || !m_pControl)
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
m_dtDraggingStartPoint = pHitTest->dt;
|
|
m_spDraggingStartOffset_Time = 0.;
|
|
|
|
m_nAllDayEventsCountMin_WhenDrag = max(1, GetAllDayEventsMaxCount());
|
|
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateRedraw);
|
|
|
|
TBase::OnStartDragging(point, pHitTest);
|
|
|
|
if (double(m_spDraggingStartOffset) != 0.0
|
|
&& IsUseCellAlignedDraggingInTimeArea())
|
|
{
|
|
// Align to cell begin time
|
|
m_spDraggingStartOffset = pHitTest->dt - pHitTest->pViewEvent->GetEvent()->GetStartTime();
|
|
int nTmpCell = GetCellNumber((DATE)(double)m_spDraggingStartOffset, FALSE);
|
|
m_spDraggingStartOffset = (double)GetCellTime(nTmpCell);
|
|
}
|
|
|
|
m_selectedBlock.dtEnd = m_selectedBlock.dtBegin;
|
|
m_selectedBlock.bAllDayEvent = FALSE;
|
|
m_selectedBlock.nGroupIndex = pHitTest->nGroup;
|
|
|
|
CSelectionChangedContext selChanged(this, xtpCalendarSelectionDays);
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::OnDragging(CPoint point, XTP_CALENDAR_HITTESTINFO* pHitTest)
|
|
{
|
|
if (!pHitTest)
|
|
{
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
if (!m_ptrDraggingEventNew || m_eDraggingMode == xtpCalendaDragModeEditSubject ||
|
|
!GetCalendarControl())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
TRACE_DRAGGING(_T("OnDragging - [CXTPCalendarDayView] (point.x =%d, point.y =%d) \n"),
|
|
point.x, point.y);
|
|
|
|
XTP_CALENDAR_HITTESTINFO hitInfo2 = *pHitTest;
|
|
XTP_CALENDAR_HITTESTINFO* pHitTest2 = &hitInfo2;
|
|
|
|
BOOL bChanged = FALSE;
|
|
|
|
XTP_CALENDAR_HITTESTINFO_DAY_VIEW hitTestInfo;
|
|
|
|
// TODO:
|
|
//if (IsOutOfDraggingRect(point, &hitTestInfo))
|
|
//{
|
|
// return FALSE;
|
|
//}
|
|
|
|
if (!HitTestEx(point, &hitTestInfo))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//========================================================================
|
|
BOOL bScrolled = FALSE;
|
|
XTPCalendarDayViewScrollDirection scrollDir = GetNeededScrollDirection(point);
|
|
|
|
if (scrollDir != xtpCalendarDayViewScrollNotNeeded)
|
|
{
|
|
if (scrollDir == xtpCalendarDayViewScrollUp)
|
|
{
|
|
TRACE_DRAGGING(_T("OnDragging::ScrollV up\n"));
|
|
bScrolled = VertEventScroll(TRUE);//scroll up
|
|
SetMouseOutOfDragArea(FALSE);
|
|
|
|
if (bScrolled)
|
|
{
|
|
if (HitTestEx(point, &hitTestInfo))
|
|
{
|
|
pHitTest2->dt = hitTestInfo.dt;
|
|
}
|
|
}
|
|
}
|
|
else if (scrollDir == xtpCalendarDayViewScrollDown)
|
|
{
|
|
TRACE_DRAGGING(_T("OnDragging::ScrollV down\n"));
|
|
bScrolled = VertEventScroll(FALSE);//scroll down
|
|
SetMouseOutOfDragArea(FALSE);
|
|
|
|
if (bScrolled)
|
|
{
|
|
if (HitTestEx(point, &hitTestInfo))
|
|
{
|
|
pHitTest2->dt = hitTestInfo.dt;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (IsOutOfClientRect(point, &hitTestInfo))
|
|
{
|
|
TRACE_DRAGGING(_T("OnDragging::OutOfDragArea\n"));
|
|
SetMouseOutOfDragArea(TRUE);
|
|
StopVertEventScroll();
|
|
bScrolled = TRUE;
|
|
return TRUE;
|
|
}
|
|
|
|
if (!bScrolled)
|
|
{
|
|
TRACE_DRAGGING(_T("OnDragging::In DragArea\n"));
|
|
SetMouseOutOfDragArea(FALSE);
|
|
StopVertEventScroll();
|
|
}
|
|
|
|
// check drag on TimeScale:
|
|
|
|
TRACE_DRAGGING(_T("OnDragging - [CXTPCalendarDayView] (hour =%d, minute =%d) \n"),
|
|
pHitTest->dt.GetHour(), pHitTest->dt.GetMinute());
|
|
|
|
if (_IsDragModeCopyMove(m_eDraggingMode) && (
|
|
m_pTimeScaleHeader2 && m_pTimeScaleHeader2->HitTestDateTime(&hitTestInfo) ||
|
|
(m_pTimeScaleHeader && m_pTimeScaleHeader->HitTestDateTime(&hitTestInfo))))
|
|
{
|
|
COleDateTime dtNewTime = pHitTest->dt;
|
|
dtNewTime = COleDateTime(m_dtDraggingStartPoint.GetYear(),
|
|
m_dtDraggingStartPoint.GetMonth(), m_dtDraggingStartPoint.GetDay(),
|
|
dtNewTime.GetHour(), dtNewTime.GetMinute(), dtNewTime.GetSecond());
|
|
|
|
m_ptrDraggingEventNew->MoveEvent(dtNewTime);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
if (!m_ptrDraggingEventOrig)
|
|
{
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL bAllDayEventArea = 0 != (hitTestInfo.uHitCode & xtpCalendarHitTestDayViewAllDayEvent);
|
|
|
|
BOOL bAllDayEventNew_prev = m_ptrDraggingEventNew->IsAllDayEvent();
|
|
BOOL bAllMultiDayEvent = bAllDayEventNew_prev || m_ptrDraggingEventNew->GetDurationMinutes() > 24 * 60;
|
|
|
|
BOOL bAllMultiDayEventOrig = m_ptrDraggingEventOrig->IsAllDayEvent();
|
|
bAllMultiDayEventOrig |= m_ptrDraggingEventOrig->GetDurationMinutes() > 24 * 60;
|
|
|
|
bChanged = bAllDayEventArea != bAllMultiDayEvent;
|
|
|
|
if (bChanged)
|
|
{
|
|
if (!bAllDayEventArea && bAllMultiDayEventOrig && _IsDragModeCopyMove(m_eDraggingMode))
|
|
{
|
|
m_ptrDraggingEventNew->SetDuration(GetCellDuration());
|
|
}
|
|
else if (bAllDayEventArea && !bAllMultiDayEventOrig && _IsDragModeCopyMove(m_eDraggingMode))
|
|
{
|
|
m_ptrDraggingEventNew->SetStartTime(CXTPCalendarUtils::ResetTime(m_ptrDraggingEventOrig->GetStartTime()));
|
|
m_ptrDraggingEventNew->SetEndTime(m_ptrDraggingEventNew->GetStartTime()+COleDateTimeSpan(1, 0, 0, 0));
|
|
}
|
|
else
|
|
{
|
|
m_ptrDraggingEventNew->SetStartTime(m_ptrDraggingEventOrig->GetStartTime());
|
|
m_ptrDraggingEventNew->SetEndTime(m_ptrDraggingEventOrig->GetEndTime());
|
|
}
|
|
|
|
if (_IsDragModeCopyMove(m_eDraggingMode))
|
|
{
|
|
if (bAllDayEventArea == bAllMultiDayEventOrig)
|
|
{
|
|
m_spDraggingStartOffset = m_spDraggingStartOffset_Time;
|
|
m_spDraggingStartOffset_Time = 0.;
|
|
}
|
|
else
|
|
{
|
|
m_spDraggingStartOffset_Time = m_spDraggingStartOffset;
|
|
m_spDraggingStartOffset = 0.;
|
|
}
|
|
|
|
if (bAllDayEventArea)
|
|
{
|
|
if (GetCalendarControl()->DayView_IsAutoResetBusyFlag())
|
|
{
|
|
if (!bAllDayEventNew_prev &&
|
|
xtpCalendarBusyStatusBusy == m_ptrDraggingEventNew->GetBusyStatus()
|
|
&&
|
|
!(bAllMultiDayEventOrig &&
|
|
xtpCalendarBusyStatusBusy == m_ptrDraggingEventOrig->GetBusyStatus()))
|
|
{
|
|
m_ptrDraggingEventNew->SetBusyStatus(xtpCalendarBusyStatusFree);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (GetCalendarControl()->DayView_IsAutoResetBusyFlag())
|
|
{
|
|
if (bAllMultiDayEvent &&
|
|
xtpCalendarBusyStatusFree == m_ptrDraggingEventNew->GetBusyStatus()
|
|
&&
|
|
!(!bAllMultiDayEventOrig &&
|
|
xtpCalendarBusyStatusFree == m_ptrDraggingEventOrig->GetBusyStatus()))
|
|
{
|
|
m_ptrDraggingEventNew->SetBusyStatus(xtpCalendarBusyStatusBusy);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//========================================================================
|
|
if (m_eDraggingMode == xtpCalendaDragModeResizeEnd)
|
|
{
|
|
if (pHitTest2->bTimePartValid)
|
|
{
|
|
pHitTest2->dt += GetCellDuration();
|
|
}
|
|
}
|
|
|
|
BOOL bChangedBase = TBase::OnDragging(point, pHitTest2);
|
|
|
|
//-------------------------------------------------------------------------
|
|
// multi-resources movement
|
|
|
|
if (_IsDragModeCopyMove(m_eDraggingMode))
|
|
{
|
|
UINT uScheduleID = XTP_SAFE_GET2(pHitTest2, pViewGroup, GetScheduleID(), 0);
|
|
if (uScheduleID != m_ptrDraggingEventNew->GetScheduleID())
|
|
{
|
|
if (uScheduleID != XTP_CALENDAR_UNKNOWN_SCHEDULE_ID)
|
|
{
|
|
m_ptrDraggingEventNew->SetScheduleID(uScheduleID);
|
|
bChanged = TRUE;
|
|
}
|
|
else if (m_ptrDraggingEventNew->GetScheduleID() != m_ptrDraggingEventOrig->GetScheduleID())
|
|
{
|
|
m_ptrDraggingEventNew->SetScheduleID(m_ptrDraggingEventOrig->GetScheduleID());
|
|
bChanged = TRUE;
|
|
}
|
|
}
|
|
}
|
|
//---
|
|
CXTPCalendarData* pHitData = XTP_SAFE_GET2(pHitTest2, pViewGroup, GetDataProvider(), NULL);
|
|
if (pHitData && pHitData != m_ptrDraggingEventNew->GetDataProvider())
|
|
{
|
|
CXTPCalendarEventPtr ptrHitEventNew = pHitData->CreateNewEvent();
|
|
if (ptrHitEventNew)
|
|
{
|
|
if (m_ptrDraggingEventNew->CloneEventTo(ptrHitEventNew))
|
|
{
|
|
m_ptrDraggingEventNew = ptrHitEventNew;
|
|
bChanged = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------
|
|
//COleDateTimeSpan spDurationNew = m_ptrDraggingEventNew->GetEndTime() -
|
|
// m_ptrDraggingEventNew->GetStartTime();
|
|
|
|
// TRACE(_T("bAllDayEventArea =%d, Orig->IsAllDayEvent =%d, bAllMultiDayEventOrig =%d, New->GetDurationMinutes=%d [%s - %s]\n"),
|
|
// bAllDayEventArea, m_ptrDraggingEventOrig->IsAllDayEvent(),
|
|
//bAllMultiDayEventOrig, (int)spDurationNew.GetTotalMinutes(),
|
|
//m_ptrDraggingEventNew->GetStartTime().Format(),
|
|
//m_ptrDraggingEventNew->GetEndTime().Format());
|
|
|
|
BOOL bIsResizing = m_eDraggingMode == xtpCalendaDragModeResizeBegin ||
|
|
m_eDraggingMode == xtpCalendaDragModeResizeEnd;
|
|
|
|
BOOL bIsZeroLen = CXTPCalendarUtils::IsEqual(m_ptrDraggingEventNew->GetStartTime(),
|
|
m_ptrDraggingEventNew->GetEndTime());
|
|
|
|
if (bAllDayEventArea && (bIsResizing && !bIsZeroLen || !bIsResizing) &&
|
|
(m_ptrDraggingEventOrig->IsAllDayEvent() || !bAllMultiDayEventOrig
|
|
|| m_ptrDraggingEventNew->IsAllDayEvent()))
|
|
{
|
|
m_ptrDraggingEventNew->SetAllDayEvent(TRUE);
|
|
}
|
|
else
|
|
{
|
|
m_ptrDraggingEventNew->SetAllDayEvent(FALSE);
|
|
}
|
|
//------------------------------------------------------------------------
|
|
|
|
return bChanged || bChangedBase;
|
|
}
|
|
|
|
XTPCalendarDayViewScrollDirection CXTPCalendarDayView::GetNeededScrollDirection(CPoint pnt)
|
|
{
|
|
static const int nVScrollZone = 20;
|
|
CRect rcCtrl;
|
|
|
|
if (!m_pControl)
|
|
{
|
|
return xtpCalendarDayViewScrollNotNeeded;
|
|
}
|
|
|
|
m_pControl->GetWindowRect(rcCtrl);
|
|
CRect rcAllDayEvents = GetAllDayEventsRectangle();
|
|
SCROLLINFO si;
|
|
GetScrollBarInfoV(&si);
|
|
|
|
int nCurPos = si.nPos;
|
|
int nLimit = m_pControl->GetScrollLimit(SB_VERT);
|
|
|
|
BOOL bWidtdhOK = (rcAllDayEvents.left <= pnt.x &&
|
|
rcAllDayEvents.right >= pnt.x);
|
|
|
|
if (!bWidtdhOK)
|
|
return xtpCalendarDayViewScrollNotNeeded;
|
|
|
|
if ((pnt.y >= rcAllDayEvents.bottom) &&
|
|
(pnt.y - rcAllDayEvents.bottom <= nVScrollZone) && nCurPos > 0 &&
|
|
m_ptLBtnDownMousePos.y - pnt.y > 2)
|
|
{
|
|
// Scroll up
|
|
return xtpCalendarDayViewScrollUp;
|
|
}
|
|
|
|
if ((pnt.y + 3 < rcCtrl.Height()) &&
|
|
(rcCtrl.Height() - (pnt.y + 3) <= nVScrollZone) && nCurPos < nLimit &&
|
|
pnt.y - m_ptLBtnDownMousePos.y > 2)
|
|
{
|
|
return xtpCalendarDayViewScrollDown;
|
|
}
|
|
|
|
return xtpCalendarDayViewScrollNotNeeded;
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::IsOutOfClientRect(CPoint pnt, XTP_CALENDAR_HITTESTINFO_DAY_VIEW* pHitInfo)
|
|
{
|
|
if (!m_pControl)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
CRect rcCtrl;
|
|
m_pControl->GetWindowRect(rcCtrl);
|
|
|
|
if (m_pTimeScaleHeader2 && m_pTimeScaleHeader2->HitTestDateTime(pHitInfo))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if (m_pTimeScaleHeader && m_pTimeScaleHeader->HitTestDateTime(pHitInfo))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//bottom
|
|
if (pnt.y + 3 >= rcCtrl.Height())
|
|
return TRUE;
|
|
//top
|
|
CRect rcAllDayEvents = GetAllDayEventsRectangle();
|
|
if (pnt.y <= rcAllDayEvents.top)
|
|
return TRUE;
|
|
|
|
//left
|
|
if (pnt.x < rcAllDayEvents.left)
|
|
return TRUE;
|
|
|
|
//right
|
|
if (pnt.x > rcAllDayEvents.right)
|
|
return TRUE;
|
|
|
|
if (pHitInfo->uHitCode & xtpCalendarHitTestDayViewTimeScale)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void CXTPCalendarDayView::StopVertEventScroll()
|
|
{
|
|
if (m_dwScrollingEventTimerID)
|
|
{
|
|
KillTimer(m_dwScrollingEventTimerID);
|
|
m_dwScrollingEventTimerID = 0;
|
|
}
|
|
}
|
|
|
|
void CXTPCalendarDayView::SetMouseOutOfDragArea(BOOL bOutOfArea)
|
|
{
|
|
|
|
BOOL bChanged = m_bMouseOutOfDragArea != bOutOfArea;
|
|
m_bMouseOutOfDragArea = bOutOfArea;
|
|
|
|
BOOL bNeedUpd = FALSE;
|
|
|
|
if (m_bMouseOutOfDragArea)
|
|
{
|
|
if (m_ptrDraggingEventNew)
|
|
{
|
|
m_ptrDraggingEventNew->MoveEvent(m_dtDraggingStartPoint);
|
|
}
|
|
if (m_pControl && m_pControl->m_mouseMode != xtpCalendarMouseEventDraggingOut)
|
|
{
|
|
m_pControl->m_mouseMode = xtpCalendarMouseEventDraggingOut;
|
|
TRACE_DRAGGING(_T("SetMouseOutOfDragArea OUT\n"));
|
|
bNeedUpd = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
if (bChanged && !m_bMouseOutOfDragArea)
|
|
{
|
|
TRACE_DRAGGING(_T("SetMouseOutOfDragArea IN\n"));
|
|
|
|
XTPCalendarMouseMode mouseMode = xtpCalendarMouseNothing;
|
|
switch (m_eDraggingMode)
|
|
{
|
|
case xtpCalendaDragModeUnknown:
|
|
case xtpCalendaDragModeEditSubject:
|
|
mouseMode = xtpCalendarMouseNothing;
|
|
break;
|
|
case xtpCalendaDragModeCopy:
|
|
mouseMode = xtpCalendarMouseEventDragCopy;
|
|
break;
|
|
case xtpCalendaDragModeMove:
|
|
mouseMode = xtpCalendarMouseEventDragMove;
|
|
break;
|
|
case xtpCalendaDragModeResizeBegin:
|
|
case xtpCalendaDragModeResizeEnd:
|
|
mouseMode = xtpCalendarMouseEventResizingV;
|
|
break;
|
|
}
|
|
|
|
XTP_SAFE_SET1(m_pControl, m_mouseMode, mouseMode);
|
|
bNeedUpd = TRUE;
|
|
}
|
|
|
|
if (bNeedUpd && m_pControl)
|
|
m_pControl->UpdateMouseCursor();
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::VertEventScroll(BOOL bUp)
|
|
{
|
|
if (!m_pControl)
|
|
{
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
SCROLLINFO si;
|
|
if (!GetScrollBarInfoV(&si))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
int nCurPos = si.nPos;
|
|
int nCurPos_raw = si.nPos;
|
|
int nLimit = m_pControl->GetScrollLimit(SB_VERT);
|
|
|
|
|
|
if (bUp && nCurPos > 0)
|
|
{
|
|
//scroll up
|
|
nCurPos = max(nCurPos - 1, 0);
|
|
nCurPos_raw--;
|
|
m_bScrollingEventUp = TRUE;
|
|
}
|
|
else if (!bUp && nCurPos < nLimit)
|
|
{
|
|
//scroll down
|
|
nCurPos = min(nCurPos + 1, nLimit);
|
|
nCurPos_raw++;
|
|
m_bScrollingEventUp = FALSE;
|
|
}
|
|
else
|
|
{
|
|
//limit is reached
|
|
StopVertEventScroll();
|
|
return FALSE;//not handled
|
|
}
|
|
|
|
|
|
ScrollV(nCurPos, nCurPos_raw);
|
|
m_pControl->SetScrollPos(SB_VERT, nCurPos, FALSE);
|
|
m_pControl->AdjustScrollBar();
|
|
|
|
if (!m_dwScrollingEventTimerID)
|
|
{
|
|
//Start timer
|
|
m_dwScrollingEventTimerID = SetTimer(XTP_SCROLL_TIMER_RESOLUTION_MS);
|
|
DBG_TRACE_TIMER(_T("SET Timer: ID =%d, m_dwScrollingEventTimerID, CXTPCalendarDayView::VertEventScroll() \n"), m_dwScrollingEventTimerID);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPCalendarDayView::OnActivateView(BOOL bActivate, CXTPCalendarView* pActivateView,
|
|
CXTPCalendarView* pInactiveView)
|
|
{
|
|
TBase::OnActivateView(bActivate, pActivateView, pInactiveView);
|
|
|
|
if (!bActivate)
|
|
{
|
|
if (m_dwRedrawNowLineTimerID)
|
|
{
|
|
KillTimer(m_dwRedrawNowLineTimerID);
|
|
m_dwRedrawNowLineTimerID = 0;
|
|
//TRACE(_T("DayView: Auto redraw timer was KILLED. \n"));
|
|
}
|
|
|
|
if (m_dwScrollingEventTimerID)
|
|
{
|
|
KillTimer(m_dwScrollingEventTimerID);
|
|
m_dwScrollingEventTimerID = 0;
|
|
}
|
|
}
|
|
|
|
if (bActivate && m_dwRedrawNowLineTimerID == 0)
|
|
{
|
|
m_dwRedrawNowLineTimerID = SetTimer(XTP_REDRAW_TIMER_RESOLUTION_MS);
|
|
DBG_TRACE_TIMER(_T("SET Timer: ID =%d, m_dwRedrawNowLineTimerID, CXTPCalendarDayView::OnActivateView() \n"), m_dwRedrawNowLineTimerID);
|
|
//TRACE(_T("DayView: Auto redraw timer was SET. \n"));
|
|
}
|
|
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::OnTimer(UINT_PTR uTimerID)
|
|
{
|
|
if (uTimerID == m_dwScrollingEventTimerID)
|
|
{
|
|
OnMouseMove(MK_LBUTTON, m_ptLastMousePos);
|
|
return TRUE;
|
|
}
|
|
else if (uTimerID == m_dwRedrawNowLineTimerID)
|
|
{
|
|
COleDateTime dtNow = CXTPCalendarUtils::GetCurrentTime();
|
|
|
|
//COleDateTimeSpan spDiff = dtNow - m_dtLastRedrawTime;
|
|
//if ((spDiff.GetTotalSeconds() >= 15 || dtNow.GetSecond()%15 == 0) &&
|
|
// dtNow.GetSecond() != m_dtLastRedrawTime.GetSecond())
|
|
|
|
if (dtNow.GetMinute() != m_dtLastRedrawTime.GetMinute())
|
|
{
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateRedraw);
|
|
//TRACE(_T("DayView: Auto REDRAW (%d:%d:%d). \n"), (int)dtNow.GetHour(),
|
|
// (int)dtNow.GetMinute(), (int)dtNow.GetSecond());
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
return TBase::OnTimer(uTimerID);
|
|
}
|
|
|
|
|
|
BOOL CXTPCalendarDayView::OnEndDragging(CPoint point, XTP_CALENDAR_HITTESTINFO* pHitInfo)
|
|
{
|
|
if (!m_pControl || !pHitInfo)
|
|
{
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
CRect rcCtrl;
|
|
m_pControl->GetWindowRect(rcCtrl);
|
|
BOOL bReturnBack = point.y + 3 >= rcCtrl.Height();
|
|
|
|
if (m_dwScrollingEventTimerID)
|
|
{
|
|
if (bReturnBack)
|
|
{
|
|
pHitInfo->dt = m_dtDraggingStartPoint;
|
|
OnDragging(point, pHitInfo);
|
|
}
|
|
else
|
|
{
|
|
OnDragging(point, pHitInfo);
|
|
}
|
|
}
|
|
|
|
StopVertEventScroll();
|
|
|
|
|
|
m_dtDraggingStartPoint = COleDateTime(0, 0, 0, 0, 0, 0);
|
|
|
|
if (_IsDragModeCopyMove(m_eDraggingMode) && m_ptrDraggingEventNew && m_ptrDraggingEventOrig)
|
|
{
|
|
if (!m_ptrDraggingEventNew->IsEqualStartEnd(m_ptrDraggingEventOrig))
|
|
{
|
|
COleDateTime dtS = m_ptrDraggingEventNew->GetStartTime();
|
|
COleDateTime dtE = m_ptrDraggingEventNew->GetEndTime();
|
|
COleDateTime dtS0 = CXTPCalendarUtils::ResetDate(dtS);
|
|
COleDateTime dtE0 = CXTPCalendarUtils::ResetDate(dtE);
|
|
|
|
m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateTime(dtS, GetCellTime(GetCellNumber(dtS0, FALSE)));
|
|
m_selectedBlock.dtEnd = GetCellTime(GetCellNumber(dtE0, dtS0 == dtE0 ? FALSE : TRUE)) + GetCellDuration();
|
|
m_selectedBlock.dtEnd = CXTPCalendarUtils::UpdateTime(dtE, m_selectedBlock.dtEnd);
|
|
|
|
if (m_ptrDraggingEventNew->IsAllDayEvent() ||
|
|
m_ptrDraggingEventNew->GetDurationMinutes() > 24 * 60)
|
|
{
|
|
m_selectedBlock.bAllDayEvent = TRUE;
|
|
}
|
|
m_selectedBlock.nGroupIndex = pHitInfo->nGroup;
|
|
CSelectionChangedContext selChanged(this, xtpCalendarSelectionDays);
|
|
}
|
|
}
|
|
|
|
m_nAllDayEventsCountMin_WhenDrag = 0;
|
|
{
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateScrollBar);
|
|
}
|
|
|
|
return TBase::OnEndDragging(point, pHitInfo);
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
m_ptLBtnDownMousePos = CPoint(0, 0);
|
|
|
|
return TBase::OnLButtonUp(nFlags, point);
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
CSelectionChangedContext selChanged(this);
|
|
|
|
TBase::OnLButtonDown(nFlags, point);
|
|
|
|
|
|
m_ptLBtnDownMousePos = point;
|
|
|
|
if (m_eDraggingMode != xtpCalendaDragModeUnknown)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
XTP_CALENDAR_HITTESTINFO_DAY_VIEW hitTestInfo;
|
|
|
|
if (HitTestEx(point, &hitTestInfo))
|
|
{
|
|
if (hitTestInfo.dt.GetStatus() != COleDateTime::valid)
|
|
return FALSE;
|
|
|
|
ASSERT(hitTestInfo.dt.GetStatus() == COleDateTime::valid);
|
|
|
|
BOOL bEvent = (hitTestInfo.uHitCode & xtpCalendarHitTestEvent_Mask) != 0;
|
|
|
|
if (bEvent)
|
|
{
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateRedraw);
|
|
|
|
m_selectedBlock.dtEnd = m_selectedBlock.dtBegin = hitTestInfo.dt;
|
|
m_dtSelectionStart = hitTestInfo.dt;
|
|
m_selectedBlock.bAllDayEvent = FALSE;
|
|
m_selectedBlock.nGroupIndex = hitTestInfo.nGroup;
|
|
|
|
CSelectionChangedContext selChanged1(this, xtpCalendarSelectionDays);
|
|
}
|
|
else
|
|
{
|
|
BOOL bFixBegin = (nFlags & MK_SHIFT);
|
|
BOOL bAllDay = 0 != (hitTestInfo.uHitCode & xtpCalendarHitTestDayViewAllDayEvent);
|
|
COleDateTime dtNewEnd = m_selectedBlock.dtEnd;
|
|
|
|
if (hitTestInfo.uHitCode & xtpCalendarHitTestDayViewTimeScale)
|
|
{
|
|
dtNewEnd = CXTPCalendarUtils::UpdateTime(dtNewEnd, hitTestInfo.dt + GetCellDuration());
|
|
hitTestInfo.nGroup = max(0, m_selectedBlock.nGroupIndex);
|
|
}
|
|
else if (hitTestInfo.uHitCode & xtpCalendarHitTestDayViewCell)
|
|
{
|
|
dtNewEnd = hitTestInfo.dt + GetCellDuration();
|
|
}
|
|
else if (bAllDay)
|
|
{
|
|
dtNewEnd = hitTestInfo.dt + COleDateTimeSpan(1, 0, 0, 0);
|
|
}
|
|
else {
|
|
return TRUE;
|
|
}
|
|
|
|
ProcessCellSelection(dtNewEnd, bFixBegin, bAllDay, hitTestInfo.nGroup);
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void CXTPCalendarDayView::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateRedrawIfNeed);
|
|
CSelectionChangedContext selChanged(this);
|
|
|
|
m_ptLastMousePos = point;
|
|
|
|
TBase::OnMouseMove(nFlags, point);
|
|
|
|
if (m_eDraggingMode != xtpCalendaDragModeUnknown)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// process selection mode
|
|
if ((nFlags & MK_LBUTTON) == 0)
|
|
{
|
|
return;
|
|
}
|
|
else if (!m_bStartedClickInside)
|
|
{
|
|
return;
|
|
}
|
|
|
|
XTP_CALENDAR_HITTESTINFO_DAY_VIEW hitTestInfo;
|
|
if (HitTestEx(point, &hitTestInfo))
|
|
{
|
|
COleDateTime dtEnd = m_selectedBlock.dtEnd;
|
|
BOOL bAllDayEvent = m_selectedBlock.bAllDayEvent;
|
|
|
|
|
|
BOOL bScrolled = FALSE;
|
|
XTPCalendarDayViewScrollDirection direction = GetNeededScrollDirection(point);
|
|
if (direction != xtpCalendarDayViewScrollNotNeeded &&
|
|
hitTestInfo.dt.GetStatus() == COleDateTime::valid)
|
|
{
|
|
if (direction == xtpCalendarDayViewScrollUp)
|
|
{
|
|
bScrolled = VertEventScroll(TRUE);//scroll up
|
|
hitTestInfo.dt -= GetCellDuration();
|
|
}
|
|
else if (direction == xtpCalendarDayViewScrollDown)
|
|
{
|
|
bScrolled = VertEventScroll(FALSE);
|
|
hitTestInfo.dt += GetCellDuration();
|
|
}
|
|
|
|
}
|
|
if (!bScrolled)
|
|
{
|
|
StopVertEventScroll();
|
|
}
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
// selection processing
|
|
|
|
if (hitTestInfo.uHitCode & xtpCalendarHitTestDayViewTimeScale)
|
|
{
|
|
m_selectedBlock.bAllDayEvent = FALSE;
|
|
if (bAllDayEvent)
|
|
{
|
|
m_selectedBlock.dtBegin = m_dtSelectionStart;
|
|
}
|
|
|
|
m_selectedBlock.dtEnd = CXTPCalendarUtils::UpdateTime(m_selectedBlock.dtEnd, hitTestInfo.dt);
|
|
if (m_selectedBlock.dtEnd >= m_selectedBlock.dtBegin)
|
|
{
|
|
m_selectedBlock.dtEnd += GetCellDuration();
|
|
}
|
|
}
|
|
else if (hitTestInfo.uHitCode & xtpCalendarHitTestDayViewCell)
|
|
{
|
|
m_selectedBlock.bAllDayEvent = FALSE;
|
|
if (bAllDayEvent)
|
|
{
|
|
m_selectedBlock.dtBegin = m_dtSelectionStart;
|
|
}
|
|
|
|
m_selectedBlock.dtEnd = hitTestInfo.dt;
|
|
if (m_selectedBlock.dtEnd >= m_selectedBlock.dtBegin)
|
|
{
|
|
m_selectedBlock.dtEnd += GetCellDuration();
|
|
}
|
|
}
|
|
else if (hitTestInfo.uHitCode & xtpCalendarHitTestDayViewAllDayEvent)
|
|
{
|
|
if (!bAllDayEvent)
|
|
{
|
|
m_dtSelectionStart = m_selectedBlock.dtBegin;
|
|
m_selectedBlock.dtBegin = CXTPCalendarUtils::ResetTime(m_selectedBlock.dtBegin);
|
|
}
|
|
m_selectedBlock.dtEnd = hitTestInfo.dt;
|
|
if (m_selectedBlock.dtEnd >= m_selectedBlock.dtBegin)
|
|
{
|
|
m_selectedBlock.dtEnd += COleDateTimeSpan(1, 0, 0, 0);
|
|
}
|
|
m_selectedBlock.bAllDayEvent = TRUE;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
if (m_selectedBlock.dtEnd != dtEnd || m_selectedBlock.bAllDayEvent != bAllDayEvent)
|
|
{
|
|
CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateRedraw);
|
|
CSelectionChangedContext selChanged1(this, xtpCalendarSelectionDays);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::GetSelection(COleDateTime* pBegin, COleDateTime* pEnd,
|
|
BOOL* pbAllDayEvent, int* pnGroupIndex,
|
|
COleDateTimeSpan* pspSelectionResolution)
|
|
{
|
|
if (!m_selectedBlock.IsValid())
|
|
return FALSE;
|
|
|
|
COleDateTime dtBegin = m_selectedBlock.dtBegin, dtEnd = m_selectedBlock.dtEnd;
|
|
|
|
BOOL bAllDayEvent = m_selectedBlock.bAllDayEvent;
|
|
|
|
if (pbAllDayEvent)
|
|
{
|
|
*pbAllDayEvent = bAllDayEvent;
|
|
}
|
|
|
|
if (bAllDayEvent)
|
|
{
|
|
if (dtBegin > dtEnd)
|
|
{
|
|
COleDateTime dt = dtEnd;
|
|
dtEnd = dtBegin + COleDateTimeSpan(1, 0, 0, 0);
|
|
|
|
dtBegin = dt;
|
|
}
|
|
|
|
dtBegin = CXTPCalendarUtils::ResetTime(dtBegin);
|
|
if (!CXTPCalendarUtils::IsZeroTime(dtEnd))
|
|
{
|
|
dtEnd += COleDateTimeSpan(1, 0, 0, 0);
|
|
}
|
|
dtEnd = CXTPCalendarUtils::ResetTime(dtEnd);
|
|
|
|
}
|
|
else
|
|
{
|
|
if (dtBegin >= dtEnd)
|
|
{
|
|
COleDateTime dt = dtEnd;
|
|
dtEnd = dtBegin + GetCellDuration();
|
|
dtBegin = dt;
|
|
}
|
|
|
|
bAllDayEvent = CXTPCalendarUtils::IsZeroTime(dtBegin) &&
|
|
CXTPCalendarUtils::IsZeroTime(dtEnd);
|
|
}
|
|
|
|
if (pBegin)
|
|
*pBegin = dtBegin;
|
|
|
|
if (pEnd)
|
|
*pEnd = dtEnd;
|
|
|
|
if (pnGroupIndex)
|
|
{
|
|
*pnGroupIndex = m_selectedBlock.nGroupIndex;
|
|
}
|
|
|
|
if (pspSelectionResolution)
|
|
{
|
|
if (bAllDayEvent)
|
|
{
|
|
*pspSelectionResolution = COleDateTimeSpan(1, 0, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
*pspSelectionResolution = GetCellDuration();
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPCalendarDayView::ShowDay(const COleDateTime& date, BOOL bSelect)
|
|
{
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl);
|
|
ClearDays();
|
|
AddDay(date);
|
|
|
|
if (bSelect)
|
|
{
|
|
CXTPCalendarDayViewDay* pDay = m_arDays.GetCount() > 0 ? m_arDays.GetAt(0) : NULL;
|
|
if (pDay)
|
|
SelectDay(pDay);
|
|
}
|
|
}
|
|
|
|
void CXTPCalendarDayView::AddDay(const COleDateTime& date)
|
|
{
|
|
CXTPCalendarControl::CViewChangedContext viewChanged(this);
|
|
|
|
_AddDay(date);
|
|
}
|
|
|
|
void CXTPCalendarDayView::_AddDay(const COleDateTime& date)
|
|
{
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl);
|
|
CXTPCalendarDayViewDay* pDay = new CXTPCalendarDayViewDay(this, date);
|
|
if (pDay)
|
|
{
|
|
m_arDays.Add(pDay);
|
|
pDay->Populate(date);
|
|
}
|
|
}
|
|
|
|
void CXTPCalendarDayView::ShowDays(const COleDateTime& dtBegin, const COleDateTime& dtEnd)
|
|
{
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl);
|
|
|
|
CXTPCalendarControl::CViewChangedContext viewChanged(this);
|
|
|
|
ClearDays();
|
|
|
|
COleDateTimeSpan spDay(1, 0, 0, 0);
|
|
COleDateTimeSpan spDaysRange = CXTPCalendarUtils::ResetTime(dtEnd) - CXTPCalendarUtils::ResetTime(dtBegin);
|
|
|
|
int nDays = GETTOTAL_DAYS_DTS(spDaysRange) + 1;
|
|
COleDateTime dtDay = CXTPCalendarUtils::ResetTime(dtBegin);
|
|
|
|
nDays = max(1, nDays); // to be sure that at leas one day will be added
|
|
for (int i = 0; i < nDays; i++)
|
|
{
|
|
_AddDay(dtDay);
|
|
dtDay += spDay;
|
|
}
|
|
}
|
|
|
|
void CXTPCalendarDayView::ShowWorkingDays(const COleDateTime& dtDay)
|
|
{
|
|
if (!m_pControl)
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl);
|
|
CXTPCalendarControl::CViewChangedContext viewChanged(this);
|
|
|
|
COleDateTime dtWeekDay(dtDay);
|
|
|
|
int nFirstWeekDay = m_pControl->GetFirstDayOfWeek();
|
|
// adjust beginning of the week iteration period to the FirstDayOfWeek
|
|
while (dtWeekDay.GetDayOfWeek() != nFirstWeekDay)
|
|
{
|
|
dtWeekDay -= COleDateTimeSpan(1);
|
|
}
|
|
|
|
// add all working days during the week to the collection
|
|
ClearDays();
|
|
for (int nWeekDay = 0; nWeekDay < 7; nWeekDay++)
|
|
{
|
|
int nWWMask = m_pControl->GetWorkWeekMask();
|
|
int nDayOfWeek = dtWeekDay.GetDayOfWeek();
|
|
int nDayMask = CXTPCalendarUtils::GetDayOfWeekMask(nDayOfWeek);
|
|
if (nWWMask & nDayMask)
|
|
{
|
|
_AddDay(dtWeekDay);
|
|
}
|
|
dtWeekDay += COleDateTimeSpan(1);
|
|
}
|
|
|
|
if (GetViewDayCount() == 0)
|
|
{
|
|
_AddDay(CXTPCalendarUtils::ResetTime(COleDateTime::GetCurrentTime()));
|
|
}
|
|
}
|
|
|
|
COleDateTimeSpan CXTPCalendarDayView::GetScaleInterval() const
|
|
{
|
|
int nSI_min = XTP_SAFE_GET2(m_pControl, GetCalendarOptions(), nDayView_ScaleInterval, 30);
|
|
return COleDateTimeSpan(0, 0, nSI_min, 0);
|
|
}
|
|
|
|
void CXTPCalendarDayView::SetScaleInterval(const COleDateTimeSpan spScaleInterval)
|
|
{
|
|
BOOL bValidSVal = GETTOTAL_MINUTES_DTS(spScaleInterval) >= 1;
|
|
ASSERT(bValidSVal);
|
|
|
|
if (m_pTimeScaleHeader && bValidSVal)
|
|
{
|
|
int nOldScaleInterval = XTP_SAFE_GET2(m_pControl, GetCalendarOptions(), nDayView_ScaleInterval, 30);
|
|
int nScaleInterval = (int)GETTOTAL_MINUTES_DTS(spScaleInterval);
|
|
|
|
if (nScaleInterval != nOldScaleInterval)
|
|
{
|
|
XTP_SAFE_SET2(m_pControl, GetCalendarOptions(), nDayView_ScaleInterval, nScaleInterval);
|
|
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateAll);
|
|
|
|
SendNotification(XTP_NC_CALENDAROPTIONSWASCHANGED, xtpCalendarDayView, 0);
|
|
SendNotification(XTP_NC_CALENDARVIEWTIMESCALEWASCHANGED, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPCalendarDayView::SetScaleText(LPCTSTR strText)
|
|
{
|
|
XTP_SAFE_CALL1(m_pTimeScaleHeader, SetCaption(strText));
|
|
|
|
XTP_SAFE_SET2(m_pControl, GetCalendarOptions(), strDayView_ScaleLabel, strText);
|
|
|
|
SendNotification(XTP_NC_CALENDAROPTIONSWASCHANGED, xtpCalendarDayView, 0);
|
|
|
|
SendNotification(XTP_NC_CALENDARVIEWTIMESCALEWASCHANGED, 0, 0);
|
|
}
|
|
CString CXTPCalendarDayView::GetScaleText()
|
|
{
|
|
return XTP_SAFE_GET2(m_pControl, GetCalendarOptions(), strDayView_ScaleLabel, _T(""));
|
|
}
|
|
|
|
void CXTPCalendarDayView::SetScale2Text(LPCTSTR strText)
|
|
{
|
|
XTP_SAFE_CALL1(m_pTimeScaleHeader2, SetCaption(strText));
|
|
|
|
XTP_SAFE_SET2(m_pControl, GetCalendarOptions(), strDayView_Scale2Label, strText);
|
|
|
|
SendNotification(XTP_NC_CALENDAROPTIONSWASCHANGED, xtpCalendarDayView, 0);
|
|
SendNotification(XTP_NC_CALENDARVIEWTIMESCALEWASCHANGED, 0, 0);
|
|
}
|
|
CString CXTPCalendarDayView::GetScale2Text()
|
|
{
|
|
return XTP_SAFE_GET2(m_pControl, GetCalendarOptions(), strDayView_Scale2Label, _T(""));
|
|
}
|
|
|
|
void CXTPCalendarDayView::SetScale2TimeZone(const TIME_ZONE_INFORMATION* pTzInfo)
|
|
{
|
|
if (!pTzInfo || !m_pControl || !m_pControl->GetCalendarOptions())
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
m_pControl->GetCalendarOptions()->tziDayView_Scale2TimeZone = *pTzInfo;
|
|
|
|
AdjustScale2TimeZone();
|
|
|
|
SendNotification(XTP_NC_CALENDAROPTIONSWASCHANGED, xtpCalendarDayView, 0);
|
|
SendNotification(XTP_NC_CALENDARVIEWTIMESCALEWASCHANGED, 0, 0);
|
|
}
|
|
|
|
void CXTPCalendarDayView::AdjustScale2TimeZone()
|
|
{
|
|
TIME_ZONE_INFORMATION tziCurrent;
|
|
::ZeroMemory(&tziCurrent, sizeof(tziCurrent));
|
|
|
|
if (::GetTimeZoneInformation(&tziCurrent) == TIME_ZONE_ID_INVALID)
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
TIME_ZONE_INFORMATION tziScale2 = GetScale2TimeZone();
|
|
|
|
SYSTEMTIME systm00, systmScale1, systmScale2;
|
|
ZeroMemory(&systm00, sizeof(systm00));
|
|
ZeroMemory(&systmScale1, sizeof(systmScale1));
|
|
ZeroMemory(&systmScale2, sizeof(systmScale2));
|
|
|
|
::GetLocalTime(&systm00);
|
|
systm00.wHour = systm00.wMinute = systm00.wSecond = 0;
|
|
|
|
if (!CXTPCalendarUtils::SystemTimeToTzSpecificLocalTime(&tziCurrent,
|
|
&systm00, &systmScale1))
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
if (!CXTPCalendarUtils::SystemTimeToTzSpecificLocalTime(&tziScale2,
|
|
&systm00, &systmScale2))
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
COleDateTime dtScale1(systmScale1), dtScale2(systmScale2);
|
|
COleDateTimeSpan spScale2Offset = dtScale2 - dtScale1;
|
|
ASSERT((GETTOTAL_SECONDS_DTS(spScale2Offset) % 60) == 0);
|
|
|
|
int nTimeShift2_min = GETTOTAL_MINUTES_DTS(spScale2Offset);
|
|
|
|
XTP_SAFE_CALL1(m_pTimeScaleHeader2, SetTimeshift(nTimeShift2_min));
|
|
}
|
|
|
|
const TIME_ZONE_INFORMATION& CXTPCalendarDayView::GetScale2TimeZone()
|
|
{
|
|
static TIME_ZONE_INFORMATION s_tzEmty = {0};
|
|
|
|
return XTP_SAFE_GET2(m_pControl, GetCalendarOptions(), tziDayView_Scale2TimeZone, s_tzEmty);
|
|
}
|
|
|
|
|
|
void CXTPCalendarDayView::ShowScale2(BOOL bShow)
|
|
{
|
|
if (!m_pTimeScaleHeader2 || !m_pControl)
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
m_pTimeScaleHeader2->SetVisible(bShow);
|
|
|
|
m_pControl->GetCalendarOptions()->bDayView_Scale2Visible = bShow;
|
|
m_pControl->AdjustLayout();
|
|
|
|
SendNotification(XTP_NC_CALENDAROPTIONSWASCHANGED, xtpCalendarDayView, 0);
|
|
SendNotification(XTP_NC_CALENDARVIEWTIMESCALEWASCHANGED, 0, 0);
|
|
}
|
|
BOOL CXTPCalendarDayView::IsScale2Visible()
|
|
{
|
|
return XTP_SAFE_GET2(m_pControl, GetCalendarOptions(), bDayView_Scale2Visible, FALSE);
|
|
}
|
|
|
|
COleDateTime CXTPCalendarDayView::GetViewDayDate(int nIndex)
|
|
{
|
|
CXTPCalendarDayViewDay* pViewDay = GetViewDay(nIndex);
|
|
ASSERT(pViewDay);
|
|
return pViewDay ? pViewDay->m_dtDate :
|
|
CXTPCalendarUtils::ResetTime(CXTPCalendarUtils::GetCurrentTime());
|
|
}
|
|
|
|
void CXTPCalendarDayView::_ScrollDays(int nScrollDaysCount, BOOL bPrev)
|
|
{
|
|
ASSERT(nScrollDaysCount >= 1 && nScrollDaysCount <= 14);
|
|
nScrollDaysCount = min(14, max(1, nScrollDaysCount));
|
|
|
|
int nCount = GetViewDayCount();
|
|
if (!nCount)
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl);
|
|
CXTPCalendarControl::CViewChangedContext viewChanged(this);
|
|
|
|
COleDateTimeSpan spDay(bPrev ? -1 : 1, 0, 0, 0);
|
|
COleDateTime dtNewDay = GetViewDayDate(bPrev ? 0 : nCount-1);
|
|
|
|
for (int i = 0; i < nScrollDaysCount; i++)
|
|
{
|
|
dtNewDay += spDay;
|
|
|
|
CXTPCalendarDayViewDay* pDay = new CXTPCalendarDayViewDay(this, dtNewDay);
|
|
if (pDay)
|
|
{
|
|
m_arDays.RemoveAt(bPrev ? nCount-1 : 0);
|
|
m_arDays.InsertAt(bPrev ? 0 : nCount-1, pDay);
|
|
|
|
pDay->Populate(dtNewDay);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CXTPCalendarDayView::ScrollDaysToPrev(int nScrollDaysCount)
|
|
{
|
|
_ScrollDays(nScrollDaysCount, TRUE);
|
|
}
|
|
|
|
void CXTPCalendarDayView::ScrollDaysToNext(int nScrollDaysCount)
|
|
{
|
|
_ScrollDays(nScrollDaysCount, FALSE);
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::IsExpandDown()
|
|
{
|
|
int nDays = GetViewDayCount();
|
|
for (int nDay = 0; nDay < nDays; nDay++)
|
|
{
|
|
CXTPCalendarDayViewDay* pDay = GetViewDay(nDay);
|
|
ASSERT(pDay);
|
|
if (!pDay)
|
|
continue;
|
|
int nGroupsCount = pDay->GetViewGroupsCount();
|
|
for (int i = 0; i < nGroupsCount; i++)
|
|
{
|
|
if (pDay->GetViewGroup(i) && pDay->GetViewGroup(i)->IsExpandDown())
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::IsExpandUp()
|
|
{
|
|
int nDays = GetViewDayCount();
|
|
for (int nDay = 0; nDay < nDays; nDay++)
|
|
{
|
|
CXTPCalendarDayViewDay* pDay = GetViewDay(nDay);
|
|
ASSERT(pDay);
|
|
if (!pDay)
|
|
continue;
|
|
int nGroupsCount = pDay->GetViewGroupsCount();
|
|
for (int i = 0; i < nGroupsCount; i++)
|
|
{
|
|
if (pDay->GetViewGroup(i) && pDay->GetViewGroup(i)->IsExpandUp())
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
CXTPCalendarDayViewDay* CXTPCalendarDayView::GetDay(COleDateTime dtDay)
|
|
{
|
|
dtDay = CXTPCalendarUtils::ResetTime(dtDay);
|
|
|
|
int nDays = GetViewDayCount();
|
|
for (int i = 0; i < nDays; i++)
|
|
{
|
|
COleDateTime dtDay_I = GetViewDayDate(i);
|
|
|
|
if (CXTPCalendarUtils::IsEqual(dtDay, dtDay_I))
|
|
{
|
|
return GetViewDay(i);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void CXTPCalendarDayView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
|
|
{
|
|
CSelectionChangedContext selChanged(this);
|
|
|
|
TBase::OnKeyDown(nChar, nRepCnt, nFlags);
|
|
|
|
if (nChar == VK_LEFT || nChar == VK_RIGHT || nChar == VK_UP || nChar == VK_DOWN ||
|
|
nChar == VK_PRIOR || nChar == VK_NEXT)
|
|
{
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateRedraw);
|
|
|
|
UnselectAllEvents();
|
|
|
|
BOOL bVKShift = !!(GetKeyState(VK_SHIFT) & 0x8000);
|
|
COleDateTimeSpan spCell = GetCellDuration();
|
|
COleDateTimeSpan spDay(1, 0, 0, 0);
|
|
COleDateTime dtNewSelEnd = m_selectedBlock.dtEnd;
|
|
|
|
BOOL bEndIsEnd = m_selectedBlock.dtEnd > m_selectedBlock.dtBegin || !bVKShift;
|
|
int nSelCell = GetCellNumber(CXTPCalendarUtils::ResetDate(m_selectedBlock.dtEnd -
|
|
COleDateTimeSpan(0, 0, 0, bEndIsEnd ? 1 : 0)), bEndIsEnd);
|
|
|
|
CXTPDrawHelpers::KeyToLayout(m_pControl, nChar);
|
|
|
|
int nDVCount = GetViewDayCount();
|
|
COleDateTime dtFirstDay = GetViewDayDate(0);
|
|
COleDateTime dtLastDay = GetViewDayDate(nDVCount-1);
|
|
|
|
if (nChar == VK_LEFT)
|
|
{
|
|
if (!m_bScrollH_Disabled || CXTPCalendarUtils::ResetTime(dtNewSelEnd) > dtFirstDay)
|
|
{
|
|
if (!bVKShift && m_selectedBlock.nGroupIndex > 0)
|
|
{
|
|
m_selectedBlock.nGroupIndex--;
|
|
}
|
|
else
|
|
{
|
|
dtNewSelEnd -= spDay;
|
|
|
|
CXTPCalendarDayViewDay* pDay = GetDay(dtNewSelEnd);
|
|
if (!bVKShift && pDay)
|
|
{
|
|
m_selectedBlock.nGroupIndex = pDay->GetViewGroupsCount() - 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
if (nChar == VK_RIGHT)
|
|
{
|
|
if (!m_bScrollH_Disabled || CXTPCalendarUtils::ResetTime(dtNewSelEnd) < dtLastDay)
|
|
{
|
|
CXTPCalendarDayViewDay* pDay = GetDay(dtNewSelEnd);
|
|
if (!bVKShift && pDay && m_selectedBlock.nGroupIndex < pDay->GetViewGroupsCount() - 1)
|
|
{
|
|
m_selectedBlock.nGroupIndex++;
|
|
}
|
|
else
|
|
{
|
|
dtNewSelEnd += spDay;
|
|
m_selectedBlock.nGroupIndex = 0;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
if (nChar == VK_UP)
|
|
{
|
|
BOOL bRange = !m_bScrollV_Disabled || nSelCell > m_LayoutX.m_nTopRow;
|
|
|
|
if (nSelCell > 0 && bRange)
|
|
{
|
|
dtNewSelEnd = CXTPCalendarUtils::UpdateTime(dtNewSelEnd, GetCellTime(nSelCell));
|
|
}
|
|
if (m_selectedBlock.bAllDayEvent)
|
|
{
|
|
m_selectedBlock.bAllDayEvent = FALSE;
|
|
dtNewSelEnd -= spDay;
|
|
}
|
|
}
|
|
else
|
|
if (nChar == VK_DOWN)
|
|
{
|
|
BOOL bRange = !m_bScrollV_Disabled || nSelCell < m_LayoutX.m_nTopRow + m_LayoutX.m_nVisibleRowCount - 1;
|
|
if (nSelCell + 1 < GetRowCount() && bRange)
|
|
{
|
|
dtNewSelEnd = CXTPCalendarUtils::UpdateTime(dtNewSelEnd, GetCellTime(nSelCell+1)) + spCell;
|
|
if (nSelCell == GetRowCount()-2)
|
|
{
|
|
dtNewSelEnd -= COleDateTimeSpan(0, 0, 0, 1);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
if (nChar == VK_PRIOR)
|
|
{
|
|
if (!m_bScrollV_Disabled)
|
|
{
|
|
nSelCell = max(1, nSelCell - m_LayoutX.m_nVisibleRowCount + 1);
|
|
m_LayoutX.m_nTopRow = max(0, m_LayoutX.m_nTopRow - m_LayoutX.m_nVisibleRowCount);
|
|
dtNewSelEnd = CXTPCalendarUtils::UpdateTime(dtNewSelEnd, GetCellTime(nSelCell));
|
|
|
|
CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateScrollBar);
|
|
}
|
|
}
|
|
else
|
|
if (nChar == VK_NEXT)
|
|
{
|
|
if (!m_bScrollV_Disabled)
|
|
{
|
|
nSelCell = min(max(0, GetRowCount()-1), nSelCell + m_LayoutX.m_nVisibleRowCount);
|
|
m_LayoutX.m_nTopRow += m_LayoutX.m_nVisibleRowCount;
|
|
dtNewSelEnd = CXTPCalendarUtils::UpdateTime(dtNewSelEnd, GetCellTime(nSelCell)) + spCell;
|
|
if (nSelCell == GetRowCount()-1)
|
|
{
|
|
dtNewSelEnd -= COleDateTimeSpan(0, 0, 0, 1);
|
|
}
|
|
|
|
CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateScrollBar);
|
|
}
|
|
}
|
|
|
|
ProcessCellSelection(dtNewSelEnd, bVKShift, m_selectedBlock.bAllDayEvent,
|
|
m_selectedBlock.nGroupIndex);
|
|
}
|
|
}
|
|
|
|
void CXTPCalendarDayView::ProcessCellSelection(COleDateTime dtNewSelEnd,
|
|
BOOL bFixSelBegin, BOOL bAllDayEventSel, int nGroupIndex)
|
|
{
|
|
int nCount = GetViewDayCount();
|
|
if (!nCount)
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateRedraw);
|
|
|
|
COleDateTimeSpan spDay(1, 0, 0, 0);
|
|
COleDateTimeSpan spCell = GetCellDuration();
|
|
COleDateTimeSpan spSelStep = bAllDayEventSel ? spDay : spCell;
|
|
|
|
COleDateTime dtFirstDay = GetViewDayDate(0);
|
|
|
|
COleDateTime dtSelBegin_prev = m_selectedBlock.dtBegin;
|
|
COleDateTime dtSelEnd_prev = m_selectedBlock.dtEnd;
|
|
|
|
if (CXTPCalendarUtils::IsEqual(m_selectedBlock.dtEnd, m_selectedBlock.dtBegin))
|
|
{
|
|
int nSelRow = GetTopRow() + min(2, GetVisibleRowCount());
|
|
m_selectedBlock.dtBegin = CXTPCalendarUtils::UpdateTime(dtFirstDay, GetCellTime(nSelRow));
|
|
m_dtSelectionStart = m_selectedBlock.dtBegin;
|
|
|
|
m_selectedBlock.dtEnd = m_selectedBlock.dtBegin + spCell;
|
|
}
|
|
|
|
m_selectedBlock.dtEnd = dtNewSelEnd;
|
|
|
|
if (!bFixSelBegin)
|
|
{
|
|
m_selectedBlock.dtBegin = m_selectedBlock.dtEnd - spSelStep;
|
|
m_dtSelectionStart = m_selectedBlock.dtBegin;
|
|
}
|
|
else
|
|
if (CXTPCalendarUtils::IsEqual(m_selectedBlock.dtEnd, m_selectedBlock.dtBegin) ||
|
|
(!bAllDayEventSel && m_selectedBlock.dtEnd < m_selectedBlock.dtBegin &&
|
|
dtSelEnd_prev > dtSelBegin_prev)
|
|
)
|
|
{
|
|
m_selectedBlock.dtEnd -= spSelStep;
|
|
}
|
|
|
|
m_selectedBlock.bAllDayEvent = bAllDayEventSel;
|
|
m_selectedBlock.nGroupIndex = nGroupIndex;
|
|
|
|
//===========================================================================
|
|
int nDVCount = GetViewDayCount();
|
|
COleDateTime dtLastDay = GetViewDayDate(nDVCount-1);
|
|
COleDateTime& rdtSel1 = m_selectedBlock.dtEnd < m_selectedBlock.dtBegin ?
|
|
m_selectedBlock.dtEnd : m_selectedBlock.dtBegin;
|
|
COleDateTime& rdtSel2 = m_selectedBlock.dtEnd > m_selectedBlock.dtBegin ?
|
|
m_selectedBlock.dtEnd : m_selectedBlock.dtBegin;
|
|
|
|
COleDateTime dtSelDay1 = CXTPCalendarUtils::ResetTime(rdtSel1);
|
|
COleDateTime dtSelDay2 = CXTPCalendarUtils::ResetTime(rdtSel2-COleDateTimeSpan(0, 0, 0, 1));
|
|
|
|
//---------------------------------------------------------------------------
|
|
if (!m_bScrollH_Disabled)
|
|
{
|
|
if (dtSelDay1 < dtFirstDay)
|
|
{
|
|
ScrollDaysToPrev();
|
|
}
|
|
else if (dtSelDay2 > dtLastDay)
|
|
{
|
|
ScrollDaysToNext();
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// update variables after scrolling
|
|
nDVCount = GetViewDayCount();
|
|
dtFirstDay = GetViewDayDate(0);
|
|
dtLastDay = GetViewDayDate(nDVCount-1);
|
|
|
|
if (dtSelDay1 < dtFirstDay || (!bFixSelBegin && dtSelDay2 >= dtLastDay))
|
|
{
|
|
if (bFixSelBegin)
|
|
{
|
|
rdtSel1 = CXTPCalendarUtils::UpdateTime(dtFirstDay, rdtSel1);
|
|
rdtSel2 = rdtSel1 + spSelStep;
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
if (dtSelDay2 > dtLastDay || (!bFixSelBegin && dtSelDay1 <= dtFirstDay))
|
|
{
|
|
rdtSel2 = rdtSel1 + spSelStep;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
BOOL bEndIsEnd = m_selectedBlock.dtEnd > m_selectedBlock.dtBegin;
|
|
int nSelEndCell = GetCellNumber(CXTPCalendarUtils::ResetDate(m_selectedBlock.dtEnd -
|
|
COleDateTimeSpan(0, 0, 0, bEndIsEnd ? 1 : 0)), bEndIsEnd);
|
|
|
|
if (nSelEndCell < m_LayoutX.m_nTopRow && !bAllDayEventSel)
|
|
{
|
|
if (!m_bScrollV_Disabled)
|
|
{
|
|
m_LayoutX.m_nTopRow = min(max(0, nSelEndCell), max(0, GetRowCount()-1));
|
|
|
|
CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateScrollBar);
|
|
}
|
|
}
|
|
else if (nSelEndCell >= m_LayoutX.m_nTopRow + m_LayoutX.m_nVisibleRowCount && !bAllDayEventSel)
|
|
{
|
|
if (!m_bScrollV_Disabled)
|
|
{
|
|
m_LayoutX.m_nTopRow = nSelEndCell - m_LayoutX.m_nVisibleRowCount + 1;
|
|
m_LayoutX.m_nTopRow = min(max(0, m_LayoutX.m_nTopRow), max(0, GetRowCount() - 1));
|
|
|
|
CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateScrollBar);
|
|
}
|
|
}
|
|
|
|
if (_EnsureVisibleSelectionH())
|
|
{
|
|
GetCalendarControl()->AdjustLayout();
|
|
CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateScrollBar);
|
|
}
|
|
|
|
CSelectionChangedContext selChanged(this, xtpCalendarSelectionDays);
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::_EnsureVisibleSelectionH()
|
|
{
|
|
if (!m_selectedBlock.IsValid())
|
|
return FALSE;
|
|
|
|
CXTPCalendarViewDay* pVDay = _GetViewDay(CXTPCalendarUtils::ResetTime(m_selectedBlock.dtEnd));
|
|
ASSERT(pVDay);
|
|
|
|
if (!pVDay)
|
|
return FALSE;
|
|
|
|
CRect rcGroup = pVDay->GetDayRect();
|
|
{
|
|
CXTPCalendarViewGroup* pVGroup = pVDay->GetViewGroup_(m_selectedBlock.nGroupIndex);
|
|
ASSERT(pVGroup);
|
|
if (pVGroup)
|
|
rcGroup = pVGroup->GetRect();
|
|
}
|
|
|
|
CRect rcVisible = _GetScrollRectClient();
|
|
|
|
int nNewScrollPos = m_nScrollOffsetX;
|
|
|
|
if (rcGroup.left < rcVisible.left)
|
|
{
|
|
nNewScrollPos -= rcVisible.left - rcGroup.left;
|
|
if (nNewScrollPos <= 2) nNewScrollPos = 0;
|
|
}
|
|
else if (rcGroup.right > rcVisible.right)
|
|
{
|
|
nNewScrollPos += rcGroup.right - rcVisible.right + 1;
|
|
}
|
|
|
|
if (nNewScrollPos != m_nScrollOffsetX)
|
|
{
|
|
ScrollH(nNewScrollPos, nNewScrollPos);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::EnsureVisibleH(CXTPCalendarViewGroup* pViewGroup)
|
|
{
|
|
ASSERT(pViewGroup);
|
|
if (!pViewGroup)
|
|
return FALSE;
|
|
|
|
SCROLLINFO si;
|
|
if (!GetScrollBarInfoH(&si))
|
|
return FALSE;
|
|
|
|
CRect rcVisible = _GetScrollRectClient();
|
|
CRect rcGroup = pViewGroup->GetRect();
|
|
|
|
int nNewScrollPos = m_nScrollOffsetX;
|
|
|
|
if (rcGroup.left < rcVisible.left)
|
|
{
|
|
nNewScrollPos -= rcVisible.left - rcGroup.left;
|
|
}
|
|
else if (rcGroup.right > rcVisible.right)
|
|
{
|
|
nNewScrollPos += rcGroup.right - rcVisible.right + 1;
|
|
}
|
|
|
|
if (nNewScrollPos != m_nScrollOffsetX)
|
|
{
|
|
ScrollH(nNewScrollPos, nNewScrollPos);
|
|
|
|
GetCalendarControl()->AdjustLayout();
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateScrollBar);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::_EnsureVisibleH(CXTPCalendarViewEvent* pViewEvent)
|
|
{
|
|
ASSERT(pViewEvent);
|
|
|
|
CXTPCalendarViewGroup* pVGroup = pViewEvent ? pViewEvent->GetViewGroup_() : NULL;
|
|
ASSERT(pVGroup);
|
|
|
|
if (!pVGroup)
|
|
return FALSE;
|
|
|
|
SCROLLINFO si;
|
|
if (!GetScrollBarInfoH(&si))
|
|
return FALSE;
|
|
|
|
CRect rcVisible = _GetScrollRectClient();
|
|
|
|
CRect rcObj = pViewEvent->GetEventRect();
|
|
CRect rcGroup = pVGroup->GetRect();
|
|
|
|
if (pViewEvent->IsMultidayEvent() && (pViewEvent->GetMultiDayEventFlags() & xtpCalendarMultiDayMaster))
|
|
{
|
|
rcObj.left = max(rcObj.left, rcVisible.left);
|
|
rcObj.right = min(rcObj.right, rcVisible.right);
|
|
|
|
rcGroup.right = rcGroup.left + rcVisible.Width();
|
|
}
|
|
|
|
int nNewScrollPos = m_nScrollOffsetX;
|
|
|
|
if (rcObj.left < rcVisible.left)
|
|
{
|
|
nNewScrollPos -= rcVisible.left - rcGroup.left;
|
|
}
|
|
else if (rcObj.right > rcVisible.right)
|
|
{
|
|
nNewScrollPos += rcGroup.right - rcVisible.right + 1;
|
|
}
|
|
|
|
if (nNewScrollPos != m_nScrollOffsetX)
|
|
{
|
|
ScrollH(nNewScrollPos, nNewScrollPos);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::_EnsureVisibleV(CXTPCalendarViewEvent* pViewEvent)
|
|
{
|
|
if (!pViewEvent || !pViewEvent->GetEvent() || !GetCalendarControl() ||
|
|
!XTP_SAFE_GET2(pViewEvent, GetViewGroup_(), GetViewDay_(), NULL) )
|
|
{
|
|
ASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
if (pViewEvent->IsMultidayEvent())
|
|
{
|
|
//return pViewEvent->IsVisible();
|
|
return FALSE;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
COleDateTime dtDay = XTP_SAFE_GET3(pViewEvent, GetViewGroup_(), GetViewDay_(), GetDayDate(), (DATE)0);
|
|
dtDay = CXTPCalendarUtils::ResetTime(dtDay);
|
|
|
|
COleDateTime dtStart = pViewEvent->GetEvent()->GetStartTime();
|
|
COleDateTime dtEnd = pViewEvent->GetEvent()->GetEndTime();
|
|
|
|
COleDateTime stSTime = CXTPCalendarUtils::ResetDate(dtStart);
|
|
COleDateTime stETime = CXTPCalendarUtils::ResetDate(dtEnd);
|
|
|
|
if (CXTPCalendarUtils::IsZeroTime(stETime))
|
|
stETime = CXTPCalendarUtils::SetTime_235959(stETime);
|
|
|
|
int nSCell = 0;
|
|
int nECell = max(0, GetRowCount() - 1);
|
|
|
|
if (CXTPCalendarUtils::ResetTime(dtStart) == dtDay)
|
|
nSCell = GetCellNumber(stSTime, FALSE);
|
|
|
|
if (CXTPCalendarUtils::ResetTime(dtEnd) == dtDay)
|
|
nECell = GetCellNumber(stETime, TRUE);
|
|
|
|
if (nSCell < m_LayoutX.m_nTopRow)
|
|
{
|
|
m_LayoutX.m_nTopRow = min(max(0, nSCell-1), max(0, GetRowCount()-1));
|
|
|
|
return TRUE;
|
|
}
|
|
else if (nECell >= m_LayoutX.m_nTopRow + m_LayoutX.m_nVisibleRowCount)
|
|
{
|
|
int nTopRowPrev = m_LayoutX.m_nTopRow;
|
|
|
|
m_LayoutX.m_nTopRow = nECell - m_LayoutX.m_nVisibleRowCount + 1;
|
|
m_LayoutX.m_nTopRow = min(max(0, m_LayoutX.m_nTopRow), max(0, GetRowCount()-1));
|
|
m_LayoutX.m_nTopRow = min(max(0, nSCell-1), m_LayoutX.m_nTopRow);
|
|
|
|
if (nTopRowPrev != m_LayoutX.m_nTopRow)
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::EnsureVisible(CXTPCalendarViewEvent* pViewEvent)
|
|
{
|
|
ASSERT(pViewEvent);
|
|
if (!pViewEvent)
|
|
return FALSE;
|
|
|
|
BOOL bChanged1 = _EnsureVisibleH(pViewEvent);
|
|
BOOL bChanged2 = _EnsureVisibleV(pViewEvent);
|
|
|
|
if (bChanged1 || bChanged2)
|
|
{
|
|
GetCalendarControl()->AdjustLayout();
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateScrollBar);
|
|
}
|
|
|
|
ASSERT(pViewEvent->IsVisible());
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPCalendarDayView::EnsureVisibleH(CXTPCalendarViewEvent* pViewEvent)
|
|
{
|
|
ASSERT(pViewEvent);
|
|
if (!pViewEvent)
|
|
return FALSE;
|
|
|
|
BOOL bChanged1 = _EnsureVisibleH(pViewEvent);
|
|
|
|
if (bChanged1)
|
|
{
|
|
GetCalendarControl()->AdjustLayout();
|
|
CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateScrollBar);
|
|
}
|
|
|
|
ASSERT(pViewEvent->IsVisible());
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
CXTPCalendarViewEvent* CXTPCalendarDayView::FindEventToEditByTAB(COleDateTime dtMinStart,
|
|
BOOL bReverse, CXTPCalendarEvent* pAfterEvent)
|
|
{
|
|
CXTPCalendarViewEvent* pViewEvent = TBase::FindEventToEditByTAB(dtMinStart, bReverse, pAfterEvent);
|
|
if (pViewEvent)
|
|
{
|
|
if (EnsureVisible(pViewEvent))
|
|
{
|
|
return pViewEvent;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
COleDateTime CXTPCalendarDayView::GetNextTimeEditByTAB()
|
|
{
|
|
COleDateTime dtSel1 = min(m_selectedBlock.dtBegin, m_selectedBlock.dtEnd);
|
|
COleDateTime dtSel2 = max(m_selectedBlock.dtBegin, m_selectedBlock.dtEnd);
|
|
COleDateTime dtSel1Day = CXTPCalendarUtils::ResetTime(dtSel1);
|
|
COleDateTime dtSel2Day = CXTPCalendarUtils::ResetTime(dtSel2);
|
|
|
|
int nDVCount = GetViewDayCount();
|
|
COleDateTime dtFirstDay = GetViewDayDate(0);
|
|
COleDateTime dtLastDay = GetViewDayDate(nDVCount-1);
|
|
|
|
if (dtSel1Day >= dtFirstDay && dtSel1Day <= dtLastDay)
|
|
{
|
|
return dtSel1;
|
|
}
|
|
else
|
|
if (dtSel2Day >= dtFirstDay && dtSel2Day <= dtLastDay)
|
|
{
|
|
return dtSel2;
|
|
}
|
|
return TBase::GetNextTimeEditByTAB();
|
|
}
|
|
|
|
void CXTPCalendarDayView::UpdateNextTimeEditByTAB(COleDateTime dtNext, BOOL bReverse, BOOL bReset)
|
|
{
|
|
m_selectedBlock.dtBegin = m_selectedBlock.dtEnd = GetNextTimeEditByTAB();
|
|
m_dtSelectionStart = m_selectedBlock.dtBegin;
|
|
|
|
COleDateTime dtNextDay = CXTPCalendarUtils::ResetTime(dtNext);
|
|
COleDateTime dtCurrDay = CXTPCalendarUtils::ResetTime(GetNextTimeEditByTAB());
|
|
|
|
if (dtNextDay != dtCurrDay || bReset)
|
|
{
|
|
m_selectedBlock.dtBegin = m_selectedBlock.dtEnd = dtNextDay;
|
|
m_dtSelectionStart = m_selectedBlock.dtBegin;
|
|
|
|
COleDateTime dtFirstDay = GetViewDayDate(bReverse ? GetViewDayCount()-1 : 0);
|
|
if (dtNextDay == dtFirstDay || bReset)
|
|
{
|
|
if (bReverse)
|
|
{
|
|
m_selectedBlock.dtBegin = m_selectedBlock.dtEnd = dtNextDay + COleDateTimeSpan(1, 0, 0, 0);
|
|
m_selectedBlock.dtBegin = m_selectedBlock.dtEnd - GetCellDuration();
|
|
}
|
|
else
|
|
{
|
|
m_selectedBlock.dtEnd = m_selectedBlock.dtBegin + GetCellDuration();
|
|
}
|
|
ProcessCellSelection(m_selectedBlock.dtEnd, FALSE, FALSE, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
COleDateTimeSpan CXTPCalendarDayView::GetEventDurationMin() const
|
|
{
|
|
return GetCellDuration();
|
|
}
|
|
|
|
CXTPCalendarTimeZonePtr CXTPCalendarDayView::GetCurrentTimeZoneInfo()
|
|
{
|
|
TIME_ZONE_INFORMATION tziCurrent;
|
|
::ZeroMemory(&tziCurrent, sizeof(tziCurrent));
|
|
|
|
if (::GetTimeZoneInformation(&tziCurrent) == TIME_ZONE_ID_INVALID)
|
|
{
|
|
ASSERT(FALSE);
|
|
return NULL;
|
|
}
|
|
|
|
return CXTPCalendarTimeZone::GetTimeZoneInfo(&tziCurrent);
|
|
}
|
|
|
|
CXTPCalendarTimeZonePtr CXTPCalendarDayView::GetScale2TimeZoneInfo()
|
|
{
|
|
return CXTPCalendarTimeZone::GetTimeZoneInfo(&GetScale2TimeZone());
|
|
}
|
|
|
|
void CXTPCalendarDayView::ScrollToWorkDayBegin()
|
|
{
|
|
if (!m_pControl || !m_pControl->GetCalendarOptions())
|
|
{
|
|
ASSERT(FALSE);
|
|
return;
|
|
}
|
|
|
|
COleDateTime dtStartDate = GetViewDayDate(0);
|
|
COleDateTime dtSelBegin = CXTPCalendarUtils::UpdateTime(dtStartDate, m_pControl->GetCalendarOptions()->dtWorkDayStartTime);
|
|
COleDateTime dtSelEnd = dtSelBegin + GetCellDuration();
|
|
|
|
SetSelection(dtSelBegin, dtSelEnd, FALSE);
|
|
|
|
int nWDStartCell = GetCellNumber(m_pControl->GetCalendarOptions()->dtWorkDayStartTime, FALSE);
|
|
_ScrollV(nWDStartCell, nWDStartCell);
|
|
}
|
|
|
|
int CXTPCalendarDayView::_GetTimeScaleWith()
|
|
{
|
|
int nWidth = XTP_SAFE_GET1(GetTimeScale(), GetWidth(), 0);
|
|
if (IsScale2Visible())
|
|
nWidth += XTP_SAFE_GET1(GetTimeScale(2), GetWidth(), 0);
|
|
|
|
return nWidth;
|
|
}
|
|
|
|
CRect CXTPCalendarDayView::_GetScrollRectClient()
|
|
{
|
|
CXTPClientRect rcClient(GetCalendarControl());
|
|
rcClient.left += _GetTimeScaleWith();
|
|
rcClient.left = min(rcClient.left, rcClient.right);
|
|
|
|
return rcClient;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|