You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

430 lines
11 KiB
C++

2 years ago
// XTPCalendarWeekView.cpp: implementation of the CXTPCalendarWeekView class.
//
// This file is a part of the XTREME CALENDAR MFC class library.
// (c)1998-2012 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 "Common/XTPDrawHelpers.h"
#include "Common/XTPSmartPtrInternalT.h"
#include "Common/XTPColorManager.h"
#include "XTPCalendarUtils.h"
#include "XTPCalendarDefines.h"
#include "XTPCalendarPtrCollectionT.h"
#include "XTPCalendarView.h"
#include "XTPCalendarViewDay.h"
#include "XTPCalendarViewEvent.h"
#include "XTPCalendarViewPart.h"
#include "XTPCalendarWeekViewEvent.h"
#include "XTPCalendarWeekViewDay.h"
#include "XTPCalendarWeekView.h"
#include "XTPCalendarControl.h"
#include "XTPCalendarPaintManager.h"
#include "XTPCalendarTheme.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CXTPCalendarWeekView, CXTPCalendarView)
CXTPCalendarWeekView::CXTPCalendarWeekView(CXTPCalendarControl* pCalendarControl) :
TBase(pCalendarControl, xtpCalendarWeekView)
{
m_LayoutX.m_nGridColumns = 2;
m_nCurrPos = 180;//365;
m_LayoutX.m_nDayHeaderHeight = 18;
m_LayoutX.m_nDayWidth = 1;
m_LayoutX.m_nDayHeidht = 1;
m_nFirstDayOfWeekIndex = 0; // 1 = Sunday, 2 = Monday ...
COleDateTime dtNow = CXTPCalendarUtils::GetCurrentTime();
SetBeginDate(dtNow);
AdjustFirstDayOfWeek();
SetBeginDate(dtNow);
//---------------------------------------------------------------------------
for (int i = 0; i < 7; i++)
{
CXTPCalendarWeekViewDay* pWDayView = new CXTPCalendarWeekViewDay(this);
m_arDays.Add(pWDayView);
}
}
CXTPCalendarWeekView::~CXTPCalendarWeekView()
{
}
/////////////////////////////////////////////////////////////////////////////////////////////////
void CXTPCalendarWeekView::ShowDay(const COleDateTime& date, BOOL bSelect)
{
CXTPCalendarControl::CUpdateContext updateContext(m_pControl, xtpCalendarUpdateRedrawIfNeed);
CXTPCalendarControl::CViewChangedContext viewChanged(this);
CXTPCalendarControl::CUpdateContext updateContext2(m_pControl, xtpCalendarUpdateAll);
SetBeginDate(date);
Populate();
if (bSelect)
SelectDay(CXTPCalendarUtils::ResetTime(date));
}
void CXTPCalendarWeekView::Populate()
{
AdjustFirstDayOfWeek();
TBase::Populate();
}
void CXTPCalendarWeekView::AdjustLayout(CDC* pDC, const CRect& rcView, BOOL bCallPostAdjustLayout)
{
if (!GetPaintManager() || !GetPaintManager()->GetWeekViewPart() ||
!GetPaintManager()->GetWeekViewEventPart() || !pDC)
{
ASSERT(FALSE);
return;
}
TBase::AdjustLayout(pDC, rcView, FALSE);
AdjustFirstDayOfWeek();
CXTPCalendarViewPart* pWVPart = GetPaintManager()->GetWeekViewPart();
m_LayoutX.m_nDayHeaderHeight = pWVPart->GetTextExtent(pDC, _T("A")).cy + 7;
m_Layout.m_nRowHeight = GetPaintManager()->GetWeekViewEventPart()->GetTextExtent(pDC, _T("(")).cy + 6;
// Adjust Week's Grid
CRect rcView2 = rcView;
rcView2.DeflateRect(-1, -1, -1, -1);
int nRows = 6/m_LayoutX.m_nGridColumns;
ASSERT(6 % m_LayoutX.m_nGridColumns == 0);
m_LayoutX.m_nDayWidth = rcView2.Width() / m_LayoutX.m_nGridColumns;
m_LayoutX.m_nDayHeidht = rcView2.Height() / nRows;
CalculateHeaderFormat(pDC, m_LayoutX.m_nDayWidth, &pWVPart->GetTextFont());
int nDayIndex = 0;
CRect rc(0, 0, 0, 0);
for (int nDayCol = 0; nDayCol < m_LayoutX.m_nGridColumns; nDayCol++)
{
for (int nDayRow = 0; nDayRow < nRows; nDayRow++)
{
CXTPCalendarWeekViewDay* pDay = GetViewDay(nDayIndex);
ASSERT(pDay);
if (!pDay)
{
continue;
}
COleDateTime dtDayDate = GetViewDayDate(nDayIndex);
rc.SetRect( rcView2.left + m_LayoutX.m_nDayWidth * nDayCol,
rcView2.top + m_LayoutX.m_nDayHeidht* nDayRow,
rcView2.left + m_LayoutX.m_nDayWidth + m_LayoutX.m_nDayWidth * nDayCol,
rcView2.top + m_LayoutX.m_nDayHeidht + m_LayoutX.m_nDayHeidht * nDayRow);
int nWday = dtDayDate.GetDayOfWeek();
//Allow Sunday as 1st day of week
//ASSERT(nWday != 1);
//if (nWday == 7)
//Wrong code - this code give Sat and Sun in half-height - ignored working days assignment -
//e.g. Wed and Thu as free days!
//if (nWday == m_nFirstDayOfWeekIndex + 5)
if (nWday == 1 + (m_nFirstDayOfWeekIndex + 4) % 7)
{
CRect rc2 = rc;
rc2.bottom = rc.top + rc.Height()/2;
pDay->AdjustLayout(pDC, rc2);
nDayIndex++;
pDay = GetViewDay(nDayIndex);
rc.top = rc2.bottom;
}
ASSERT(pDay);
if (pDay)
{
pDay->AdjustLayout(pDC, rc);
}
nDayIndex++;
}
}
//---------------------------------------------------------------------------
if (bCallPostAdjustLayout)
{
OnPostAdjustLayout();
}
}
void CXTPCalendarWeekView::AdjustLayout2(CDC* pDC, const CRect& rcView, BOOL bCallPostAdjustLayout)
{
if (!GetTheme())
{
ASSERT(FALSE);
return;
}
TBase::AdjustLayout(pDC, rcView, FALSE);
AdjustFirstDayOfWeek();
XTP_SAFE_CALL2(GetTheme(), GetWeekViewPart(), AdjustLayout(pDC, rcView, bCallPostAdjustLayout));
}
void CXTPCalendarWeekView::AdjustFirstDayOfWeek()
{
if (!GetCalendarControl())
{
return;
}
int nFDPrev = m_nFirstDayOfWeekIndex;
//- Adjust First day of Week ------------------------------------------
m_nFirstDayOfWeekIndex = GetCalendarControl()->GetFirstDayOfWeek();
//Allow Sunday as 1st day of week
//if (m_nFirstDayOfWeekIndex == 1)
// m_nFirstDayOfWeekIndex = 2;
int nDShift = m_nFirstDayOfWeekIndex - nFDPrev;
COleDateTime dtBeginDate_prev = GetBeginDate();
COleDateTime dtBeginDate = dtBeginDate_prev + COleDateTimeSpan(nDShift);
SetBeginDate(dtBeginDate);
dtBeginDate = GetBeginDate();
}
COleDateTime CXTPCalendarWeekView::ShiftDateToCell_00(COleDateTime dtDate) const
{
int iDoW = dtDate.GetDayOfWeek();
int nShift = (iDoW - m_nFirstDayOfWeekIndex + 7) % 7;
if (nShift)
{
COleDateTimeSpan spShift(nShift, 0, 0, 0);
dtDate -= spShift;
}
return dtDate;
}
void CXTPCalendarWeekView::SetBeginDate(COleDateTime dtNewBeginDate)
{
m_dtBeginDate = ShiftDateToCell_00(CXTPCalendarUtils::ResetTime(dtNewBeginDate));
}
void CXTPCalendarWeekView::Draw(CDC* pDC)
{
XTP_SAFE_CALL2(GetPaintManager(), GetWeekViewPart(), OnDraw(pDC, this));
// Draw events
int nDays = m_arDays.GetCount();
for (int nDay = 0; nDay < nDays; nDay++)
{
XTP_SAFE_CALL1(m_arDays.GetAt(nDay), Draw(pDC));
}
}
void CXTPCalendarWeekView::Draw2(CDC* pDC)
{
if (!GetTheme())
{
ASSERT(FALSE);
return;
}
GetTheme()->GetWeekViewPart()->Draw(pDC);
}
void CXTPCalendarWeekView::ScrollV(int /*nPos*/, int nPos_raw)
{
if (nPos_raw == m_nCurrPos || m_bScrollV_Disabled)
return;
CXTPCalendarControl::CViewChangedContext viewChanged(this);
if (IsEditingSubject())
{
EndEditSubject(xtpCalendarEditSubjectCommit, FALSE);
}
int nShift = nPos_raw - m_nCurrPos;
COleDateTimeSpan spWeeks(nShift * 7, 0, 0, 0);
m_dtBeginDate += spWeeks;
m_nCurrPos = nPos_raw;
if (GetSelection())
{
m_selectedBlock.dtBegin += spWeeks;
m_selectedBlock.dtEnd += spWeeks;
CSelectionChangedContext selChanged(this, xtpCalendarSelectionDays);
}
UnselectAllEvents();
Populate();
}
BOOL CXTPCalendarWeekView::GetScrollBarInfoV(SCROLLINFO* pSI) const
{
ASSERT(pSI);
if (!pSI || m_bScrollV_Disabled)
{
return FALSE;
}
pSI->nPos = m_nCurrPos;
pSI->nMax = 360;//730;
pSI->nPage = 1;
return TRUE;
}
COleDateTime CXTPCalendarWeekView::GetViewDayDate(int nIndex) const
{
ASSERT(nIndex >= 0 && nIndex < 7);
COleDateTimeSpan spDays(nIndex, 0, 0, 0);
COleDateTime dtDayDate = m_dtBeginDate + spDays;
return dtDayDate;
}
void CXTPCalendarWeekView::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);
BOOL bVKShift = (GetKeyState(VK_SHIFT) < 0);
COleDateTimeSpan spDay(1, 0, 0, 0);
COleDateTimeSpan spWeek(7, 0, 0, 0);
int nDVCount = GetViewDayCount();
BOOL bSelReseted = !m_selectedBlock.dtEnd.GetStatus() == COleDateTime::valid;
COleDateTime dtLastSelDay = GetLastSelectedDate();
int nLastSelDayIdx = (dtLastSelDay.GetDayOfWeek() - m_nFirstDayOfWeekIndex + 7) % 7;
COleDateTime dtNewSelDay = dtLastSelDay;
int nSatDayIdx = 7 - m_nFirstDayOfWeekIndex;
int nNewIdx = nLastSelDayIdx + 3;
int nHalfShift = nNewIdx > nSatDayIdx && nLastSelDayIdx <= nSatDayIdx ||
nNewIdx > nSatDayIdx + 7 && nLastSelDayIdx <= nSatDayIdx + 7 ? 4 : 3;
COleDateTimeSpan spHalfWeekPlus(nHalfShift, 0, 0, 0);
COleDateTimeSpan spHalfWeekMinus(7 - nHalfShift, 0, 0, 0);
CXTPDrawHelpers::KeyToLayout(m_pControl, nChar);
if (nChar == VK_LEFT)
{
dtNewSelDay -= spHalfWeekMinus;
}
else if (nChar == VK_RIGHT)
{
dtNewSelDay += spHalfWeekPlus;
}
else if (nChar == VK_UP)
{
dtNewSelDay -= spDay;
}
else if (nChar == VK_DOWN)
{
dtNewSelDay += spDay;
}
else if (nChar == VK_PRIOR)
{
dtNewSelDay -= spWeek;
}
else if (nChar == VK_NEXT)
{
dtNewSelDay += spWeek;
}
//---------------------------------------------------------------------------
COleDateTime dtFirstDay = GetViewDayDate(0);
COleDateTime dtLastDay = GetViewDayDate(nDVCount-1);
BOOL bNeedScroll = dtNewSelDay < dtFirstDay || dtNewSelDay > dtLastDay;
if (bNeedScroll && !m_bScrollV_Disabled)
{
if (dtNewSelDay < dtFirstDay)
{
ScrollV(m_nCurrPos-1, m_nCurrPos-1);
bSelReseted = TRUE;
CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateScrollBar);
}
if (dtNewSelDay > dtLastDay)
{
ScrollV(m_nCurrPos + 1, m_nCurrPos + 1);
bSelReseted = TRUE;
CXTPCalendarControl::CUpdateContext updateContext1(m_pControl, xtpCalendarUpdateScrollBar);
}
}
//---------------------------------------------------------------------------
if (!bNeedScroll || !m_bScrollV_Disabled)
{
if (bVKShift && !bSelReseted)
{
SelectDays(dtNewSelDay);
}
else
{
SelectDay(dtNewSelDay);
}
}
}
}