4461 lines
		
	
	
		
			133 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			4461 lines
		
	
	
		
			133 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
#if FRAMEWORK20
 | 
						|
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Drawing;
 | 
						|
using System.Drawing.Drawing2D;
 | 
						|
using System.Windows.Forms;
 | 
						|
using DevComponents.Schedule.Model;
 | 
						|
 | 
						|
namespace DevComponents.DotNetBar.Schedule
 | 
						|
{
 | 
						|
    public class WeekDayView : BaseView
 | 
						|
    {
 | 
						|
        #region Constants
 | 
						|
 | 
						|
        private const int HoursPerDay = 24;
 | 
						|
        private const int MinutesPerHour = 60;
 | 
						|
        private const int MaxNumberOfColumns = 3 * 31;
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Private variables
 | 
						|
 | 
						|
        private AllDayPanel _AllDayPanel;       // AllDay items panel
 | 
						|
 | 
						|
        private DayColumn[] _DayColumns;        // Array of DayColumns
 | 
						|
        private int _NumberOfColumns;           // Number of DayColumns
 | 
						|
        private Size[] _DayColumnSize;          // Array of day text sizes
 | 
						|
 | 
						|
        private CalendarWeekDayColor _ViewColor =     // View display color table
 | 
						|
            new CalendarWeekDayColor(eCalendarColor.Automatic);
 | 
						|
 | 
						|
        private int _LastCol;                   // Last processed column
 | 
						|
        private Point _LastMovePoint;           // Last mouse move Point
 | 
						|
        private Point _LastPointOffset;         // Last Point offset
 | 
						|
        private Rectangle _LastBounds;          // MouseDown item bounds
 | 
						|
 | 
						|
        int _LastMoveCol;
 | 
						|
        int _LastDm;
 | 
						|
 | 
						|
        private bool _IsPanelResizing;          // Flag denoting panel resizing
 | 
						|
        private bool _WasAllDayItem;
 | 
						|
 | 
						|
        private int _SelectedSliceStart;        // Absolute slice start
 | 
						|
        private int _SelectedSliceEnd;          // Absolute slice end (e.g. 450 - 1440)
 | 
						|
 | 
						|
        private Timer _ScrollViewTimer;         // Timer used to implement auto view scrolling
 | 
						|
        private int _VScrollPos;                // Vertical scroll bar pos
 | 
						|
 | 
						|
        private Color _BusyColor;               // Cached brush colors
 | 
						|
        private Color _WorkColor;
 | 
						|
        private Color _OffWorkColor;
 | 
						|
        private Color _SelectedColor;
 | 
						|
 | 
						|
        private Brush _BusyBrush;               // Cached brushes
 | 
						|
        private Brush _WorkBrush;
 | 
						|
        private Brush _OffWorkBrush;
 | 
						|
        private Brush _SelectedBrush;
 | 
						|
        private Brush _AllDayBrush;
 | 
						|
        private Color _AllDayColor;
 | 
						|
 | 
						|
        private int _LocalStartSlice;
 | 
						|
        private int _LocalNumberOfSlices;
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Constructor
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="calendarView">CalendarView</param>
 | 
						|
        /// <param name="eCalendarView"></param>
 | 
						|
        public WeekDayView(CalendarView calendarView, eCalendarView eCalendarView)
 | 
						|
            : base(calendarView, eCalendarView)
 | 
						|
        {
 | 
						|
            // Allocate our AllDayPanel
 | 
						|
 | 
						|
            _AllDayPanel = new AllDayPanel(this);
 | 
						|
            _AllDayPanel.Displayed = true;
 | 
						|
 | 
						|
            // Set our non-client drawing info and CalendarColor
 | 
						|
 | 
						|
            NClientData = new NonClientData(
 | 
						|
                eTabOrientation.Horizontal,
 | 
						|
                (int)eCalendarWeekDayPart.OwnerTabBorder,
 | 
						|
                (int)eCalendarWeekDayPart.OwnerTabForeground,
 | 
						|
                (int)eCalendarWeekDayPart.OwnerTabBackground,
 | 
						|
                (int)eCalendarWeekDayPart.OwnerTabContentBackground,
 | 
						|
                (int)eCalendarWeekDayPart.OwnerTabSelectedForeground,
 | 
						|
                (int)eCalendarWeekDayPart.OwnerTabSelectedBackground);
 | 
						|
 | 
						|
            CalendarColorTable = _ViewColor;
 | 
						|
 | 
						|
            // Hook onto our events
 | 
						|
 | 
						|
            HookEvents(true);
 | 
						|
        }
 | 
						|
 | 
						|
        #region Public properties
 | 
						|
 | 
						|
        #region DayColumns
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the view DayColumns
 | 
						|
        /// </summary>
 | 
						|
        public DayColumn[] DayColumns
 | 
						|
        {
 | 
						|
            get { return (_DayColumns); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region NumberOfColumns
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the view's number of DayColumns
 | 
						|
        /// </summary>
 | 
						|
        public int NumberOfColumns
 | 
						|
        {
 | 
						|
            get { return (_NumberOfColumns); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region VScrollBar
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the WeekDay vertical scrollbar
 | 
						|
        /// </summary>
 | 
						|
        public VScrollBarAdv VScrollBar
 | 
						|
        {
 | 
						|
            get { return (CalendarView.WeekDayVScrollBar ); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Internal properties
 | 
						|
 | 
						|
        #region Base calendar properties
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the Sub-Day view rectangle
 | 
						|
        /// </summary>
 | 
						|
        internal Rectangle ViewRect
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                Rectangle r = ClientRect;
 | 
						|
 | 
						|
                int n = DayOfWeekHeaderHeight + _AllDayPanel.PanelHeight;
 | 
						|
 | 
						|
                r.Y += n;
 | 
						|
                r.Height -= (n + 1);
 | 
						|
 | 
						|
                return (r);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the CalendarColor
 | 
						|
        /// </summary>
 | 
						|
        internal CalendarWeekDayColor WeekDayColor
 | 
						|
        {
 | 
						|
            get { return (_ViewColor); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DayColumn properties
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the local StartSlice
 | 
						|
        /// </summary>
 | 
						|
        internal int LocalStartSlice
 | 
						|
        {
 | 
						|
            get { return (_LocalStartSlice); }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the local NumberOfSlices
 | 
						|
        /// </summary>
 | 
						|
        internal int LocalNumberOfSlices
 | 
						|
        {
 | 
						|
            get { return (_LocalNumberOfSlices); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region AllDayPanel properties
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the view's AllDayPanel
 | 
						|
        /// </summary>
 | 
						|
        internal AllDayPanel AllDayPanel
 | 
						|
        {
 | 
						|
            get { return (_AllDayPanel); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Private properties
 | 
						|
 | 
						|
        #region DayColumnWidth
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the DayColumnWidth
 | 
						|
        /// </summary>
 | 
						|
        private float DayColumnWidth
 | 
						|
        {
 | 
						|
            get { return (((float)ClientRect.Width - 1) / _NumberOfColumns); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region AllDay Panel properties
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the maximum AllDayPanel height
 | 
						|
        /// </summary>
 | 
						|
        private int MaximumAllDayPanelHeight
 | 
						|
        {
 | 
						|
            get { return (CalendarView.MaximumAllDayPanelHeight); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Time Slice properties
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the TimeSlotDuration
 | 
						|
        /// </summary>
 | 
						|
        private int TimeSlotDuration
 | 
						|
        {
 | 
						|
            get { return (CalendarView.TimeSlotDuration); }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the default Time Slice height
 | 
						|
        /// </summary>
 | 
						|
        private float TimeSliceHeight
 | 
						|
        {
 | 
						|
            get { return (CalendarView.TimeSliceHeight); }
 | 
						|
            set { CalendarView.TimeSliceHeight = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the SlotsPerHour
 | 
						|
        /// </summary>
 | 
						|
        private int SlotsPerHour
 | 
						|
        {
 | 
						|
            get { return (CalendarView.SlotsPerHour); }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the NumberOfSlices
 | 
						|
        /// </summary>
 | 
						|
        private int NumberOfSlices
 | 
						|
        {
 | 
						|
            get { return (CalendarView.NumberOfSlices); }
 | 
						|
            set { CalendarView.NumberOfSlices = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the NumberOfActiveSlices
 | 
						|
        /// </summary>
 | 
						|
        private int NumberOfActiveSlices
 | 
						|
        {
 | 
						|
            get { return (CalendarView.NumberOfActiveSlices); }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the StartSlice
 | 
						|
        /// </summary>
 | 
						|
        private int StartSlice
 | 
						|
        {
 | 
						|
            get { return (CalendarView.StartSlice); }
 | 
						|
            set { CalendarView.StartSlice = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region BusyBrush
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets and sets the Busy time brush
 | 
						|
        /// </summary>
 | 
						|
        private Brush BusyBrush
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                Color color = _ViewColor.GetColor(
 | 
						|
                    (int)eCalendarWeekDayPart.DayAllDayEventBackground);
 | 
						|
 | 
						|
                if (_BusyColor != color)
 | 
						|
                {
 | 
						|
                    _BusyColor = color;
 | 
						|
 | 
						|
                    BusyBrush = new SolidBrush(color);
 | 
						|
                }
 | 
						|
 | 
						|
                return (_BusyBrush);
 | 
						|
            }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (_BusyBrush != value)
 | 
						|
                {
 | 
						|
                    if (_BusyBrush != null)
 | 
						|
                        _BusyBrush.Dispose();
 | 
						|
 | 
						|
                    _BusyBrush = value;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region WorkBrush
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets and sets the Work time brush
 | 
						|
        /// </summary>
 | 
						|
        private Brush WorkBrush
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                Color color = _ViewColor.GetColor(
 | 
						|
                    (int)eCalendarWeekDayPart.DayWorkHoursBackground);
 | 
						|
 | 
						|
                if (_WorkColor != color)
 | 
						|
                {
 | 
						|
                    _WorkColor = color;
 | 
						|
 | 
						|
                    WorkBrush = new SolidBrush(color);
 | 
						|
                }
 | 
						|
 | 
						|
                return (_WorkBrush);
 | 
						|
            }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (_WorkBrush != value)
 | 
						|
                {
 | 
						|
                    if (_WorkBrush != null)
 | 
						|
                        _WorkBrush.Dispose();
 | 
						|
 | 
						|
                    _WorkBrush = value;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region OffWorkBrush
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets and sets the Off-hours work time brush
 | 
						|
        /// </summary>
 | 
						|
        private Brush OffWorkBrush
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                Color color = _ViewColor.GetColor(
 | 
						|
                    (int)eCalendarWeekDayPart.DayOffWorkHoursBackground);
 | 
						|
 | 
						|
                if (_OffWorkColor != color)
 | 
						|
                {
 | 
						|
                    _OffWorkColor = color;
 | 
						|
 | 
						|
                    OffWorkBrush = new SolidBrush(color);
 | 
						|
                }
 | 
						|
 | 
						|
                return (_OffWorkBrush);
 | 
						|
            }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (_OffWorkBrush != value)
 | 
						|
                {
 | 
						|
                    if (_OffWorkBrush != null)
 | 
						|
                        _OffWorkBrush.Dispose();
 | 
						|
 | 
						|
                    _OffWorkBrush = value;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region AllDayBrush
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets and sets the Off-hours work time brush
 | 
						|
        /// </summary>
 | 
						|
        private Brush AllDayBrush
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                Color color = _ViewColor.GetColor(
 | 
						|
                    (int)eCalendarWeekDayPart.DayAllDayEventBackground);
 | 
						|
 | 
						|
                if (_AllDayColor != color)
 | 
						|
                {
 | 
						|
                    _AllDayColor = color;
 | 
						|
 | 
						|
                    AllDayBrush = new SolidBrush(color);
 | 
						|
                }
 | 
						|
 | 
						|
                return (_AllDayBrush);
 | 
						|
            }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (_AllDayBrush != value)
 | 
						|
                {
 | 
						|
                    if (_AllDayBrush != null)
 | 
						|
                        _AllDayBrush.Dispose();
 | 
						|
 | 
						|
                    _AllDayBrush = value;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SelectedBrush
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets and sets the selected brush
 | 
						|
        /// </summary>
 | 
						|
        private Brush SelectedBrush
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                Color color = _ViewColor.GetColor(
 | 
						|
                    (int)eCalendarWeekDayPart.SelectionBackground);
 | 
						|
 | 
						|
                if (_SelectedColor != color)
 | 
						|
                {
 | 
						|
                    _SelectedColor = color;
 | 
						|
 | 
						|
                    SelectedBrush = new SolidBrush(color);
 | 
						|
                }
 | 
						|
 | 
						|
                return (_SelectedBrush);
 | 
						|
            }
 | 
						|
 | 
						|
            set
 | 
						|
            {
 | 
						|
                if (_SelectedBrush != value)
 | 
						|
                {
 | 
						|
                    if (_SelectedBrush != null)
 | 
						|
                        _SelectedBrush.Dispose();
 | 
						|
 | 
						|
                    _SelectedBrush = value;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region FirstOnScreenSlice
 | 
						|
 | 
						|
        private int FirstOnScreenSlice
 | 
						|
        {
 | 
						|
            get { return ((int)(-_VScrollPos / TimeSliceHeight)); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region LastOnScreenSlice
 | 
						|
 | 
						|
        private int LastOnScreenSlice
 | 
						|
        {
 | 
						|
            get { return (FirstOnScreenSlice + OnScreenSlices - 1); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region OnScreenSlices
 | 
						|
 | 
						|
        private int OnScreenSlices
 | 
						|
        {
 | 
						|
            get { return ((int)Math.Ceiling(VsPanel.ScrollBar.Height / TimeSliceHeight)); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region VsPanel
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the WeekDay vertical scroll panel
 | 
						|
        /// </summary>
 | 
						|
        private VScrollPanel VsPanel
 | 
						|
        {
 | 
						|
            get { return (CalendarView.WeekDayVScrollPanel); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Hook / Unhook Events
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Routine hooks all necessary events for this control
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="hook">True to hook, false to unhook</param>
 | 
						|
        private void HookEvents(bool hook)
 | 
						|
        {
 | 
						|
            if (hook == true)
 | 
						|
            {
 | 
						|
                CalendarView.SelectedViewChanged += SelectedViewChanged;
 | 
						|
                CalendarView.TimeSlotDurationChanged += TimeSlotDurationChanged;
 | 
						|
                CalendarView.FixedAllDayPanelHeightChanged += FixedAllDayPanelHeightChanged;
 | 
						|
                CalendarView.MaximumAllDayPanelHeightChanged += MaximumAllDayPanelHeightChanged;
 | 
						|
                CalendarView.WeekDayVScrollPanel.ScrollBarChanged += VScrollPanelScrollBarChanged;
 | 
						|
 | 
						|
                if (this.ECalendarView == eCalendarView.Day)
 | 
						|
                {
 | 
						|
                    CalendarView.DayViewDateChanged += DayViewDateChanged;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    CalendarView.WeekViewStartDateChanged += WeekViewStartDateChanged;
 | 
						|
                    CalendarView.WeekViewEndDateChanged += WeekViewEndDateChanged;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                CalendarView.SelectedViewChanged -= SelectedViewChanged;
 | 
						|
                CalendarView.TimeSlotDurationChanged -= TimeSlotDurationChanged;
 | 
						|
                CalendarView.FixedAllDayPanelHeightChanged -= FixedAllDayPanelHeightChanged;
 | 
						|
                CalendarView.MaximumAllDayPanelHeightChanged -= MaximumAllDayPanelHeightChanged;
 | 
						|
                CalendarView.WeekDayVScrollPanel.ScrollBarChanged -= VScrollPanelScrollBarChanged;
 | 
						|
 | 
						|
                if (this.ECalendarView == eCalendarView.Day)
 | 
						|
                {
 | 
						|
                    CalendarView.DayViewDateChanged -= DayViewDateChanged;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    CalendarView.WeekViewStartDateChanged -= WeekViewStartDateChanged;
 | 
						|
                    CalendarView.WeekViewEndDateChanged -= WeekViewEndDateChanged;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Event handling routines
 | 
						|
 | 
						|
        #region SelectedViewChanged
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes view changes
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender">object</param>
 | 
						|
        /// <param name="e">SelectedViewEventArgs</param>
 | 
						|
        void SelectedViewChanged(object sender, SelectedViewEventArgs e)
 | 
						|
        {
 | 
						|
            // Update our IsViewSelected state
 | 
						|
 | 
						|
            IsViewSelected = (e.NewValue == this.ECalendarView);
 | 
						|
 | 
						|
            if (IsViewSelected == true)
 | 
						|
            {
 | 
						|
                AutoSyncViewDate(e.OldValue);
 | 
						|
 | 
						|
                UpdateDateSelection();
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                ResetView();
 | 
						|
            }
 | 
						|
 | 
						|
            // Update our AllDayPanel view
 | 
						|
 | 
						|
            _AllDayPanel.UpdateView();
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DayViewDateChanged
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes DayViewDate changes
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender"></param>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        void DayViewDateChanged(object sender, DateChangeEventArgs e)
 | 
						|
        {
 | 
						|
            StartDate = e.NewValue;
 | 
						|
            EndDate = e.NewValue;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region WeekViewStartDateChanged
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes StartDate changes
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender"></param>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        void WeekViewStartDateChanged(object sender, DateChangeEventArgs e)
 | 
						|
        {
 | 
						|
            StartDate = e.NewValue;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region WeekViewEndDateChanged
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes EndDate changes
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender"></param>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        void WeekViewEndDateChanged(object sender, DateChangeEventArgs e)
 | 
						|
        {
 | 
						|
            EndDate = e.NewValue;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region TimeSlotDurationChanged
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles TimeSlotDurationChanged events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender">object</param>
 | 
						|
        /// <param name="e">TimeSlotDurationChangedEventArgs</param>
 | 
						|
        void TimeSlotDurationChanged(
 | 
						|
            object sender, TimeSlotDurationChangedEventArgs e)
 | 
						|
        {
 | 
						|
            // Reset our slice selection range and
 | 
						|
            // invalidate our control
 | 
						|
 | 
						|
            _SelectedSliceStart = 0;
 | 
						|
            _SelectedSliceEnd = 0;
 | 
						|
 | 
						|
            NeedRecalcLayout = true;
 | 
						|
            RecalcSize();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region FixedAllDayPanelHeightChanged
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles FixedAllDayPanelHeightChanged events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender"></param>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        void FixedAllDayPanelHeightChanged(
 | 
						|
            object sender, FixedAllDayPanelHeightChangedEventArgs e)
 | 
						|
        {
 | 
						|
            NeedRecalcLayout = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MaximumAllDayPanelHeightChanged
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles MaximumAllDayPanelHeightChanged events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender"></param>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        void MaximumAllDayPanelHeightChanged(
 | 
						|
            object sender, MaximumAllDayPanelHeightChangedEventArgs e)
 | 
						|
        {
 | 
						|
            NeedRecalcLayout = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region VScrollPanel_ScrollBarChanged
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles ScrollBarChanged events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender"></param>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        void VScrollPanelScrollBarChanged(object sender, EventArgs e)
 | 
						|
        {
 | 
						|
            int vdelta = -VsPanel.ScrollBar.Value - _VScrollPos;
 | 
						|
 | 
						|
            if (vdelta != 0)
 | 
						|
            {
 | 
						|
                _VScrollPos = -VsPanel.ScrollBar.Value;
 | 
						|
 | 
						|
                // Offset our DayColumn accordingly
 | 
						|
 | 
						|
                for (int i = 0; i < _NumberOfColumns; i++)
 | 
						|
                {
 | 
						|
                    DayColumn dayColumn = _DayColumns[i];
 | 
						|
 | 
						|
                    Rectangle r = dayColumn.Bounds;
 | 
						|
                    r.Y += vdelta;
 | 
						|
 | 
						|
                    dayColumn.Bounds = r;
 | 
						|
 | 
						|
                    for (int j = 0; j < dayColumn.CalendarItems.Count; j++)
 | 
						|
                    {
 | 
						|
                        dayColumn.CalendarItems[j].Displayed =
 | 
						|
                            dayColumn.CalendarItems[j].Bounds.IntersectsWith(ClientRect);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                
 | 
						|
                // Redraw our view
 | 
						|
 | 
						|
                InvalidateRect(ViewRect);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetViewAreaFromPoint
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the view area under the given mouse
 | 
						|
        /// point (tab, header, content, etc)
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pt">Point</param>
 | 
						|
        /// <returns>eViewArea</returns>
 | 
						|
        public override eViewArea GetViewAreaFromPoint(Point pt)
 | 
						|
        {
 | 
						|
            if (Bounds.Contains(pt) == true)
 | 
						|
            {
 | 
						|
                if (pt.Y >= ClientRect.Y)
 | 
						|
                {
 | 
						|
                    if (AllDayPanel.Bounds.Contains(pt))
 | 
						|
                        return (eViewArea.InAllDayPanel);
 | 
						|
 | 
						|
                    if (pt.Y < ClientRect.Y + DayOfWeekHeaderHeight)
 | 
						|
                        return (eViewArea.InDayOfWeekHeader);
 | 
						|
 | 
						|
                    return (eViewArea.InContent);
 | 
						|
                }
 | 
						|
 | 
						|
                return (base.GetViewAreaFromPoint(pt));
 | 
						|
            }
 | 
						|
 | 
						|
            return (eViewArea.NotInView);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDateSelectionFromPoint
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the date selection from the given point. The startDate
 | 
						|
        /// and endDate will vary based upon the view type (WeekDay / Month)
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pt">Point in question</param>
 | 
						|
        /// <param name="startDate">out start date</param>
 | 
						|
        /// <param name="endDate">out end date</param>
 | 
						|
        /// <returns>True if a valid selection exists
 | 
						|
        /// at the given point</returns>
 | 
						|
        public override bool GetDateSelectionFromPoint(
 | 
						|
            Point pt, out DateTime startDate, out DateTime endDate)
 | 
						|
        {
 | 
						|
            base.GetDateSelectionFromPoint(pt, out startDate, out endDate);
 | 
						|
 | 
						|
            int col, slice;
 | 
						|
 | 
						|
            if (GetPointItem(pt, out col, out slice, true) == true)
 | 
						|
            {
 | 
						|
                startDate = GetTime(_DayColumns[col].Date, slice, 0);
 | 
						|
                endDate = startDate.AddMinutes(TimeSlotDuration);
 | 
						|
 | 
						|
                return (true);
 | 
						|
            }
 | 
						|
 | 
						|
            return (false);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDateBounds
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the bounding display rectangle for the given date/time.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="date">The date/time</param>
 | 
						|
        /// <returns>Bounding display rectangle</returns>
 | 
						|
        public Rectangle GetDateBounds(DateTime date)
 | 
						|
        {
 | 
						|
            int col = GetColumnFromDate(date);
 | 
						|
 | 
						|
            if (col >= 0)
 | 
						|
            {
 | 
						|
                int slice = GetDateSlice(date);
 | 
						|
 | 
						|
                if (slice >= 0)
 | 
						|
                    return (GetSliceRect(col, slice));
 | 
						|
            }
 | 
						|
 | 
						|
            return (Rectangle.Empty);
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the bounding display rectangle for the given
 | 
						|
        /// starting and ending date/time range.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="startDate">Start date</param>
 | 
						|
        /// <param name="endDate">End date</param>
 | 
						|
        /// <returns>Bounding display rectangle</returns>
 | 
						|
        public Rectangle GetDateBounds(DateTime startDate, DateTime endDate)
 | 
						|
        {
 | 
						|
            Rectangle r1 = GetDateBounds(startDate);
 | 
						|
            Rectangle r2 = GetDateBounds(endDate);
 | 
						|
 | 
						|
            return (Rectangle.Union(r1, r2));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region IsAllDayItem
 | 
						|
 | 
						|
        internal bool IsAllDayItem(CalendarItem item)
 | 
						|
        {
 | 
						|
            if (item.Equals(SelectedItem) &&
 | 
						|
                (IsEndResizing || IsStartResizing || IsMoving))
 | 
						|
            {
 | 
						|
                return (false);
 | 
						|
            }
 | 
						|
 | 
						|
            return (IsAllDayItem(item.StartTime, item.EndTime));
 | 
						|
        }
 | 
						|
 | 
						|
        internal bool IsAllDayItem(Appointment item)
 | 
						|
        {
 | 
						|
            if (SelectedItem != null && item.Equals(SelectedItem.ModelItem) &&
 | 
						|
                (IsEndResizing || IsStartResizing || IsMoving))
 | 
						|
            {
 | 
						|
                return (false);
 | 
						|
            }
 | 
						|
 | 
						|
            return (IsAllDayItem(item.StartTime, item.EndTime));
 | 
						|
        }
 | 
						|
 | 
						|
        private bool IsAllDayItem(DateTime startTime, DateTime endTime)
 | 
						|
        {
 | 
						|
            //if (NumberOfColumns > 1 || 
 | 
						|
            if (    CalendarView.AllDayDisplayMode != eAllDayDisplayMode.None)
 | 
						|
            {
 | 
						|
                if ((endTime - startTime).TotalDays >= 1)
 | 
						|
                    return (true);
 | 
						|
            }
 | 
						|
 | 
						|
            //if (NumberOfColumns > 1 ||
 | 
						|
            if (    CalendarView.AllDayDisplayMode == eAllDayDisplayMode.ByDayBoundary)
 | 
						|
            {
 | 
						|
                return (startTime.Day != endTime.Day ||
 | 
						|
                        (endTime - startTime).TotalDays > 1);
 | 
						|
            }
 | 
						|
 | 
						|
            return (false);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SetSelectedItem
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles selected item changes
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender">CalendarItem</param>
 | 
						|
        /// <param name="e">EventArgs</param>
 | 
						|
        internal void ItemIsSelectedChanged(object sender, EventArgs e)
 | 
						|
        {
 | 
						|
            CalendarItem ci = sender as CalendarItem;
 | 
						|
 | 
						|
            if (ci != null)
 | 
						|
            {
 | 
						|
                if (ci.IsSelected == true)
 | 
						|
                {
 | 
						|
                    SelectedItem = SetSelectedItem(SelectedItem, ci);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    if (ci == SelectedItem)
 | 
						|
                        SelectedItem = null;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region SetSelectedItem
 | 
						|
 | 
						|
        protected override CalendarItem SetSelectedItem(CalendarItem pci, CalendarItem nci)
 | 
						|
        {
 | 
						|
            CalendarItem selItem = null;
 | 
						|
 | 
						|
            for (int i = 0; i < DayColumns.Length; i++)
 | 
						|
                selItem = SetSelectedCalendarItem(nci, DayColumns[i].CalendarItems, selItem);
 | 
						|
 | 
						|
            selItem = SetSelectedCalendarItem(nci, AllDayPanel.CalendarItems, selItem);
 | 
						|
 | 
						|
            return (selItem);
 | 
						|
        }
 | 
						|
 | 
						|
        #region SetSelectedCalendarItem
 | 
						|
 | 
						|
        private CalendarItem SetSelectedCalendarItem(
 | 
						|
            CalendarItem nci, List<CalendarItem> items, CalendarItem selItem)
 | 
						|
        {
 | 
						|
            for (int i = 0; i < items.Count; i++)
 | 
						|
            {
 | 
						|
                CalendarItem item = items[i];
 | 
						|
 | 
						|
                item.IsSelected = (nci != null ? (item.ModelItem == nci.ModelItem) : false);
 | 
						|
 | 
						|
                if (item.IsSelected == true && selItem == null)
 | 
						|
                {
 | 
						|
                    selItem = item;
 | 
						|
                    SelectedItem = item;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (selItem);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region UpdateDateSelection
 | 
						|
 | 
						|
        #region UpdateDateSelection
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Updates our slice selection range to reflect
 | 
						|
        /// the given date selection start and end values
 | 
						|
        /// </summary>
 | 
						|
        protected override void UpdateDateSelection()
 | 
						|
        {
 | 
						|
            if (IsViewSelected == true)
 | 
						|
            {
 | 
						|
                // Get the new absolute slice selection range
 | 
						|
 | 
						|
                int sliceStart = 0;
 | 
						|
                int sliceEnd = 0;
 | 
						|
 | 
						|
                if (DateSelectionStart.HasValue && DateSelectionEnd.HasValue)
 | 
						|
                {
 | 
						|
                    sliceStart = GetDateSlice(DateSelectionStart);
 | 
						|
                    sliceEnd = GetDateSlice(DateSelectionEnd);
 | 
						|
 | 
						|
                    if (sliceStart < 0 && sliceEnd < 0)
 | 
						|
                    {
 | 
						|
                        sliceStart = 0;
 | 
						|
                        sliceEnd = 0;
 | 
						|
                    }
 | 
						|
 | 
						|
                    if (sliceStart < 0)
 | 
						|
                        sliceStart = 0;
 | 
						|
 | 
						|
                    if (sliceEnd < 0)
 | 
						|
                        sliceEnd = _NumberOfColumns * NumberOfActiveSlices;
 | 
						|
                }
 | 
						|
 | 
						|
                // Limit our range to only those slices
 | 
						|
                // that are visible on the screen
 | 
						|
 | 
						|
                int s1 = (int)(-_VScrollPos / TimeSliceHeight);
 | 
						|
                int s2 = (int)(s1 + ViewRect.Height / TimeSliceHeight + 2);
 | 
						|
 | 
						|
                if (s2 > s1)
 | 
						|
                {
 | 
						|
                    ProcessSelRange(sliceStart, sliceEnd, s1, s2);
 | 
						|
 | 
						|
                    // Save our new selection range
 | 
						|
 | 
						|
                    _SelectedSliceStart = sliceStart;
 | 
						|
                    _SelectedSliceEnd = sliceEnd;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDateSlice
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the absolute slice value for the given date
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="selDate">Selection date</param>
 | 
						|
        /// <returns>Absolute slice</returns>
 | 
						|
        private int GetDateSlice(DateTime? selDate)
 | 
						|
        {
 | 
						|
            if (selDate.HasValue)
 | 
						|
                return (GetDateSlice(selDate.Value));
 | 
						|
 | 
						|
            return (-1);
 | 
						|
        }
 | 
						|
 | 
						|
        private int GetDateSlice(DateTime selDate)
 | 
						|
        {
 | 
						|
            // Loop through each column
 | 
						|
 | 
						|
            for (int i = 0; i < _NumberOfColumns; i++)
 | 
						|
            {
 | 
						|
                DateTime date = _DayColumns[i].Date;
 | 
						|
 | 
						|
                // If we have found our containing column, then
 | 
						|
                // calculate the absolute slice value and return it
 | 
						|
 | 
						|
                if (selDate >= date && selDate < date.AddDays(1))
 | 
						|
                {
 | 
						|
                    int slice = ((selDate.Hour * MinutesPerHour) + selDate.Minute) / TimeSlotDuration;
 | 
						|
 | 
						|
                    return (i * NumberOfActiveSlices + slice - StartSlice);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (-1);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessSelRange
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes the selection time slice range
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sliceStart">Slice range start</param>
 | 
						|
        /// <param name="sliceEnd">Slice range end</param>
 | 
						|
        /// <param name="s1">Slice start limit</param>
 | 
						|
        /// <param name="s2">Slice end limit</param>
 | 
						|
        private void ProcessSelRange(int sliceStart, int sliceEnd, int s1, int s2)
 | 
						|
        {
 | 
						|
            // Calculate our starting and ending column range
 | 
						|
 | 
						|
            int fcol = Math.Min(_SelectedSliceStart / NumberOfActiveSlices, sliceStart / NumberOfActiveSlices);
 | 
						|
            int lcol = Math.Max(_SelectedSliceEnd / NumberOfActiveSlices, sliceEnd / NumberOfActiveSlices);
 | 
						|
 | 
						|
            lcol = Math.Min(_NumberOfColumns - 1, lcol);
 | 
						|
 | 
						|
            // Loop through each column
 | 
						|
 | 
						|
            for (int i = fcol; i <= lcol; i++)
 | 
						|
            {
 | 
						|
                // Get the selection status for the given range
 | 
						|
 | 
						|
                bool[] oldSelected = SelectedSlices(s1, s2, i, _SelectedSliceStart, _SelectedSliceEnd);
 | 
						|
                bool[] newSelected = SelectedSlices(s1, s2, i, sliceStart, sliceEnd);
 | 
						|
 | 
						|
                // Invalidate those slices whose
 | 
						|
                // selection status changed
 | 
						|
 | 
						|
                Rectangle vRect = ViewRect;
 | 
						|
 | 
						|
                for (int j = 0; j < s2 - s1; j++)
 | 
						|
                {
 | 
						|
                    if (oldSelected[j] != newSelected[j])
 | 
						|
                    {
 | 
						|
                        Rectangle r = GetSliceRect(i, s1 + j);
 | 
						|
 | 
						|
                        r.Intersect(vRect);
 | 
						|
 | 
						|
                        if (r.Width > 0 && r.Height > 0)
 | 
						|
                            InvalidateRect(r);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SelectedSlices
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets an array of slice selection values
 | 
						|
        /// over the given range of column slices
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="s1">Slice start limit</param>
 | 
						|
        /// <param name="s2">Slice end limit</param>
 | 
						|
        /// <param name="col">Column</param>
 | 
						|
        /// <param name="sliceStart">Slice range start</param>
 | 
						|
        /// <param name="sliceEnd">Slice range end</param>
 | 
						|
        /// <returns>Array of selection values</returns>
 | 
						|
        private bool[] SelectedSlices(int s1, int s2, int col, int sliceStart, int sliceEnd)
 | 
						|
        {
 | 
						|
            // Calculate our number of entries and
 | 
						|
            // allocate our IsSelected array accordingly
 | 
						|
 | 
						|
            int n = s2 - s1;
 | 
						|
 | 
						|
            bool[] sel = new bool[n + 1];
 | 
						|
 | 
						|
            // Loop through the range of entries determining if
 | 
						|
            // the specific slice is within the selection range
 | 
						|
 | 
						|
            int slice = col * NumberOfActiveSlices + s1;
 | 
						|
 | 
						|
            for (int i = 0; i < n; i++)
 | 
						|
            {
 | 
						|
                sel[i] = (slice >= sliceStart && slice < sliceEnd);
 | 
						|
 | 
						|
                slice++;
 | 
						|
            }
 | 
						|
 | 
						|
            // Return the array to the caller
 | 
						|
 | 
						|
            return (sel);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RecalcSize routines
 | 
						|
 | 
						|
        #region RecalcSize
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Performs NeedRecalcSize requests
 | 
						|
        /// </summary>
 | 
						|
        public override void RecalcSize()
 | 
						|
        {
 | 
						|
            base.RecalcSize();
 | 
						|
 | 
						|
            if (IsViewSelected == true)
 | 
						|
            {
 | 
						|
                // Normalize our start and end dates
 | 
						|
 | 
						|
                DateTime startDate;
 | 
						|
                DateTime endDate;
 | 
						|
 | 
						|
                NormalizeDates(out startDate, out endDate);
 | 
						|
 | 
						|
                if (NeedRecalcLayout == true)
 | 
						|
                    _DayColumnSize = null;
 | 
						|
 | 
						|
                // Allocate our DayColumns
 | 
						|
 | 
						|
                AllocateDayColumns(startDate, endDate);
 | 
						|
 | 
						|
                // Update our Model connection view,
 | 
						|
                // AllDayPanel, CalendarItems, and DateSelection
 | 
						|
 | 
						|
                UpdateView();
 | 
						|
 | 
						|
                UpdateAllDayPanelItems();
 | 
						|
                UpdateDayColumns(startDate, endDate);
 | 
						|
                UpdateCalendarItems();
 | 
						|
 | 
						|
                UpdateDateSelection();
 | 
						|
 | 
						|
                // Set our display view rectangle
 | 
						|
 | 
						|
                Rectangle r = ClientRect;
 | 
						|
 | 
						|
                r.Y += DayOfWeekHeaderHeight;
 | 
						|
                r.Height -= DayOfWeekHeaderHeight;
 | 
						|
 | 
						|
                SetViewRectangle(r);
 | 
						|
 | 
						|
                // Final Recalc cleanup
 | 
						|
 | 
						|
                if (DaysOfTheWeek != null)
 | 
						|
                    DaysOfTheWeek.NeedsMeasured = true;
 | 
						|
 | 
						|
                NeedRecalcLayout = false;
 | 
						|
 | 
						|
                CalendarView.DoViewLoadComplete(this);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region NormalizeDates
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Normalizes the user specified start and end dates
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="startDate">[out] Normalized start date</param>
 | 
						|
        /// <param name="endDate">[out] Normalized end date</param>
 | 
						|
        protected virtual void NormalizeDates(out DateTime startDate, out DateTime endDate)
 | 
						|
        {
 | 
						|
            startDate = this.StartDate;
 | 
						|
            endDate = this.EndDate;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region AllocateDayColumns
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Allocates out DayColumns
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="startDate"></param>
 | 
						|
        /// <param name="endDate"></param>
 | 
						|
        private void AllocateDayColumns(DateTime startDate, DateTime endDate)
 | 
						|
        {
 | 
						|
            // Allocate our DayColumns array to
 | 
						|
            // hold our info
 | 
						|
 | 
						|
            _NumberOfColumns = (endDate - startDate).Days + 1;
 | 
						|
            _NumberOfColumns = Math.Max(_NumberOfColumns, 1);
 | 
						|
            _NumberOfColumns = Math.Min(_NumberOfColumns, MaxNumberOfColumns);
 | 
						|
 | 
						|
            if (_DayColumns == null || _DayColumns.Length != _NumberOfColumns)
 | 
						|
                _DayColumns = new DayColumn[_NumberOfColumns];
 | 
						|
 | 
						|
            // Prepare to update display info on each time slot
 | 
						|
 | 
						|
            Rectangle r = ViewRect;
 | 
						|
            r.Y += _VScrollPos;
 | 
						|
 | 
						|
            // Loop through each day column
 | 
						|
 | 
						|
            float dcWidth = DayColumnWidth;
 | 
						|
            float x1 = r.X;
 | 
						|
 | 
						|
            // Update each DayColumn
 | 
						|
 | 
						|
            for (int i = 0; i < _NumberOfColumns; i++)
 | 
						|
            {
 | 
						|
                if (_DayColumns[i] == null)
 | 
						|
                    _DayColumns[i] = new DayColumn(0);
 | 
						|
 | 
						|
                _DayColumns[i].Date = startDate.AddDays(i);
 | 
						|
 | 
						|
                float x2 = (i == _NumberOfColumns - 1) ? r.Right - 1 : x1 + dcWidth;
 | 
						|
 | 
						|
                if (IsLayoutNeeded(i) == true)
 | 
						|
                    _DayColumns[i].Bounds = new Rectangle((int) x1, r.Y, (int) x2 - (int) x1, r.Height);
 | 
						|
 | 
						|
                x1 = x2;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region UpdateView
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Updates our connection model view
 | 
						|
        /// </summary>
 | 
						|
        private void UpdateView()
 | 
						|
        {
 | 
						|
            // If we have had a date range change, just
 | 
						|
            // reset our entire view
 | 
						|
 | 
						|
            if (DateRangeChanged == true)
 | 
						|
                ResetView();
 | 
						|
 | 
						|
            // If we have no Model connection, attempt
 | 
						|
            // to reconnect if this view is selected
 | 
						|
 | 
						|
            if (Connector == null)
 | 
						|
            {
 | 
						|
                if (CalendarModel != null)
 | 
						|
                {
 | 
						|
                    Connector = new ModelWeekDayViewConnector(CalendarModel, this);
 | 
						|
 | 
						|
                    SubItems.Insert(0, _AllDayPanel);
 | 
						|
                }
 | 
						|
            }
 | 
						|
       }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ResetView
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Disconnects and resets the Model connection
 | 
						|
        /// </summary>
 | 
						|
        internal override void ResetView()
 | 
						|
        {
 | 
						|
            _AllDayPanel.ResetView();
 | 
						|
 | 
						|
            base.ResetView();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region UpdateAllDayPanelItems
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Updates our AllDayPanel items
 | 
						|
        /// </summary>
 | 
						|
        private void UpdateAllDayPanelItems()
 | 
						|
        {
 | 
						|
            if (NeedRecalcLayout == true)
 | 
						|
            {
 | 
						|
                // Initiate a RecalcSize for the panel
 | 
						|
 | 
						|
                _AllDayPanel.WidthInternal = ClientRect.Width;
 | 
						|
                _AllDayPanel.HeightInternal = MaximumAllDayPanelHeight;
 | 
						|
 | 
						|
                _AllDayPanel.RecalcSize();
 | 
						|
 | 
						|
                // Set the panel's bounding rect accordingly
 | 
						|
 | 
						|
                Rectangle r = ClientRect;
 | 
						|
 | 
						|
                r.Width = _AllDayPanel.WidthInternal;
 | 
						|
 | 
						|
                r.Y += DayOfWeekHeaderHeight;
 | 
						|
                r.Height = _AllDayPanel.HeightInternal;
 | 
						|
 | 
						|
                _AllDayPanel.Bounds = r;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        private bool IsLayoutNeeded(int col)
 | 
						|
        {
 | 
						|
            return (NeedRecalcLayout == true ||
 | 
						|
                _DayColumns[col].NeedRecalcLayout == true);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region UpdateDayColumns
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Calculates and updates DayColumn bounds
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="startDate">Start date</param>
 | 
						|
        /// <param name="endDate">End date</param>
 | 
						|
        protected void UpdateDayColumns(DateTime startDate, DateTime endDate)
 | 
						|
        {
 | 
						|
            // Establish our current TimeSlice range
 | 
						|
 | 
						|
            GetTimeSliceData();
 | 
						|
 | 
						|
            // Updating display info on each column
 | 
						|
 | 
						|
            Rectangle r = ViewRect;
 | 
						|
 | 
						|
            r.Y += _VScrollPos;
 | 
						|
            r.Height = (int) (TimeSliceHeight * NumberOfSlices);
 | 
						|
 | 
						|
            for (int i = 0; i < _NumberOfColumns; i++)
 | 
						|
            {
 | 
						|
                _DayColumns[i].TimeSliceHeight = TimeSliceHeight;
 | 
						|
 | 
						|
                if (IsLayoutNeeded(i) == true)
 | 
						|
                {
 | 
						|
                    _DayColumns[i].Bounds = new
 | 
						|
                        Rectangle(_DayColumns[i].Bounds.X, r.Y, _DayColumns[i].Bounds.Width, r.Height);
 | 
						|
 | 
						|
                    InvalidateRect(_DayColumns[i].Bounds);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetTimeSliceData
 | 
						|
 | 
						|
        private void GetTimeSliceData()
 | 
						|
        {
 | 
						|
            _LocalStartSlice = 0;
 | 
						|
            _LocalNumberOfSlices = (HoursPerDay * MinutesPerHour) / TimeSlotDuration + 1;
 | 
						|
 | 
						|
            if (CalendarView.ShowOnlyWorkDayHours == true)
 | 
						|
            {
 | 
						|
                WorkTime startTime = new WorkTime(23, 59);
 | 
						|
                WorkTime endTime = new WorkTime(0, 0);
 | 
						|
 | 
						|
                for (int i = 0; i < NumberOfColumns; i++)
 | 
						|
                {
 | 
						|
                    DayColumn dc = _DayColumns[i];
 | 
						|
 | 
						|
                    if (dc.WorkStartTime.IsEmpty == false || dc.WorkEndTime.IsEmpty == false)
 | 
						|
                    {
 | 
						|
                        if (dc.WorkStartTime <= dc.WorkEndTime)
 | 
						|
                        {
 | 
						|
                            if (dc.WorkStartTime < startTime)
 | 
						|
                                startTime = dc.WorkStartTime;
 | 
						|
 | 
						|
                            if (dc.WorkEndTime > endTime)
 | 
						|
                                endTime = dc.WorkEndTime;
 | 
						|
                        }
 | 
						|
                        else
 | 
						|
                        {
 | 
						|
                            startTime = new WorkTime(0, 0);
 | 
						|
                            endTime = new WorkTime(23, 59);
 | 
						|
 | 
						|
                            break;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                if (endTime > startTime)
 | 
						|
                {
 | 
						|
                    int startMinutes = (startTime.Hour * MinutesPerHour) + startTime.Minute;
 | 
						|
                    int endMinutes = (endTime.Hour * MinutesPerHour) + endTime.Minute;
 | 
						|
 | 
						|
                    _LocalStartSlice = startMinutes / TimeSlotDuration;
 | 
						|
                    _LocalNumberOfSlices = (endMinutes - startMinutes) / TimeSlotDuration + 1;
 | 
						|
                }
 | 
						|
 | 
						|
                if (StartSlice >= 0)
 | 
						|
                {
 | 
						|
                    int endSlice = _LocalStartSlice + _LocalNumberOfSlices - 1;
 | 
						|
 | 
						|
                    if (_LocalStartSlice > StartSlice)
 | 
						|
                        _LocalStartSlice = StartSlice;
 | 
						|
 | 
						|
                    if (StartSlice + NumberOfSlices > endSlice)
 | 
						|
                        endSlice = StartSlice + NumberOfSlices - 1;
 | 
						|
 | 
						|
                    _LocalNumberOfSlices = endSlice - _LocalStartSlice + 1;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            StartSlice = _LocalStartSlice;
 | 
						|
            NumberOfSlices = _LocalNumberOfSlices;
 | 
						|
            
 | 
						|
            TimeSliceHeight = (float)ViewRect.Height / NumberOfActiveSlices;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region UpdateCalendarItems
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Updates our CalendarItems list
 | 
						|
        /// </summary>
 | 
						|
        private void UpdateCalendarItems()
 | 
						|
        {
 | 
						|
            List<ColumnList> list = new List<ColumnList>();
 | 
						|
 | 
						|
            for (int i = 0; i < _NumberOfColumns; i++)
 | 
						|
            {
 | 
						|
                if (IsLayoutNeeded(i) == true)
 | 
						|
                {
 | 
						|
                    if (_DayColumns[i].CalendarItems.Count > 0)
 | 
						|
                    {
 | 
						|
                        List<CalendarItem> items = SortCalendarItems(i);
 | 
						|
 | 
						|
                        list.Clear();
 | 
						|
 | 
						|
                        for (int j = 0; j < items.Count; j++)
 | 
						|
                        {
 | 
						|
                            ColumnList colList = GetColList(list, items[j]);
 | 
						|
 | 
						|
                            colList.AddColumnSlot(items[j], 0);
 | 
						|
                        }
 | 
						|
 | 
						|
                        foreach (ColumnList colList in list)
 | 
						|
                            colList.CountColumns();
 | 
						|
 | 
						|
                        CalcAppointmentBounds(i, list);
 | 
						|
                    }
 | 
						|
 | 
						|
                    _DayColumns[i].NeedRecalcLayout = false;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetColList
 | 
						|
 | 
						|
        private ColumnList GetColList(List<ColumnList> list, CalendarItem item)
 | 
						|
        {
 | 
						|
            int id = CalendarView.DoGetAppointmentGroupId(item, -1);
 | 
						|
 | 
						|
            int index;
 | 
						|
            if (GetColListIndex(list, id, out index) == true)
 | 
						|
                return (list[index]);
 | 
						|
 | 
						|
            ColumnList clist = new ColumnList(id);
 | 
						|
 | 
						|
            if (index < list.Count)
 | 
						|
                list.Insert(index, clist);
 | 
						|
            else
 | 
						|
                list.Add(clist);
 | 
						|
 | 
						|
            return (clist);
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetColListIndex
 | 
						|
 | 
						|
        private bool GetColListIndex(List<ColumnList> list, int id, out int index)
 | 
						|
        {
 | 
						|
            for (index=0; index < list.Count; index++)
 | 
						|
            {
 | 
						|
                ColumnList colList = list[index];
 | 
						|
 | 
						|
                if (colList.Id == id)
 | 
						|
                    return (true);
 | 
						|
 | 
						|
                if (colList.Id > id)
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
 | 
						|
            return (false);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SortCalendarItems
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Sorts the DayColumn CalendarItem list
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">DayColumn index</param>
 | 
						|
        private List<CalendarItem> SortCalendarItems(int col)
 | 
						|
        {
 | 
						|
            List<CalendarItem> items = new List<CalendarItem>();
 | 
						|
 | 
						|
            items.AddRange(_DayColumns[col].CalendarItems);
 | 
						|
 | 
						|
            if (items.Count > 0)
 | 
						|
            {
 | 
						|
                items.Sort(
 | 
						|
 | 
						|
                   delegate(CalendarItem c1, CalendarItem c2)
 | 
						|
                   {
 | 
						|
                       if (c1.StartTime > c2.StartTime)
 | 
						|
                           return (1);
 | 
						|
 | 
						|
                       if (c1.StartTime < c2.StartTime)
 | 
						|
                           return (-1);
 | 
						|
 | 
						|
                       if (c1.EndTime - c1.StartTime > c2.EndTime - c2.StartTime)
 | 
						|
                           return (1);
 | 
						|
 | 
						|
                       if (c1.EndTime - c1.StartTime < c2.EndTime - c2.StartTime)
 | 
						|
                           return (-1);
 | 
						|
 | 
						|
                       int result = 0;
 | 
						|
                       CalendarView.DoDetailSortEvent(this, c1, c2, ref result);
 | 
						|
 | 
						|
                       return (result);
 | 
						|
                   }
 | 
						|
               );
 | 
						|
            }
 | 
						|
 | 
						|
            return (items);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CalcAppointmentBounds
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Calculates normal appointment bounds
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">DayColumn column</param>
 | 
						|
        /// <param name="colList">Accumulated ColumnList</param>
 | 
						|
        private void CalcAppointmentBounds(int col, List<ColumnList> list)
 | 
						|
        {
 | 
						|
            Rectangle r = _DayColumns[col].Bounds;
 | 
						|
 | 
						|
            r.X++;
 | 
						|
            r.Width -= 8;
 | 
						|
 | 
						|
            for (int k = 0; k < list.Count; k++)
 | 
						|
            {
 | 
						|
                ColumnList colList = list[k];
 | 
						|
 | 
						|
                Rectangle r3 = r;
 | 
						|
                float dx3 = (float)r3.Width / list.Count;
 | 
						|
 | 
						|
                r3.X += (int)(dx3 * k);
 | 
						|
                r3.Width = (int)dx3;
 | 
						|
 | 
						|
                for (int i = 0; i < colList.SList.Count; i++)
 | 
						|
                {
 | 
						|
                    for (int j = 0; j < colList.SList[i].Count; j++)
 | 
						|
                    {
 | 
						|
                        Rectangle r2 = r3;
 | 
						|
                        SlotItem si = colList.SList[i][j];
 | 
						|
                        CalendarItem item = si.CItem;
 | 
						|
 | 
						|
                        float dx = (float)r2.Width / si.Count;
 | 
						|
                        r2.X += (int)(dx * i);
 | 
						|
 | 
						|
                        if (si.SList != null && si.SList.Count == 1)
 | 
						|
                            r2.Width = (int)(dx * (si.SList[0].Column - si.Column));
 | 
						|
 | 
						|
                        else if (si.SList == null)
 | 
						|
                            r2.Width = r3.Width - (r2.X - r3.X);
 | 
						|
 | 
						|
                        else
 | 
						|
                            r2.Width = (int)dx;
 | 
						|
 | 
						|
                        DateTime startTime = item.StartTime;
 | 
						|
 | 
						|
                        if (startTime.Date < _DayColumns[col].Date)
 | 
						|
                            startTime = _DayColumns[col].Date;
 | 
						|
 | 
						|
                        DateTime endTime = item.EndTime;
 | 
						|
 | 
						|
                        if (endTime > _DayColumns[col].Date.AddDays(1))
 | 
						|
                            endTime = _DayColumns[col].Date.AddDays(1);
 | 
						|
 | 
						|
                        DateTime date = startTime.Date;
 | 
						|
 | 
						|
                        TimeSpan ts1 = startTime.AddMinutes(-StartSlice * TimeSlotDuration) - date;
 | 
						|
                        TimeSpan ts2 = endTime - startTime;
 | 
						|
 | 
						|
                        int pos = (int)(ts1.TotalMinutes / TimeSlotDuration * TimeSliceHeight);
 | 
						|
                        int height = (int)Math.Round(ts2.TotalMinutes / TimeSlotDuration * TimeSliceHeight);
 | 
						|
 | 
						|
                        AppointmentView view = item as AppointmentView;
 | 
						|
 | 
						|
                        if (view != null)
 | 
						|
                        {
 | 
						|
                            Font font = view.Font ?? CalendarView.Font;
 | 
						|
 | 
						|
                            if (font != null)
 | 
						|
                                height = Math.Max(font.Height + 6, height);
 | 
						|
                        }
 | 
						|
 | 
						|
                        r2.Y = r.Y + (int)pos;
 | 
						|
                        r2.Height = height;
 | 
						|
 | 
						|
                        // Now that we have calculated the items height and
 | 
						|
                        // width, invoke a Recalc on the item
 | 
						|
 | 
						|
                        item.WidthInternal = r2.Width;
 | 
						|
                        item.HeightInternal = r2.Height - 1;
 | 
						|
 | 
						|
                        item.RecalcSize();
 | 
						|
 | 
						|
                        // Set our bounds for the item
 | 
						|
 | 
						|
                        r2.Width = item.WidthInternal;
 | 
						|
                        r2.Height = item.HeightInternal;
 | 
						|
 | 
						|
                        if (item.Bounds != r2)
 | 
						|
                        {
 | 
						|
                            InvalidateRect(item.Bounds);
 | 
						|
                            InvalidateRect(r2);
 | 
						|
                        }
 | 
						|
 | 
						|
                        item.Bounds = r2;
 | 
						|
 | 
						|
                        // Set it's display state
 | 
						|
 | 
						|
                        item.Displayed = r2.IntersectsWith(ClientRect);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Paint processing
 | 
						|
 | 
						|
        #region Root paint code
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Paint processing
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e">ItemPaintArgs</param>
 | 
						|
        public override void Paint(ItemPaintArgs e)
 | 
						|
        {
 | 
						|
            Graphics g = e.Graphics;
 | 
						|
 | 
						|
            // Set our current color table
 | 
						|
 | 
						|
            _ViewColor.SetColorTable();
 | 
						|
 | 
						|
            // Only draw something if we have something to draw
 | 
						|
 | 
						|
            if (_DayColumns != null)
 | 
						|
            {
 | 
						|
                // Calculate our drawing ranges
 | 
						|
 | 
						|
                int dayStart, dayEnd;
 | 
						|
                int sliceStart, sliceEnd;
 | 
						|
 | 
						|
                int dayCount = GetDayRange(e, out dayStart, out dayEnd);
 | 
						|
                int sliceCount = GetSliceRange(e, out sliceStart, out sliceEnd);
 | 
						|
 | 
						|
                // Draw our calendar parts
 | 
						|
 | 
						|
                if (dayCount > 0)
 | 
						|
                    DrawDayOfTheWeekHeader(e, dayStart, dayEnd);
 | 
						|
 | 
						|
                if (sliceCount > 0 && dayCount > 0)
 | 
						|
                {
 | 
						|
                    // Set our clipping region
 | 
						|
 | 
						|
                    Rectangle r = ViewRect;
 | 
						|
 | 
						|
                    r.X = ClientRect.X;
 | 
						|
                    r.Width = ClientRect.Width;
 | 
						|
 | 
						|
                    Region regSave = g.Clip;
 | 
						|
                    g.SetClip(r, CombineMode.Intersect);
 | 
						|
 | 
						|
                    // Draw our slices and appointments
 | 
						|
 | 
						|
                    DrawSlices(e, sliceStart, sliceEnd, dayStart, dayEnd);
 | 
						|
                    DrawTimeIndicators(g, sliceStart, sliceEnd, eTimeIndicatorLevel.Bottom);
 | 
						|
 | 
						|
                    if (Connector != null && Connector.IsConnected)
 | 
						|
                        DrawWeekAppointments(e, dayStart, dayEnd);
 | 
						|
 | 
						|
                    DrawTimeIndicators(g, sliceStart, sliceEnd, eTimeIndicatorLevel.Top);
 | 
						|
 | 
						|
                    // Restore our original clip region
 | 
						|
 | 
						|
                    g.Clip = regSave;
 | 
						|
                }
 | 
						|
 | 
						|
                // Initiate the painting of our AllDay Panel
 | 
						|
 | 
						|
                _AllDayPanel.Paint(e);
 | 
						|
 | 
						|
                // Update our Alt-Key window
 | 
						|
 | 
						|
                UpdatePosWin(ViewRect);
 | 
						|
            }
 | 
						|
 | 
						|
            // Let the base painting take place
 | 
						|
 | 
						|
            base.Paint(e);
 | 
						|
        }
 | 
						|
 | 
						|
        #region Clip range routines
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Calculates the range of days needed to be drawn
 | 
						|
        /// to satisfy the specified paint request
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e">ItemPaintArgs</param>
 | 
						|
        /// <param name="dayStart">[out] Day start index</param>
 | 
						|
        /// <param name="dayEnd">[out] Day end index</param>
 | 
						|
        /// <returns>Day range count (end - start)</returns>
 | 
						|
        private int GetDayRange(ItemPaintArgs e, out int dayStart, out int dayEnd)
 | 
						|
        {
 | 
						|
            // Calc our starting index
 | 
						|
 | 
						|
            int start = 0;
 | 
						|
 | 
						|
            while (start < _NumberOfColumns)
 | 
						|
            {
 | 
						|
                if (_DayColumns[start].Bounds.Right > e.ClipRectangle.X)
 | 
						|
                    break;
 | 
						|
 | 
						|
                start++;
 | 
						|
            }
 | 
						|
 | 
						|
            // Calc our ending index
 | 
						|
 | 
						|
            int end = start;
 | 
						|
 | 
						|
            while (end < _NumberOfColumns)
 | 
						|
            {
 | 
						|
                if (_DayColumns[end].Bounds.X >= e.ClipRectangle.Right)
 | 
						|
                    break;
 | 
						|
 | 
						|
                end++;
 | 
						|
            }
 | 
						|
 | 
						|
            // Set the user supplied 'out' values, and
 | 
						|
            // return the range count to the caller
 | 
						|
 | 
						|
            if (end - start == 0)
 | 
						|
            {
 | 
						|
                dayStart = 0;
 | 
						|
                dayEnd = 0;
 | 
						|
 | 
						|
                return (0);
 | 
						|
            }
 | 
						|
 | 
						|
            dayStart = start;
 | 
						|
            dayEnd = end - 1;
 | 
						|
 | 
						|
            return (end - start);
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Calculates the range of slices needed to be drawn
 | 
						|
        /// to satisfy the specified paint request
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e">ItemPaintArgs</param>
 | 
						|
        /// <param name="sliceStart">[out] Slice start index</param>
 | 
						|
        /// <param name="sliceEnd">[out] Slice end index</param>
 | 
						|
        /// <returns>Slice range count (end - start)</returns>
 | 
						|
        internal int GetSliceRange(ItemPaintArgs e, out int sliceStart, out int sliceEnd)
 | 
						|
        {
 | 
						|
            // Calc our starting index
 | 
						|
 | 
						|
            int start = 0;
 | 
						|
 | 
						|
            Rectangle v = ViewRect;
 | 
						|
 | 
						|
            while (start < NumberOfSlices)
 | 
						|
            {
 | 
						|
                Rectangle r = GetSliceRect(0, start);
 | 
						|
 | 
						|
                if (r.Bottom > v.Top)
 | 
						|
                {
 | 
						|
                    if (r.Bottom > e.ClipRectangle.Y)
 | 
						|
                        break;
 | 
						|
                }
 | 
						|
 | 
						|
                start++;
 | 
						|
            }
 | 
						|
 | 
						|
            // Calc our ending index
 | 
						|
 | 
						|
            int end = start;
 | 
						|
 | 
						|
            while (end < NumberOfSlices)
 | 
						|
            {
 | 
						|
                Rectangle r = GetSliceRect(0, end);
 | 
						|
 | 
						|
                if (r.Y >= e.ClipRectangle.Bottom)
 | 
						|
                    break;
 | 
						|
 | 
						|
                end++;
 | 
						|
            }
 | 
						|
 | 
						|
            // Set the user supplied 'out' values, and
 | 
						|
            // return the range count to the caller
 | 
						|
 | 
						|
            if (end - start == 0)
 | 
						|
            {
 | 
						|
                sliceStart = 0;
 | 
						|
                sliceEnd = 0;
 | 
						|
 | 
						|
                return (0);
 | 
						|
            }
 | 
						|
 | 
						|
            sliceStart = start;
 | 
						|
            sliceEnd = end - 1;
 | 
						|
 | 
						|
            return (end - start);
 | 
						|
        }
 | 
						|
 | 
						|
        private bool SliceIsSelected(int col, int slice)
 | 
						|
        {
 | 
						|
            int nslice = col * NumberOfActiveSlices + slice;
 | 
						|
 | 
						|
            return (nslice >= _SelectedSliceStart && nslice < _SelectedSliceEnd);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DayOfTheWeek header drawing
 | 
						|
 | 
						|
        #region DrawDayOfTheWeekHeader
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws the top Day of the week header
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e">ItemPaintArgs</param>
 | 
						|
        /// <param name="dayStart">Start day index</param>
 | 
						|
        /// <param name="dayEnd">End day index</param>
 | 
						|
        private void DrawDayOfTheWeekHeader(ItemPaintArgs e, int dayStart, int dayEnd)
 | 
						|
        {
 | 
						|
            Graphics g = e.Graphics;
 | 
						|
 | 
						|
            Rectangle r = new Rectangle(
 | 
						|
                _DayColumns[dayStart].Bounds.X, ClientRect.Y,
 | 
						|
                _DayColumns[dayEnd].Bounds.Right -
 | 
						|
                _DayColumns[dayStart].Bounds.X, DayOfWeekHeaderHeight);
 | 
						|
 | 
						|
            if (r.Width > 0 && r.Height > 0)
 | 
						|
            {
 | 
						|
                // Establish our Days Of The Week text type
 | 
						|
 | 
						|
                DaysOfTheWeek.eDayType type = GetDaysOfTheWeekType(g);
 | 
						|
 | 
						|
                // Loop through each day, drawing the
 | 
						|
                // day of the week text in the header area
 | 
						|
 | 
						|
                int nowHeader = -1;
 | 
						|
 | 
						|
                using (Brush br =
 | 
						|
                    _ViewColor.BrushPart((int) eCalendarWeekDayPart.DayHeaderBackground, r))
 | 
						|
                {
 | 
						|
                    using (Pen pen = new Pen(
 | 
						|
                        _ViewColor.GetColor((int) eCalendarWeekDayPart.DayHeaderBorder)))
 | 
						|
                    {
 | 
						|
                        for (int i = dayStart; i <= dayEnd; i++)
 | 
						|
                        {
 | 
						|
                            if (CalendarView.HighlightCurrentDay == true &&
 | 
						|
                                _DayColumns[i].Date.Date.Equals(DateTime.Now.Date))
 | 
						|
                            {
 | 
						|
                                nowHeader = i;
 | 
						|
                                continue;
 | 
						|
                            }
 | 
						|
 | 
						|
                            DrawColumnHeader(g, i, type, r, br, pen, eCalendarWeekDayPart.DayHeaderForeground);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                // Draw the current "Now" header
 | 
						|
 | 
						|
                if (nowHeader >= 0)
 | 
						|
                {
 | 
						|
                    using (Brush br =
 | 
						|
                        _ViewColor.BrushPart((int) eCalendarWeekDayPart.NowDayHeaderBackground, r))
 | 
						|
                    {
 | 
						|
                        using (Pen pen = new Pen(
 | 
						|
                            _ViewColor.GetColor((int) eCalendarWeekDayPart.NowDayHeaderBorder)))
 | 
						|
                        {
 | 
						|
                            DrawColumnHeader(g, nowHeader, type, r, br, pen, eCalendarWeekDayPart.NowDayHeaderForeground);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region DrawColumnHeader
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// DrawColumnHeader
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="i"></param>
 | 
						|
        /// <param name="type"></param>
 | 
						|
        /// <param name="r"></param>
 | 
						|
        /// <param name="br"></param>
 | 
						|
        /// <param name="pen"></param>
 | 
						|
        /// <param name="part"></param>
 | 
						|
        private void DrawColumnHeader(Graphics g, int i,
 | 
						|
            DaysOfTheWeek.eDayType type, Rectangle r, Brush br, Pen pen, eCalendarWeekDayPart part)
 | 
						|
        {
 | 
						|
            r.X = _DayColumns[i].Bounds.X;
 | 
						|
            r.Width = _DayColumns[i].Bounds.Width;
 | 
						|
 | 
						|
            g.FillRectangle(br, r);
 | 
						|
            g.DrawRectangle(pen, r);
 | 
						|
 | 
						|
            Rectangle t = r;
 | 
						|
 | 
						|
            if (CalendarView.DoPreRenderWeekDayHeader(g, this, i, t) == false)
 | 
						|
            {
 | 
						|
                // Draw the header text
 | 
						|
 | 
						|
                int n = i % DaysInWeek;
 | 
						|
 | 
						|
                eTextFormat tf = eTextFormat.VerticalCenter | eTextFormat.NoPadding;
 | 
						|
 | 
						|
                r.Inflate(-2, 0);
 | 
						|
                r.X += 1;
 | 
						|
 | 
						|
                TextDrawing.DrawString(g,
 | 
						|
                                       _DayColumns[i].Date.Day.ToString(), BoldFont, Color.Black, r, tf);
 | 
						|
 | 
						|
                r.X += _DayColumnSize[n].Width;
 | 
						|
                r.Width -= _DayColumnSize[n].Width;
 | 
						|
 | 
						|
                if (type != DaysOfTheWeek.eDayType.None)
 | 
						|
                {
 | 
						|
                    tf |= eTextFormat.HorizontalCenter;
 | 
						|
 | 
						|
                    TextDrawing.DrawString(g, DaysOfTheWeek.DayText[(int) type][n],
 | 
						|
                                           Font, _ViewColor.GetColor((int) part), r, tf);
 | 
						|
                }
 | 
						|
 | 
						|
                CalendarView.DoPostRenderWeekDayHeader(g, this, i, t);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDaysOfTheWeekType
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Get the index for our day of the week text
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g">Graphics handle</param>
 | 
						|
        /// <returns>Index to header text</returns>
 | 
						|
        private DaysOfTheWeek.eDayType GetDaysOfTheWeekType(Graphics g)
 | 
						|
        {
 | 
						|
            // Resize our DayColumn day text if it
 | 
						|
            // hasn't been resized previously
 | 
						|
 | 
						|
            if (_DayColumnSize == null)
 | 
						|
            {
 | 
						|
                _DayColumnSize = new Size[_NumberOfColumns];
 | 
						|
 | 
						|
                for (int i = 0; i < _NumberOfColumns; i++)
 | 
						|
                {
 | 
						|
                    _DayColumnSize[i] = TextDrawing.MeasureString(g,
 | 
						|
                        _DayColumns[i].Date.Day.ToString(), BoldFont, 0, eTextFormat.NoPadding);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            // Determine if the current DayRect bounds
 | 
						|
            // are constrained by the text threshold
 | 
						|
 | 
						|
            DaysOfTheWeek.MeasureText(g, Font);
 | 
						|
 | 
						|
            for (int i = 0; i < _NumberOfColumns; i++)
 | 
						|
            {
 | 
						|
                if (_DayColumns[i].Bounds.Width <
 | 
						|
                    _DayColumnSize[i].Width + DaysOfTheWeek.DaySize[(int)DaysOfTheWeek.eDayType.Short][i % 7].Width)
 | 
						|
                {
 | 
						|
                    return (DaysOfTheWeek.eDayType.None);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            for (int i = 0; i < _NumberOfColumns; i++)
 | 
						|
            {
 | 
						|
                if (_DayColumns[i].Bounds.Width <
 | 
						|
                    _DayColumnSize[i].Width + DaysOfTheWeek.DaySize[(int)DaysOfTheWeek.eDayType.Long][i % 7].Width)
 | 
						|
                {
 | 
						|
                    return (DaysOfTheWeek.eDayType.Short);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (DaysOfTheWeek.eDayType.Long);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawSlices
 | 
						|
 | 
						|
        #region DrawSlices
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws Normal Appointment time slices
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e">ItemPaintArgs</param>
 | 
						|
        /// <param name="sliceStart">Start slice</param>
 | 
						|
        /// <param name="sliceEnd">End slice</param>
 | 
						|
        /// <param name="dayStart">Day start</param>
 | 
						|
        /// <param name="dayEnd">Day end</param>
 | 
						|
        private void DrawSlices(ItemPaintArgs e,
 | 
						|
            int sliceStart, int sliceEnd, int dayStart, int dayEnd)
 | 
						|
        {
 | 
						|
            Graphics g = e.Graphics;
 | 
						|
 | 
						|
            DaySlot[,] daySlots = GetDaySlots(sliceStart, sliceEnd, dayStart, dayEnd);
 | 
						|
 | 
						|
            DrawContent(g, sliceStart, sliceEnd, dayStart, dayEnd, daySlots);
 | 
						|
            DrawDaySlot(g, sliceStart, sliceEnd, dayStart, dayEnd, daySlots, false);
 | 
						|
 | 
						|
            DrawBorders(g, sliceStart, sliceEnd, dayStart, dayEnd, daySlots);
 | 
						|
            DrawDaySlot(g, sliceStart, sliceEnd, dayStart, dayEnd, daySlots, true);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDaySlots
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the array of DaySlot information
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sliceStart"></param>
 | 
						|
        /// <param name="sliceEnd"></param>
 | 
						|
        /// <param name="dayStart"></param>
 | 
						|
        /// <param name="dayEnd"></param>
 | 
						|
        /// <returns>array of DaySlots</returns>
 | 
						|
        private DaySlot[,] GetDaySlots(int sliceStart, int sliceEnd, int dayStart, int dayEnd)
 | 
						|
        {
 | 
						|
            DaySlot[,] daySlots = new DaySlot[dayEnd - dayStart + 1, sliceEnd - sliceStart + 1];
 | 
						|
 | 
						|
            for (int i = dayStart; i <= dayEnd; i++)
 | 
						|
            {
 | 
						|
                for (int j = sliceStart; j <= sliceEnd; j++)
 | 
						|
                {
 | 
						|
                    DaySlot daySlot = new DaySlot();
 | 
						|
 | 
						|
                    daySlots[i - dayStart, j - sliceStart] = daySlot;
 | 
						|
 | 
						|
                    daySlot.Bounds = GetSliceRect(i, j);
 | 
						|
                    daySlot.Selected = SliceIsSelected(i, j);
 | 
						|
 | 
						|
                    if (j <= sliceEnd &&
 | 
						|
                        CalendarView.HasViewDisplayCustomizations == true)
 | 
						|
                    {
 | 
						|
                        int start = ((StartSlice + j) * TimeSlotDuration) % 1440;
 | 
						|
                        int end = Math.Min(start + TimeSlotDuration, 1439);
 | 
						|
 | 
						|
                        WorkTime wkStart = new WorkTime(start / MinutesPerHour, start % MinutesPerHour);
 | 
						|
                        WorkTime wkEnd = new WorkTime(end / MinutesPerHour, end % MinutesPerHour);
 | 
						|
 | 
						|
                        daySlot.Appearance = CalendarView.ViewDisplayCustomizations.GetDaySlotAppearance(
 | 
						|
                            OwnerKey, _DayColumns[i].Date, wkStart, wkEnd);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (daySlots);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawContent
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Time slice content drawing
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g">Graphics</param>
 | 
						|
        /// <param name="sliceStart">Start slice</param>
 | 
						|
        /// <param name="sliceEnd">End slice</param>
 | 
						|
        /// <param name="dayStart">Day start</param>
 | 
						|
        /// <param name="dayEnd">Day end</param>
 | 
						|
        /// <param name="daySlots"></param>
 | 
						|
        private void DrawContent(Graphics g,
 | 
						|
            int sliceStart, int sliceEnd, int dayStart, int dayEnd, DaySlot[,] daySlots)
 | 
						|
        {
 | 
						|
            // Loop through each day in each week, displaying
 | 
						|
            // the associated day content
 | 
						|
 | 
						|
            for (int i = dayStart; i <= dayEnd; i++)
 | 
						|
            {
 | 
						|
                for (int j = sliceStart; j <= sliceEnd; j++)
 | 
						|
                {
 | 
						|
                    DaySlot daySlot = daySlots[i - dayStart, j - sliceStart];
 | 
						|
                    DaySlotAppearance dsa = daySlot.Appearance;
 | 
						|
 | 
						|
                    if (CalendarView.DoPreRenderWeekDaySlotBackground(g, this, i, j, daySlot.Bounds) == false)
 | 
						|
                    {
 | 
						|
                        if (dsa != null && daySlot.Selected == false)
 | 
						|
                        {
 | 
						|
                            using (Brush br = new SolidBrush(dsa.BackColor))
 | 
						|
                                g.FillRectangle(br, daySlot.Bounds);
 | 
						|
 | 
						|
                            continue;
 | 
						|
                        }
 | 
						|
 | 
						|
                        g.FillRectangle(GetContentBrush(daySlot, i, j), daySlot.Bounds);
 | 
						|
                    }
 | 
						|
 | 
						|
                    CalendarView.DoPostRenderWeekDaySlotBackground(g, this, i, j, daySlot.Bounds);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetContentBrush
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the background content brush
 | 
						|
        /// for the given time slice
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="daySlot"></param>
 | 
						|
        /// <param name="col">Column index</param>
 | 
						|
        /// <param name="slice">Time slice</param>
 | 
						|
        /// <returns>Background brush</returns>
 | 
						|
        private Brush GetContentBrush(DaySlot daySlot, int col, int slice)
 | 
						|
        {
 | 
						|
            int start = (StartSlice + slice) * TimeSlotDuration;
 | 
						|
 | 
						|
            if (slice < NumberOfActiveSlices)
 | 
						|
            {
 | 
						|
                if (daySlot.Selected == true)
 | 
						|
                    return (SelectedBrush);
 | 
						|
 | 
						|
                WorkTime wkStart = new
 | 
						|
                    WorkTime(start / MinutesPerHour, start % MinutesPerHour);
 | 
						|
 | 
						|
                if (_DayColumns[col].IsWorkTime(wkStart) == true)
 | 
						|
                    return (WorkBrush);
 | 
						|
 | 
						|
                if (_DayColumns[col].IsBusyTime(wkStart) == true)
 | 
						|
                    return (BusyBrush);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                return (AllDayBrush);
 | 
						|
            }
 | 
						|
 | 
						|
            return (OffWorkBrush);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawDaySlot
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Initiates DaySlot drawing
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="sliceStart"></param>
 | 
						|
        /// <param name="sliceEnd"></param>
 | 
						|
        /// <param name="dayStart"></param>
 | 
						|
        /// <param name="dayEnd"></param>
 | 
						|
        /// <param name="daySlots"></param>
 | 
						|
        /// <param name="onTop">On top of borders</param>
 | 
						|
        private void DrawDaySlot(Graphics g, int sliceStart,
 | 
						|
            int sliceEnd, int dayStart, int dayEnd, DaySlot[,] daySlots, bool onTop)
 | 
						|
        {
 | 
						|
            List<DaySlotAppearance> dsaList = null;
 | 
						|
            Rectangle dRect = Rectangle.Empty;
 | 
						|
 | 
						|
            for (int i = dayStart; i <= dayEnd; i++)
 | 
						|
            {
 | 
						|
                DaySlot lastDaySlot = null;
 | 
						|
 | 
						|
                for (int j = sliceStart; j <= sliceEnd; j++)
 | 
						|
                {
 | 
						|
                    DaySlot daySlot = daySlots[i - dayStart, j - sliceStart];
 | 
						|
 | 
						|
                    Rectangle r = daySlot.Bounds;
 | 
						|
                    DaySlotAppearance dsa = daySlot.Appearance;
 | 
						|
 | 
						|
                    if (lastDaySlot != null &&
 | 
						|
                        (lastDaySlot.Appearance != dsa || lastDaySlot.Selected != daySlot.Selected))
 | 
						|
                    {
 | 
						|
                        FlushDaySlotText(g, i, dsaList, ref dRect, lastDaySlot.Selected);
 | 
						|
                    }
 | 
						|
 | 
						|
                    lastDaySlot = daySlot;
 | 
						|
 | 
						|
                    if (dsa != null)
 | 
						|
                    {
 | 
						|
                        if (dsa.OnTop == onTop)
 | 
						|
                        {
 | 
						|
                           if (daySlot.Selected == true)
 | 
						|
                           {
 | 
						|
                               if (dsa.ShowTextWhenSelected == true)
 | 
						|
                                   dRect = dRect.IsEmpty ? r : Rectangle.Union(dRect, r);
 | 
						|
                           }
 | 
						|
                           else
 | 
						|
                           {
 | 
						|
                               dRect = dRect.IsEmpty ? r : Rectangle.Union(dRect, r);
 | 
						|
                           }
 | 
						|
 | 
						|
                           if (dsaList == null)
 | 
						|
                                dsaList = new List<DaySlotAppearance>();
 | 
						|
 | 
						|
                            if (dsaList.Contains(dsa) == false)
 | 
						|
                                dsaList.Add(dsa);
 | 
						|
                        }
 | 
						|
 | 
						|
                        continue;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                if (lastDaySlot != null)
 | 
						|
                    FlushDaySlotText(g, i, dsaList, ref dRect, lastDaySlot.Selected);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region FlushDaySlotText
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Flushes out pending DaySlot drawing
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="dayCol"></param>
 | 
						|
        /// <param name="dsaList"></param>
 | 
						|
        /// <param name="dRect">Display rect</param>
 | 
						|
        /// <param name="selected"></param>
 | 
						|
        private void FlushDaySlotText(Graphics g,
 | 
						|
            int dayCol, List<DaySlotAppearance> dsaList, ref Rectangle dRect, bool selected)
 | 
						|
        {
 | 
						|
            if (dsaList != null && dsaList.Count > 0)
 | 
						|
            {
 | 
						|
                if (dRect.IsEmpty == false)
 | 
						|
                    DrawDaySlotText(g, dayCol, dsaList, dRect, selected);
 | 
						|
 | 
						|
                dsaList.Clear();
 | 
						|
 | 
						|
                dRect = Rectangle.Empty;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawDaySlotText
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws the DaySlot Text
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="dayCol"></param>
 | 
						|
        /// <param name="dsaList"></param>
 | 
						|
        /// <param name="cRect"></param>
 | 
						|
        /// <param name="selected"></param>
 | 
						|
        private void DrawDaySlotText(Graphics g,
 | 
						|
            int dayCol, IEnumerable<DaySlotAppearance> dsaList, Rectangle cRect, bool selected)
 | 
						|
        {
 | 
						|
            foreach (DaySlotAppearance dsa in dsaList)
 | 
						|
            {
 | 
						|
                DateTime startTime = GetSlotTime(dayCol, dsa.StartTime);
 | 
						|
                DateTime endTime = GetSlotTime(dayCol, dsa.EndTime);
 | 
						|
 | 
						|
                DateTime e = endTime.AddMinutes(-1);
 | 
						|
                WorkTime wkEnd = new WorkTime(e.Hour, e.Minute);
 | 
						|
 | 
						|
                int start = GetWorkTimeSlice(dsa.StartTime);
 | 
						|
                int end = GetWorkTimeSlice(wkEnd);
 | 
						|
 | 
						|
                Rectangle r = GetSliceRect(dayCol, start);
 | 
						|
                r = Rectangle.Union(r, GetSliceRect(dayCol, end));
 | 
						|
 | 
						|
                Region rgnSave = g.Clip;
 | 
						|
                g.SetClip(cRect, CombineMode.Intersect);
 | 
						|
 | 
						|
                string text = dsa.Text;
 | 
						|
 | 
						|
                if (CalendarView.DoRenderDaySlotAppearanceText(g,
 | 
						|
                    r, dsa, startTime, endTime, selected, ref text) == false)
 | 
						|
                {
 | 
						|
                    if (String.IsNullOrEmpty(dsa.Text) == false)
 | 
						|
                    {
 | 
						|
                        eTextFormat tf = GetTextFormat(dsa.TextAlignment);
 | 
						|
 | 
						|
                        Font font = dsa.Font ?? Font;
 | 
						|
 | 
						|
                        Color color = (selected == true)
 | 
						|
                                          ? (dsa.SelectedTextColor.IsEmpty ? Color.Black : dsa.SelectedTextColor)
 | 
						|
                                          : (dsa.TextColor.IsEmpty ? Color.Black : dsa.TextColor);
 | 
						|
 | 
						|
                        TextDrawing.DrawString(g, text, font, color, r, tf);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                g.Clip = rgnSave;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetSlotTime
 | 
						|
 | 
						|
        private DateTime GetSlotTime(int dayCol, WorkTime wkTime)
 | 
						|
        {
 | 
						|
            DateTime time = _DayColumns[dayCol].Date;
 | 
						|
 | 
						|
            time = time.AddHours(wkTime.Hour);
 | 
						|
            time = time.AddMinutes(wkTime.Minute);
 | 
						|
 | 
						|
            return (time);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetWorkTimeSlice
 | 
						|
 | 
						|
        private int GetWorkTimeSlice(WorkTime wkTime)
 | 
						|
        {
 | 
						|
            int slice = ((wkTime.Hour * MinutesPerHour) +
 | 
						|
                wkTime.Minute) / TimeSlotDuration;
 | 
						|
 | 
						|
            return (slice - StartSlice);
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetTextFormat
 | 
						|
 | 
						|
        private eTextFormat GetTextFormat(ContentAlignment alignment)
 | 
						|
        {
 | 
						|
            eTextFormat tf = eTextFormat.WordBreak;
 | 
						|
 | 
						|
            switch (alignment)
 | 
						|
            {
 | 
						|
                case ContentAlignment.TopLeft:
 | 
						|
                    tf |= eTextFormat.Top | eTextFormat.Left;
 | 
						|
                    break;
 | 
						|
 | 
						|
                case ContentAlignment.TopCenter:
 | 
						|
                    tf |= eTextFormat.Top | eTextFormat.HorizontalCenter;
 | 
						|
                    break;
 | 
						|
 | 
						|
                case ContentAlignment.TopRight:
 | 
						|
                    tf |= eTextFormat.Top | eTextFormat.Right;
 | 
						|
                    break;
 | 
						|
 | 
						|
                case ContentAlignment.MiddleLeft:
 | 
						|
                    tf |= eTextFormat.VerticalCenter | eTextFormat.Left;
 | 
						|
                    break;
 | 
						|
 | 
						|
                case ContentAlignment.MiddleCenter:
 | 
						|
                    tf |= eTextFormat.VerticalCenter | eTextFormat.HorizontalCenter;
 | 
						|
                    break;
 | 
						|
 | 
						|
                case ContentAlignment.MiddleRight:
 | 
						|
                    tf |= eTextFormat.VerticalCenter | eTextFormat.Right;
 | 
						|
                    break;
 | 
						|
 | 
						|
                case ContentAlignment.BottomLeft:
 | 
						|
                    tf |= eTextFormat.Bottom | eTextFormat.Left;
 | 
						|
                    break;
 | 
						|
 | 
						|
                case ContentAlignment.BottomCenter:
 | 
						|
                    tf |= eTextFormat.Bottom | eTextFormat.HorizontalCenter;
 | 
						|
                    break;
 | 
						|
 | 
						|
                case ContentAlignment.BottomRight:
 | 
						|
                    tf |= eTextFormat.Bottom | eTextFormat.Right;
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
 | 
						|
            return (tf);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawTimeIndicators
 | 
						|
 | 
						|
        #region DrawTimeIndicators
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draw view TimeIndicators
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="sliceStart"></param>
 | 
						|
        /// <param name="sliceEnd"></param>
 | 
						|
        private void DrawTimeIndicators(Graphics g, 
 | 
						|
            int sliceStart, int sliceEnd, eTimeIndicatorLevel level)
 | 
						|
        {
 | 
						|
            DateTime start = _DayColumns[0].Date;
 | 
						|
            DateTime end = _DayColumns[_NumberOfColumns - 1].Date.AddDays(1);
 | 
						|
            Rectangle r = Rectangle.Union(GetSliceRect(0, sliceStart), GetSliceRect(0, sliceEnd));
 | 
						|
 | 
						|
            for (int i = 0; i < CalendarView.TimeIndicators.Count; i++)
 | 
						|
            {
 | 
						|
                TimeIndicator ti = CalendarView.TimeIndicators[i];
 | 
						|
 | 
						|
                if (ti.IndicatorLevel == level)
 | 
						|
                {
 | 
						|
                    if (ti.IndicatorArea == eTimeIndicatorArea.All ||
 | 
						|
                        ti.IndicatorArea == eTimeIndicatorArea.Content)
 | 
						|
                    {
 | 
						|
                        if (ti.IsVisible(CalendarView, this))
 | 
						|
                        {
 | 
						|
                            DateTime time = ti.IndicatorDisplayTime;
 | 
						|
 | 
						|
                            if (time >= start && time < end)
 | 
						|
                                DrawTimeIndicator(g, r, ti);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawTimeIndicator
 | 
						|
 | 
						|
        #region DrawTimeIndicator
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws individual view TimeIndicator
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="sRect"></param>
 | 
						|
        /// <param name="ti"></param>
 | 
						|
        private void DrawTimeIndicator(Graphics g, Rectangle sRect, TimeIndicator ti)
 | 
						|
        {
 | 
						|
            Rectangle r = GetIndicatorRect(ti);
 | 
						|
 | 
						|
            if (r.IntersectsWith(sRect) == true)
 | 
						|
            {
 | 
						|
                if (r.Height > 0)
 | 
						|
                {
 | 
						|
                    ColorDef cdef = GetIndicatorColor(ti);
 | 
						|
 | 
						|
                    if (cdef != null)
 | 
						|
                    {
 | 
						|
                        using (Brush br = _ViewColor.BrushPart(cdef, r))
 | 
						|
                        {
 | 
						|
                            if (br is LinearGradientBrush)
 | 
						|
                                ((LinearGradientBrush) br).WrapMode = WrapMode.TileFlipX;
 | 
						|
 | 
						|
                            g.FillRectangle(br, r);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                Color color = GetIndicatorBorder(ti);
 | 
						|
 | 
						|
                if (color.IsEmpty == false)
 | 
						|
                {
 | 
						|
                    using (Pen pen = new Pen(color))
 | 
						|
                        g.DrawLine(pen, r.X + 1, r.Bottom, r.Right - 1, r.Bottom);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetIndicatorRect
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the TimeIndicator rectangle
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="ti"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        internal override Rectangle GetIndicatorRect(TimeIndicator ti)
 | 
						|
        {
 | 
						|
            return (GetIndicatorRect(ti, ti.IndicatorDisplayTime));
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the TimeIndicator rectangle for the
 | 
						|
        /// given DataTime
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="ti"></param>
 | 
						|
        /// <param name="time"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        internal override Rectangle GetIndicatorRect(TimeIndicator ti, DateTime time)
 | 
						|
        {
 | 
						|
            DateTime startTime = GetTime(_DayColumns[0].Date, 0, 0);
 | 
						|
            DateTime endTime = GetTime(_DayColumns[NumberOfColumns - 1].Date, NumberOfActiveSlices, 0);
 | 
						|
 | 
						|
            if (time >= startTime && time < endTime)
 | 
						|
            {
 | 
						|
                int offset = (int) (time.Hour * SlotsPerHour * TimeSliceHeight +
 | 
						|
                                    (TimeSliceHeight * time.Minute) / TimeSlotDuration);
 | 
						|
 | 
						|
                offset -= (int) (StartSlice * TimeSliceHeight);
 | 
						|
 | 
						|
                Rectangle r = ViewRect;
 | 
						|
                r.Width -= 1;
 | 
						|
 | 
						|
                r.Y = _DayColumns[0].Bounds.Y + offset - ti.Thickness;
 | 
						|
                r.Height = ti.Thickness;
 | 
						|
 | 
						|
                return (r);
 | 
						|
            }
 | 
						|
 | 
						|
            return (Rectangle.Empty);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetIndicatorColor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the Indicator Back color
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="ti"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        private ColorDef GetIndicatorColor(TimeIndicator ti)
 | 
						|
        {
 | 
						|
            ColorDef cdef = ti.IndicatorColor;
 | 
						|
 | 
						|
            if (cdef == null || cdef.IsEmpty == true)
 | 
						|
                cdef = _ViewColor.GetColorDef((int)eCalendarWeekDayPart.TimeIndicator);
 | 
						|
 | 
						|
            return (cdef);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetIndicatorBorder
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the Indicator Border color
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="ti"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        private Color GetIndicatorBorder(TimeIndicator ti)
 | 
						|
        {
 | 
						|
            return (ti.BorderColor.IsEmpty == false ? ti.BorderColor :
 | 
						|
                _ViewColor.GetColor((int)eCalendarWeekDayPart.TimeIndicatorBorder));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawBorders
 | 
						|
 | 
						|
        #region DrawBorders
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws time slice borders
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g">Graphics</param>
 | 
						|
        /// <param name="sliceStart">Start slice</param>
 | 
						|
        /// <param name="sliceEnd">End slice</param>
 | 
						|
        /// <param name="dayStart">Day start</param>
 | 
						|
        /// <param name="dayEnd">Day end</param>
 | 
						|
        /// <param name="daySlots"></param>
 | 
						|
        private void DrawBorders(Graphics g,
 | 
						|
            int sliceStart, int sliceEnd, int dayStart, int dayEnd, DaySlot[,] daySlots)
 | 
						|
        {
 | 
						|
            // Draw the horizontal and vertical borders, and
 | 
						|
            // the current "Now" border
 | 
						|
 | 
						|
            DrawHorizontalBorders(g, sliceStart, sliceEnd, dayStart, dayEnd, daySlots);
 | 
						|
            DrawVerticalBorders(g, sliceStart, sliceEnd, dayStart, dayEnd);
 | 
						|
 | 
						|
            if (CalendarView.HighlightCurrentDay == true)
 | 
						|
                DrawNowBorder(g, dayStart, dayEnd);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawHorizontalBorders
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws horizontal borders
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="sliceStart"></param>
 | 
						|
        /// <param name="sliceEnd"></param>
 | 
						|
        /// <param name="dayStart"></param>
 | 
						|
        /// <param name="dayEnd"></param>
 | 
						|
        /// <param name="daySlots"></param>
 | 
						|
        private void DrawHorizontalBorders(Graphics g,
 | 
						|
            int sliceStart, int sliceEnd, int dayStart, int dayEnd, DaySlot[,] daySlots)
 | 
						|
        {
 | 
						|
            if (CalendarView.HasViewDisplayCustomizations == true)
 | 
						|
            {
 | 
						|
                int n = MinutesPerHour / TimeSlotDuration;
 | 
						|
 | 
						|
                Color hourBorderColor = _ViewColor.GetColor((int)eCalendarWeekDayPart.DayHourBorder);
 | 
						|
                Color halfHourBorderColor = _ViewColor.GetColor((int)eCalendarWeekDayPart.DayHalfHourBorder);
 | 
						|
 | 
						|
                for (int i = dayStart; i <= dayEnd; i++)
 | 
						|
                {
 | 
						|
                    for (int j = sliceStart; j <= sliceEnd; j++)
 | 
						|
                    {
 | 
						|
                        DaySlot daySlot = daySlots[i - dayStart, j - sliceStart];
 | 
						|
 | 
						|
                        Rectangle r = daySlot.Bounds;
 | 
						|
                        DaySlotAppearance dsa = daySlot.Appearance;
 | 
						|
 | 
						|
                        Point pt1 = r.Location;
 | 
						|
                        Point pt2 = new Point(r.Right - 1, r.Y);
 | 
						|
 | 
						|
                        if (dsa != null && daySlot.Selected == false)
 | 
						|
                        {
 | 
						|
                            using (Pen pen = new Pen(j % n == 0 ? dsa.HourBorderColor : dsa.HalfHourBorderColor))
 | 
						|
                                g.DrawLine(pen, pt1, pt2);
 | 
						|
 | 
						|
                            continue;
 | 
						|
                        }
 | 
						|
 | 
						|
                        using (Pen pen = new Pen(j % n == 0 ? hourBorderColor : halfHourBorderColor))
 | 
						|
                            g.DrawLine(pen, pt1, pt2);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                using (Pen pen1 = new Pen(
 | 
						|
                    _ViewColor.GetColor((int) eCalendarWeekDayPart.DayHourBorder)))
 | 
						|
                {
 | 
						|
                    using (Pen pen2 = new Pen(
 | 
						|
                        _ViewColor.GetColor((int) eCalendarWeekDayPart.DayHalfHourBorder)))
 | 
						|
                    {
 | 
						|
                        Point pt1 = new Point(_DayColumns[dayStart].Bounds.X, 0);
 | 
						|
                        Point pt2 = new Point(_DayColumns[dayEnd].Bounds.Right - 1, 0);
 | 
						|
 | 
						|
                        int n = MinutesPerHour/TimeSlotDuration;
 | 
						|
 | 
						|
                        for (int i = sliceStart; i <= sliceEnd; i++)
 | 
						|
                        {
 | 
						|
                            Rectangle r = GetSliceRect(0, i);
 | 
						|
 | 
						|
                            pt1.Y = pt2.Y = r.Y;
 | 
						|
 | 
						|
                            g.DrawLine((i%n) == 0 ? pen1 : pen2, pt1, pt2);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawVerticalBorders
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws the vertical borders
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="sliceStart"></param>
 | 
						|
        /// <param name="sliceEnd"></param>
 | 
						|
        /// <param name="dayStart"></param>
 | 
						|
        /// <param name="dayEnd"></param>
 | 
						|
        private void DrawVerticalBorders(Graphics g,
 | 
						|
            int sliceStart, int sliceEnd, int dayStart, int dayEnd)
 | 
						|
        {
 | 
						|
            Rectangle r1 = GetSliceRect(0, sliceStart);
 | 
						|
            Rectangle r2 = GetSliceRect(0, sliceEnd);
 | 
						|
 | 
						|
            using (Pen pen1 = new Pen(
 | 
						|
                _ViewColor.GetColor((int)eCalendarWeekDayPart.DayViewBorder)))
 | 
						|
            {
 | 
						|
                Point pt1 = new Point(0, r1.Y);
 | 
						|
                Point pt2 = new Point(0, r2.Bottom);
 | 
						|
 | 
						|
                for (int i = dayStart; i <= dayEnd; i++)
 | 
						|
                {
 | 
						|
                    pt1.X = pt2.X = _DayColumns[i].Bounds.X;
 | 
						|
 | 
						|
                    g.DrawLine(pen1, pt1, pt2);
 | 
						|
                }
 | 
						|
 | 
						|
                pt1.X = pt2.X = _DayColumns[dayEnd].Bounds.Right;
 | 
						|
 | 
						|
                g.DrawLine(pen1, pt1, pt2);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawNowBorder
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws the Current-Day Now border
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="dayStart"></param>
 | 
						|
        /// <param name="dayEnd"></param>
 | 
						|
        private void DrawNowBorder(Graphics g, int dayStart, int dayEnd)
 | 
						|
        {
 | 
						|
            // Draw the "Current" day border
 | 
						|
 | 
						|
            for (int i = dayStart; i <= dayEnd; i++)
 | 
						|
            {
 | 
						|
                if (_DayColumns[i].Date.Date.Equals(DateTime.Now.Date))
 | 
						|
                {
 | 
						|
                    Rectangle r = _DayColumns[i].Bounds;
 | 
						|
 | 
						|
                    using (Pen pen = new Pen(
 | 
						|
                        _ViewColor.GetColor((int)eCalendarWeekDayPart.NowDayHeaderBorder)))
 | 
						|
                    {
 | 
						|
                        g.DrawRectangle(pen, r);
 | 
						|
                    }
 | 
						|
                    break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawWeekAppointments
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Initiates the drawing of weekly appointments
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e">ItemPaintArgs</param>
 | 
						|
        /// <param name="dayStart">Day start index</param>
 | 
						|
        /// <param name="dayEnd">Day end index</param>
 | 
						|
        private void DrawWeekAppointments(ItemPaintArgs e, int dayStart, int dayEnd)
 | 
						|
        {
 | 
						|
            if (e.ClipRectangle.IntersectsWith(ViewRect) == true)
 | 
						|
            {
 | 
						|
                // Loop through each day in each week, displaying
 | 
						|
                // the associated day content
 | 
						|
 | 
						|
                List<CalendarItem> selItems = null;
 | 
						|
 | 
						|
                for (int i = 0; i <= dayEnd; i++)
 | 
						|
                {
 | 
						|
                    List<CalendarItem> items = _DayColumns[i].CalendarItems;
 | 
						|
 | 
						|
                    if (items != null && items.Count > 0)
 | 
						|
                    {
 | 
						|
                        int right = _DayColumns[i].Bounds.Right - 1;
 | 
						|
 | 
						|
                        for (int j = 0; j < items.Count; j++)
 | 
						|
                        {
 | 
						|
                            CalendarItem item = items[j];
 | 
						|
 | 
						|
                            if ((item.Displayed == true) &&
 | 
						|
                                (i >= dayStart || item.Bounds.Right > right))
 | 
						|
                            {
 | 
						|
                                if (item.IsSelected == false)
 | 
						|
                                {
 | 
						|
                                    item.Paint(e);
 | 
						|
                                }
 | 
						|
                                else
 | 
						|
                                {
 | 
						|
                                    if (selItems == null)
 | 
						|
                                        selItems = new List<CalendarItem>();
 | 
						|
 | 
						|
                                    selItems.Add(item);
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                if (selItems != null)
 | 
						|
                {
 | 
						|
                    foreach (CalendarItem item in selItems)
 | 
						|
                        item.Paint(e);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Mouse routines
 | 
						|
 | 
						|
        #region MouseDown processing
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// MouseDown event processing
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        public override void InternalMouseDown(MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            // Forward on the event
 | 
						|
 | 
						|
            base.InternalMouseDown(objArg);
 | 
						|
 | 
						|
            if (SelectedItem != null)
 | 
						|
                _WasAllDayItem = IsAllDayItem(SelectedItem);
 | 
						|
 | 
						|
            if (objArg.Button == MouseButtons.Left)
 | 
						|
            {
 | 
						|
                if (IsTabMoving == false)
 | 
						|
                {
 | 
						|
                    // Locate where the event took place
 | 
						|
 | 
						|
                    if (InPanelResize(objArg.Location) == true)
 | 
						|
                    {
 | 
						|
                        MyCursor = Cursors.HSplit;
 | 
						|
 | 
						|
                        _IsPanelResizing = true;
 | 
						|
                    }
 | 
						|
                    else if (ViewRect.Contains(objArg.Location) == true)
 | 
						|
                    {
 | 
						|
                        int col, slice;
 | 
						|
 | 
						|
                        if (GetPointItem(objArg.Location, out col, out slice, true))
 | 
						|
                        {
 | 
						|
                            MyCursor = GetContentCursor();
 | 
						|
                            
 | 
						|
                            if (ProcessCilButtonDown(col, objArg) == false)
 | 
						|
                                ProcessDvlButtonDown(col, slice);
 | 
						|
 | 
						|
                            IsMouseDown = true;
 | 
						|
                        }
 | 
						|
 | 
						|
                        IsCopyDrag = false;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region CalendarItem MouseDown processing
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// CalendarItem left mouseDown processing
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">DayColumn col index</param>
 | 
						|
        /// <param name="objArg">MouseEventArgs</param>
 | 
						|
        private bool ProcessCilButtonDown(int col, MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            CalendarItem item = m_HotSubItem as CalendarItem;
 | 
						|
 | 
						|
            if (item != null)
 | 
						|
            {
 | 
						|
                _WasAllDayItem = IsAllDayItem(item);
 | 
						|
 | 
						|
                if (item.HitArea != CalendarItem.eHitArea.None)
 | 
						|
                {
 | 
						|
                    // Give the user a chance to cancel the
 | 
						|
                    // operation before it starts
 | 
						|
 | 
						|
                    if (CalendarView.DoBeforeAppointmentViewChange(this, item,
 | 
						|
                        ((item.HitArea == CalendarItem.eHitArea.Move) ?
 | 
						|
                        eViewOperation.AppointmentMove : eViewOperation.AppointmentResize)) == false)
 | 
						|
                    {
 | 
						|
                        _LastCol = col;
 | 
						|
                        _LastBounds = item.Bounds;
 | 
						|
                        _LastPointOffset = objArg.Location;
 | 
						|
                        _LastMovePoint = objArg.Location;
 | 
						|
 | 
						|
                        _LastMoveCol = -1;
 | 
						|
                        _LastDm = int.MinValue;
 | 
						|
 | 
						|
                        if (IsResizing == false && IsMoving == false)
 | 
						|
                        {
 | 
						|
                            OldStartTime = item.StartTime;
 | 
						|
                            OldEndTime = item.EndTime;
 | 
						|
                            OldOwnerKey = OwnerKey;
 | 
						|
                        }
 | 
						|
 | 
						|
                        // Flag appropriate action
 | 
						|
 | 
						|
                        if (item.HitArea == CalendarItem.eHitArea.TopResize)
 | 
						|
                            IsStartResizing = true;
 | 
						|
 | 
						|
                        else if (item.HitArea == CalendarItem.eHitArea.BottomResize)
 | 
						|
                            IsEndResizing = true;
 | 
						|
 | 
						|
                        else if (item.HitArea == CalendarItem.eHitArea.Move)
 | 
						|
                            IsMoving = true;
 | 
						|
 | 
						|
                        // Update our initial PosWin display
 | 
						|
 | 
						|
                        UpdatePosWin(ViewRect);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                return (true);
 | 
						|
            }
 | 
						|
 | 
						|
            return (false);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DayView MouseDown processing
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles DayView left MouseDown events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">DayColumn col index</param>
 | 
						|
        /// <param name="slice">Time slice</param>
 | 
						|
        private void ProcessDvlButtonDown(int col, int slice)
 | 
						|
        {
 | 
						|
            DateTime startDate = GetTime(_DayColumns[col].Date, slice, 0);
 | 
						|
            DateTime endDate = startDate.AddMinutes(TimeSlotDuration);
 | 
						|
 | 
						|
            ExtendSelection(ref startDate, ref endDate);
 | 
						|
 | 
						|
            CalendarView.DateSelectionStart = startDate;
 | 
						|
            CalendarView.DateSelectionEnd = endDate;
 | 
						|
 | 
						|
            SelectedItem = null;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MouseUp processing
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// MouseUp event processing
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg">MouseEventArgs</param>
 | 
						|
        public override void InternalMouseUp(MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            base.InternalMouseUp(objArg);
 | 
						|
 | 
						|
            CancelScrollTimer();
 | 
						|
 | 
						|
            // Reset our panel resizing flag
 | 
						|
 | 
						|
            _IsPanelResizing = false;
 | 
						|
 | 
						|
            if (SelectedItem != null &&
 | 
						|
                (IsAllDayItem(SelectedItem) != _WasAllDayItem))
 | 
						|
            {
 | 
						|
                ReloadView();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MouseMove processing
 | 
						|
 | 
						|
        #region InternalMouseMove
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// MouseMove event processing
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg">MouseEventArgs</param>
 | 
						|
        public override void InternalMouseMove(MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            // Forward on the event, but only if we are not in
 | 
						|
            // the middle of moving or resizing a CalendarItem
 | 
						|
 | 
						|
            if (Control.MouseButtons == MouseButtons.None)
 | 
						|
                ClearMouseStates();
 | 
						|
 | 
						|
            if (!IsMoving && !IsStartResizing && !IsEndResizing)
 | 
						|
                base.InternalMouseMove(objArg);
 | 
						|
 | 
						|
            if (IsTabMoving == false)
 | 
						|
            {
 | 
						|
                if (_IsPanelResizing == true)
 | 
						|
                {
 | 
						|
                    MyCursor = Cursors.HSplit;
 | 
						|
 | 
						|
                    ProcessPanelMove(objArg);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    if (InPanelResize(objArg.Location) == true)
 | 
						|
                    {
 | 
						|
                        MyCursor = Cursors.HSplit;
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        MyCursor = GetContentCursor();
 | 
						|
 | 
						|
                        if (objArg.Button == MouseButtons.Left)
 | 
						|
                            ProcessContentMove(objArg);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region InPanelResize
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Determines if the mouse is in the
 | 
						|
        /// panel resize area
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pt">Mouse location</param>
 | 
						|
        /// <returns>true if in the resize area</returns>
 | 
						|
        private bool InPanelResize(Point pt)
 | 
						|
        {
 | 
						|
            if (CalendarView.IsMultiCalendar == true)
 | 
						|
            {
 | 
						|
                Rectangle r = ViewRect;
 | 
						|
 | 
						|
                if (pt.X > r.Left && pt.X < r.Right &&
 | 
						|
                    pt.Y > r.Y - 3 && pt.Y < r.Y + 3)
 | 
						|
                {
 | 
						|
                    return (true);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (false);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessPanelMove
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes the actual panel resizing
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg">MouseEventArgs</param>
 | 
						|
        private void ProcessPanelMove(MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            if (_IsPanelResizing == true)
 | 
						|
            {
 | 
						|
                Point pt = objArg.Location;
 | 
						|
 | 
						|
                if (pt.Y < ClientRect.Y + DayOfWeekHeaderHeight)
 | 
						|
                    pt.Y = ClientRect.Y + DayOfWeekHeaderHeight;
 | 
						|
 | 
						|
                else if (pt.Y > ClientRect.Bottom - 50)
 | 
						|
                    pt.Y = ClientRect.Bottom - 50;
 | 
						|
 | 
						|
                int n = pt.Y - (ClientRect.Y + DayOfWeekHeaderHeight);
 | 
						|
 | 
						|
                CalendarView.FixedAllDayPanelHeight = n;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessContentMove
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes content mouse moves
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg">MouseEventArgs</param>
 | 
						|
        private void ProcessContentMove(MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            // Locate where the event took place
 | 
						|
            // and process it accordingly
 | 
						|
 | 
						|
            int col, slice;
 | 
						|
 | 
						|
            if (GetPointItem(objArg.Location, out col, out slice, false))
 | 
						|
            {
 | 
						|
                // The slice is visible, so no need to
 | 
						|
                // enable scrolling - just process the event
 | 
						|
 | 
						|
                EnableViewScrolling(false);
 | 
						|
 | 
						|
                ProcessMouseMove(col, slice, objArg);
 | 
						|
            }
 | 
						|
            else if (IsMouseDown == true)
 | 
						|
            {
 | 
						|
                if (DragDropAppointment(objArg) == false)
 | 
						|
                {
 | 
						|
                    // The selected slice is not visible,
 | 
						|
                    // so we need to enable scrolling
 | 
						|
 | 
						|
                    EnableViewScrolling(true);
 | 
						|
 | 
						|
                    // Only process the event if the user is selecting
 | 
						|
                    // time slice cells (auto moving apps is intrusive looking)
 | 
						|
 | 
						|
                    if (DateSelectionAnchor != null)
 | 
						|
                    {
 | 
						|
                        if (col >= 0)
 | 
						|
                        {
 | 
						|
                            if (slice < 0)
 | 
						|
                                slice = 0;
 | 
						|
 | 
						|
                            ProcessDvMouseMove(col, slice);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region DragDropAppointment
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Initiates a user "DragDrop" operation - if enabled
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArgs"></param>
 | 
						|
        /// <returns>True if operation started</returns>
 | 
						|
        private bool DragDropAppointment(MouseEventArgs objArgs)
 | 
						|
        {
 | 
						|
            if (IsMoving == true && CanDrag == true)
 | 
						|
            {
 | 
						|
                Point pt = objArgs.Location;
 | 
						|
                BaseView bv = CalendarView.GetViewFromPoint(pt);
 | 
						|
                WeekDayView wv = bv as WeekDayView;
 | 
						|
 | 
						|
                if (wv != null && wv != this)
 | 
						|
                {
 | 
						|
                    eViewArea area = bv.GetViewAreaFromPoint(pt);
 | 
						|
 | 
						|
                    if (area == eViewArea.InContent)
 | 
						|
                    {
 | 
						|
                        if (CalendarView.DoAppointmentViewChanging(SelectedItem, wv.OwnerKey, SelectedItem.StartTime,
 | 
						|
                            SelectedItem.EndTime, eViewOperation.AppointmentMove, IsNewCopyDrag) == false)
 | 
						|
                        {
 | 
						|
                            DragCopy();
 | 
						|
 | 
						|
                            ClearMouseStates();
 | 
						|
                            CancelScrollTimer();
 | 
						|
 | 
						|
                            if (PosWin != null)
 | 
						|
                                PosWin.Hide();
 | 
						|
 | 
						|
                            AppointmentView av = SelectedItem as AppointmentView;
 | 
						|
 | 
						|
                            if (av != null)
 | 
						|
                                return (wv.DragAppointment(this, av, objArgs.Location));
 | 
						|
 | 
						|
                            CustomCalendarItem ci = SelectedItem as CustomCalendarItem;
 | 
						|
 | 
						|
                            if (ci != null)
 | 
						|
                                return (wv.DragCustomItem(this, ci, objArgs.Location));
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (false);
 | 
						|
        }
 | 
						|
 | 
						|
        #region DragCustomItem
 | 
						|
 | 
						|
        private bool DragCustomItem(WeekDayView pv, CustomCalendarItem ci, Point pt)
 | 
						|
        {
 | 
						|
            // Set the new owner and selected view, and
 | 
						|
            // recalc the new layout
 | 
						|
 | 
						|
            if (ci.BaseCalendarItem != null)
 | 
						|
                ci = ci.BaseCalendarItem;
 | 
						|
 | 
						|
            ci.OwnerKey = OwnerKey;
 | 
						|
 | 
						|
            _LastMoveCol = 0;
 | 
						|
            _LastDm = int.MinValue;
 | 
						|
 | 
						|
            if (NumberOfColumns > 1)
 | 
						|
            {
 | 
						|
                DateTime sd = ci.StartTime;
 | 
						|
                TimeSpan ts = ci.EndTime.Subtract(ci.StartTime);
 | 
						|
 | 
						|
                if (Bounds.X > pv.Bounds.X)
 | 
						|
                {
 | 
						|
                    ci.StartTime = new DateTime(_DayColumns[0].Date.Year,
 | 
						|
                        _DayColumns[0].Date.Month, _DayColumns[0].Date.Day, sd.Hour, sd.Minute, 0);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    _LastMoveCol = NumberOfColumns - 1;
 | 
						|
 | 
						|
                    ci.StartTime = new DateTime(_DayColumns[NumberOfColumns - 1].Date.Year,
 | 
						|
                        _DayColumns[NumberOfColumns - 1].Date.Month,
 | 
						|
                        _DayColumns[NumberOfColumns - 1].Date.Day, sd.Hour, sd.Minute, 0);
 | 
						|
                }
 | 
						|
 | 
						|
                ci.EndTime = ci.StartTime.Add(ts);
 | 
						|
            }
 | 
						|
 | 
						|
            NeedRecalcLayout = true;
 | 
						|
            RecalcSize();
 | 
						|
 | 
						|
            CalendarView.SelectedOwnerIndex = this.DisplayedOwnerKeyIndex;
 | 
						|
 | 
						|
            // Get the new view
 | 
						|
 | 
						|
            CustomCalendarItem view = GetCustomCalendarItem(ci);
 | 
						|
 | 
						|
            if (view != null)
 | 
						|
                SetNewDragItem(pv, view, pt);
 | 
						|
 | 
						|
            return (true);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DragAppointment
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Drags the given appointment from one view to another
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pv">Previous view</param>
 | 
						|
        /// <param name="av">Item to move</param>
 | 
						|
        private bool DragAppointment(WeekDayView pv, AppointmentView av, Point pt)
 | 
						|
        {
 | 
						|
            // Set the new owner and selected view, and
 | 
						|
            // recalc the new layout
 | 
						|
 | 
						|
            av.Appointment.OwnerKey = OwnerKey;
 | 
						|
 | 
						|
            _LastMoveCol = 0;
 | 
						|
            _LastDm = int.MinValue;
 | 
						|
 | 
						|
            if (NumberOfColumns > 1)
 | 
						|
            {
 | 
						|
                DateTime sd = av.Appointment.StartTime;
 | 
						|
 | 
						|
                if (Bounds.X > pv.Bounds.X)
 | 
						|
                {
 | 
						|
                    av.Appointment.MoveTo(
 | 
						|
                        new DateTime(_DayColumns[0].Date.Year, _DayColumns[0].Date.Month,
 | 
						|
                        _DayColumns[0].Date.Day, sd.Hour, sd.Minute, 0));
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    _LastMoveCol = NumberOfColumns - 1;
 | 
						|
 | 
						|
                    av.Appointment.MoveTo(
 | 
						|
                        new DateTime(_DayColumns[NumberOfColumns - 1].Date.Year,
 | 
						|
                        _DayColumns[NumberOfColumns - 1].Date.Month,
 | 
						|
                        _DayColumns[NumberOfColumns - 1].Date.Day, sd.Hour, sd.Minute, 0));
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            NeedRecalcLayout = true;
 | 
						|
            RecalcSize();
 | 
						|
 | 
						|
            CalendarView.SelectedOwnerIndex = this.DisplayedOwnerKeyIndex;
 | 
						|
 | 
						|
            // Get the new view
 | 
						|
 | 
						|
            AppointmentView view = GetAppointmentView(av.Appointment);
 | 
						|
 | 
						|
            if (view != null)
 | 
						|
                SetNewDragItem(pv, view, pt);
 | 
						|
 | 
						|
            return (true);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SetNewDragItem
 | 
						|
 | 
						|
        private void SetNewDragItem(WeekDayView pv, CalendarItem view, Point pt)
 | 
						|
        {
 | 
						|
            _LastBounds = pv._LastBounds;
 | 
						|
            _LastMovePoint = pv._LastMovePoint;
 | 
						|
            _LastPointOffset = pv._LastPointOffset;
 | 
						|
 | 
						|
            int dy = _LastPointOffset.Y - _LastBounds.Y;
 | 
						|
 | 
						|
            CalendarView.CalendarPanel.InternalMouseMove(new
 | 
						|
                MouseEventArgs(MouseButtons.None, 0, view.Bounds.X, view.Bounds.Y - dy, 0));
 | 
						|
 | 
						|
            MouseEventArgs args = new
 | 
						|
                MouseEventArgs(MouseButtons.Left, 1, view.Bounds.X, view.Bounds.Y + dy, 0);
 | 
						|
 | 
						|
            IsMoving = true;
 | 
						|
 | 
						|
            InternalMouseMove(args);
 | 
						|
            CalendarView.CalendarPanel.InternalMouseDown(args);
 | 
						|
 | 
						|
            SelectedItem = view;
 | 
						|
 | 
						|
            IsNewCopyDrag = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetContentCursor
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the cursor
 | 
						|
        /// </summary>
 | 
						|
        /// <returns>Cursor</returns>
 | 
						|
        private Cursor GetContentCursor()
 | 
						|
        {
 | 
						|
            CalendarItem item = m_HotSubItem as CalendarItem;
 | 
						|
 | 
						|
            if (item != null)
 | 
						|
            {
 | 
						|
                switch (item.HitArea)
 | 
						|
                {
 | 
						|
                    case CalendarItem.eHitArea.TopResize:
 | 
						|
                    case CalendarItem.eHitArea.BottomResize:
 | 
						|
                        return (Cursors.SizeNS);
 | 
						|
 | 
						|
                    case CalendarItem.eHitArea.Move:
 | 
						|
                        return (IsMoving ? Cursors.SizeAll : DefaultCursor);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (DefaultCursor);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessMouseMove
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes user MouseMove
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">DayColumn</param>
 | 
						|
        /// <param name="slice">Slice</param>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        private void ProcessMouseMove(int col, int slice, MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            if (DateSelectionAnchor != null)
 | 
						|
            {
 | 
						|
                ProcessDvMouseMove(col, slice);
 | 
						|
            }
 | 
						|
            else if (SelectedItem != null)
 | 
						|
            {
 | 
						|
                if (objArg.Location.Equals(_LastMovePoint) == false)
 | 
						|
                {
 | 
						|
                    if (IsMoving == true)
 | 
						|
                        ProcessItemMove(col, slice, objArg);
 | 
						|
 | 
						|
                    else if (IsStartResizing == true)
 | 
						|
                        ProcessItemTopResize(col, slice, objArg);
 | 
						|
 | 
						|
                    else if (IsEndResizing == true)
 | 
						|
                        ProcessItemBottomResize(col, slice, objArg);
 | 
						|
 | 
						|
                    _LastMovePoint = objArg.Location;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DayView mouseMove processing
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes DayView mouseMove events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">DayColumn col index</param>
 | 
						|
        /// <param name="slice">Time slice</param>
 | 
						|
        private void ProcessDvMouseMove(int col, int slice)
 | 
						|
        {
 | 
						|
            DateTime date = GetTime(_DayColumns[col].Date, slice, 0);
 | 
						|
 | 
						|
            // Let the user select forwards or backwards
 | 
						|
 | 
						|
            if (date >= DateSelectionAnchor)
 | 
						|
            {
 | 
						|
                CalendarView.DateSelectionStart = DateSelectionAnchor.Value;
 | 
						|
                CalendarView.DateSelectionEnd = date.AddMinutes(TimeSlotDuration);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                CalendarView.DateSelectionStart = date;
 | 
						|
                CalendarView.DateSelectionEnd = DateSelectionAnchor.Value.AddMinutes(TimeSlotDuration);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CalendarItem MouseMove processing
 | 
						|
 | 
						|
        #region ProcessItemMove
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes CalendarItem mouseMove events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">DayColumn col index</param>
 | 
						|
        /// <param name="slice">Time slice</param>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        private void ProcessItemMove(int col, int slice, MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            // Calculate our new item date
 | 
						|
 | 
						|
            int dm = GetDeltaMinutes(slice, true, objArg);
 | 
						|
 | 
						|
            if (_LastDm == int.MinValue)
 | 
						|
                _LastDm = dm;
 | 
						|
 | 
						|
            int ddm = dm - _LastDm;
 | 
						|
 | 
						|
            if (_LastMoveCol == -1)
 | 
						|
                _LastMoveCol = col;
 | 
						|
 | 
						|
            if (col != _LastMoveCol)
 | 
						|
                ddm += ((col - _LastMoveCol) * HoursPerDay * MinutesPerHour);
 | 
						|
 | 
						|
            _LastDm = dm;
 | 
						|
            _LastMoveCol = col;
 | 
						|
 | 
						|
            DateTime newDate = SelectedItem.StartTime.AddMinutes(ddm);
 | 
						|
            TimeSpan ts = SelectedItem.EndTime - SelectedItem.StartTime;
 | 
						|
 | 
						|
            if (newDate != SelectedItem.StartTime)
 | 
						|
            {
 | 
						|
                if (CalendarView.AllDayDisplayMode != eAllDayDisplayMode.None)
 | 
						|
                {
 | 
						|
                    // Make sure we don't cross day boundaries
 | 
						|
 | 
						|
                    DateTime start = GetTime(_DayColumns[col].Date, 0, 0);
 | 
						|
                    DateTime end = start.AddMinutes(NumberOfActiveSlices * TimeSlotDuration);
 | 
						|
 | 
						|
                    if (newDate < start)
 | 
						|
                        newDate = start;
 | 
						|
 | 
						|
                    if (newDate + ts > end)
 | 
						|
                        newDate -= (newDate + ts) - end;
 | 
						|
                }
 | 
						|
 | 
						|
                // If we have a new date, set our item to it
 | 
						|
 | 
						|
                if (newDate != SelectedItem.StartTime)
 | 
						|
                {
 | 
						|
                    if (DragCopy() == false)
 | 
						|
                    {
 | 
						|
                        try
 | 
						|
                        {
 | 
						|
                            if (SelectedItem is CustomCalendarItem)
 | 
						|
                                CalendarView.CustomItems.BeginUpdate();
 | 
						|
                            else
 | 
						|
                                CalendarModel.BeginUpdate();
 | 
						|
 | 
						|
                            // Make the move
 | 
						|
 | 
						|
                            if (CalendarView.DoAppointmentViewChanging(SelectedItem, null, newDate,
 | 
						|
                                newDate + ts, eViewOperation.AppointmentMove,
 | 
						|
                                IsCopyDrag) == false)
 | 
						|
                            {
 | 
						|
                                SelectedItem.StartTime = newDate;
 | 
						|
                                SelectedItem.EndTime = newDate + ts;
 | 
						|
 | 
						|
                                InvalidateItems(col);
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                        finally
 | 
						|
                        {
 | 
						|
                            if (SelectedItem is CustomCalendarItem)
 | 
						|
                                CalendarView.CustomItems.EndUpdate();
 | 
						|
                            else
 | 
						|
                                CalendarModel.EndUpdate();
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        _LastMoveCol = _LastCol;
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CalendarItem MouseResize processing
 | 
						|
 | 
						|
        #region ProcessItemTopResize
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes CalendarItem left resizing
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="slice">Time slice</param>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        private void ProcessItemTopResize(int col, int slice, MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            int dm = GetDeltaMinutes(slice, true, objArg);
 | 
						|
 | 
						|
            DateTime newStartTime;
 | 
						|
 | 
						|
            if (CalendarView.AllDayDisplayMode != eAllDayDisplayMode.None)
 | 
						|
            {
 | 
						|
                newStartTime = new DateTime(
 | 
						|
                    SelectedItem.StartTime.Year, SelectedItem.StartTime.Month, SelectedItem.StartTime.Day);
 | 
						|
 | 
						|
                newStartTime = GetTime(newStartTime, 0, dm);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                newStartTime = GetTime(_DayColumns[col].Date.Date, 0, dm);
 | 
						|
 | 
						|
                if (newStartTime < _DayColumns[0].Date)
 | 
						|
                    newStartTime = _DayColumns[0].Date;
 | 
						|
            }
 | 
						|
 | 
						|
            if (newStartTime != SelectedItem.StartTime && newStartTime < SelectedItem.EndTime)
 | 
						|
            {
 | 
						|
                if ((SelectedItem.EndTime - newStartTime).TotalMinutes < 0)
 | 
						|
                    newStartTime = SelectedItem.EndTime.AddMinutes(-1);
 | 
						|
 | 
						|
                ResizeItem(_LastCol, newStartTime, SelectedItem.EndTime);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessItemBottomResize
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes CalendarItem right resizing
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="slice">Time slice</param>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        private void ProcessItemBottomResize(int col, int slice, MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            int dm = GetDeltaMinutes(slice, false, objArg);
 | 
						|
 | 
						|
            DateTime newEndTime;
 | 
						|
            DateTime end;
 | 
						|
 | 
						|
            if (CalendarView.AllDayDisplayMode != eAllDayDisplayMode.None)
 | 
						|
            {
 | 
						|
                newEndTime = new DateTime(
 | 
						|
                    SelectedItem.StartTime.Year, SelectedItem.StartTime.Month, SelectedItem.StartTime.Day);
 | 
						|
 | 
						|
                if (newEndTime < _DayColumns[0].Date)
 | 
						|
                    newEndTime = _DayColumns[0].Date;
 | 
						|
 | 
						|
                newEndTime = GetTime(newEndTime, 0, dm);
 | 
						|
 | 
						|
                end = GetTime(_DayColumns[_LastCol].Date, NumberOfActiveSlices, 0);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                newEndTime = GetTime(_DayColumns[col].Date.Date, 0, dm);
 | 
						|
 | 
						|
                if (newEndTime < _DayColumns[0].Date)
 | 
						|
                    newEndTime = _DayColumns[0].Date;
 | 
						|
 | 
						|
                end = GetTime(_DayColumns[_DayColumns.Length - 1].Date, NumberOfActiveSlices, 0);
 | 
						|
            }
 | 
						|
 | 
						|
            if (newEndTime > end)
 | 
						|
                newEndTime = end;
 | 
						|
 | 
						|
            if (newEndTime != SelectedItem.EndTime && newEndTime > SelectedItem.StartTime)
 | 
						|
            {
 | 
						|
                if ((newEndTime - SelectedItem.StartTime).TotalMinutes < 0)
 | 
						|
                    newEndTime = SelectedItem.StartTime.AddMinutes(1);
 | 
						|
 | 
						|
                ResizeItem(_LastCol, SelectedItem.StartTime, newEndTime);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ResizeItem
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Initiates the resize of the selected item
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col"></param>
 | 
						|
        /// <param name="startTime"></param>
 | 
						|
        /// <param name="endTime"></param>
 | 
						|
        private void ResizeItem(int col, DateTime startTime, DateTime endTime)
 | 
						|
        {
 | 
						|
            // Let the user cancel the operation if desired
 | 
						|
 | 
						|
            if (CalendarView.DoAppointmentViewChanging(SelectedItem, null, startTime,
 | 
						|
                endTime, eViewOperation.AppointmentResize, IsNewCopyDrag) == false)
 | 
						|
            {
 | 
						|
                InvalidateItems(col);
 | 
						|
 | 
						|
                SelectedItem.StartTime = startTime;
 | 
						|
                SelectedItem.EndTime = endTime;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDeltaMinutes
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the changes in minutes
 | 
						|
        /// from the last mouse operation (move or resize)
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="slice">Current slice</param>
 | 
						|
        /// <param name="ftop">Flag denoting top or bottom delta</param>
 | 
						|
        /// <param name="objArg">MouseEventArgs</param>
 | 
						|
        /// <returns>Delta minutes</returns>
 | 
						|
        private int GetDeltaMinutes(int slice, bool ftop, MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            // Calculate our delta minutes
 | 
						|
 | 
						|
            Rectangle t = GetSliceRect(0, slice);
 | 
						|
 | 
						|
            int dm = (objArg.Location.Y - _LastPointOffset.Y);
 | 
						|
 | 
						|
            dm += ftop ? _LastBounds.Top - t.Top
 | 
						|
                       : _LastBounds.Bottom - t.Bottom;
 | 
						|
 | 
						|
            dm = (int)(TimeSlotDuration * dm / TimeSliceHeight);
 | 
						|
 | 
						|
            // If the Alt key is not pressed, then round
 | 
						|
            // our value off to the nearest slice
 | 
						|
 | 
						|
            if ((Control.ModifierKeys & Keys.Alt) != Keys.Alt)
 | 
						|
            {
 | 
						|
                slice += (dm / TimeSlotDuration);
 | 
						|
                dm = 0;
 | 
						|
            }
 | 
						|
 | 
						|
            dm += (slice * TimeSlotDuration);
 | 
						|
 | 
						|
            // Make sure we don't cross our day boundaries
 | 
						|
 | 
						|
            if (CalendarView.AllDayDisplayMode != eAllDayDisplayMode.None)
 | 
						|
            {
 | 
						|
                if (ftop == true)
 | 
						|
                {
 | 
						|
                    if (dm < 0)
 | 
						|
                        dm = 0;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    dm += TimeSlotDuration;
 | 
						|
 | 
						|
                    if (dm >= MinutesPerHour * HoursPerDay)
 | 
						|
                        dm = MinutesPerHour * HoursPerDay - 1;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (dm);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region InvalidateItems
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Invalidates altered DayColumns
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">Current column</param>
 | 
						|
        internal void InvalidateItems(int col)
 | 
						|
        {
 | 
						|
            if (SelectedItem.IsRecurring == false)
 | 
						|
            {
 | 
						|
                _DayColumns[_LastCol].NeedRecalcLayout = true;
 | 
						|
                _DayColumns[col].NeedRecalcLayout = true;
 | 
						|
 | 
						|
                InvalidateRect(_DayColumns[col].Bounds, true);
 | 
						|
 | 
						|
                if (_LastCol != col)
 | 
						|
                    InvalidateRect(_DayColumns[_LastCol].Bounds);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                NeedRecalcLayout = true;
 | 
						|
            }
 | 
						|
 | 
						|
            _LastCol = col;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region View Scrolling support
 | 
						|
 | 
						|
        #region EnableViewScrolling
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Routine to enable or disable view scrolling
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="enable">true to enable</param>
 | 
						|
        private void EnableViewScrolling(bool enable)
 | 
						|
        {
 | 
						|
            if (enable == true)
 | 
						|
            {
 | 
						|
                if (VsPanel.ScrollBar.Maximum > VsPanel.ScrollBar.LargeChange)
 | 
						|
                {
 | 
						|
                    if (_ScrollViewTimer == null)
 | 
						|
                    {
 | 
						|
                        _ScrollViewTimer = new Timer();
 | 
						|
 | 
						|
                        _ScrollViewTimer.Interval = 10;
 | 
						|
                        _ScrollViewTimer.Tick += ScrollViewTimerTick;
 | 
						|
                        _ScrollViewTimer.Start();
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                CancelScrollTimer();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CancelScrollTimer
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Cancels the view scroll timer
 | 
						|
        /// </summary>
 | 
						|
        private void CancelScrollTimer()
 | 
						|
        {
 | 
						|
            // Dispose of our scroll timer
 | 
						|
 | 
						|
            if (_ScrollViewTimer != null)
 | 
						|
            {
 | 
						|
                _ScrollViewTimer.Stop();
 | 
						|
                _ScrollViewTimer.Tick -= ScrollViewTimerTick;
 | 
						|
 | 
						|
                _ScrollViewTimer = null;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ScrollAmount
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Determines the amount to scroll (which is
 | 
						|
        /// based loosely upon the delta magnitude)
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="delta">Point delta</param>
 | 
						|
        /// <returns>Scroll amount</returns>
 | 
						|
        private int ScrollAmount(int delta)
 | 
						|
        {
 | 
						|
            int dy = Math.Abs(delta);
 | 
						|
            int amt = (dy < 16 ? 2 : dy < 32 ? 8 : 32);
 | 
						|
 | 
						|
            return (delta < 0 ? -amt : amt);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ScrollViewTimer_Tick
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles view scroll timer ticks
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender">object</param>
 | 
						|
        /// <param name="e">EventArgs</param>
 | 
						|
        private void ScrollViewTimerTick(object sender, EventArgs e)
 | 
						|
        {
 | 
						|
            Control c = (Control)this.GetContainerControl(true);
 | 
						|
 | 
						|
            if (c != null)
 | 
						|
            {
 | 
						|
                // Calculate our delta
 | 
						|
 | 
						|
                Point pt = c.PointToClient(Cursor.Position);
 | 
						|
                Rectangle r = ViewRect;
 | 
						|
 | 
						|
                int dy = (pt.Y < r.Top) ? ScrollAmount(pt.Y - r.Top) :
 | 
						|
                    (pt.Y >= r.Bottom) ? ScrollAmount(pt.Y - r.Bottom) : 0;
 | 
						|
 | 
						|
                // Scroll if necessary
 | 
						|
 | 
						|
                if (dy != 0)
 | 
						|
                {
 | 
						|
                    int value = VsPanel.ScrollBar.Value + dy;
 | 
						|
 | 
						|
                    value = Math.Max(value, 0);
 | 
						|
                    value = Math.Min(value, VsPanel.ScrollBar.Maximum);
 | 
						|
 | 
						|
                    if (VsPanel.ScrollBar.Value != value)
 | 
						|
                    {
 | 
						|
                        VsPanel.ScrollBar.Value = value;
 | 
						|
 | 
						|
                        if (PosWin != null)
 | 
						|
                            PosWin.Hide();
 | 
						|
 | 
						|
                        InternalMouseMove(new
 | 
						|
                            MouseEventArgs(MouseButtons.Left, 0, pt.X, pt.Y, 0));
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region InternalKeyDown
 | 
						|
 | 
						|
        #region InternalKeyDown
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes KeyDown events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        public override void InternalKeyDown(KeyEventArgs objArg)
 | 
						|
        {
 | 
						|
            switch (objArg.KeyData)
 | 
						|
            {
 | 
						|
                case Keys.Up:
 | 
						|
                case Keys.Up | Keys.Shift:
 | 
						|
                case Keys.Up | Keys.Control:
 | 
						|
                case Keys.Up | Keys.Control | Keys.Shift:
 | 
						|
                    ProcessUpDownKey(objArg, -CalendarView.TimeSlotDuration);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case Keys.Down:
 | 
						|
                case Keys.Down | Keys.Shift:
 | 
						|
                case Keys.Down | Keys.Control:
 | 
						|
                case Keys.Down | Keys.Control | Keys.Shift:
 | 
						|
                    ProcessUpDownKey(objArg, CalendarView.TimeSlotDuration);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case Keys.Left:
 | 
						|
                case Keys.Left | Keys.Shift:
 | 
						|
                case Keys.Left | Keys.Control:
 | 
						|
                case Keys.Left | Keys.Control | Keys.Shift:
 | 
						|
                    ProcessLeftRightKey(objArg, -1);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case Keys.Right:
 | 
						|
                case Keys.Right | Keys.Shift:
 | 
						|
                case Keys.Right | Keys.Control:
 | 
						|
                case Keys.Right | Keys.Control | Keys.Shift:
 | 
						|
                    ProcessLeftRightKey(objArg, 1);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case Keys.Home:
 | 
						|
                case Keys.Home | Keys.Shift:
 | 
						|
                case Keys.Home | Keys.Control:
 | 
						|
                case Keys.Home | Keys.Control | Keys.Shift:
 | 
						|
                    ProcessHomeKey(objArg);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case Keys.End:
 | 
						|
                case Keys.End | Keys.Shift:
 | 
						|
                case Keys.End | Keys.Control:
 | 
						|
                case Keys.End | Keys.Control | Keys.Shift:
 | 
						|
                    ProcessEndKey(objArg);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case Keys.PageUp:
 | 
						|
                case Keys.PageUp | Keys.Shift:
 | 
						|
                case Keys.PageUp | Keys.Control:
 | 
						|
                case Keys.PageUp | Keys.Control | Keys.Shift:
 | 
						|
                    ProcessPageUpDownKey(objArg, -1);
 | 
						|
                    break;
 | 
						|
 | 
						|
                case Keys.PageDown:
 | 
						|
                case Keys.PageDown | Keys.Shift:
 | 
						|
                case Keys.PageDown | Keys.Control:
 | 
						|
                case Keys.PageDown | Keys.Control | Keys.Shift:
 | 
						|
                    ProcessPageUpDownKey(objArg, 1);
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessUpDownKey
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes Up and Down key events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        /// <param name="dy"></param>
 | 
						|
        protected virtual void ProcessUpDownKey(KeyEventArgs objArg, int dy)
 | 
						|
        {
 | 
						|
            if (ValidDateSelection())
 | 
						|
            {
 | 
						|
                DateTime startDate = CalendarView.DateSelectionStart.Value;
 | 
						|
                DateTime endDate = CalendarView.DateSelectionEnd.Value;
 | 
						|
 | 
						|
                if (startDate.Equals(DateSelectionAnchor.Value) == true)
 | 
						|
                    startDate = endDate.AddMinutes(-TimeSlotDuration);
 | 
						|
 | 
						|
                startDate = startDate.AddMinutes(dy);
 | 
						|
 | 
						|
                DateTime viewStart = GetTime(DayColumns[0].Date, 0, 0);
 | 
						|
                DateTime viewEnd = viewStart.AddMinutes(NumberOfActiveSlices * TimeSlotDuration);
 | 
						|
 | 
						|
                endDate = startDate.AddMinutes(TimeSlotDuration);
 | 
						|
 | 
						|
                if (startDate >= viewStart && endDate <= viewEnd)
 | 
						|
                {
 | 
						|
                    ExtendSelection(ref startDate, ref endDate);
 | 
						|
 | 
						|
                    CalendarView.DateSelectionStart = startDate;
 | 
						|
                    CalendarView.DateSelectionEnd = endDate;
 | 
						|
 | 
						|
                    EnsureSelectionVisible();
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            objArg.Handled = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessLeftRightKey
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes Left and Right key events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        /// <param name="dx"></param>
 | 
						|
        protected virtual void ProcessLeftRightKey(KeyEventArgs objArg, int dx)
 | 
						|
        {
 | 
						|
            if (CalendarView.WeekDayCanExtendRange == true)
 | 
						|
            {
 | 
						|
                DateTime oldDate = CalendarView.DayViewDate;
 | 
						|
                DateTime newDate = CalendarView.DayViewDate.AddDays(dx);
 | 
						|
 | 
						|
                if (CalendarView.DoViewDateChanging(this,
 | 
						|
                    oldDate, oldDate, ref newDate, ref newDate) == false)
 | 
						|
                {
 | 
						|
                    if (ValidDateSelection())
 | 
						|
                    {
 | 
						|
                        dx = (newDate - oldDate).Days;
 | 
						|
 | 
						|
                        DateTime startDate = CalendarView.DateSelectionStart.Value;
 | 
						|
                        DateTime endDate = CalendarView.DateSelectionEnd.Value;
 | 
						|
 | 
						|
                        startDate = startDate.AddDays(dx);
 | 
						|
                        endDate = endDate.AddDays(dx);
 | 
						|
 | 
						|
                        CalendarView.DateSelectionStart = startDate;
 | 
						|
                        CalendarView.DateSelectionEnd = endDate;
 | 
						|
                        DateSelectionAnchor = DateSelectionAnchor.Value.AddDays(dx);
 | 
						|
                    }
 | 
						|
 | 
						|
                    CalendarView.DayViewDate = CalendarView.DayViewDate.AddDays(dx);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            objArg.Handled = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessHomeKey
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes Home key events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        protected virtual void ProcessHomeKey(KeyEventArgs objArg)
 | 
						|
        {
 | 
						|
            int col = GetHomeEndCol();
 | 
						|
 | 
						|
            if (col >= 0)
 | 
						|
            {
 | 
						|
                DateTime startDate = GetTime(DayColumns[col].Date, 0, 0);
 | 
						|
 | 
						|
                if ((objArg.Modifiers & Keys.Control) != Keys.Control)
 | 
						|
                {
 | 
						|
                    WorkTime wt = DayColumns[col].WorkStartTime;
 | 
						|
 | 
						|
                    if (wt.IsEmpty == false)
 | 
						|
                        startDate = DayColumns[col].Date.AddMinutes(wt.Hour * 60 + wt.Minute);
 | 
						|
                }
 | 
						|
 | 
						|
                DateTime endDate = startDate.AddMinutes(TimeSlotDuration);
 | 
						|
 | 
						|
                ExtendSelection(ref startDate, ref endDate);
 | 
						|
 | 
						|
                CalendarView.DateSelectionStart = startDate;
 | 
						|
                CalendarView.DateSelectionEnd = endDate;
 | 
						|
 | 
						|
                EnsureSelectionVisible();
 | 
						|
            }
 | 
						|
 | 
						|
            objArg.Handled = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessEndKey
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes End Key events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        protected virtual void ProcessEndKey(KeyEventArgs objArg)
 | 
						|
        {
 | 
						|
            int col = GetHomeEndCol();
 | 
						|
 | 
						|
            if (col >= 0)
 | 
						|
            {
 | 
						|
                DateTime startDate = GetTime(DayColumns[col].Date, NumberOfActiveSlices, 0);
 | 
						|
 | 
						|
                if ((objArg.Modifiers & Keys.Control) != Keys.Control)
 | 
						|
                {
 | 
						|
                    WorkTime wt = DayColumns[col].WorkEndTime;
 | 
						|
 | 
						|
                    if (wt.IsEmpty == false)
 | 
						|
                        startDate = DayColumns[col].Date.AddMinutes(wt.Hour * 60 + wt.Minute);
 | 
						|
                }
 | 
						|
 | 
						|
                DateTime endDate = startDate;
 | 
						|
                startDate = startDate.AddMinutes(-TimeSlotDuration);
 | 
						|
 | 
						|
                ExtendSelection(ref startDate, ref endDate);
 | 
						|
 | 
						|
                CalendarView.DateSelectionStart = startDate;
 | 
						|
                CalendarView.DateSelectionEnd = endDate;
 | 
						|
 | 
						|
                EnsureSelectionVisible();
 | 
						|
            }
 | 
						|
 | 
						|
            objArg.Handled = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessPageUpDownKey
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes Page Up and Down key events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        /// <param name="dy">Paging direction (-1, 1)</param>
 | 
						|
        protected virtual void ProcessPageUpDownKey(KeyEventArgs objArg, int dy)
 | 
						|
        {
 | 
						|
            if (ValidDateSelection())
 | 
						|
            {
 | 
						|
                DateTime startDate = CalendarView.DateSelectionStart.Value;
 | 
						|
                DateTime endDate = CalendarView.DateSelectionEnd.Value;
 | 
						|
 | 
						|
                int col = GetColumnFromDate(startDate);
 | 
						|
 | 
						|
                if ((uint)col < DayColumns.Length)
 | 
						|
                {
 | 
						|
                    DateTime viewStart = GetTime(DayColumns[col].Date, 0, 0);
 | 
						|
                    DateTime viewEnd = viewStart.AddMinutes(NumberOfActiveSlices * TimeSlotDuration);
 | 
						|
 | 
						|
                    if (startDate.Equals(DateSelectionAnchor.Value) == true)
 | 
						|
                        startDate = endDate.AddMinutes(-TimeSlotDuration);
 | 
						|
 | 
						|
                    startDate = (dy < 0)
 | 
						|
                        ? GetPageUpStartDate(viewStart, startDate)
 | 
						|
                        : GetPageDownStartDate(viewStart, viewEnd, startDate);
 | 
						|
 | 
						|
                    endDate = startDate.AddMinutes(TimeSlotDuration);
 | 
						|
 | 
						|
                    if (startDate >= viewStart && endDate <= viewEnd)
 | 
						|
                    {
 | 
						|
                        ExtendSelection(ref startDate, ref endDate);
 | 
						|
 | 
						|
                        CalendarView.DateSelectionStart = startDate;
 | 
						|
                        CalendarView.DateSelectionEnd = endDate;
 | 
						|
 | 
						|
                        EnsureSelectionVisible();
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            objArg.Handled = true;
 | 
						|
        }
 | 
						|
 | 
						|
        private DateTime GetPageUpStartDate(
 | 
						|
            DateTime viewStart, DateTime startDate)
 | 
						|
        {
 | 
						|
            DateTime fosDate = viewStart.AddMinutes(TimeSlotDuration*FirstOnScreenSlice);
 | 
						|
 | 
						|
            if (startDate.Equals(fosDate) == false)
 | 
						|
                return (fosDate);
 | 
						|
 | 
						|
            startDate = startDate.AddMinutes(-TimeSlotDuration * OnScreenSlices);
 | 
						|
 | 
						|
            if (startDate < viewStart)
 | 
						|
                startDate = viewStart;
 | 
						|
 | 
						|
            return (startDate);
 | 
						|
        }
 | 
						|
 | 
						|
        private DateTime GetPageDownStartDate(
 | 
						|
            DateTime viewStart, DateTime viewEnd, DateTime startDate)
 | 
						|
        {
 | 
						|
            DateTime eosDate = viewStart.AddMinutes(TimeSlotDuration * LastOnScreenSlice);
 | 
						|
 | 
						|
            if (startDate.Equals(eosDate) == false)
 | 
						|
                return (eosDate);
 | 
						|
 | 
						|
            startDate = eosDate.AddMinutes(TimeSlotDuration * OnScreenSlices);
 | 
						|
 | 
						|
            if (startDate > viewEnd)
 | 
						|
                startDate = viewEnd;
 | 
						|
 | 
						|
            return (startDate);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetHomeEndCol
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the Home and End column from the current
 | 
						|
        /// selection range
 | 
						|
        /// </summary>
 | 
						|
        /// <returns></returns>
 | 
						|
        private int GetHomeEndCol()
 | 
						|
        {
 | 
						|
            if (ValidDateSelection() == true)
 | 
						|
            {
 | 
						|
                if (CalendarView.DateSelectionStart.Equals(DateSelectionAnchor.Value) == true)
 | 
						|
                    return (GetColumnFromDate(DateSelectionEnd.Value.AddMinutes(-TimeSlotDuration)));
 | 
						|
 | 
						|
                return (GetColumnFromDate(DateSelectionStart.Value));
 | 
						|
            }
 | 
						|
 | 
						|
            return ((NumberOfColumns == 1) ? 0 : -1);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetColumnFromDate
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the view column from the given date
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="date"></param>
 | 
						|
        /// <returns>The DayColumns index, or -1 if invalid.</returns>
 | 
						|
        public int GetColumnFromDate(DateTime date)
 | 
						|
        {
 | 
						|
            for (int i = 0; i < DayColumns.Length; i++)
 | 
						|
            {
 | 
						|
                DateTime dc = DayColumns[i].Date.Date;
 | 
						|
 | 
						|
                if (dc <= date && dc.AddDays(1) > date)
 | 
						|
                    return (i);
 | 
						|
            }
 | 
						|
 | 
						|
            return (-1);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region EnsureSelectionVisible
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Ensures the given selection is visible
 | 
						|
        /// </summary>
 | 
						|
        protected virtual void EnsureSelectionVisible()
 | 
						|
        {
 | 
						|
            DateTime start = CalendarView.DateSelectionStart.Value;
 | 
						|
            DateTime end = CalendarView.DateSelectionEnd.Value;
 | 
						|
 | 
						|
            bool refreshed = start.Equals(DateSelectionAnchor) ?
 | 
						|
                EnsureDateVisible(end.AddMinutes(-CalendarView.TimeSlotDuration)) :
 | 
						|
                EnsureDateVisible(start);
 | 
						|
 | 
						|
            if (refreshed == false)
 | 
						|
                Refresh();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region EnsureDateVisible
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Ensures the given date is visible
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="date"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        protected virtual bool EnsureDateVisible(DateTime date)
 | 
						|
        {
 | 
						|
            if (CalendarView.WeekDayVScrollPanel.ScrollBar.Maximum > 
 | 
						|
                CalendarView.WeekDayVScrollPanel.ScrollBar.LargeChange)
 | 
						|
            {
 | 
						|
                Rectangle r = ViewRect;
 | 
						|
 | 
						|
                int offset = (int)(date.Hour * CalendarView.SlotsPerHour * CalendarView.TimeSliceHeight +
 | 
						|
                    (CalendarView.TimeSliceHeight * date.Minute) / CalendarView.TimeSlotDuration);
 | 
						|
 | 
						|
                offset -= (int)(CalendarView.StartSlice * CalendarView.TimeSliceHeight);
 | 
						|
 | 
						|
                int top = CalendarView.WeekDayVScrollPanel.ScrollBar.Value;
 | 
						|
                int bottom = top + r.Height;
 | 
						|
 | 
						|
                if (offset < top || offset + CalendarView.TimeSliceHeight > bottom)
 | 
						|
                {
 | 
						|
                    if (offset + CalendarView.TimeSliceHeight > bottom)
 | 
						|
                        offset -= (int)(r.Height - CalendarView.TimeSliceHeight);
 | 
						|
 | 
						|
                    offset = Math.Min(offset, CalendarView.WeekDayVScrollPanel.ScrollBar.Maximum);
 | 
						|
                    offset = Math.Max(offset, 0);
 | 
						|
 | 
						|
                    CalendarView.WeekDayVScrollPanel.ScrollBar.Value = offset;
 | 
						|
 | 
						|
                    return (true);
 | 
						|
                }
 | 
						|
 | 
						|
                return (false);
 | 
						|
            }
 | 
						|
 | 
						|
            return (true);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region TimeSlice support routines
 | 
						|
 | 
						|
        #region GetPointItem
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the column and slice index item for
 | 
						|
        /// the given point
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pt">Point</param>
 | 
						|
        /// <param name="col">[out] DayColumn column</param>
 | 
						|
        /// <param name="slice">[out] Time slice</param>
 | 
						|
        /// <param name="partial"></param>
 | 
						|
        /// <returns>Item visible state</returns>
 | 
						|
        private bool GetPointItem(Point pt, out int col, out int slice, bool partial)
 | 
						|
        {
 | 
						|
            slice = -1;
 | 
						|
 | 
						|
            if ((col = GetPointCol(pt)) >= 0)
 | 
						|
            {
 | 
						|
                slice = GetPointSlice(pt, col);
 | 
						|
 | 
						|
                if (slice >= 0 && slice < NumberOfActiveSlices)
 | 
						|
                    return (IsSliceVisible(col, slice, partial));
 | 
						|
            }
 | 
						|
 | 
						|
            return (false);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region IsSliceVisible
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Determines if a given slice is visible
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">DayColumn</param>
 | 
						|
        /// <param name="slice">Slice in question</param>
 | 
						|
        /// <param name="partial">Partially visible is ok</param>
 | 
						|
        /// <returns>Slice visibility</returns>
 | 
						|
        private bool IsSliceVisible(int col, int slice, bool partial)
 | 
						|
        {
 | 
						|
            Rectangle r = GetSliceRect(col, slice);
 | 
						|
            Rectangle t = ViewRect;
 | 
						|
 | 
						|
            if (partial == true)
 | 
						|
            {
 | 
						|
                if (r.Bottom < t.Top)
 | 
						|
                    return (false);
 | 
						|
 | 
						|
                if (r.Top > t.Bottom)
 | 
						|
                    return (false);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                if (r.Top < t.Top)
 | 
						|
                    return (false);
 | 
						|
 | 
						|
                if (r.Bottom > t.Bottom)
 | 
						|
                    return (false);
 | 
						|
            }
 | 
						|
 | 
						|
            return (true);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetSliceRect
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the given slice rectangle
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">Column</param>
 | 
						|
        /// <param name="slice">Slice</param>
 | 
						|
        /// <returns>Bounding rectangle</returns>
 | 
						|
        private Rectangle GetSliceRect(int col, int slice)
 | 
						|
        {
 | 
						|
            if ((uint)col < _DayColumns.Length)
 | 
						|
            {
 | 
						|
                Rectangle r = _DayColumns[col].Bounds;
 | 
						|
 | 
						|
                float n = slice * TimeSliceHeight;
 | 
						|
 | 
						|
                r.Y += (int)(n);
 | 
						|
                r.Height = (int)(n + TimeSliceHeight) - (int)n;
 | 
						|
 | 
						|
                return (r);
 | 
						|
            }
 | 
						|
 | 
						|
            return (Rectangle.Empty);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetPointCol
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the col index for the given point
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pt">Point</param>
 | 
						|
        /// <returns>Column</returns>
 | 
						|
        private int GetPointCol(Point pt)
 | 
						|
        {
 | 
						|
            for (int i = 0; i < _NumberOfColumns; i++)
 | 
						|
            {
 | 
						|
                if (pt.X >= _DayColumns[i].Bounds.X &&
 | 
						|
                    pt.X < _DayColumns[i].Bounds.Right)
 | 
						|
                {
 | 
						|
                    return (i);
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (-1);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetPointSlice
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the slice index for the given point
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pt">Point</param>
 | 
						|
        /// <param name="col"></param>
 | 
						|
        /// <returns>Slice index</returns>
 | 
						|
        private int GetPointSlice(Point pt, int col)
 | 
						|
        {
 | 
						|
            int s1 = (int)(-_VScrollPos / TimeSliceHeight);
 | 
						|
 | 
						|
            Rectangle r = GetSliceRect(col, s1);
 | 
						|
 | 
						|
            if (pt.Y < r.Top)
 | 
						|
                return (s1 - 1);
 | 
						|
 | 
						|
            for (int i = s1; i < NumberOfActiveSlices; i++)
 | 
						|
            {
 | 
						|
                r = GetSliceRect(col, i);
 | 
						|
 | 
						|
                if (pt.Y >= r.Top && pt.Y < r.Bottom)
 | 
						|
                    return (i);
 | 
						|
            }
 | 
						|
 | 
						|
            return (NumberOfActiveSlices - 1);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetTime
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the DateTime adjusted by the given
 | 
						|
        /// slice and minutes delta
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="date"></param>
 | 
						|
        /// <param name="slice"></param>
 | 
						|
        /// <param name="minutes"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        private DateTime GetTime(DateTime date, int slice, int minutes)
 | 
						|
        {
 | 
						|
            return (date.AddMinutes((StartSlice + slice) * TimeSlotDuration + minutes));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region IDisposable Members
 | 
						|
 | 
						|
        protected override void Dispose(bool disposing)
 | 
						|
        {
 | 
						|
            if (disposing == true && IsDisposed == false)
 | 
						|
            {
 | 
						|
                ResetView();
 | 
						|
 | 
						|
                BusyBrush = null;
 | 
						|
                WorkBrush = null;
 | 
						|
                OffWorkBrush = null;
 | 
						|
                SelectedBrush = null;
 | 
						|
 | 
						|
                HookEvents(false);
 | 
						|
            }
 | 
						|
 | 
						|
            base.Dispose(disposing);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Copy object support
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Returns copy of the item.
 | 
						|
        /// </summary>
 | 
						|
        public override BaseItem Copy()
 | 
						|
        {
 | 
						|
            WeekDayView objCopy = new WeekDayView(this.CalendarView, this.ECalendarView);
 | 
						|
            CopyToItem(objCopy);
 | 
						|
 | 
						|
            return (objCopy);
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Copies the WeekDayView specific properties to new instance of the item.
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="copy">New WeekDayView instance</param>
 | 
						|
        protected override void CopyToItem(BaseItem copy)
 | 
						|
        {
 | 
						|
            WeekDayView objCopy = copy as WeekDayView;
 | 
						|
            base.CopyToItem(objCopy);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DaySlot class def
 | 
						|
 | 
						|
        private class DaySlot
 | 
						|
        {
 | 
						|
            public Rectangle Bounds;
 | 
						|
            public bool Selected;
 | 
						|
            public DaySlotAppearance Appearance;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
    }
 | 
						|
}
 | 
						|
#endif
 |