CBCGPPlannerView::BCGP_PLANNER_HITTEST
CBCGPPlannerViewMonth::HitTestArea (const CPoint& point) const
{
	BCGP_PLANNER_HITTEST hit = CBCGPPlannerView::HitTestArea (point);

	if (hit == BCGP_PLANNER_HITTEST_CLIENT)
	{
		const int nDuration = GetViewDuration ();

		for (int i = 0; i < nDuration; i++)
		{
			CRect rt (m_ViewRects[i]);
			rt.right++;
			rt.bottom++;

			if (rt.PtInRect (point))
			{
				rt.bottom = rt.top + min(rt.Height (), m_nRowHeight);

				if (rt.PtInRect (point))
				{
					hit = BCGP_PLANNER_HITTEST_DAY_CAPTION;
				}

				break;
			}
		}
	}
	else if (hit == BCGP_PLANNER_HITTEST_NOWHERE)
	{
		if (m_rectApps.left <= point.x && point.x <= m_rectApps.right)
		{
			if (0 <= point.y && point.y < m_nHeaderHeight)
			{
				hit = BCGP_PLANNER_HITTEST_HEADER;
			}
		}
		else if (0 <= point.x && point.x < m_nWeekBarWidth)
		{
			hit = BCGP_PLANNER_HITTEST_WEEKBAR;

			for (int iRow = 0; iRow < m_WeekRects.GetSize (); iRow++)
			{
				if (m_WeekRects[iRow].PtInRect (point))
				{
					hit = BCGP_PLANNER_HITTEST_WEEK_CAPTION;
					break;
				}
			}
		}
	}
		
	return hit;
}
void CBCGPPlannerViewMulti::OnDrawHeaderResource (CDC* pDC, const CRect& rectHeader)
{
	ASSERT_VALID (pDC);

	const int nDays = GetViewDuration ();

	DWORD dwFlags = GetPlanner ()->GetDrawFlags ();
	BOOL bBold = (dwFlags & BCGP_PLANNER_DRAW_VIEW_CAPTION_DAY_BOLD) ==
			BCGP_PLANNER_DRAW_VIEW_CAPTION_DAY_BOLD;

	HFONT hOldFont = NULL;
	if (bBold)
	{
		hOldFont = SetCurrFont (pDC, bBold);
	}

	for (int nDay = 0; nDay < nDays; nDay ++)
	{
		CRect rectCaption (rectHeader);
		rectCaption.left = m_ViewRects[nDay].left;
		rectCaption.right = m_ViewRects[nDay].right;

		DrawHeader (pDC, rectCaption, m_Resources [0].m_Rects[nDay].Width ());

		CRect rectResCaption (rectCaption);

		for (int i = 0; i < m_Resources.GetSize (); i++)
		{
			XResource& res = m_Resources[i];

			rectResCaption.left = res.m_Rects[nDay].left;
			rectResCaption.right = res.m_Rects[nDay].right;

			visualManager->PreparePlannerCaptionBackItem (TRUE);
			COLORREF clrText = OnFillPlannerCaption (
				pDC, rectResCaption, FALSE, FALSE, FALSE);

			DrawCaptionText (pDC, rectResCaption, res.m_Description, clrText, 
				res.m_bToolTipNeeded ? DT_LEFT : DT_CENTER);
		}
	}

	if (hOldFont != NULL)
	{
		::SelectObject (pDC->GetSafeHdc (), hOldFont);
	}
}
CRect CBCGPPlannerViewMulti::GetRectFromDate(const COleDateTime& date) const
{
	CRect rect(0, 0, 0, 0);

	if (date < GetDateStart() || GetDateEnd() < date)
	{
		return rect;
	}

	int nResourceIndex = FindResourceIndexByID (GetCurrentResourceID ());
	if (nResourceIndex == -1)
	{
		return rect;
	}

	const int nDays = GetViewDuration ();
	if (m_ViewRects.GetSize() != nDays)
	{
		return rect;
	}

	COleDateTime dt(date.GetYear(), date.GetMonth(), date.GetDay(), 0, 0, 0);
	COleDateTime dtCur(GetDateStart());

	int nIndex = (int)((dt - dtCur).GetTotalDays());
	if (nIndex < 0 || nDays <= nIndex)
	{
		return rect;
	}

	rect = const_cast<XResourceCollection&>(m_Resources)[nResourceIndex].m_Rects[nIndex];
	rect.top += ((date.GetHour() * 60 + date.GetMinute()) / CBCGPPlannerView::GetTimeDeltaInMinuts (GetTimeDelta ()) - m_nScrollOffset) * m_nRowHeight;
	rect.bottom = rect.top + m_nRowHeight;

	return rect;
}
BOOL CBCGPPlannerViewMonth::OnKeyDown(UINT nChar, UINT /*nRepCnt*/, UINT /*nFlags*/)
{
	if (m_pCapturedAppointment != NULL)
	{
		GetPlanner ()->SendMessage (WM_CANCELMODE, 0, 0);
		return TRUE;
	}

	BOOL isShiftPressed = (0x8000 & GetKeyState(VK_SHIFT)) != 0;

	BOOL bHandled = FALSE;

	if (nChar == VK_PRIOR || nChar == VK_NEXT) // Page Up, Page Down
	{
		OnVScroll (nChar == VK_PRIOR ? SB_PAGEUP : SB_PAGEDOWN, 0, NULL);

		SetSelection (m_Date, m_Date);

		bHandled = TRUE;
	}
	else if (nChar == VK_HOME || nChar == VK_END)
	{
		COleDateTime date
			(
				GetFirstWeekDay2 (m_Date, CBCGPPlannerManagerCtrl::GetFirstDayOfWeek () + 1)
			);

		if (nChar == VK_END)
		{
			date += COleDateTimeSpan (6, 0, 0, 0);
		}

		if (!isShiftPressed)
		{
			m_Date = date;
		}
		else
		{
			if (nChar == VK_HOME)
			{
				COleDateTime oldDate (m_Date);

				m_Date = date;
				date   = oldDate;
			}
			else
			{
				m_Date = m_Selection[1];
			}
		}

		SetSelection (m_Date, date);

		bHandled = TRUE;
	}
	else if (nChar == VK_UP || nChar == VK_DOWN || nChar == VK_LEFT || nChar == VK_RIGHT)
	{
		COleDateTime date (m_Selection [1]);

		COleDateTimeSpan span (1, 0, 0 ,0);

		if (nChar == VK_LEFT)
		{
			date -= span;
		}
		else if (nChar == VK_RIGHT)
		{
			date += span;
		}
		else
		{
			span = COleDateTimeSpan (7, 0, 0 ,0);

			if (nChar == VK_UP)
			{
				date -= span;
			}
			else if (nChar == VK_DOWN)
			{
				date += span;
			}
		}

		BOOL bScroll = FALSE;

		if (date < m_DateStart)
		{
			OnVScroll (SB_LINEUP, 0, NULL);
			bScroll = TRUE;
		}
		else if (date >= (m_DateStart + COleDateTimeSpan (GetViewDuration (), 0, 0, 0)))
		{
			OnVScroll (SB_LINEDOWN, 0, NULL);
			bScroll = TRUE;
		}

		if (!isShiftPressed || bScroll)
		{
			m_Date = date;
			SetSelection (m_Date, m_Date);
		}
		else
		{
			SetSelection (m_Selection [0], date);

			if (date <= m_Date)
			{
				m_Date = date;
			}
		}

		bHandled = TRUE;
	}

	return bHandled;
}
void CBCGPPlannerViewMulti::OnDrawAppointmentsDuration (CDC* pDC)
{
	if ((GetPlanner ()->GetDrawFlags () & BCGP_PLANNER_DRAW_VIEW_NO_DURATION) == 
			BCGP_PLANNER_DRAW_VIEW_NO_DURATION)
	{
		return;
	}

	XBCGPAppointmentArray& arQueryApps = GetQueryedAppointments ();
	XBCGPAppointmentArray& arDragApps  = GetDragedAppointments ();

	if (arQueryApps.GetSize () == 0 && arDragApps.GetSize () == 0)
	{
		return;
	}

	BOOL bDragDrop        = IsDragDrop ();
	DROPEFFECT dragEffect = GetDragEffect ();
	BOOL bDragMatch       = IsCaptureMatched ();

	COleDateTime dtS = GetDateStart ();
	COleDateTime dtE = GetDateEnd ();

	const int nMinuts = CBCGPPlannerView::GetTimeDeltaInMinuts (GetTimeDelta ());
	const int nCount = GetViewHours() * 60 / nMinuts;
	const int yOffset = GetViewHourOffset () * m_nRowHeight;

	for (int nApp = 0; nApp < 2; nApp++)
	{
		XBCGPAppointmentArray& arApps = nApp == 1 ? arDragApps : arQueryApps;

		if (nApp == 1)
		{
			bDragDrop = bDragDrop && arDragApps.GetSize ();
		}

		if (arApps.GetSize () == 0)
		{
			continue;
		}

		for (int i = 0; i < arApps.GetSize (); i++)
		{
			CBCGPAppointment* pApp = arApps [i];
			if (pApp == NULL || !(pApp->IsAllDay () || pApp->IsMultiDay ()) || 
				pApp->GetDurationColor () == CLR_DEFAULT)
			{
				continue;
			}

			BOOL bDraw = FALSE;

			if (bDragDrop && dragEffect != DROPEFFECT_NONE && 
				pApp->IsSelected () && nApp == 0)
			{
				if ((dragEffect & DROPEFFECT_COPY) == DROPEFFECT_COPY || bDragMatch)
				{
					bDraw = TRUE;
				}
			}
			else
			{
				bDraw = TRUE;
			}

			if(!bDraw)
			{
				continue;
			}

			int nResourceIndex = FindResourceIndexByID (pApp->GetResourceID ());
			ASSERT(nResourceIndex != -1);
			XResource& resource = m_Resources[nResourceIndex];

			COleDateTime dtStart  = pApp->GetStart ();
			COleDateTime dtFinish = pApp->GetFinish ();

			dtStart.SetDate (dtStart.GetYear (), dtStart.GetMonth (), dtStart.GetDay ());
			dtFinish.SetDate (dtFinish.GetYear (), dtFinish.GetMonth (), dtFinish.GetDay ());

			BOOL bStart = FALSE;
			BOOL bEnd   = FALSE;

			if (dtStart < dtS)
			{
				dtStart = dtS;
				bStart  = TRUE;
			}

			if (dtE < dtFinish)
			{
				dtFinish = dtE;
				bEnd     = TRUE;
			}

			COleDateTimeSpan span (dtFinish - dtStart);

			int nStart = (dtStart - dtS).GetDays ();
			int nEnd   = min(nStart + span.GetDays () + 1, GetViewDuration ());

			CBrush br (pApp->GetDurationColor () == CLR_DEFAULT
				? globalData.clrWindow
				: pApp->GetDurationColor ());

			for(int i = nStart; i < nEnd; i++)
			{
				CRect rt (resource.m_Rects[i]);

				rt.right  = rt.left + 
					CBCGPPlannerViewMulti::BCGP_PLANNER_DURATION_BAR_WIDTH + 1;		
				rt.left  -= (i == 0) ? 1 : 0;
				rt.top   -= 1;
				rt.bottom = rt.top + nCount * m_nRowHeight;
				rt.DeflateRect (1, 0);
				
				if (!pApp->IsAllDay ())
				{
					rt.OffsetRect (0, -yOffset);

					if (i == (nEnd - 1) && !bEnd)
					{
						dtFinish = pApp->GetFinish ();
						const double dDelta = (dtFinish.GetHour () * 60 + dtFinish.GetMinute ()) / (double)nMinuts;

						rt.bottom = rt.top + CBCGPPlannerView::round(dDelta * m_nRowHeight);
					}

					if (i == nStart && !bStart)
					{
						dtStart  = pApp->GetStart ();
						const double dDelta = 
							(dtStart.GetHour () * 60 + dtStart.GetMinute ()) / (double)nMinuts;

						rt.top += CBCGPPlannerView::round(dDelta * m_nRowHeight);
					}

					rt.IntersectRect (rt, resource.m_Rects[i]);
				}

				pDC->FillRect (rt, &br);
			}
		}
	}
}
void CBCGPPlannerViewMulti::AdjustAppointments ()
{
	XBCGPAppointmentArray& arQueryApps = GetQueryedAppointments ();
	XBCGPAppointmentArray& arDragApps = GetDragedAppointments ();

	const int nDays = GetViewDuration ();

	if ((arQueryApps.GetSize () == 0 && arDragApps.GetSize () == 0) || 
		m_ViewRects.GetSize () != nDays)
	{
		ClearVisibleUpDownIcons ();
		return;
	}

	BOOL bDrawShadow = IsDrawAppsShadow ();

	BOOL bDragDrop        = IsDragDrop ();
	DROPEFFECT dragEffect = GetDragEffect ();
	BOOL bDragMatch       = IsCaptureMatched ();

	bDragDrop = !bDragDrop || 
		(bDragDrop && ((dragEffect & DROPEFFECT_COPY) == DROPEFFECT_COPY && bDragMatch) || 
		!bDragMatch);
	bDragDrop = bDragDrop && arDragApps.GetSize ();

	const int nTimeDelta = CBCGPPlannerView::GetTimeDeltaInMinuts (GetTimeDelta ());
	const int yOffset = GetViewHourOffset () * m_nRowHeight;
	const int yHeaderOffset = m_nHeaderScrollOffset * (m_nRowHeight + s_HeaderAllDayPadding);

	COleDateTime date (m_DateStart);

	for (int nApp = 0; nApp < 2; nApp++)
	{
		if (!bDragDrop && nApp == 0)
		{
			continue;
		}

		XBCGPAppointmentArray& arApps = nApp == 0 ? arDragApps : arQueryApps;

		for (int i = 0; i < arApps.GetSize (); i++)
		{
			CBCGPAppointment* pApp = arApps[i];
			ASSERT_VALID (pApp);

			pApp->ResetDraw ();
			pApp->GetDSDraw ().SetConcatenate (FALSE);
		}
	}

	COleDateTimeSpan spanDay (1, 0, 0, 0);

	int nDay = 0;

	const BOOL bNoDuration = 
		(GetPlanner ()->GetDrawFlags () & BCGP_PLANNER_DRAW_VIEW_NO_DURATION) == 
		BCGP_PLANNER_DRAW_VIEW_NO_DURATION;

	for (int nRes = 0; nRes < m_Resources.GetSize (); nRes++)
	{
		XResource& resource = m_Resources[nRes];

		date = m_DateStart;

		for (nDay = 0; nDay < nDays; nDay ++)
		{
			XBCGPAppointmentArray arAllDays;

			for (int nApp = 0; nApp < 2; nApp++)
			{
				if (!bDragDrop && nApp == 1)
				{
					continue;
				}

				XBCGPAppointmentArray& arApps = nApp == 1 ? arDragApps : arQueryApps;

				XBCGPAppointmentArray arByDate;

				int i;

				CRect rectFill (resource.m_Rects[nDay]);
				rectFill.top -= yOffset;

				if (bNoDuration && nDay > 0)
				{
					rectFill.left++;
				}

				int nStartIndex = 0;
				for (i = 0; i < arApps.GetSize (); i++)
				{
					const CBCGPAppointment* pApp = arApps[i];
					if (pApp != NULL && pApp->GetResourceID () == resource.m_ResourceID)
					{
						nStartIndex = i;
						break;
					}
				}

				for (i = nStartIndex; i < arApps.GetSize (); i++)
				{
					CBCGPAppointment* pApp = arApps[i];
					ASSERT_VALID (pApp);

					if (pApp->GetResourceID () != resource.m_ResourceID)
					{
						break;
					}

					if (CBCGPPlannerView::IsAppointmentInDate (*pApp, date))
					{
						CRect rtApp (rectFill);

						// trimming top and bottom edge, starting from TimeDelta and Appointment interval
						rtApp.top = rectFill.top + m_nRowHeight * 
							long((pApp->GetStart ().GetHour () * 60 + 
								 pApp->GetStart ().GetMinute ()) / nTimeDelta) - 1;

						if (pApp->IsAllDay () || pApp->IsMultiDay ())
						{
							BOOL bAdd = TRUE;

							for (int i = 0; i < arAllDays.GetSize (); i++)
							{
								if (arAllDays[i] == pApp)
								{
									bAdd = FALSE;
									break;
								}
							}

							if (bAdd)
							{
								arAllDays.Add (pApp);
							}
						}
						else
						{
							rtApp.right -= 2 * BCGP_PLANNER_APPOINTMENT_SPACE;

							if (pApp->GetStart () != pApp->GetFinish ())
							{
								COleDateTime dtAF (pApp->GetFinish ());
								int minutes = dtAF.GetHour () * 60 + dtAF.GetMinute ();

								if (!IsOneDay (pApp->GetStart (), dtAF))
								{
									BOOL bStartDay   = IsOneDay (date, pApp->GetStart ());
									BOOL bFinishNULL = dtAF.GetHour () == 0 && 
													   dtAF.GetMinute () == 0;

									if (bStartDay)
									{
										minutes = 24 * 60;
									}

									if (bFinishNULL)
									{
										if (!bStartDay)
										{
											if (pApp->GetDSDraw ().GetCount () == 1)
											{
												pApp->GetDSDraw ()[0].m_date2 = date;
												continue;
											}
										}
									}
									else
									{
										if (!bStartDay)
										{
											rtApp.top = rectFill.top - 1;
										}
									}
								}

								rtApp.bottom = rectFill.top + m_nRowHeight * 
									(long)ceil(minutes / (double)nTimeDelta) - 1;
							}
							else
							{
								rtApp.bottom = rtApp.top + m_nRowHeight;
							}

							pApp->SetRectDraw (rtApp, date);
							arByDate.Add (pApp);
						}
					}
				}

				// resort appointments in the view, if count of collection is great than 1
				if (arByDate.GetSize () > 1)
				{
					XBCGPAppointmentArray* ar = new XBCGPAppointmentArray;

					// array, that contains columns
					CArray<XBCGPAppointmentArray*, XBCGPAppointmentArray*> arColumns;
					arColumns.Add (ar);

					// initialize first column
					ar->Copy (arByDate);

					while (ar != NULL)
					{
						CBCGPAppointment* pApp1 = ar->GetAt (0);

						XBCGPAppointmentArray* arNew = NULL;

						i = 1;

						// remove appointments, that have collisions in rects, from previous column 
						// to the next column
						while (i < ar->GetSize ())
						{
							CBCGPAppointment* pApp2 = ar->GetAt (i);

							CRect rtInter;
							if (rtInter.IntersectRect (pApp1->GetRectDraw (date), pApp2->GetRectDraw (date)))
							{
								if (arNew == NULL)
								{
									// add a new column
									arNew = new XBCGPAppointmentArray;
									arColumns.Add (arNew);
								}

								arNew->Add (pApp2);
								ar->RemoveAt (i);
							}
							else
							{
								pApp1 = pApp2;
								i++;
							}
						}

						ar = arNew;
					}

					int nCount = (int) arColumns.GetSize ();

					// reinitialize drawing rects, if found great than 1 columns
					if (nCount > 1)
					{
						int nWidth = rectFill.Width () / nCount;
						int nL = rectFill.left;

						// left border of appointments, based on column order
						for (i = 0; i < nCount; i++)
						{
							ar = arColumns[i];

							for (int j = 0; j < ar->GetSize (); j++)
							{
								CBCGPAppointment* pApp = ar->GetAt (j);
								ASSERT_VALID (pApp);

								CRect rtApp (pApp->GetRectDraw (date));
								rtApp.left = nL;

								pApp->SetRectDraw (rtApp, date);
							}

							nL += nWidth;
						}

						// correcting right border of appointments
						for (i = 0; i < nCount; i++)
						{
							ar = arColumns[i];

							for (int j = 0; j < ar->GetSize (); j++)
							{
								CBCGPAppointment* pApp = ar->GetAt (j);
								CRect rtApp (pApp->GetRectDraw (date));

								for (int k = i + 1; k < nCount; k++)
								{
									XBCGPAppointmentArray* arNext = arColumns[k];

									for (int m = 0; m < arNext->GetSize (); m++)
									{
										CBCGPAppointment* pAppNext = arNext->GetAt (m);
									
										CRect rtInter;
										if (rtInter.IntersectRect (rtApp, pAppNext->GetRectDraw (date)))
										{
											rtApp.right = rectFill.left + nWidth * k - 
												(bDrawShadow ? BCGP_PLANNER_APPOINTMENT_SPACE : 0);
											pApp->SetRectDraw (rtApp, date);
											break;
										}
									}
								}
							}
						}
					}

					// clean up columns array
					for (i = 0; i < nCount; i++)
					{
						delete arColumns[i];
					}

					arColumns.RemoveAll ();
				}
			}

			// adjust "all day" or "multi day" appointments
			if (arAllDays.GetSize () > 0)
			{
				const int c_Count = (int) arAllDays.GetSize ();

				CRect rectFill (0, 0, 0, 0);

				rectFill.top    = m_nHeaderHeight + 1 - yHeaderOffset;
				rectFill.bottom = rectFill.top + m_nRowHeight;

				int i = 0;

				for (i = 0; i < c_Count; i++)
				{
					CBCGPAppointment* pApp = arAllDays[i];

					rectFill.left  = resource.m_Rects [nDay].left;
					rectFill.right = resource.m_Rects [nDay].right;

					if (CBCGPPlannerView::IsAppointmentInDate (*pApp, date))
					{
						pApp->SetRectDraw (rectFill, date);
					}
				}

				for (i = 1; i < c_Count; i++)
				{
					CBCGPAppointment* pApp1 = arAllDays[i];

					CRect rtApp1;
					if (pApp1->GetDSDraw ().IsEmpty ())
					{
						rtApp1 = pApp1->GetRectDraw ();
					}
					else
					{
						rtApp1 = pApp1->GetDSDraw ().Get (date)->GetRect ();
					}

					for (int j = 0; j < i; j++)
					{
						CBCGPAppointment* pApp2 = arAllDays[j];

						CRect rtApp2;
						if (pApp2->GetDSDraw ().IsEmpty ())
						{
							rtApp2 = pApp2->GetRectDraw ();
						}
						else
						{
							rtApp2 = pApp2->GetDSDraw ().Get (date)->GetRect ();
						}

						CRect rtInter;
						if (rtInter.IntersectRect (rtApp1, rtApp2))
						{
							rtApp1.top    = rtApp2.top;
							rtApp1.bottom = rtApp2.bottom;
							rtApp1.OffsetRect (0, m_nRowHeight + 2);
							
							if (pApp1->GetDSDraw ().IsEmpty ())
							{
								pApp1->SetRectDraw (rtApp1);
							}
							else
							{
								pApp1->GetDSDraw ().Get (date)->SetRect (rtApp1);
							}

							j = 0;
						}
					}
				}
			}

			date += spanDay;
		}
	}	

	date = m_DateStart;

	for (nDay = 0; nDay < nDays; nDay ++)
	{
		CheckVisibleAppointments (date, m_rectApps, FALSE);

		date += spanDay;
	}

	CheckVisibleUpDownIcons(FALSE);

	m_bUpdateToolTipInfo = TRUE;
}
void CBCGPPlannerViewMulti::AdjustLayout (CDC* /*pDC*/, const CRect& rectClient)
{
	if (IsCurrentTimeVisible ())
	{
		StartTimer (FALSE);
	}
	else
	{
		StopTimer (FALSE);
	}

	m_nHeaderHeight       = 2;
	m_nHeaderAllDayHeight = 1;

	const int nMinuts = CBCGPPlannerView::GetTimeDeltaInMinuts (GetTimeDelta ());
	const int nCount = GetViewHours() * 60 / nMinuts;

	m_rectTimeBar = rectClient;
	m_rectTimeBar.right = m_rectTimeBar.left + (long)(m_nRowHeight * (nMinuts == 60 ? 2.5 : 3.0)) + 5;

	m_rectApps.left = m_rectTimeBar.right;

	{
		// finding allday or multiday events
		const int nDays = GetViewDuration ();

		CDWordArray arDays;
		arDays.SetSize (nDays);

		COleDateTime dtS = GetDateStart ();

		XBCGPAppointmentArray& arQueryApps = GetQueryedAppointments ();
		XBCGPAppointmentArray& arDragApps  = GetDragedAppointments ();

		BOOL bDragDrop        = IsDragDrop ();
		DROPEFFECT dragEffect = GetDragEffect ();
		BOOL bDragMatch       = IsCaptureMatched ();

		bDragDrop = !bDragDrop || 
			(bDragDrop && ((dragEffect & DROPEFFECT_COPY) == DROPEFFECT_COPY && bDragMatch) || 
			!bDragMatch);
		bDragDrop = bDragDrop && arDragApps.GetSize ();

		DWORD maxCount = 0;

		for (int nRes = 0; nRes < m_Resources.GetSize (); nRes++)
		{
			UINT nResourceID = m_Resources[nRes].m_ResourceID;

			for (int nApp = 0; nApp < 2; nApp++)
			{
				if (!bDragDrop && nApp == 0)
				{
					continue;
				}

				XBCGPAppointmentArray& arApps = nApp == 0 ? arDragApps : arQueryApps;

				int nStartIndex = 0;
				int i = 0;
				for (i = 0; i < arApps.GetSize (); i++)
				{
					const CBCGPAppointment* pApp = arApps[i];
					if (pApp != NULL && pApp->GetResourceID () == nResourceID)
					{
						nStartIndex = i;
						break;
					}
				}

				for (i = nStartIndex; i < (int)arApps.GetSize (); i++)
				{
					const CBCGPAppointment* pApp = arApps[i];
					if (pApp == NULL)
					{
						continue;
					}

					ASSERT_VALID (pApp);

					if (pApp->GetResourceID () != nResourceID)
					{
						break;
					}

					if (pApp->IsAllDay () || pApp->IsMultiDay ())
					{
						if (nDays > 1)
						{
							COleDateTime dtStart  = pApp->GetStart ();
							COleDateTime dtFinish = pApp->GetFinish ();

							dtStart = COleDateTime (dtStart.GetYear (), dtStart.GetMonth (), dtStart.GetDay (),
								0, 0, 0);

							if (pApp->IsAllDay ())
							{
								dtFinish += COleDateTimeSpan (1, 0, 0, 0);
							}
							else if (pApp->GetFinish ().GetHour () != 0 ||
									 pApp->GetFinish ().GetMinute () != 0)
							{
								dtFinish = COleDateTime (dtFinish.GetYear (), dtFinish.GetMonth (), dtFinish.GetDay (),
									0, 0, 0);
								dtFinish += COleDateTimeSpan (1, 0, 0, 0);
							}

							if (dtStart < dtS)
							{
								dtStart = dtS;
							}

							COleDateTimeSpan span (dtFinish - dtStart);

							int nStart = (dtStart - dtS).GetDays ();
							int nEnd   = nStart + span.GetDays ();

							if (nEnd > (int) nDays)
							{
								nEnd = (int) nDays;
							}

							for (int j = nStart; j < nEnd; j++)
							{
								arDays[j] = arDays[j] + 1;
							}
						}
						else
						{
							arDays[0] = arDays[0] + 1;
						}
					}
				}
			}

			for (int i = 0; i < nDays; i++)
			{
				if (maxCount < arDays[i])
				{
					maxCount = arDays[i];
				}

				arDays[i] = 0;
			}
		}	

		if (maxCount > 0)
		{
			m_nHeaderAllDayHeight = maxCount;
		}
	}

	int nRow = rectClient.Height () / 
		(nCount + m_nHeaderHeight + m_nHeaderAllDayHeight);

	int nOldRowHeight = m_nRowHeight;

	if (nRow > m_nRowHeight)
	{
		m_nRowHeight = nRow;
	}

	const int nRowHeightPadding = m_nRowHeight + s_HeaderAllDayPadding;
	int nHeaderAllDayCount = m_nHeaderAllDayHeight;
	m_nHeaderHeight       *= m_nRowHeight;
	m_nHeaderAllDayHeight *= nRowHeightPadding;

	m_rectApps.top += m_nHeaderHeight;

	m_nHeaderScrollTotal = 0;
	m_nHeaderScrollPage  = 1;

	if (GetPlanner()->IsHeaderScrollingEnabled() && 
		nHeaderAllDayCount > 0 && m_nHeaderAllDayHeight > m_rectApps.Height () / 2)
	{
		m_nHeaderAllDayHeight = min(m_rectApps.Height () / (nRowHeightPadding * 2), nHeaderAllDayCount);
		if (m_nHeaderAllDayHeight == 0)
		{
			m_nHeaderAllDayHeight = 1;
		}

		if (m_nHeaderAllDayHeight != nHeaderAllDayCount)
		{
			m_nHeaderScrollTotal = nHeaderAllDayCount - 1;
			m_nHeaderScrollPage  = m_nHeaderAllDayHeight;
		}

		m_nHeaderAllDayHeight *= nRowHeightPadding;
	}

	nRow = (m_rectApps.Height () - m_nHeaderAllDayHeight) / nCount;

	if (nRow > nOldRowHeight)
	{
		m_nRowHeight = nRow;
	}

	int delta = m_rectApps.Height () - m_nHeaderAllDayHeight;

	if (delta < 0)
	{
		m_nHeaderAllDayHeight = m_rectApps.Height ();
	}
	else
	{
		int nc = (int)(delta / m_nRowHeight);

		if (nc >= nCount)
		{
			m_nHeaderAllDayHeight = m_rectApps.Height () - nCount * m_nRowHeight;
		}
		else
		{
			m_nHeaderAllDayHeight += delta - nc * m_nRowHeight;
		}
	}

	m_rectApps.top += m_nHeaderAllDayHeight;

	AdjustScrollSizes ();
	
	// correct selection
	COleDateTime sel1 (GetSelectionStart ());
	COleDateTime sel2 (GetSelectionEnd ());

	SetSelection (sel1, sel2, FALSE);
}
void CBCGPPlannerViewMulti::OnDrawHeaderAllDay (CDC* pDC, const CRect& rectHeader)
{
	ASSERT_VALID (pDC);

	const int nDays = GetViewDuration ();
	const int nRes  = (int) m_Resources.GetSize ();
	const int nAll  = nDays * nRes;

	visualManager->OnFillPlannerHeaderAllDay (pDC, this, rectHeader);

	int nDay = 0;

	COleDateTime date (GetDateStart ());
	COleDateTimeSpan span (1, 0, 0, 0);

	CRect rt (rectHeader);
	rt.bottom--;

	COleDateTime dayCurrent = COleDateTime::GetCurrentTime ();
	dayCurrent.SetDateTime (dayCurrent.GetYear (), dayCurrent.GetMonth (), 
		dayCurrent.GetDay (), 0, 0, 0);

	if (nAll > 1)
	{
		CPen penBlack (PS_SOLID, 0, visualManager->GetPlannerSeparatorColor (this));
		CPen* pOldPen = pDC->SelectObject (&penBlack);

		for (nDay = 1; nDay < nDays; nDay++)
		{
			pDC->MoveTo (m_ViewRects [nDay].left, rectHeader.top);
			pDC->LineTo (m_ViewRects [nDay].left, rectHeader.bottom - 1);
		}

		for (int i = 1; i < nRes; i++)
		{
			for (nDay = 0; nDay < nDays; nDay++)
			{
				CRect& rectRes = m_Resources[i].m_Rects[nDay];
				pDC->MoveTo (rectRes.left, rectHeader.top);
				pDC->LineTo (rectRes.left, rectHeader.bottom - 1);
			}
		}

		pDC->SelectObject (pOldPen);
	}

	UINT nResourceID = GetCurrentResourceID ();

	for (nDay = 0; nDay < nDays; nDay++)
	{
		for (int i = 0; i < nRes; i++)
		{
			rt.left  = m_Resources [i].m_Rects [nDay].left;
			rt.right = m_Resources [i].m_Rects [nDay].right;

			visualManager->OnDrawPlannerHeaderAllDayItem (pDC, this, rt, 
				FALSE, 
				m_SelectionAllDay[nDay] && m_Resources [i].m_ResourceID == nResourceID);
		}

		if (date == dayCurrent)
		{
			rt.left  = m_ViewRects [nDay].left;
			rt.right = m_ViewRects [nDay].right;

			visualManager->OnDrawPlannerHeaderAllDayItem (pDC, this, rt, TRUE, FALSE);
		}

		date += span;
	}
}
예제 #9
0
void CBCGPPlannerPrintMonth::OnDrawClient (CDC* pDC)
{
	ASSERT_VALID (pDC);

	CRect rectFill (m_rectApps);

	int nMonth = m_Date.GetMonth ();

	const int nRows = GetViewDuration () / 7;

	COleDateTime day (GetDateStart ());

	int nIndex = 0;
	int iRow = 0;

	{
		CPen* pOldPen = pDC->SelectObject (&m_penBlack);

		const int nEnd = 7;

		int nCol = 0;
		int iColumn = 1;

		for (iColumn = 1; iColumn < 7; iColumn++)
		{
			if (m_ViewRects [iColumn - 1].right == m_ViewRects [iColumn].right)
			{
				nCol = iColumn - 1;
				break;
			}
		}

		for (iColumn = 1; iColumn < nEnd; iColumn++)
		{
			pDC->MoveTo (m_ViewRects [iColumn].left - m_OnePoint.cx, m_rectApps.top);
			pDC->LineTo (m_ViewRects [iColumn].left - m_OnePoint.cx, m_rectApps.bottom);
		}

		for (iRow = 0; iRow < nRows; iRow++)
		{
			int nIndex = iRow * 7 + 6;

			pDC->MoveTo (m_rectApps.left , m_ViewRects [nIndex].bottom);
			pDC->LineTo (m_rectApps.right, m_ViewRects [nIndex].bottom);

			if (m_bCompressWeekend)
			{
				nIndex -= (6 - nCol);
				pDC->MoveTo (m_ViewRects [nIndex].left, m_ViewRects [nIndex].bottom);
				pDC->LineTo (m_ViewRects [nIndex].right, m_ViewRects [nIndex].bottom);
			}
		}

		pDC->SelectObject (pOldPen);
	}

	DWORD dwFlags = GetDrawFlags ();
	BOOL bBold = (dwFlags & BCGP_PLANNER_DRAW_VIEW_CAPTION_DAY_BOLD) ==
			BCGP_PLANNER_DRAW_VIEW_CAPTION_DAY_BOLD;
	BOOL bCompact = (dwFlags & BCGP_PLANNER_DRAW_VIEW_CAPTION_DAY_COMPACT) ==
			BCGP_PLANNER_DRAW_VIEW_CAPTION_DAY_COMPACT;

	CFont* pOldFont = NULL;
	if (bBold)
	{
		pOldFont = pDC->SelectObject (&m_FontBold);
	}

	const BOOL bDateBeforeMonth = CBCGPPlannerView::IsDateBeforeMonth ();

	for (iRow = 0; iRow < nRows; iRow++)
	{
		for (int iDay = 0; iDay < 7; iDay++)
		{
			BOOL bAnotherMonth = nMonth != day.GetMonth ();

			int nDay = iRow * 7 + iDay;

			CRect rectDayCaption (m_ViewRects [nDay]);

			if (m_nRowHeight <= rectDayCaption.Height () + 2 * m_OnePoint.cy)
			{
				rectDayCaption.bottom = rectDayCaption.top + m_nRowHeight + m_OnePoint.cy;

				CString strFormat (_T("d"));
				CString strDate;

				BOOL bNewYear = FALSE;

				if (!bCompact)
				{
					if ((iRow == 0 && iDay == 0) || day.GetDay () == 1)
					{
						if (bDateBeforeMonth)
						{
							strFormat = _T("d MMMM");
						}
						else
						{
							strFormat = _T("MMMM d");
						}

						if (day.GetDay () == 1 && day.GetMonth () == 1)
						{
							bNewYear = TRUE;
							strFormat += _T(" yyyy");
						}			
					}

					if (!strFormat.IsEmpty ())
					{
						strDate.GetBuffer (_MAX_PATH);

						SYSTEMTIME st;
						day.GetAsSystemTime (st);

						::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st, 
							strFormat, (LPTSTR)(LPCTSTR)strDate, _MAX_PATH);

						strDate.ReleaseBuffer ();

						CSize szSize (pDC->GetTextExtent (strDate));

						if (rectDayCaption.Width () - 4 < szSize.cx)
						{
							if (bDateBeforeMonth)
							{
								strFormat = _T("d MMM");
							}
							else
							{
								strFormat = _T("MMM d");
							}

							if (bNewYear)
							{
								strFormat += _T(" yy");
							}

							strDate.GetBuffer (_MAX_PATH);

							::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st, 
								strFormat, (LPTSTR)(LPCTSTR)strDate, _MAX_PATH);

							strDate.ReleaseBuffer ();
						}
					}
				}
				else
				{
					if ((iRow == 0 && iDay == 0) || day.GetDay () == 1)
					{
						if (bDateBeforeMonth)
						{
							strFormat = _T("d MMM");
						}
						else
						{
							strFormat = _T("MMM d");
						}

						if (day.GetDay () == 1 && day.GetMonth () == 1)
						{
							bNewYear = TRUE;
							strFormat += _T(" yy");
						}
					}

					if (!strFormat.IsEmpty ())
					{
						strDate.GetBuffer (_MAX_PATH);

						SYSTEMTIME st;
						day.GetAsSystemTime (st);

						::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st, 
							strFormat, (LPTSTR)(LPCTSTR)strDate, _MAX_PATH);

						strDate.ReleaseBuffer ();

						CSize szSize (pDC->GetTextExtent (strDate));

						if (rectDayCaption.Width () - 4 < szSize.cx)
						{
							strFormat = _T("d");
							BOOL bNeedFormat = TRUE;

							if (bNewYear)
							{
								if (bDateBeforeMonth)
								{
									strFormat += _T(" MMM");
								}
								else
								{
									strFormat = _T("MMM ") + strFormat;
								}

								bNeedFormat = FALSE;

								strDate.GetBuffer (_MAX_PATH);

								::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st, 
									strFormat, (LPTSTR)(LPCTSTR)strDate, _MAX_PATH);

								strDate.ReleaseBuffer ();

								szSize = pDC->GetTextExtent (strDate);

								if (rectDayCaption.Width () - 4 < szSize.cx)
								{
									strFormat = _T("d");
									bNeedFormat = TRUE;
								}
							}

							if (bNeedFormat)
							{
								strDate.GetBuffer (_MAX_PATH);

								::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st, 
									strFormat, (LPTSTR)(LPCTSTR)strDate, _MAX_PATH);

								strDate.ReleaseBuffer ();
							}
						}
					}
				}

				DrawCaption (pDC, rectDayCaption, strDate, FALSE, TRUE, 
					bAnotherMonth ? m_brDarkGray : m_brGray);
			}

			day += COleDateTimeSpan (1, 0, 0, 0);

			nIndex++;
		}
	}

	if (bBold && pOldFont != NULL)
	{
		pDC->SelectObject (pOldFont);
	}
}
void CBCGPPlannerViewMonth::AdjustRects ()
{
	const int nDays = GetViewDuration ();

	const int nRows    = nDays / 7;
	const int dxColumn = CBCGPPlannerView::round (m_rectApps.Width () / (m_bCompressWeekend ? 6.0 : 7.0)) - 1;
	const int dxRow    = CBCGPPlannerView::round (m_rectApps.Height () / (double)nRows) - 1;

	const int nDayStart = (IsCompressWeekend () && CBCGPPlannerManagerCtrl::GetFirstDayOfWeek () == 0)
		? 1
		: CBCGPPlannerManagerCtrl::GetFirstDayOfWeek ();

	if (m_ViewRects.GetSize () != nDays)
	{
		m_ViewRects.SetSize (nDays);
	}

	int iRow = 0;
	for (iRow = 0; iRow < nRows; iRow++)
	{
		CRect rect (m_rectApps);
		rect.right   = rect.left + dxColumn;
		rect.top    += iRow * (dxRow + 1);
		rect.bottom  = iRow == (nRows - 1) ? rect.bottom : rect.top + dxRow;

		int nTop    = rect.top;
		int nBottom = rect.bottom;

		int nColumn = 0;

		for (int iDay = 0; iDay < 7; iDay++)
		{
			int nWeekDay = nDayStart + iDay - 7;

			if (m_bCompressWeekend)
			{
				if (nWeekDay == -1)
				{
					rect.bottom = rect.top + dxRow / 2;
				}
				else if (nWeekDay == 0)
				{
					rect.top = rect.bottom + 1;
					rect.bottom = nBottom;
				}
				else
				{
					rect.top = nTop;
				}
			}

			m_ViewRects[iRow * 7 + iDay] = rect;

			if ((m_bCompressWeekend && nWeekDay != -1) || !m_bCompressWeekend)
			{
				rect.OffsetRect (dxColumn + 1, 0);

				nColumn++;

				if ((m_bCompressWeekend && nColumn == 5) ||
					(!m_bCompressWeekend && nColumn == 6))
				{
					rect.right = m_rectApps.right;
				}
			}
		}
	}

	if (m_nWeekBarWidth > 0)
	{
		int nIndex = 0;
		if (IsCompressWeekend () && m_ViewRects[0].top != m_ViewRects[1].top)
		{
			nIndex = 2;
		}

		m_WeekRects.SetSize (nRows);

		for (iRow = 0; iRow < nRows; iRow++)
		{
			CRect rect (m_ViewRects[nIndex]);
			rect.right = m_rectApps.left;
			rect.left  = rect.right - m_nRowHeight;

			rect.top    += m_nRowHeight;
			rect.InflateRect (0, 1);

			m_WeekRects[iRow] = rect;

			nIndex += 7;
		}
	}
}
예제 #11
0
void CBCGPPlannerPrintMonth::AdjustAppointments ()
{
	XBCGPAppointmentArray& arQueryApps = GetQueryedAppointments ();

	const int nDays = GetViewDuration ();

	if (arQueryApps.GetSize () == 0 || m_ViewRects.GetSize () != nDays)
	{
		return;
	}

	for (int i = 0; i < arQueryApps.GetSize (); i++)
	{
		CBCGPAppointment* pApp = arQueryApps[i];
		ASSERT_VALID (pApp);

		pApp->ResetPrint ();
	}

	COleDateTime date (m_DateStart);

	COleDateTimeSpan spanDay (1, 0, 0, 0);
	const int delta = m_nRowHeight + 2 * m_OnePoint.cy;

	for (int nDay = 0; nDay < nDays; nDay ++)
	{
		CRect rect (m_ViewRects [nDay]);
		rect.top += m_nRowHeight + 2 * m_OnePoint.cy;
		rect.DeflateRect (m_OnePoint.cx, 0);

		BOOL bTopEq    = TRUE;
		BOOL bBottomEq = TRUE;
		
		if (nDay > 0)
		{
			bTopEq    = m_ViewRects [nDay].top == m_ViewRects [nDay - 1].top;
			bBottomEq = m_ViewRects [nDay].bottom == m_ViewRects [nDay - 1].bottom;
		}

		CList<int, int> lsItems;

		for (int i = 0; i < arQueryApps.GetSize (); i++)
		{
			CBCGPAppointment* pApp = arQueryApps[i];
			ASSERT_VALID (pApp);

			if (CBCGPPlannerView::IsAppointmentInDate (*pApp, date))
			{
				CRect rtApp (rect);

				int nItem = 0;

				while(TRUE)
				{
					POSITION pos = lsItems.Find (nItem);
					if (pos != NULL)
					{
						nItem++;
					}
					else
					{
						break;
					}
				}

				rtApp.top += nItem * delta;
				rtApp.bottom = rtApp.top + m_nRowHeight;

				BOOL bAllOrMulti = pApp->IsAllDay () || pApp->IsMultiDay ();

				// check for add new rect
				if (nDay > 0)
				{
					if (bTopEq && bAllOrMulti)
					{
						if (!pApp->GetDSPrint ().IsEmpty ())
						{
							CRect rt;
							rt = pApp->GetRectPrint (date - spanDay);

							if (!rt.IsRectEmpty () && rtApp.top != rt.top)
							{
								rtApp.top    = rt.top;
								rtApp.bottom = rt.bottom;
							}
						}
					}
				}

				if (((bTopEq && !bBottomEq) ||
					 (!bAllOrMulti && 
					  !CBCGPPlannerView::IsOneDay (pApp->GetStart (), pApp->GetFinish ()))) &&
					!pApp->GetDSDraw ().IsEmpty ())
				{
					CRect rtInter;
					rtInter.IntersectRect (rtApp, m_ViewRects [nDay]);

					if (rtInter.Height () < rtApp.Height () || 
						rtInter.bottom >= rect.bottom || !bAllOrMulti)
					{
						// add impossible rect
						rtApp.OffsetRect (0, m_OnePoint.cy);
						pApp->SetRectPrint (rtApp, date);
						// return rect
						rtApp.OffsetRect (0, -m_OnePoint.cy);
					}
				}

				pApp->SetRectPrint (rtApp, date);

				lsItems.AddTail ((rtApp.top - rect.top) / delta);
			}
		}

		CheckVisibleAppointments(date, rect, TRUE);

		date += spanDay;
	}
}
예제 #12
0
void CBCGPPlannerPrintMonth::OnDrawWeekBar (CDC* pDC, const CRect& rectBar)
{
	if (rectBar.IsRectEmpty ())
	{
		return;
	}

	ASSERT_VALID (pDC);

	const int nRows = GetViewDuration () / 7;

	const BOOL bDateBeforeMonth = CBCGPPlannerView::IsDateBeforeMonth ();

	CStringArray saFormat;
	{
		CString strMonthFmt (_T("MMM"));
		CString strSep (_T(" "));

		CFont* pOldFont = pDC->SelectObject (&m_Font);

		CSize szText (pDC->GetTextExtent (_T("AAA 00 - AAA 00")));

		CRect rect (m_ViewRects[0]);
		rect.right = rectBar.right;
		rect.left  = rectBar.left - m_OnePoint.cy;
		rect.top   += m_nRowHeight + m_OnePoint.cy;
		if (rect.Height() < (szText.cx * 1.5))
		{
			strMonthFmt = _T("M");
			strSep      = CBCGPPlannerView::GetDateSeparator ();
		}

		pDC->SelectObject (pOldFont);

		CString strFormat;
		if (bDateBeforeMonth)
		{
			strFormat = _T("d") + strSep + strMonthFmt;
			saFormat.Add (_T("d"));
			saFormat.Add (strFormat);
			saFormat.Add (strFormat);
		}
		else
		{
			strFormat = strMonthFmt + strSep + _T("d");
			saFormat.Add (strFormat);
			saFormat.Add (_T("d"));
			saFormat.Add (strFormat);
		}
	}

	COLORREF clrTextOld = pDC->SetTextColor (m_clrText);
	CFont* pOldFont = pDC->SelectObject (&m_FontVert);
	CPen* pOldPen = pDC->SelectObject (&m_penBlack);

	COleDateTime day1 (GetDateStart ());
	COleDateTime day2 (day1);
	day2 += COleDateTimeSpan (6, 0, 0, 0);

	COleDateTimeSpan span (7, 0, 0, 0);

	int nIndex = 0;

	if (IsCompressWeekend () && m_ViewRects[0].top != m_ViewRects[1].top)
	{
		nIndex = 2;
	}

	for (int iRow = 0; iRow < nRows; iRow++)
	{
		CRect rect (m_ViewRects[nIndex]);
		rect.right = rectBar.right;
		rect.left  = rectBar.left - m_OnePoint.cy;
		rect.top    += m_nRowHeight + m_OnePoint.cy;

		if (rect.top < rect.bottom)
		{
			pDC->FillRect (rect, &m_brGray);
			pDC->MoveTo (rect.right, rect.top);
			pDC->LineTo (rect.left, rect.top);
			pDC->LineTo (rect.left, rect.bottom);
			pDC->LineTo (rect.right, rect.bottom);

			rect.DeflateRect (m_OnePoint.cx, m_OnePoint.cy);

			SYSTEMTIME st1;
			day1.GetAsSystemTime (st1);
			SYSTEMTIME st2;
			day2.GetAsSystemTime (st2);

			CString strDate1;
			CString strDate2;

			if (day1.GetMonth () == day2.GetMonth ())
			{
				strDate1.GetBuffer (_MAX_PATH);
				::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st1, 
					saFormat[0], (LPTSTR)(LPCTSTR)strDate1, _MAX_PATH);
				strDate1.ReleaseBuffer ();

				strDate2.GetBuffer (_MAX_PATH);
				::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st2, 
					saFormat[1], (LPTSTR)(LPCTSTR)strDate2, _MAX_PATH);
				strDate2.ReleaseBuffer ();
			}
			else
			{
				strDate1.GetBuffer (_MAX_PATH);
				::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st1, 
					saFormat[2], (LPTSTR)(LPCTSTR)strDate1, _MAX_PATH);
				strDate1.ReleaseBuffer ();

				strDate2.GetBuffer (_MAX_PATH);
				::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st2, 
					saFormat[2], (LPTSTR)(LPCTSTR)strDate2, _MAX_PATH);
				strDate2.ReleaseBuffer ();
			}

			CString strText = strDate1 + _T(" - ") + strDate2;

			CSize szText (pDC->GetTextExtent (strText));

			CRect rectText (rect);
			rectText.left = rectText.left + (rect.Width () - szText.cy + m_OnePoint.cx) / 2;

			rectText.top = rectText.bottom;
			if (szText.cx < rect.Height ())
			{
				rectText.top -= (rect.Height () - szText.cx + m_OnePoint.cy) / 2;
			}
			rectText.bottom = rect.top;

			pDC->DrawText (strText, rectText, DT_SINGLELINE);
		}

		nIndex += 7;
		day1 += span;
		day2 += span;
	}

	pDC->SelectObject (pOldPen);
	pDC->SelectObject (pOldFont);
	pDC->SetTextColor (clrTextOld);
}
예제 #13
0
void CBCGPPlannerPrintMonth::AdjustRects ()
{
	const int nDays = GetViewDuration ();

	const int nRows    = nDays / 7;
	const int dxColumn = CBCGPPlannerView::round (m_rectApps.Width () / (m_bCompressWeekend ? 6.0 : 7.0)) - m_OnePoint.cx;
	const int dxRow    = CBCGPPlannerView::round (m_rectApps.Height () / (double)nRows) - m_OnePoint.cy;

	const int nDayStart = (IsCompressWeekend () && CBCGPPlannerManagerCtrl::GetFirstDayOfWeek () == 0)
		? 1
		: CBCGPPlannerManagerCtrl::GetFirstDayOfWeek ();

	for (int iRow = 0; iRow < nRows; iRow++)
	{
		CRect rect (m_rectApps);
		rect.right   = rect.left + dxColumn;
		rect.top    += iRow * (dxRow + m_OnePoint.cy);
		rect.bottom  = iRow == (nRows - 1) ? rect.bottom : rect.top + dxRow;

		int nTop    = rect.top;
		int nBottom = rect.bottom;

		for (int iDay = 0; iDay < 7; iDay++)
		{
			int nWeekDay = nDayStart + iDay - 7;

			if (m_bCompressWeekend)
			{
				if (nWeekDay == -1)
				{
					if (iDay == 5)
					{
						rect.right = m_rectApps.right;
					}
					
					rect.bottom = rect.top + dxRow / 2;
				}
				else if (nWeekDay == 0)
				{
					rect.top = rect.bottom + m_OnePoint.cy;
					rect.bottom = nBottom;
				}
				else
				{
					rect.top = nTop;
				}
			}
			else
			{
				if (iDay == 6)
				{
					rect.right = m_rectApps.right;
				}
			}

			m_ViewRects.Add (rect);

			if ((m_bCompressWeekend && nWeekDay != -1) || !m_bCompressWeekend)
			{
				rect.OffsetRect (dxColumn + m_OnePoint.cx, 0);
			}
		}
	}
}
void CBCGPPlannerViewMonth::OnDrawWeekBar (CDC* pDC, const CRect& rectBar)
{
	if (rectBar.IsRectEmpty ())
	{
		return;
	}

	ASSERT_VALID (pDC);

	visualManager->PreparePlannerCaptionBackItem (FALSE);
	visualManager->OnFillPlannerWeekBar (pDC, this, rectBar);

	COLORREF clrLine = visualManager->GetPlannerSeparatorColor (this);

	const int nRows = GetViewDuration () / 7;

	const BOOL bDateBeforeMonth = CBCGPPlannerView::IsDateBeforeMonth ();

	CStringArray saFormat;
	{
		CString strMonthFmt (_T("MMM"));
		CString strSep (_T(" "));

		HFONT hOldFont = (HFONT)::SelectObject (pDC->GetSafeHdc (), GetFont ());

		CSize szText (pDC->GetTextExtent (_T("AAA 00 - AAA 00")));

		CRect rect (m_WeekRects[0]);
		if (rect.Height() < (szText.cx * 1.5))
		{
			strMonthFmt = _T("M");
			strSep      = CBCGPPlannerView::GetDateSeparator ();
		}

		if (hOldFont != NULL)
		{
			::SelectObject (pDC->GetSafeHdc (), hOldFont);
		}

		CString strFormat;
		if (bDateBeforeMonth)
		{
			strFormat = _T("d") + strSep + strMonthFmt;
			saFormat.Add (_T("d"));
			saFormat.Add (strFormat);
			saFormat.Add (strFormat);
		}
		else
		{
			strFormat = strMonthFmt + strSep + _T("d");
			saFormat.Add (strFormat);
			saFormat.Add (_T("d"));
			saFormat.Add (strFormat);
		}
	}

	COLORREF clrTextOld = pDC->GetTextColor ();
	HFONT hOldFont = (HFONT)::SelectObject (pDC->GetSafeHdc (), GetFontVert ());

	COleDateTime day1 (GetDateStart ());
	COleDateTime day2 (day1);
	day2 += COleDateTimeSpan (6, 0, 0, 0);

	COleDateTimeSpan span (7, 0, 0, 0);

	for (int iRow = 0; iRow < nRows; iRow++)
	{
		CRect rect (m_WeekRects[iRow]);

		if (rect.top < rect.bottom)
		{
			COLORREF clrText = 
				visualManager->OnFillPlannerCaption (pDC, this, rect, FALSE, FALSE, TRUE, FALSE);

			pDC->SetTextColor (clrText);

			pDC->Draw3dRect (rect, clrLine, clrLine);

			rect.DeflateRect (1, 1);

			SYSTEMTIME st1;
			day1.GetAsSystemTime (st1);
			SYSTEMTIME st2;
			day2.GetAsSystemTime (st2);

			CString strDate1;
			CString strDate2;

			if (day1.GetMonth () == day2.GetMonth ())
			{
				strDate1.GetBuffer (_MAX_PATH);
				::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st1, 
					saFormat[0], (LPTSTR)(LPCTSTR)strDate1, _MAX_PATH);
				strDate1.ReleaseBuffer ();

				strDate2.GetBuffer (_MAX_PATH);
				::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st2, 
					saFormat[1], (LPTSTR)(LPCTSTR)strDate2, _MAX_PATH);
				strDate2.ReleaseBuffer ();
			}
			else
			{
				strDate1.GetBuffer (_MAX_PATH);
				::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st1, 
					saFormat[2], (LPTSTR)(LPCTSTR)strDate1, _MAX_PATH);
				strDate1.ReleaseBuffer ();

				strDate2.GetBuffer (_MAX_PATH);
				::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st2, 
					saFormat[2], (LPTSTR)(LPCTSTR)strDate2, _MAX_PATH);
				strDate2.ReleaseBuffer ();
			}

			CString strText = strDate1 + _T(" - ") + strDate2;

			CSize szText (pDC->GetTextExtent (strText));

			CRect rectText (rect);
			rectText.left = rectText.left + (rect.Width () - szText.cy + 1) / 2;

			rectText.top = rectText.bottom;
			if (szText.cx < rect.Height ())
			{
				rectText.top -= (rect.Height () - szText.cx + 1) / 2;
			}
			rectText.bottom = rect.top;

			pDC->DrawText (strText, rectText, DT_SINGLELINE);
		}

		day1 += span;
		day2 += span;
	}

	pDC->SetTextColor (clrTextOld);
	if (hOldFont != NULL)
	{
		::SelectObject (pDC->GetSafeHdc (), hOldFont);
	}
}
void CBCGPPlannerViewMonth::OnDrawClient (CDC* pDC, const CRect& rect)
{
	ASSERT_VALID (pDC);

	CRect rectFill (rect);

	int nMonth = m_Date.GetMonth ();

	BOOL bIsWorking = nMonth % 2;

	const int nRows = GetViewDuration () / 7;

	COleDateTime day (GetDateStart ());

	COleDateTime dayCurrent = COleDateTime::GetCurrentTime ();
	dayCurrent.SetDateTime (dayCurrent.GetYear (), dayCurrent.GetMonth (), 
		dayCurrent.GetDay (), 0, 0, 0);

	int iRow = 0;

	int nStartColumn = 1;
	if (m_nWeekBarWidth != 0)
	{
		nStartColumn = 0;
	}

	{
		CPen penBlack (PS_SOLID, 0, visualManager->GetPlannerSeparatorColor (this));
		CPen* pOldPen = pDC->SelectObject (&penBlack);

		const int nEnd = 7;

		int nCol = 0;
		int iColumn = 1;

		for (iColumn = 1; iColumn < 7; iColumn++)
		{
			if (m_ViewRects [iColumn - 1].right == m_ViewRects [iColumn].right)
			{
				nCol = iColumn - 1;
				break;
			}
		}

		for (iColumn = nStartColumn; iColumn < nEnd; iColumn++)
		{
			pDC->MoveTo (m_ViewRects [iColumn].left - 1, rect.top);
			pDC->LineTo (m_ViewRects [iColumn].left - 1, rect.bottom);
		}

		for (iRow = 0; iRow < nRows; iRow++)
		{
			int nIndex = iRow * 7 + 6;

			pDC->MoveTo (rect.left , m_ViewRects [nIndex].bottom);
			pDC->LineTo (rect.right, m_ViewRects [nIndex].bottom);

			if (m_bCompressWeekend)
			{
				nIndex -= (6 - nCol);
				pDC->MoveTo (m_ViewRects [nIndex].left, m_ViewRects [nIndex].bottom);
				pDC->LineTo (m_ViewRects [nIndex].right, m_ViewRects [nIndex].bottom);
			}
		}

		pDC->SelectObject (pOldPen);
	}

	DWORD dwFlags = GetPlanner ()->GetDrawFlags ();
	BOOL bBold = (dwFlags & BCGP_PLANNER_DRAW_VIEW_CAPTION_DAY_BOLD) ==
			BCGP_PLANNER_DRAW_VIEW_CAPTION_DAY_BOLD;
	BOOL bCompact = (dwFlags & BCGP_PLANNER_DRAW_VIEW_CAPTION_DAY_COMPACT) ==
			BCGP_PLANNER_DRAW_VIEW_CAPTION_DAY_COMPACT;

	HFONT hOldFont = NULL;
	if (bBold)
	{
		hOldFont = SetCurrFont (pDC, bBold);
	}

	const BOOL bDateBeforeMonth = CBCGPPlannerView::IsDateBeforeMonth ();

	for (iRow = 0; iRow < nRows; iRow++)
	{
		for (int iDay = 0; iDay < 7; iDay++)
		{
			int nDay = iRow * 7 + iDay;

			CRect rectDayCaption (m_ViewRects [nDay]);

			BOOL bToday = day == dayCurrent;
			BOOL bSelected = IsDateInSelection (day);

			bIsWorking = day.GetMonth () % 2;

			visualManager->PreparePlannerBackItem (bToday, bSelected);
			OnFillPlanner (pDC, rectDayCaption, bIsWorking);

			rectDayCaption.bottom = rectDayCaption.top + m_nRowHeight + 1;

			CString strFormat (_T("d"));
			CString strDate;

			BOOL bNewYear = FALSE;

			if (!bCompact)
			{
				if ((iRow == 0 && iDay == 0) || day.GetDay () == 1)
				{
					if (bDateBeforeMonth)
					{
						strFormat = _T("d MMMM");
					}
					else
					{
						strFormat = _T("MMMM d");
					}

					if (day.GetDay () == 1 && day.GetMonth () == 1)
					{
						bNewYear = TRUE;
						strFormat += _T(" yyyy");
					}			
				}

				if (!strFormat.IsEmpty ())
				{
					strDate.GetBuffer (_MAX_PATH);

					SYSTEMTIME st;
					day.GetAsSystemTime (st);

					::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st, 
						strFormat, (LPTSTR)(LPCTSTR)strDate, _MAX_PATH);

					strDate.ReleaseBuffer ();

					CSize szSize (pDC->GetTextExtent (strDate));

					if (rectDayCaption.Width () - 4 < szSize.cx)
					{
						if (bDateBeforeMonth)
						{
							strFormat = _T("d MMM");
						}
						else
						{
							strFormat = _T("MMM d");
						}

						if (bNewYear)
						{
							strFormat += _T(" yy");
						}

						strDate.GetBuffer (_MAX_PATH);

						::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st, 
							strFormat, (LPTSTR)(LPCTSTR)strDate, _MAX_PATH);

						strDate.ReleaseBuffer ();
					}
				}
			}
			else
			{
				if ((iRow == 0 && iDay == 0) || day.GetDay () == 1)
				{
					if (bDateBeforeMonth)
					{
						strFormat = _T("d MMM");
					}
					else
					{
						strFormat = _T("MMM d");
					}

					if (day.GetDay () == 1 && day.GetMonth () == 1)
					{
						bNewYear = TRUE;
						strFormat += _T(" yy");
					}
				}

				if (!strFormat.IsEmpty ())
				{
					strDate.GetBuffer (_MAX_PATH);

					SYSTEMTIME st;
					day.GetAsSystemTime (st);

					::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st, 
						strFormat, (LPTSTR)(LPCTSTR)strDate, _MAX_PATH);

					strDate.ReleaseBuffer ();

					CSize szSize (pDC->GetTextExtent (strDate));

					if (rectDayCaption.Width () - 4 < szSize.cx)
					{
						strFormat = _T("d");
						BOOL bNeedFormat = TRUE;

						if (bNewYear)
						{
							if (bDateBeforeMonth)
							{
								strFormat += _T(" MMM");
							}
							else
							{
								strFormat = _T("MMM ") + strFormat;
							}

							bNeedFormat = FALSE;

							strDate.GetBuffer (_MAX_PATH);

							::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st, 
								strFormat, (LPTSTR)(LPCTSTR)strDate, _MAX_PATH);

							strDate.ReleaseBuffer ();

							szSize = pDC->GetTextExtent (strDate);

							if (rectDayCaption.Width () - 4 < szSize.cx)
							{
								strFormat = _T("d");
								bNeedFormat = TRUE;
							}
						}

						if (bNeedFormat)
						{
							strDate.GetBuffer (_MAX_PATH);

							::GetDateFormat (LOCALE_USER_DEFAULT, 0, &st, 
								strFormat, (LPTSTR)(LPCTSTR)strDate, _MAX_PATH);

							strDate.ReleaseBuffer ();
						}
					}
				}
			}

			if (bToday)
			{
				rectDayCaption.bottom--;
			}

			visualManager->PreparePlannerCaptionBackItem (FALSE);
			COLORREF clrText = OnFillPlannerCaption (
				pDC, rectDayCaption, bToday, bSelected, FALSE);

			DrawCaptionText (pDC, rectDayCaption, strDate, clrText, bCompact ? DT_LEFT : DT_RIGHT,
				bToday && bSelected);

			day += COleDateTimeSpan (1, 0, 0, 0);
		}
	}

	if (hOldFont != NULL)
	{
		::SelectObject (pDC->GetSafeHdc (), hOldFont);
	}
}
void CBCGPPlannerViewMonth::AdjustAppointments ()
{
	XBCGPAppointmentArray& arQueryApps = GetQueryedAppointments ();
	XBCGPAppointmentArray& arDragApps = GetDragedAppointments ();

	const int nDays = GetViewDuration ();

	if ((arQueryApps.GetSize () == 0 && arDragApps.GetSize () == 0) || 
		m_ViewRects.GetSize () != nDays)
	{
		ClearVisibleUpDownIcons ();		
		return;
	}

	BOOL bDragDrop        = IsDragDrop ();
	DROPEFFECT dragEffect = GetDragEffect ();
	BOOL bDragMatch       = IsCaptureMatched ();

	bDragDrop = !bDragDrop || 
		(bDragDrop && ((dragEffect & DROPEFFECT_COPY) == DROPEFFECT_COPY && bDragMatch) || 
		!bDragMatch);
	bDragDrop = bDragDrop && arDragApps.GetSize ();
	
	int nApp = 0;

	for (nApp = 0; nApp < 2; nApp++)
	{
		if (!bDragDrop && nApp == 0)
		{
			continue;
		}

		XBCGPAppointmentArray& arApps = nApp == 0 ? arDragApps : arQueryApps;

		for (int i = 0; i < arApps.GetSize (); i++)
		{
			CBCGPAppointment* pApp = arApps[i];
			ASSERT_VALID (pApp);

			pApp->ResetDraw ();
		}
	}

	COleDateTime date (m_DateStart);

	COleDateTimeSpan spanDay (1, 0, 0, 0);
	const int delta = m_nRowHeight + 2;

	XBCGPAppointmentArray arAllOrMulti;

	for (nApp = 0; nApp < 2; nApp++)
	{
		if (!bDragDrop && nApp == 1)
		{
			continue;
		}

		XBCGPAppointmentArray& arApps = nApp == 1 ? arDragApps : arQueryApps;

		for (int i = 0; i < arApps.GetSize (); i++)
		{
			CBCGPAppointment* pApp = arApps[i];
			ASSERT_VALID (pApp);

			if (pApp->IsAllDay () || pApp->IsMultiDay ())
			{
				arAllOrMulti.Add (pApp);
			}
		}
	}

	if (arAllOrMulti.GetSize () > 0)
	{
		SortAppointments (arAllOrMulti, (int) arAllOrMulti.GetSize ());
	}

	for (int nDay = 0; nDay < nDays; nDay ++)
	{
		CRect rect (m_ViewRects [nDay]);
		rect.top += m_nRowHeight + 1;
		rect.DeflateRect (1, 0);

		BOOL bTopEq    = TRUE;
		BOOL bBottomEq = TRUE;
		
		if (nDay > 0)
		{
			bTopEq    = m_ViewRects [nDay].top == m_ViewRects [nDay - 1].top;
			bBottomEq = m_ViewRects [nDay].bottom == m_ViewRects [nDay - 1].bottom;
		}

		CList<int, int> lsItems;

		// first draw all days or multi days
		for (int n = 0; n < 2; n++)
		{
			for (nApp = 0; nApp < 2; nApp++)
			{
				if (n == 0 && nApp == 1)
				{
					continue;
				}

				if (!bDragDrop)
				{
					if(n == 1 && nApp == 0)
					{
						continue;
					}
				}

				XBCGPAppointmentArray& arApps = 
					n == 0
					? arAllOrMulti
					: (nApp == 0 ? arDragApps : arQueryApps);

				for (int i = 0; i < arApps.GetSize (); i++)
				{
					CBCGPAppointment* pApp = arApps[i];
					ASSERT_VALID (pApp);

					BOOL bAllOrMulti = pApp->IsAllDay () || pApp->IsMultiDay ();

					if (CBCGPPlannerView::IsAppointmentInDate (*pApp, date) &&
						((n == 0 && bAllOrMulti) || (n == 1 && !bAllOrMulti)))
					{
						CRect rtApp (rect);

						int nItem = 0;

						while(TRUE)
						{
							POSITION pos = lsItems.Find (nItem);
							if (pos != NULL)
							{
								nItem++;
							}
							else
							{
								break;
							}
						}

						rtApp.top += nItem * delta;
						rtApp.bottom = rtApp.top + m_nRowHeight;

						// check for add new rect
						if (nDay > 0)
						{
							if (bTopEq && bAllOrMulti)
							{
								if (!pApp->GetDSDraw ().IsEmpty ())
								{
									CRect rt;
									rt = pApp->GetRectDraw (date - spanDay);

									if (!rt.IsRectEmpty () && rtApp.top != rt.top)
									{
										rtApp.top    = rt.top;
										rtApp.bottom = rt.bottom;
									}
								}
							}
						}

						if (((bTopEq && !bBottomEq) ||
							 (!bAllOrMulti && 
							  !IsOneDay (pApp->GetStart (), pApp->GetFinish ()))) &&
							!pApp->GetDSDraw ().IsEmpty ())
						{
							CRect rtInter;
							rtInter.IntersectRect (rtApp, m_ViewRects [nDay]);

							if (rtInter.Height () < rtApp.Height () || 
								rtInter.bottom >= rect.bottom || !bAllOrMulti)
							{
								// add impossible rect
								rtApp.OffsetRect (0, 1);
								pApp->SetRectDraw (rtApp, date);
								// return rect
								rtApp.OffsetRect (0, -1);
							}
						}

						pApp->SetRectDraw (rtApp, date);

						lsItems.AddTail ((rtApp.top - rect.top) / delta);
					}
				}
			}
		}

		CheckVisibleAppointments(date, rect, TRUE);

		date += spanDay;
	}

	CheckVisibleUpDownIcons (TRUE);

	m_bUpdateToolTipInfo = TRUE;
}
void CBCGPPlannerViewMulti::OnDrawClient (CDC* pDC, const CRect& rect)
{
	ASSERT_VALID (pDC);

	CRect rectFill (rect);

//	const int nWeekStart = CBCGPPlannerManagerCtrl::GetFirstDayOfWeek () + 1;
	const int yOffset = m_nScrollOffset * m_nRowHeight;

	int nFirstWorkingHour   = GetFirstWorkingHour ();
	int nFirstWorkingMinute = GetFirstWorkingMinute ();
	int nLastWorkingHour    = GetLastWorkingHour ();
	int nLastWorkingMinute  = GetLastWorkingMinute ();

	const int nDays = GetViewDuration ();
	const int nRes  = (int) m_Resources.GetSize ();

	rectFill.OffsetRect (0, -yOffset);

	const int nMinuts = CBCGPPlannerView::GetTimeDeltaInMinuts (GetTimeDelta ());
	const int nCount = 60 / nMinuts;

	CPen     penHour[2];
	CPen     penHalfHour[2];

	for (int i = 0; i < 2; i++)
	{
		penHour[i].CreatePen (PS_SOLID, 0,
			GetHourLineColor (i == 0 /* Working */, TRUE));

		penHalfHour[i].CreatePen (PS_SOLID, 0, 
			GetHourLineColor (i == 0 /* Working */, FALSE));
	}

	XBCGPPlannerWorkingParameters WorkingParameters(this);
	COLORREF DefaultWorkingColorFill = visualManager->GetPlannerWorkColor ();

	OnFillPlanner (pDC, rect, FALSE /* Non-working */);

	CBrush brHilite (visualManager->GetPlannerSelectionColor (this));

	CPen penBlack (PS_SOLID, 0, visualManager->GetPlannerSeparatorColor (this));
	CPen* pOldPen = pDC->SelectObject (&penBlack);

	const int iStart = GetViewHourOffset();
	const int iEnd   = min (iStart + rect.Height () / m_nRowHeight, nCount * 24);

	COleDateTime dtStart (GetDateStart ());

	BOOL bShowSelection = !((m_Selection[0].GetHour ()   == 0 &&
							 m_Selection[0].GetMinute () == 0 &&
							 m_Selection[0].GetSecond () == 0 &&
							 m_Selection[1].GetHour ()   == 23 &&
							 m_Selection[1].GetMinute () == 59 &&
							 m_Selection[1].GetSecond () == 59) ||
							(m_Selection[1].GetHour ()   == 0 &&
							 m_Selection[1].GetMinute () == 0 &&
							 m_Selection[1].GetSecond () == 0 &&
							 m_Selection[0].GetHour ()   == 23 &&
							 m_Selection[0].GetMinute () == 59 &&
							 m_Selection[0].GetSecond () == 59));

	BOOL bIsDrawDuration = 
		(GetPlanner ()->GetDrawFlags () & BCGP_PLANNER_DRAW_VIEW_NO_DURATION) == 0;
	const int nDurationWidth = bIsDrawDuration ? BCGP_PLANNER_DURATION_BAR_WIDTH + 1 : 0;

	visualManager->PreparePlannerBackItem (FALSE, FALSE);

	const UINT nResourceID = GetCurrentResourceID ();

	int nDay = 0;
	for (nDay = 0; nDay < nDays; nDay++)
	{
		int nWD = dtStart.GetDayOfWeek ();
		BOOL bWeekEnd = nWD == 1 || nWD == 7;

		for (int i = 0; i < nRes; i++)
		{
			XResource& res = m_Resources[i];

			int nFirstHour   = nFirstWorkingHour;
			int nFirstMinute = nFirstWorkingMinute;
			int nLastHour    = nLastWorkingHour;
			int nLastMinute  = nLastWorkingMinute;

			if (res.m_WorkStart < res.m_WorkEnd)
			{
				nFirstHour   = res.m_WorkStart.GetHour ();
				nFirstMinute = res.m_WorkStart.GetMinute ();
				nLastHour    = res.m_WorkEnd.GetHour ();
				nLastMinute  = res.m_WorkEnd.GetMinute ();
			}

			int iWorkStart = nFirstHour * nCount + (int)(nFirstMinute / nMinuts);
			int iWorkEnd   = nLastHour * nCount + (int)(nLastMinute / nMinuts);

			rectFill = res.m_Rects[nDay];

			rectFill.left   += nDurationWidth;
			rectFill.bottom = rectFill.top + m_nRowHeight - 1;

			BCGP_PLANNER_WORKING_STATUS AllPeriodWorkingStatus = 
				GetWorkingPeriodParameters (res.m_ResourceID, dtStart + COleDateTimeSpan (0, 0, iStart * nMinuts, 0), dtStart + COleDateTimeSpan (0, 0, (iEnd * nMinuts) - 1, 59), WorkingParameters); 
			BCGP_PLANNER_WORKING_STATUS SpecificPeriodWorkingStatus = AllPeriodWorkingStatus; 

			for (int iStep = iStart; iStep < iEnd; iStep++)
			{
				BOOL bIsWork = TRUE;
				if (AllPeriodWorkingStatus == BCGP_PLANNER_WORKING_STATUS_UNKNOWN)
				{ // We don't know for the day -> we should see for the period
					COleDateTime CurrentPeriodStart = dtStart + COleDateTimeSpan (0, 0, iStep * nMinuts, 0);
					COleDateTime CurrentPeriodEnd = CurrentPeriodStart + COleDateTimeSpan (0, 0, nMinuts - 1, 59);
					SpecificPeriodWorkingStatus = GetWorkingPeriodParameters (res.m_ResourceID, CurrentPeriodStart, CurrentPeriodEnd, WorkingParameters); 
				}

				switch (SpecificPeriodWorkingStatus)
				{
				case BCGP_PLANNER_WORKING_STATUS_ISNOTWORKING: // not a working period
					bIsWork = FALSE;
					break;
				case BCGP_PLANNER_WORKING_STATUS_ISWORKING: // forced to be a working period (we do not control working hours)
					bIsWork = TRUE;
					break;
				case BCGP_PLANNER_WORKING_STATUS_ISNORMALWORKINGDAY: // regular working day without control of week-end (so it may be a week-end day !)
					bIsWork = (iWorkStart <= iStep && iStep < iWorkEnd);
					break;
				case BCGP_PLANNER_WORKING_STATUS_ISNORMALWORKINGDAYINWEEK: // regular working day in a week (the week end is not a working day)
				default: // could not determine if period is working or not so we calculate as "standard"
					bIsWork = !bWeekEnd && (iWorkStart <= iStep && iStep < iWorkEnd);
				}

				if (!IsDateInSelection (dtStart + 
					COleDateTimeSpan (0, (iStep * nMinuts) / 60, (iStep * nMinuts) % 60, 0)) ||
					!bShowSelection || res.m_ResourceID != nResourceID)
				{
					if (bIsWork)
					{
						if (WorkingParameters.m_clrWorking != CLR_DEFAULT)
						{
							CBrush brush(WorkingParameters.m_clrWorking);
							pDC->FillRect (rectFill, &brush);
						}
						else
						{
							OnFillPlanner (pDC, rectFill, TRUE /* Working */);
						}
					}
					else
					{ // IF non working color is different from default non working color -> we should draw it with new color..
						if ((WorkingParameters.m_clrNonWorking != CLR_DEFAULT) && 
							(WorkingParameters.m_clrNonWorking != DefaultWorkingColorFill))
						{
							CBrush brush(WorkingParameters.m_clrNonWorking);
							pDC->FillRect (rectFill, &brush);
						}
					}
				}
				else
				{
					pDC->FillRect (rectFill, &brHilite);
				}

				int nPenIndex = bIsWork ? 0 : 1;

				pDC->SelectObject (((iStep + 1) % nCount == 0) ? 
					&penHour [nPenIndex] : &penHalfHour [nPenIndex]);

				pDC->MoveTo (rectFill.left, rectFill.bottom);
				pDC->LineTo (rectFill.right, rectFill.bottom);

				rectFill.OffsetRect (0, m_nRowHeight);
			}
		}	

		dtStart += COleDateTimeSpan (1, 0, 0, 0);
	}

	pDC->SelectObject (&penBlack);

	if (bIsDrawDuration)
	{
		for (nDay = 0; nDay < nDays; nDay++)
		{
			for (int i = 0; i < nRes; i++)
			{
				CRect rectDurBar (m_Resources[i].m_Rects[nDay]);
				rectDurBar.right = rectDurBar.left + BCGP_PLANNER_DURATION_BAR_WIDTH;

				// Draw duration bar (at left):
				pDC->FillRect (rectDurBar, &globalData.brWindow);

				if (nDay > 0 || i > 0)
				{
					pDC->MoveTo (rectDurBar.left, rectDurBar.top);
					pDC->LineTo (rectDurBar.left, rectDurBar.bottom);
				}

				pDC->MoveTo (rectDurBar.right, rectDurBar.top);
				pDC->LineTo (rectDurBar.right, rectDurBar.bottom);
			}	
		}
	}
	else
	{
		for (nDay = 0; nDay < nDays; nDay++)
		{
			for (int i = 0; i < nRes; i++)
			{
				CRect rectDurBar (m_Resources[i].m_Rects[nDay]);

				if (nDay > 0 || i > 0)
				{
					pDC->MoveTo (rectDurBar.left, rectDurBar.top);
					pDC->LineTo (rectDurBar.left, rectDurBar.bottom);
				}
			}
		}
	}

	pDC->SelectObject (pOldPen);
}