3356 lines
		
	
	
		
			100 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			3356 lines
		
	
	
		
			100 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
#if FRAMEWORK20
 | 
						|
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Drawing;
 | 
						|
using System.Drawing.Drawing2D;
 | 
						|
using System.Windows.Forms;
 | 
						|
using DevComponents.DotNetBar.ScrollBar;
 | 
						|
using DevComponents.Schedule.Model;
 | 
						|
 | 
						|
namespace DevComponents.DotNetBar.Schedule
 | 
						|
{
 | 
						|
    public class TimeLineView : BaseView
 | 
						|
    {
 | 
						|
        #region Static variables
 | 
						|
 | 
						|
        static private AppointmentColor _appointmentColor = new AppointmentColor();
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Private variables
 | 
						|
 | 
						|
        private CalendarWeekDayColor _ViewColor =       // View display color table
 | 
						|
            new CalendarWeekDayColor(eCalendarColor.Automatic);
 | 
						|
 | 
						|
        private List<CalendarItem>
 | 
						|
            _CalendarItems = new List<CalendarItem>();
 | 
						|
 | 
						|
        private Point _LastMovePoint;           // Last mouse move Point
 | 
						|
        private Point _LastPointOffset;         // Last Point offset
 | 
						|
        private Rectangle _LastBounds;          // MouseDown item bounds
 | 
						|
 | 
						|
        private int _SelectedColStart;          // Column start selection
 | 
						|
        private int _SelectedColEnd;            // Column end selection
 | 
						|
 | 
						|
        private Timer _ScrollViewTimer;         // Timer used to implement auto view scrolling
 | 
						|
        private int _ScrollDwell;               // Scroll dwell (pause, throttle) counter
 | 
						|
 | 
						|
        private Color _WorkColor;               // Cached Brush colors
 | 
						|
        private Color _OffWorkColor;
 | 
						|
        private Color _SelectedColor;
 | 
						|
 | 
						|
        private Brush _WorkBrush;               // Cached Brushes
 | 
						|
        private Brush _OffWorkBrush;
 | 
						|
        private Brush _SelectedBrush;
 | 
						|
 | 
						|
        private int _HScrollPos;                // Horizontal scroll position
 | 
						|
 | 
						|
        private List<ColumnList> _CondensedColList;
 | 
						|
        private List<int> _CollateLines = new List<int>();
 | 
						|
 | 
						|
        private bool _ModelReloaded = true;
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        public TimeLineView(CalendarView calendarView, eCalendarView eCalendarView)
 | 
						|
            : base(calendarView, eCalendarView)
 | 
						|
        {
 | 
						|
            // Set our non-client drawing info and CalendarColor
 | 
						|
 | 
						|
            NClientData = new NonClientData(
 | 
						|
                eTabOrientation.Vertical,
 | 
						|
                (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);
 | 
						|
 | 
						|
            if (calendarView.TimeLineHScrollPanel.ScrollBar != null)
 | 
						|
            {
 | 
						|
                _HScrollPos = -calendarView.TimeLineHScrollPanel.ScrollBar.Value *
 | 
						|
                    calendarView.TimeLineColumnWidth;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region Public properties
 | 
						|
 | 
						|
        #region CalendarItems
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets array of CalendarItems
 | 
						|
        /// </summary>
 | 
						|
        public List<CalendarItem> CalendarItems
 | 
						|
        {
 | 
						|
            get { return (_CalendarItems); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region StartDate
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Start date - readonly
 | 
						|
        /// </summary>
 | 
						|
        public new DateTime StartDate
 | 
						|
        {
 | 
						|
            get { return (base.StartDate); }
 | 
						|
            internal set { base.StartDate = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region EndDate
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// End date - readonly
 | 
						|
        /// </summary>
 | 
						|
        public new DateTime EndDate
 | 
						|
        {
 | 
						|
            get { return (base.EndDate); }
 | 
						|
            internal set { base.EndDate = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ColumnWidth
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the ColumnWidth
 | 
						|
        /// </summary>
 | 
						|
        public int ColumnWidth
 | 
						|
        {
 | 
						|
            get { return (CalendarView.TimeLineColumnWidth); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region BaseInterval
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the BaseInterval (interval in total minutes)
 | 
						|
        /// </summary>
 | 
						|
        public double BaseInterval
 | 
						|
        {
 | 
						|
            get { return (CalendarView.BaseInterval); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region TimeLineColumnCount
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the number of Columns
 | 
						|
        /// </summary>
 | 
						|
        public int TimeLineColumnCount
 | 
						|
        {
 | 
						|
            get { return (CalendarView.TimeLineColumnCount); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MinAppointmentWidth
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the MinAppointmentWidth
 | 
						|
        /// </summary>
 | 
						|
        public int MinAppointmentWidth
 | 
						|
        {
 | 
						|
            get { return (CalendarView.TimeLineMinAppointmentWidth); }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Private properties
 | 
						|
 | 
						|
        #region ShowCondensed
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the CondensedView visibility state
 | 
						|
        /// </summary>
 | 
						|
        private bool ShowCondensed
 | 
						|
        {
 | 
						|
            get
 | 
						|
            {
 | 
						|
                if (CalendarView.TimeLineCondensedViewVisibility == eCondensedViewVisibility.Hidden)
 | 
						|
                    return (false);
 | 
						|
 | 
						|
                if (CalendarView.TimeLineCondensedViewHeight < 10)
 | 
						|
                    return (false);
 | 
						|
 | 
						|
                if (CalendarView.TimeLineCondensedViewVisibility == eCondensedViewVisibility.AllResources)
 | 
						|
                    return (true);
 | 
						|
 | 
						|
                return (CalendarView.SelectedOwnerIndex == DisplayedOwnerKeyIndex);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Cached Brushes
 | 
						|
 | 
						|
        #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 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
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region Internal Properties
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the first visible timeline column
 | 
						|
        /// </summary>
 | 
						|
        internal int FirstVisibleColumn
 | 
						|
        {
 | 
						|
            get { return (-_HScrollPos / ColumnWidth); }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the condensed time line height
 | 
						|
        /// </summary>
 | 
						|
        internal int CondensedLineHeight
 | 
						|
        {
 | 
						|
            get { return (CalendarView.TimeLineCondensedViewHeight); }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets and sets the model reload state
 | 
						|
        /// </summary>
 | 
						|
        internal bool ModelReloaded
 | 
						|
        {
 | 
						|
            get { return (_ModelReloaded); }
 | 
						|
            set { _ModelReloaded = value; }
 | 
						|
        }
 | 
						|
 | 
						|
        #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.SelectedOwnerChanged += SelectedOwnerChanged;
 | 
						|
 | 
						|
                CalendarView.TimeLineViewStartDateChanged += TimeLineViewStartDateChanged;
 | 
						|
                CalendarView.TimeLineViewEndDateChanged += TimeLineViewEndDateChanged;
 | 
						|
                CalendarView.TimeLineIntervalChanged += TimeLineIntervalChanged;
 | 
						|
                CalendarView.TimeLineIntervalPeriodChanged += TimeLineIntervalPeriodChanged;
 | 
						|
                CalendarView.TimeLineCondensedViewVisibilityChanged += TimeLineCondensedViewVisibilityChanged;
 | 
						|
 | 
						|
                CalendarView.TimeLineHScrollPanel.ScrollPanelChanged += ScrollPanelChanged;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                CalendarView.SelectedViewChanged -= SelectedViewChanged;
 | 
						|
                CalendarView.SelectedOwnerChanged -= SelectedOwnerChanged;
 | 
						|
 | 
						|
                CalendarView.TimeLineViewStartDateChanged -= TimeLineViewStartDateChanged;
 | 
						|
                CalendarView.TimeLineViewEndDateChanged -= TimeLineViewEndDateChanged;
 | 
						|
                CalendarView.TimeLineIntervalChanged -= TimeLineIntervalChanged;
 | 
						|
                CalendarView.TimeLineIntervalPeriodChanged -= TimeLineIntervalPeriodChanged;
 | 
						|
                CalendarView.TimeLineCondensedViewVisibilityChanged -= TimeLineCondensedViewVisibilityChanged;
 | 
						|
 | 
						|
                CalendarView.TimeLineHScrollPanel.ScrollPanelChanged -= ScrollPanelChanged;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #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 == ECalendarView);
 | 
						|
 | 
						|
            if (IsViewSelected == true)
 | 
						|
            {
 | 
						|
                AutoSyncViewDate(e.OldValue);
 | 
						|
                UpdateDateSelection();
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                ResetView();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SelectedOwnerChanged
 | 
						|
 | 
						|
        void SelectedOwnerChanged(object sender, SelectedOwnerChangedEventArgs e)
 | 
						|
        {
 | 
						|
            if (CalendarView.TimeLineStretchRowHeight == true)
 | 
						|
            {
 | 
						|
                if (CalendarView.TimeLineCondensedViewVisibility == eCondensedViewVisibility.SelectedResource)
 | 
						|
                    NeedRecalcLayout = true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region TimeLineViewStartDateChanged
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes StartDate changes
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender"></param>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        void TimeLineViewStartDateChanged(object sender, DateChangeEventArgs e)
 | 
						|
        {
 | 
						|
            StartDate = e.NewValue;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region TimeLineViewEndDateChanged
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes EndDate changes
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender"></param>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        void TimeLineViewEndDateChanged(object sender, DateChangeEventArgs e)
 | 
						|
        {
 | 
						|
            EndDate = e.NewValue;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region TimeLineIntervalPeriodChanged
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles IntervalPeriodChange notification
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender"></param>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        void TimeLineIntervalPeriodChanged(object sender, TimeLineIntervalPeriodChangedEventArgs e)
 | 
						|
        {
 | 
						|
            NeedRecalcSize = true;
 | 
						|
            NeedRecalcLayout = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region TimeLineIntervalChanged
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles IntervalChange notification
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender"></param>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        void TimeLineIntervalChanged(object sender, TimeLineIntervalChangedEventArgs e)
 | 
						|
        {
 | 
						|
            NeedRecalcSize = true;
 | 
						|
            NeedRecalcLayout = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region TimeLineCondensedViewVisibilityChanged
 | 
						|
 | 
						|
        void TimeLineCondensedViewVisibilityChanged(
 | 
						|
            object sender, TimeLineCondensedViewVisibilityChangedEventArgs e)
 | 
						|
        {
 | 
						|
            if (CalendarView.TimeLineStretchRowHeight == true)
 | 
						|
                NeedRecalcLayout = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ScrollPanelChanged
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles ScrollPanel change notification
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender"></param>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        void ScrollPanelChanged(object sender, EventArgs e)
 | 
						|
        {
 | 
						|
            TimeLineHScrollPanel panel = sender as TimeLineHScrollPanel;
 | 
						|
 | 
						|
            if (panel != null)
 | 
						|
            {
 | 
						|
                HScrollBarAdv hScrollBar = panel.ScrollBar;
 | 
						|
 | 
						|
                _HScrollPos = -hScrollBar.Value * CalendarView.TimeLineColumnWidth;
 | 
						|
 | 
						|
                // Redraw our view
 | 
						|
 | 
						|
                if (Displayed == true)
 | 
						|
                {
 | 
						|
                    NeedRecalcLayout = true;
 | 
						|
 | 
						|
                    InvalidateRect(true);
 | 
						|
                    Refresh();
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #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.X >= ClientRect.X)
 | 
						|
                {
 | 
						|
                    // CondensedView
 | 
						|
 | 
						|
                    if (ShowCondensed == true)
 | 
						|
                    {
 | 
						|
                        if (GetCondensedRect().Contains(pt) == true)
 | 
						|
                            return (eViewArea.InCondensedView);
 | 
						|
                    }
 | 
						|
 | 
						|
                    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
 | 
						|
        /// </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;
 | 
						|
 | 
						|
            if (GetPointItem(pt, out col, true) == true)
 | 
						|
            {
 | 
						|
                startDate = CalendarView.TimeLineAddInterval(StartDate, col);
 | 
						|
                endDate = CalendarView.TimeLineAddInterval(startDate, 1);
 | 
						|
 | 
						|
                return (true);
 | 
						|
            }
 | 
						|
 | 
						|
            return (false);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SetSelectedItem
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles selected item changes
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender">CalendarItem</param>
 | 
						|
        /// <param name="e">EventArgs</param>
 | 
						|
        public void ItemIsSelectedChanged(object sender, EventArgs e)
 | 
						|
        {
 | 
						|
            CalendarItem ci = sender as CalendarItem;
 | 
						|
 | 
						|
            if (ci != null)
 | 
						|
            {
 | 
						|
                if (ci.IsSelected == true)
 | 
						|
                {
 | 
						|
                    if (SelectedItem != null && ci != SelectedItem)
 | 
						|
                        SelectedItem.IsSelected = false;
 | 
						|
 | 
						|
                    SelectedItem = ci;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    if (ci == SelectedItem)
 | 
						|
                        SelectedItem = null;
 | 
						|
                }
 | 
						|
 | 
						|
                // Make sure the selection is reflected
 | 
						|
                // in the condensed view (if present)
 | 
						|
 | 
						|
                if (ShowCondensed == true)
 | 
						|
                    InvalidateRect(GetCondensedRect());
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Sets the current selected item
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pci">Previous CalendarItem</param>
 | 
						|
        /// <param name="nci">New CalendarItem</param>
 | 
						|
        /// <returns>New selected CalendarItem</returns>
 | 
						|
        protected override CalendarItem SetSelectedItem(CalendarItem pci, CalendarItem nci)
 | 
						|
        {
 | 
						|
            if (nci != null)
 | 
						|
                nci.IsSelected = true;
 | 
						|
 | 
						|
            else if (pci != null)
 | 
						|
                pci.IsSelected = false;
 | 
						|
 | 
						|
            return (nci);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #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 colStart = GetDateCol(DateSelectionStart);
 | 
						|
                int colEnd = GetDateCol(DateSelectionEnd);
 | 
						|
 | 
						|
                // Limit our range to only those columns
 | 
						|
                // that are visible on the screen
 | 
						|
 | 
						|
                int c1 = -_HScrollPos / ColumnWidth;
 | 
						|
                int c2 = c1 + ClientRect.Width / ColumnWidth + 1;
 | 
						|
 | 
						|
                if (c2 > c1)
 | 
						|
                {
 | 
						|
                    ProcessSelRange(colStart, colEnd, c1, c2);
 | 
						|
 | 
						|
                    // Save our new selection range
 | 
						|
 | 
						|
                    _SelectedColStart = colStart;
 | 
						|
                    _SelectedColEnd = colEnd;
 | 
						|
                }
 | 
						|
 | 
						|
                if (ShowCondensed == true)
 | 
						|
                {
 | 
						|
                    Rectangle r = GetCondensedRect();
 | 
						|
 | 
						|
                    this.InvalidateRect(r);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes the selection time column range
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="colStart">Column range start</param>
 | 
						|
        /// <param name="colEnd">Column range end</param>
 | 
						|
        /// <param name="c1">Column start limit</param>
 | 
						|
        /// <param name="c2">Column end limit</param>
 | 
						|
        private void ProcessSelRange(int colStart, int colEnd, int c1, int c2)
 | 
						|
        {
 | 
						|
            bool[] oldSelected = SelectedColumns(c1, c2, _SelectedColStart, _SelectedColEnd);
 | 
						|
            bool[] newSelected = SelectedColumns(c1, c2, colStart, colEnd);
 | 
						|
 | 
						|
            // Invalidate those slices whose
 | 
						|
            // selection status changed
 | 
						|
 | 
						|
            Rectangle r = GetColRect(c1);
 | 
						|
 | 
						|
            if (r.Width > 0 && r.Height > 0)
 | 
						|
            {
 | 
						|
                for (int i = 0; i < c2 - c1; i++)
 | 
						|
                {
 | 
						|
                    if (oldSelected[i] != newSelected[i])
 | 
						|
                        InvalidateRect(r);
 | 
						|
 | 
						|
                    r.X += ColumnWidth;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets an array of column selection values
 | 
						|
        /// over the given range of columns
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="c1">Column start limit</param>
 | 
						|
        /// <param name="c2">Column end limit</param>
 | 
						|
        /// <param name="colStart">Slice range start</param>
 | 
						|
        /// <param name="colEnd">Slice range end</param>
 | 
						|
        /// <returns>Array of selection values</returns>
 | 
						|
        private bool[] SelectedColumns(int c1, int c2, int colStart, int colEnd)
 | 
						|
        {
 | 
						|
            // Calculate our number of entries and
 | 
						|
            // allocate our IsSelected array accordingly
 | 
						|
 | 
						|
            int n = c2 - c1;
 | 
						|
            bool[] sel = new bool[n + 1];
 | 
						|
 | 
						|
            // Loop through the range of entries determining if
 | 
						|
            // the specific col is within the selection range
 | 
						|
 | 
						|
            for (int i = 0; i < n; i++)
 | 
						|
                sel[i] = (c1 + i >= colStart && c1 + i < colEnd);
 | 
						|
 | 
						|
            // Return the array to the caller
 | 
						|
 | 
						|
            return (sel);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region RecalcSize routines
 | 
						|
 | 
						|
        /// <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);
 | 
						|
 | 
						|
                // Update our Model connection view,
 | 
						|
                // CalendarItems, and DateSelection
 | 
						|
 | 
						|
                UpdateView();
 | 
						|
                UpdateDateSelection();
 | 
						|
            }
 | 
						|
 | 
						|
            NeedRecalcLayout = false;
 | 
						|
        }
 | 
						|
 | 
						|
        #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 UpdateView
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Updates our connection model view
 | 
						|
        /// </summary>
 | 
						|
        private void UpdateView()
 | 
						|
        {
 | 
						|
            // Make sure we have a model connection
 | 
						|
 | 
						|
            if (Connector == null)
 | 
						|
            {
 | 
						|
                if (CalendarModel != null)
 | 
						|
                    Connector = new ModelTimeLineViewConnector(CalendarModel, this);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                // The timeline range could have changed, so let
 | 
						|
                // the connection refresh the data if needed
 | 
						|
 | 
						|
                ((ModelTimeLineViewConnector)Connector).RefreshData(false);
 | 
						|
            }
 | 
						|
 | 
						|
            // We have a connection, so update our CalendarItems
 | 
						|
 | 
						|
            if (Connector != null)
 | 
						|
            {
 | 
						|
                UpdateCalendarItems();
 | 
						|
 | 
						|
                if (ShowCondensed == true)
 | 
						|
                    UpdateCondensedColumnList();
 | 
						|
 | 
						|
                CalendarView.DoViewLoadComplete(this);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ResetView
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Disconnects and resets the Model connection
 | 
						|
        /// </summary>
 | 
						|
        internal override void ResetView()
 | 
						|
        {
 | 
						|
            _ModelReloaded = true;
 | 
						|
 | 
						|
            base.ResetView();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region UpdateCalendarItems
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Updates our CalendarItems list
 | 
						|
        /// </summary>
 | 
						|
        private void UpdateCalendarItems()
 | 
						|
        {
 | 
						|
            if (NeedRecalcLayout == true)
 | 
						|
            {
 | 
						|
                _CollateLines.Clear();
 | 
						|
 | 
						|
                if (_CalendarItems.Count > 0)
 | 
						|
                {
 | 
						|
                    List<CalendarItem> items = SortCalendarItems(_CalendarItems);
 | 
						|
 | 
						|
                    if (CalendarView.HasTimeLineGetRowCollateIdCallout)
 | 
						|
                    {
 | 
						|
                        SortedDictionary<int, List<CalendarItem>> ditems = CollateCalendarItems(items);
 | 
						|
 | 
						|
                        int dy = 0;
 | 
						|
 | 
						|
                        foreach (KeyValuePair<int, List<CalendarItem>> kvp in ditems)
 | 
						|
                        {
 | 
						|
                            ColumnList colList = new ColumnList();
 | 
						|
 | 
						|
                            for (int i = 0; i < kvp.Value.Count; i++)
 | 
						|
                                colList.AddColumnSlot(kvp.Value[i], 0);
 | 
						|
 | 
						|
                            colList.CountColumns();
 | 
						|
 | 
						|
                            dy = CalcAppointmentBounds(colList, dy, true);
 | 
						|
 | 
						|
                            _CollateLines.Add(dy);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        ColumnList colList = new ColumnList();
 | 
						|
 | 
						|
                        for (int i = 0; i < items.Count; i++)
 | 
						|
                            colList.AddColumnSlot(items[i], 0);
 | 
						|
 | 
						|
                        colList.CountColumns();
 | 
						|
 | 
						|
                        CalcAppointmentBounds(colList, 0, false);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                NeedRecalcLayout = false;
 | 
						|
 | 
						|
                InvalidateRect();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region CollateCalendarItems
 | 
						|
 | 
						|
        private SortedDictionary<int, List<CalendarItem>>
 | 
						|
            CollateCalendarItems(List<CalendarItem> items)
 | 
						|
        {
 | 
						|
            SortedDictionary<int, List<CalendarItem>> citems =
 | 
						|
                new SortedDictionary<int, List<CalendarItem>>();
 | 
						|
 | 
						|
            for (int i = 0; i < items.Count; i++)
 | 
						|
            {
 | 
						|
                if (items[i].CollateId < 0)
 | 
						|
                {
 | 
						|
                    TimeLineGetRowCollateIdEventArgs e =
 | 
						|
                        new TimeLineGetRowCollateIdEventArgs(items[i]);
 | 
						|
 | 
						|
                    CalendarView.DoTimeLineGetRowCollateId(e);
 | 
						|
 | 
						|
                    items[i].CollateId = e.CollateId;
 | 
						|
                }
 | 
						|
 | 
						|
                int collateId = items[i].CollateId;
 | 
						|
 | 
						|
                if (citems.ContainsKey(collateId) == false)
 | 
						|
                    citems.Add(collateId, new List<CalendarItem>());
 | 
						|
 | 
						|
                citems[collateId].Add(items[i]);
 | 
						|
            }
 | 
						|
 | 
						|
            return (citems);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SortCalendarItems
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Sorts the provided CalendarItems
 | 
						|
        /// </summary>
 | 
						|
        /// <returns>Sorted CalendarItems</returns>
 | 
						|
        private List<CalendarItem> SortCalendarItems(IEnumerable<CalendarItem> clist)
 | 
						|
        {
 | 
						|
            List<CalendarItem> items = new List<CalendarItem>();
 | 
						|
 | 
						|
            items.AddRange(clist);
 | 
						|
 | 
						|
            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 < c2.EndTime)
 | 
						|
                           return (1);
 | 
						|
 | 
						|
                       if (c1.EndTime > c2.EndTime)
 | 
						|
                           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="colList">Accumulated ColumnList</param>
 | 
						|
        /// <param name="dy"></param>
 | 
						|
        /// <param name="collate"></param>
 | 
						|
        private int CalcAppointmentBounds(ColumnList colList, int dy, bool collate)
 | 
						|
        {
 | 
						|
            if (colList.SList.Count > 0)
 | 
						|
            {
 | 
						|
                // If we are stretching the rows height, then calculate
 | 
						|
                // the default row height and the row spread, to evenly
 | 
						|
                // distribute the fill remainder
 | 
						|
 | 
						|
                bool stretchRow = (collate == false && 
 | 
						|
                    CalendarView.TimeLineStretchRowHeight == true);
 | 
						|
 | 
						|
                int height = GetColRect(0).Height;
 | 
						|
 | 
						|
                int rowSpread;
 | 
						|
                int rowHeight = GetColumnRowHeight(colList.SList.Count, stretchRow, height, out rowSpread) - 2;
 | 
						|
 | 
						|
                for (int i = 0; i < colList.SList.Count; i++)
 | 
						|
                {
 | 
						|
                    int maxRowHeight = 0;
 | 
						|
 | 
						|
                    for (int j = 0; j < colList.SList[i].Count; j++)
 | 
						|
                    {
 | 
						|
                        SlotItem sitem = colList.SList[i][j];
 | 
						|
                        CalendarItem item = sitem.CItem;
 | 
						|
 | 
						|
                        Rectangle r = new Rectangle();
 | 
						|
 | 
						|
                        r.Y = ClientRect.Y + dy;
 | 
						|
                        r.Height = rowHeight;
 | 
						|
 | 
						|
                        if (stretchRow == false)
 | 
						|
                            r.Height = GetRowHeight(item, rowHeight);
 | 
						|
 | 
						|
                        TimeSpan ts1 = item.StartTime - StartDate;
 | 
						|
                        TimeSpan ts2 = item.EndTime - item.StartTime;
 | 
						|
 | 
						|
                        int pos = (int) ((ts1.TotalMinutes * ColumnWidth) / BaseInterval);
 | 
						|
                        int width = (int) ((ts2.TotalMinutes * ColumnWidth) / BaseInterval);
 | 
						|
 | 
						|
                        if (CalendarView.TimeLinePeriod == eTimeLinePeriod.Years)
 | 
						|
                        {
 | 
						|
                            int years = item.StartTime.Year - StartDate.Year;
 | 
						|
 | 
						|
                            pos = (years * ColumnWidth) / CalendarView.TimeLineInterval;
 | 
						|
                        }
 | 
						|
 | 
						|
                        if (width < MinAppointmentWidth)
 | 
						|
                            width = MinAppointmentWidth;
 | 
						|
 | 
						|
                        if (width < 4)
 | 
						|
                            width = 4;
 | 
						|
 | 
						|
                        r.X = ClientRect.X + pos + _HScrollPos;
 | 
						|
                        r.Width = width;
 | 
						|
 | 
						|
                        Rectangle p = ClientRect;
 | 
						|
                        int hpad = CalendarView.TimeLineHorizontalPadding;
 | 
						|
 | 
						|
                        if (r.Left >= p.Left)
 | 
						|
                        {
 | 
						|
                            r.X += hpad;
 | 
						|
                            r.Width -= hpad;
 | 
						|
                        }
 | 
						|
 | 
						|
                        if (r.Right <= p.Right)
 | 
						|
                            r.Width -= hpad;
 | 
						|
 | 
						|
                        if (i < rowSpread)
 | 
						|
                            r.Height++;
 | 
						|
 | 
						|
                        if (item.StartTime != item.EndTime)
 | 
						|
                        {
 | 
						|
                            if (r.Height + 2 > maxRowHeight)
 | 
						|
                                maxRowHeight = r.Height + 2;
 | 
						|
                        }
 | 
						|
 | 
						|
                        if (stretchRow == true)
 | 
						|
                        {
 | 
						|
                            if (CalendarView.TimeLineStretchRowHeightMode == TimeLineStretchRowHeightMode.Full)
 | 
						|
                            {
 | 
						|
                                if (sitem.SList == null)
 | 
						|
                                {
 | 
						|
                                    r.Height = height - dy - 2;
 | 
						|
                                }
 | 
						|
                                else
 | 
						|
                                {
 | 
						|
                                    int n = GetColumnCount(sitem);
 | 
						|
 | 
						|
                                    r.Height = (rowHeight + 1) * n - 1;
 | 
						|
 | 
						|
                                    for (int k = 0; k < n; k++)
 | 
						|
                                    {
 | 
						|
                                        if (i + k >= rowSpread)
 | 
						|
                                            break;
 | 
						|
 | 
						|
                                        r.Height++;
 | 
						|
                                    }
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                            
 | 
						|
                        r.Height++;
 | 
						|
 | 
						|
                        item.Bounds = r;
 | 
						|
 | 
						|
                        // Set it's display state
 | 
						|
 | 
						|
                        item.Displayed = r.IntersectsWith(ClientRect);
 | 
						|
                    }
 | 
						|
 | 
						|
                    dy += maxRowHeight;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (dy);
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetColumnCount
 | 
						|
 | 
						|
        private int GetColumnCount(SlotItem sitem)
 | 
						|
        {
 | 
						|
            int column = int.MaxValue;
 | 
						|
 | 
						|
            for (int i = 0; i < sitem.SList.Count; i++)
 | 
						|
            {
 | 
						|
                if (sitem.SList[i].Column < column)
 | 
						|
                    column = sitem.SList[i].Column;
 | 
						|
            }
 | 
						|
 | 
						|
            return (column - sitem.Column);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetColumnRowHeight
 | 
						|
 | 
						|
        private int GetColumnRowHeight(int count, bool stretchRow, int height, out int rowSpread)
 | 
						|
        {
 | 
						|
            rowSpread = 0;
 | 
						|
 | 
						|
            int rowHeight = AppointmentHeight;
 | 
						|
 | 
						|
            if (stretchRow == true)
 | 
						|
            {
 | 
						|
                rowHeight = height / count;
 | 
						|
 | 
						|
                if (rowHeight < AppointmentHeight)
 | 
						|
                    rowHeight = AppointmentHeight;
 | 
						|
                else
 | 
						|
                    rowSpread = height - (count * rowHeight);
 | 
						|
            }
 | 
						|
 | 
						|
            return (rowHeight);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetRowHeight
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Get the RowHeight for the given CalendarItem
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="item">CalendarItem</param>
 | 
						|
        /// <param name="height">Calculated height</param>
 | 
						|
        /// <returns></returns>
 | 
						|
        private int GetRowHeight(CalendarItem item, int height)
 | 
						|
        {
 | 
						|
            TimeLineGetRowHeightEventArgs e =
 | 
						|
                new TimeLineGetRowHeightEventArgs(item, height);
 | 
						|
 | 
						|
            CalendarView.DoTimeLineGetRowHeight(e);
 | 
						|
 | 
						|
            return (e.Height);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region UpdateCondensedColumnList
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Updates the condensed view column list
 | 
						|
        /// </summary>
 | 
						|
        internal void UpdateCondensedColumnList()
 | 
						|
        {
 | 
						|
            if (_ModelReloaded == true && Connector != null)
 | 
						|
            {
 | 
						|
                _CondensedColList = new List<ColumnList>();
 | 
						|
 | 
						|
                List<CalendarItem> items = new List<CalendarItem>();
 | 
						|
 | 
						|
                // Get our appointment collection
 | 
						|
 | 
						|
                GetCondensedAppts(items);
 | 
						|
                GetCondensedCustomItems(items);
 | 
						|
 | 
						|
                // If we have any items, sort them and
 | 
						|
                // create a corresponding ColumnList
 | 
						|
 | 
						|
                if (items.Count > 0)
 | 
						|
                {
 | 
						|
                    items = SortCalendarItems(items);
 | 
						|
 | 
						|
                    if (CalendarView.HasTimeLineGetRowCollateIdCallout)
 | 
						|
                    {
 | 
						|
                        SortedDictionary<int, List<CalendarItem>> ditems = CollateCalendarItems(items);
 | 
						|
 | 
						|
                        foreach (KeyValuePair<int, List<CalendarItem>> kvp in ditems)
 | 
						|
                        {
 | 
						|
                            ColumnList colList = new ColumnList();
 | 
						|
 | 
						|
                            for (int i = 0; i < kvp.Value.Count; i++)
 | 
						|
                                colList.AddColumnSlot(kvp.Value[i], 0);
 | 
						|
 | 
						|
                            colList.CountColumns();
 | 
						|
 | 
						|
                            _CondensedColList.Add(colList);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    else
 | 
						|
                    {
 | 
						|
                        _CondensedColList.Add(new ColumnList());
 | 
						|
 | 
						|
                        for (int i = 0; i < items.Count; i++)
 | 
						|
                            _CondensedColList[0].AddColumnSlot(items[i], 0);
 | 
						|
 | 
						|
                        _CondensedColList[0].CountColumns();
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                _ModelReloaded = false;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetCondensedAppts
 | 
						|
 | 
						|
        private void GetCondensedAppts(List<CalendarItem> items)
 | 
						|
        {
 | 
						|
            List<Appointment> appts =
 | 
						|
                ((ModelTimeLineViewConnector)Connector).ListAppts;
 | 
						|
 | 
						|
            if (appts != null && appts.Count > 0)
 | 
						|
            {
 | 
						|
                int n = Math.Min(appts.Count, 500);
 | 
						|
                n = Math.Max(appts.Count / n, 1);
 | 
						|
 | 
						|
                for (int i = 0; i < appts.Count; i += n)
 | 
						|
                {
 | 
						|
                    if (IsAppointmentVisible(appts[i]) == true)
 | 
						|
                    {
 | 
						|
                        CalendarItem ci = new CalendarItem();
 | 
						|
 | 
						|
                        ci.StartTime = appts[i].StartTime;
 | 
						|
                        ci.EndTime = appts[i].EndTime;
 | 
						|
                        ci.ModelItem = appts[i];
 | 
						|
 | 
						|
                        items.Add(ci);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Determines if an appointment is visible
 | 
						|
        /// for the given DisplayOwner
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="app"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        private bool IsAppointmentVisible(Appointment app)
 | 
						|
        {
 | 
						|
            if (string.IsNullOrEmpty(DisplayedOwnerKey))
 | 
						|
                return (true);
 | 
						|
 | 
						|
            return (app.OwnerKey == DisplayedOwnerKey);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetCondensedCustomItems
 | 
						|
 | 
						|
        private void GetCondensedCustomItems(List<CalendarItem> items)
 | 
						|
        {
 | 
						|
            for (int i = 0; i < CalendarView.CustomItems.Count; i++)
 | 
						|
            {
 | 
						|
                CustomCalendarItem item = CalendarView.CustomItems[i];
 | 
						|
 | 
						|
                if (IsCustomItemVisible(item) == true &&
 | 
						|
                    (item.StartTime < EndDate && item.EndTime > StartDate))
 | 
						|
                {
 | 
						|
                    CalendarItem ci = new CalendarItem();
 | 
						|
 | 
						|
                    ci.StartTime = item.StartTime;
 | 
						|
                    ci.EndTime = item.EndTime;
 | 
						|
                    ci.ModelItem = item;
 | 
						|
 | 
						|
                    items.Add(ci);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        private bool IsCustomItemVisible(CustomCalendarItem item)
 | 
						|
        {
 | 
						|
            if (string.IsNullOrEmpty(Connector.DisplayOwnerKey))
 | 
						|
                return (true);
 | 
						|
 | 
						|
            return (item.OwnerKey.Equals(Connector.DisplayOwnerKey));
 | 
						|
        }
 | 
						|
 | 
						|
        #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();
 | 
						|
 | 
						|
            // calculate our Column count and range
 | 
						|
 | 
						|
            int colStart, colEnd;
 | 
						|
 | 
						|
            if (GetColRange(e, out colStart, out colEnd) > 0)
 | 
						|
            {
 | 
						|
                Region rgnSave = g.Clip;
 | 
						|
 | 
						|
                g.SetClip(ClientRect, CombineMode.Intersect);
 | 
						|
 | 
						|
                // Draw the TimeLine
 | 
						|
 | 
						|
                DrawTimeLine(g, colStart, colEnd);
 | 
						|
                DrawTimeIndicators(g, colStart, colEnd, eTimeIndicatorLevel.Bottom);
 | 
						|
 | 
						|
                if (Connector != null && ShowCondensed == true)
 | 
						|
                    DrawCondensedLine(g);
 | 
						|
 | 
						|
                // If we have a model connection then
 | 
						|
                // draw our appointments
 | 
						|
 | 
						|
                if (Connector != null && Connector.IsConnected)
 | 
						|
                {
 | 
						|
                    Rectangle r = ClientRect;
 | 
						|
                    r.X += 1;
 | 
						|
 | 
						|
                    if (ShowCondensed == true)
 | 
						|
                    {
 | 
						|
                        Rectangle r2 = GetCondensedRect();
 | 
						|
 | 
						|
                        if (r.Bottom > r2.Top)
 | 
						|
                            r.Height -= (r.Bottom - r2.Top);
 | 
						|
                    }
 | 
						|
 | 
						|
                    g.SetClip(r, CombineMode.Intersect);
 | 
						|
 | 
						|
                    DrawAppointments(e);
 | 
						|
                }
 | 
						|
 | 
						|
                DrawTimeIndicators(g, colStart, colEnd, eTimeIndicatorLevel.Top);
 | 
						|
 | 
						|
                g.Clip = rgnSave;
 | 
						|
 | 
						|
                // Update our pos window
 | 
						|
 | 
						|
                UpdatePosWin(ClientRect);
 | 
						|
            }
 | 
						|
 | 
						|
            // Let the base painting take place
 | 
						|
 | 
						|
            base.Paint(e);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawTimeLine
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Initiates the drawing of the TimeLine
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g">Graphics</param>
 | 
						|
        /// <param name="colStart">Starting column</param>
 | 
						|
        /// <param name="colEnd">Ending column</param>
 | 
						|
        private void DrawTimeLine(Graphics g, int colStart, int colEnd)
 | 
						|
        {
 | 
						|
            int n = colEnd - colStart;
 | 
						|
 | 
						|
            eSlotDisplayState[] states = new eSlotDisplayState[n + 1];
 | 
						|
 | 
						|
            for (int i = 0; i <= n; i++)
 | 
						|
                states[i] = GetSlotState(colStart + i);
 | 
						|
 | 
						|
            DrawContent(g, colStart, colEnd, states);
 | 
						|
            DrawBorder(g, colStart, colEnd, states);
 | 
						|
        }
 | 
						|
 | 
						|
        #region DrawContent
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws the content area of the TimeLine
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="colStart">Starting column</param>
 | 
						|
        /// <param name="colEnd">Ending column</param>
 | 
						|
        /// <param name="states"></param>
 | 
						|
        private void DrawContent(Graphics g,
 | 
						|
            int colStart, int colEnd, eSlotDisplayState[] states)
 | 
						|
        {
 | 
						|
            Rectangle r = GetColRect(colStart);
 | 
						|
 | 
						|
            if (CalendarView.HasTimeLineSlotBackgroundCallout == true)
 | 
						|
            {
 | 
						|
                for (int i = colStart; i <= colEnd; i++)
 | 
						|
                {
 | 
						|
                    int n = i - colStart;
 | 
						|
 | 
						|
                    DateTime startTime = StartDate.AddMinutes(i * BaseInterval);
 | 
						|
                    DateTime endTime = startTime.AddMinutes(BaseInterval);
 | 
						|
 | 
						|
                    if (CalendarView.DoTimeLineViewPreRenderSlotBackground(
 | 
						|
                        g, this, startTime, endTime, r, ref states[n]) == false)
 | 
						|
                    {
 | 
						|
                        g.FillRectangle(GetContentBrush(states[n]), r);
 | 
						|
 | 
						|
                        DrawCollateLines(g, r);
 | 
						|
 | 
						|
                        CalendarView.DoTimeLineViewPostRenderSlotBackground(
 | 
						|
                            g, this, startTime, endTime, r, states[n]);
 | 
						|
                    }
 | 
						|
 | 
						|
                    r.X += ColumnWidth;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                Rectangle t = r;
 | 
						|
 | 
						|
                for (int i = 0; i <= colEnd - colStart; i++)
 | 
						|
                {
 | 
						|
                    g.FillRectangle(GetContentBrush(states[i]), t);
 | 
						|
 | 
						|
                    t.X += ColumnWidth;
 | 
						|
                }
 | 
						|
 | 
						|
                r.Width += (t.Right - r.Right);
 | 
						|
 | 
						|
                DrawCollateLines(g, r);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region DrawCollateLines
 | 
						|
 | 
						|
        private void DrawCollateLines(Graphics g, Rectangle r)
 | 
						|
        {
 | 
						|
            if (CalendarView.TimeLineShowCollateLines == true &&
 | 
						|
                _CollateLines.Count > 1)
 | 
						|
            {
 | 
						|
                using (Pen pen = new Pen(
 | 
						|
                    _ViewColor.GetColor((int) eCalendarWeekDayPart.DayHalfHourBorder)))
 | 
						|
                {
 | 
						|
                    for (int i = 0; i < _CollateLines.Count - 1; i++)
 | 
						|
                    {
 | 
						|
                        int y = _CollateLines[i];
 | 
						|
 | 
						|
                        g.DrawLine(pen, r.X, r.Y + y, r.Right, r.Y + y);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetSlotState
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// GetSlotState
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        private eSlotDisplayState GetSlotState(int col)
 | 
						|
        {
 | 
						|
            eSlotDisplayState state = eSlotDisplayState.None;
 | 
						|
 | 
						|
            if (DisplayedOwnerKeyIndex == CalendarView.SelectedOwnerIndex)
 | 
						|
            {
 | 
						|
                if (col >= _SelectedColStart && col < _SelectedColEnd)
 | 
						|
                    state |= eSlotDisplayState.Selected;
 | 
						|
            }
 | 
						|
 | 
						|
            DateTime date = StartDate.AddMinutes(col * CalendarView.BaseInterval);
 | 
						|
            WorkTime workTime = new WorkTime(date.Hour, date.Minute);
 | 
						|
 | 
						|
            if (IsWorkTime((int)date.DayOfWeek, workTime) == true)
 | 
						|
                state |= eSlotDisplayState.Work;
 | 
						|
 | 
						|
            return (state);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetContentBrush
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the background content brush
 | 
						|
        /// for the given time slice
 | 
						|
        /// </summary>
 | 
						|
        /// <returns>Background brush</returns>
 | 
						|
        private Brush GetContentBrush(eSlotDisplayState state)
 | 
						|
        {
 | 
						|
            if ((state & eSlotDisplayState.Selected) == eSlotDisplayState.Selected)
 | 
						|
                return (SelectedBrush);
 | 
						|
 | 
						|
            if ((state & eSlotDisplayState.Work) == eSlotDisplayState.Work)
 | 
						|
                return (WorkBrush);
 | 
						|
 | 
						|
            return (OffWorkBrush);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region IsWorkTime
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Determines if the given time is tagged as a "Work time"
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="day">Day of week</param>
 | 
						|
        /// <param name="time">WorkTime to test</param>
 | 
						|
        /// <returns>true if specified "time" is a Work time</returns>
 | 
						|
        private bool IsWorkTime(int day, WorkTime time)
 | 
						|
        {
 | 
						|
            ModelTimeLineViewConnector tlc =
 | 
						|
                (ModelTimeLineViewConnector)Connector;
 | 
						|
 | 
						|
            WorkTime workStartTime = tlc.DayInfo[day].WorkStartTime;
 | 
						|
            WorkTime workEndTime = tlc.DayInfo[day].WorkEndTime;
 | 
						|
 | 
						|
            return (time >= workStartTime && time < workEndTime);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawBorder
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws the TimeLine border
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="colStart">Starting column</param>
 | 
						|
        /// <param name="colEnd">Ending column</param>
 | 
						|
        /// <param name="states"></param>
 | 
						|
        private void DrawBorder(Graphics g,
 | 
						|
            int colStart, int colEnd, eSlotDisplayState[] states)
 | 
						|
        {
 | 
						|
            Rectangle r = GetColRect(colStart);
 | 
						|
 | 
						|
            // Draw the vertical borders
 | 
						|
 | 
						|
            if (CalendarView.TimeLinePeriod == eTimeLinePeriod.Minutes)
 | 
						|
                DrawHalfHourBorders(g, colStart, colEnd, r, states);
 | 
						|
            else
 | 
						|
                DrawHourBorders(g, colStart, colEnd, r, states);
 | 
						|
 | 
						|
            // Now draw the horizontal border
 | 
						|
 | 
						|
            r.Width = (colEnd - colStart + 1) * ColumnWidth;
 | 
						|
            r.Height = ClientRect.Height;
 | 
						|
 | 
						|
            Color color = _ViewColor.GetColor((int)eCalendarWeekDayPart.DayViewBorder);
 | 
						|
 | 
						|
            if (CalendarView.DoTimeLineViewRenderViewBorder(g, this, colStart, colEnd, r, color) == false)
 | 
						|
            {
 | 
						|
                using (Pen pen1 = new Pen(color))
 | 
						|
                {
 | 
						|
                    Point pt1 = new Point(r.X, r.Bottom - 1);
 | 
						|
                    Point pt2 = new Point(r.Right - 1, pt1.Y);
 | 
						|
 | 
						|
                    g.DrawLine(pen1, pt1, pt2);
 | 
						|
 | 
						|
                    if (CalendarView.TimeLineShowPeriodHeader == false &&
 | 
						|
                        CalendarView.TimeLineShowIntervalHeader == false)
 | 
						|
                    {
 | 
						|
                        pt1 = new Point(r.X, r.Top);
 | 
						|
                        pt2 = new Point(r.Right - 1, pt1.Y);
 | 
						|
 | 
						|
                        g.DrawLine(pen1, pt1, pt2);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region DrawHalfHourBorders
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// DrawHalfHourBorders
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="colStart"></param>
 | 
						|
        /// <param name="colEnd"></param>
 | 
						|
        /// <param name="bounds"></param>
 | 
						|
        /// <param name="states"></param>
 | 
						|
        private void DrawHalfHourBorders(Graphics g,
 | 
						|
            int colStart, int colEnd, Rectangle bounds, eSlotDisplayState[] states)
 | 
						|
        {
 | 
						|
            // Draw the vertical hour and half hour borders
 | 
						|
 | 
						|
            using (Pen pen1 = new Pen(
 | 
						|
                _ViewColor.GetColor((int)eCalendarWeekDayPart.DayHourBorder)))
 | 
						|
            {
 | 
						|
                using (Pen pen2 = new Pen(
 | 
						|
                    _ViewColor.GetColor((int)eCalendarWeekDayPart.DayHalfHourBorder)))
 | 
						|
                {
 | 
						|
                    Point pt1 = new Point(bounds.X, ClientRect.Y);
 | 
						|
                    Point pt2 = new Point(bounds.X, ClientRect.Bottom - 1);
 | 
						|
 | 
						|
                    int n = 60 / CalendarView.TimeLineInterval;
 | 
						|
                    int start = -_HScrollPos / ColumnWidth;
 | 
						|
 | 
						|
                    for (int i = colStart; i <= colEnd; i++)
 | 
						|
                    {
 | 
						|
                        bool isHour = (i == start || (i % n) == 0);
 | 
						|
                        Pen pen = (isHour ? pen1 : pen2);
 | 
						|
 | 
						|
                        if (CalendarView.DoTimeLineViewRenderSlotBorder(
 | 
						|
                            g, this, i, isHour, states[i - colStart], pt1, pt2, pen) == false)
 | 
						|
                        {
 | 
						|
                            g.DrawLine((isHour ? pen1 : pen2), pt1, pt2);
 | 
						|
                        }
 | 
						|
 | 
						|
                        pt1.X = pt2.X = (pt1.X + ColumnWidth);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawHourBorders
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// DrawHourBorders
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="colStart"></param>
 | 
						|
        /// <param name="colEnd"></param>
 | 
						|
        /// <param name="bounds"></param>
 | 
						|
        /// <param name="states"></param>
 | 
						|
        private void DrawHourBorders(Graphics g,
 | 
						|
            int colStart, int colEnd, Rectangle bounds, eSlotDisplayState[] states)
 | 
						|
        {
 | 
						|
            // Draw the vertical hour borders
 | 
						|
 | 
						|
            using (Pen pen = new Pen(
 | 
						|
                _ViewColor.GetColor((int)eCalendarWeekDayPart.DayHourBorder)))
 | 
						|
            {
 | 
						|
                Point pt1 = new Point(bounds.X, ClientRect.Y);
 | 
						|
                Point pt2 = new Point(bounds.X, ClientRect.Bottom - 1);
 | 
						|
 | 
						|
                for (int i = colStart; i <= colEnd; i++)
 | 
						|
                {
 | 
						|
                    if (CalendarView.DoTimeLineViewRenderSlotBorder(
 | 
						|
                        g, this, i, true, states[i - colStart], pt1, pt2, pen) == false)
 | 
						|
                    {
 | 
						|
                        g.DrawLine(pen, pt1, pt2);
 | 
						|
                    }
 | 
						|
 | 
						|
                    pt1.X = pt2.X = (pt1.X + ColumnWidth);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawTimeIndicators
 | 
						|
 | 
						|
        #region DrawTimeIndicators
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws view TimeIndicators
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="colStart"></param>
 | 
						|
        /// <param name="colEnd"></param>
 | 
						|
        private void DrawTimeIndicators(Graphics g, 
 | 
						|
            int colStart, int colEnd, eTimeIndicatorLevel level)
 | 
						|
        {
 | 
						|
            DateTime start = CalendarView.TimeLineAddInterval(StartDate, colStart);
 | 
						|
            DateTime end = CalendarView.TimeLineAddInterval(StartDate, colEnd);
 | 
						|
 | 
						|
            Rectangle r = Rectangle.Union(GetColRect(colStart), GetColRect(colEnd));
 | 
						|
 | 
						|
            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, start, r, ti);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawTimeIndicator
 | 
						|
 | 
						|
        #region DrawTimeIndicator
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws individual view TimeIndicator
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="startDate"></param>
 | 
						|
        /// <param name="sRect"></param>
 | 
						|
        /// <param name="ti"></param>
 | 
						|
        private void DrawTimeIndicator(Graphics g,
 | 
						|
            DateTime startDate, Rectangle sRect, TimeIndicator ti)
 | 
						|
        {
 | 
						|
            Rectangle r = GetIndicatorRect(ti, startDate, sRect);
 | 
						|
 | 
						|
            if (r.IntersectsWith(sRect) == true)
 | 
						|
            {
 | 
						|
                if (r.Width > 0)
 | 
						|
                {
 | 
						|
                    ColorDef cdef = GetIndicatorColor(ti);
 | 
						|
 | 
						|
                    if (cdef != null)
 | 
						|
                    {
 | 
						|
                        float angle = cdef.Angle - 90;
 | 
						|
 | 
						|
                        using (Brush br = _ViewColor.BrushPart(cdef, r, angle))
 | 
						|
                        {
 | 
						|
                            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.Right, r.Top, r.Right, r.Bottom - 1);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #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
 | 
						|
 | 
						|
        #region GetIndicatorRect
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the TimeIndicator Rectangle
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="ti"></param>
 | 
						|
        /// <param name="startDate"></param>
 | 
						|
        /// <param name="sRect"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        private Rectangle GetIndicatorRect(
 | 
						|
            TimeIndicator ti, DateTime startDate, Rectangle sRect)
 | 
						|
        {
 | 
						|
            double x = ColumnWidth / CalendarView.BaseInterval;
 | 
						|
 | 
						|
            int offset = (int)((ti.IndicatorDisplayTime - startDate).TotalMinutes * x);
 | 
						|
 | 
						|
            sRect.X += (offset - ti.Thickness - 1);
 | 
						|
            sRect.Width = ti.Thickness;
 | 
						|
 | 
						|
            return (sRect);
 | 
						|
        }
 | 
						|
 | 
						|
        /// <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 date
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="ti"></param>
 | 
						|
        /// <param name="time"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        internal override Rectangle GetIndicatorRect(TimeIndicator ti, DateTime time)
 | 
						|
        {
 | 
						|
            int colStart = -_HScrollPos / ColumnWidth;
 | 
						|
            DateTime startDate = CalendarView.TimeLineAddInterval(StartDate, colStart);
 | 
						|
 | 
						|
            double x = ColumnWidth / CalendarView.BaseInterval;
 | 
						|
            int offset = (int)((time - startDate).TotalMinutes * x);
 | 
						|
 | 
						|
            Rectangle r = GetColRect(colStart);
 | 
						|
 | 
						|
            r.X += (offset - ti.Thickness - 1);
 | 
						|
            r.Width = ti.Thickness;
 | 
						|
 | 
						|
            return (r);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawCondensedLine
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws the condensed TimeLine
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        private void DrawCondensedLine(Graphics g)
 | 
						|
        {
 | 
						|
            TimeSpan ts0 = EndDate - StartDate;
 | 
						|
            float scale = (float)(ClientRect.Width / (ts0.TotalMinutes + BaseInterval));
 | 
						|
 | 
						|
            Rectangle r = GetCondensedRect();
 | 
						|
 | 
						|
            using (GraphicsPath path = GetCondensedViewPath(r, scale))
 | 
						|
            {
 | 
						|
                using (Brush br =
 | 
						|
                    _ViewColor.BrushPart((int)eCalendarWeekDayPart.CondensedViewBackground, r))
 | 
						|
                {
 | 
						|
                    g.FillRectangle(br, r);
 | 
						|
                }
 | 
						|
 | 
						|
                g.FillPath(Brushes.White, path);
 | 
						|
 | 
						|
                DrawCondensedContent(g, r, scale);
 | 
						|
                DrawCondensedAppointments(g, scale);
 | 
						|
 | 
						|
                g.DrawPath(Pens.Gray, path);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region DrawCondensedContent
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws the Condensed Content area
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g"></param>
 | 
						|
        /// <param name="vRect"></param>
 | 
						|
        /// <param name="scale"></param>
 | 
						|
        private void DrawCondensedContent(Graphics g, Rectangle vRect, float scale)
 | 
						|
        {
 | 
						|
            using (Pen pen = new Pen(
 | 
						|
                _ViewColor.GetColor((int)eCalendarWeekDayPart.DayHourBorder)))
 | 
						|
            {
 | 
						|
                int selCols = _SelectedColEnd - _SelectedColStart;
 | 
						|
 | 
						|
                if (selCols > 0)
 | 
						|
                {
 | 
						|
                    Rectangle r = vRect;
 | 
						|
 | 
						|
                    r.X += (int)(_SelectedColStart * BaseInterval * scale);
 | 
						|
                    r.Width = (int)(selCols * BaseInterval * scale);
 | 
						|
 | 
						|
                    using (Brush br =
 | 
						|
                        _ViewColor.BrushPart((int)eCalendarWeekDayPart.DayOffWorkHoursBackground, r))
 | 
						|
                    {
 | 
						|
                        g.FillRectangle(br, r);
 | 
						|
                    }
 | 
						|
 | 
						|
                    g.DrawRectangle(pen, r);
 | 
						|
                }
 | 
						|
 | 
						|
                g.DrawLine(pen, vRect.Left, vRect.Y, vRect.Right, vRect.Y);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetCondensedViewPath
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the condensed view display path
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="scale">Scale factor</param>
 | 
						|
        /// <param name="vRect">Condensed view rect</param>
 | 
						|
        /// <returns>Path</returns>
 | 
						|
        private GraphicsPath GetCondensedViewPath(Rectangle vRect, float scale)
 | 
						|
        {
 | 
						|
            int pos = (int)(FirstVisibleColumn * BaseInterval * scale);
 | 
						|
            int width = (int)((BaseInterval * ClientRect.Width) / ColumnWidth * scale);
 | 
						|
 | 
						|
            Rectangle r = new
 | 
						|
                Rectangle(ClientRect.X + pos, vRect.Y, width, vRect.Height);
 | 
						|
 | 
						|
            r.Inflate(0, -1);
 | 
						|
 | 
						|
            return (DisplayHelp.GetRoundedRectanglePath(r, 2, 2, 2, 2));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawCondensedAppointments
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws condensed appointments
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="g">Graphics</param>
 | 
						|
        /// <param name="scale">Scale factor</param>
 | 
						|
        private void DrawCondensedAppointments(Graphics g, float scale)
 | 
						|
        {
 | 
						|
            // Display each item
 | 
						|
 | 
						|
            SmoothingMode saveMode = g.SmoothingMode;
 | 
						|
            g.SmoothingMode = SmoothingMode.None;
 | 
						|
 | 
						|
            int dy = 3;
 | 
						|
 | 
						|
            foreach (ColumnList clist in _CondensedColList)
 | 
						|
            {
 | 
						|
                for (int i = 0; i < clist.SList.Count; i++)
 | 
						|
                {
 | 
						|
                    for (int j = 0; j < clist.SList[i].Count; j++)
 | 
						|
                    {
 | 
						|
                        CalendarItem item = clist.SList[i][j].CItem;
 | 
						|
 | 
						|
                        TimeSpan ts1 = item.StartTime - StartDate;
 | 
						|
                        TimeSpan ts2 = item.EndTime - item.StartTime;
 | 
						|
 | 
						|
                        int pos = (int)(ts1.TotalMinutes * scale);
 | 
						|
                        int width = (int)(ts2.TotalMinutes * scale);
 | 
						|
 | 
						|
                        if (width < 4)
 | 
						|
                            width = 4;
 | 
						|
 | 
						|
                        Point pt1 = new Point(ClientRect.X + pos,
 | 
						|
                                              ClientRect.Bottom - CondensedLineHeight + (i * 3) + dy);
 | 
						|
 | 
						|
                        Point pt2 = new Point(pt1.X + width, pt1.Y);
 | 
						|
 | 
						|
                        using (Pen pen = GetCondensedPen(item.ModelItem))
 | 
						|
                            g.DrawLine(pen, pt1, pt2);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                dy += (clist.SList.Count * 3);
 | 
						|
            }
 | 
						|
 | 
						|
            g.SmoothingMode = saveMode;
 | 
						|
        }
 | 
						|
 | 
						|
        #region GetCondensedPen
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the appointments condensed pen
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="o">Appointment object</param>
 | 
						|
        /// <returns></returns>
 | 
						|
        private Pen GetCondensedPen(object o)
 | 
						|
        {
 | 
						|
            string category = null;
 | 
						|
 | 
						|
            if (o is Appointment)
 | 
						|
                category = (o as Appointment).CategoryColor;
 | 
						|
 | 
						|
            else if (o is CustomCalendarItem)
 | 
						|
                category = (o as CustomCalendarItem).CategoryColor;
 | 
						|
 | 
						|
            if (category != null)
 | 
						|
            {
 | 
						|
                // Check to see if we have any user defined
 | 
						|
                // AppointmentCategoryColors
 | 
						|
 | 
						|
                if (CalendarView.HasCategoryColors == true)
 | 
						|
                {
 | 
						|
                    AppointmentCategoryColor acc =
 | 
						|
                        CalendarView.CategoryColors[category];
 | 
						|
 | 
						|
                    if (acc != null)
 | 
						|
                    {
 | 
						|
                        ColorDef cdef = acc.BackColor;
 | 
						|
 | 
						|
                        return (new Pen(cdef.Colors[cdef.Colors.Length - 1], 2));
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                if (category.Equals(Appointment.CategoryBlue))
 | 
						|
                    return (GetCategoryPen(eAppointmentPart.BlueBackground));
 | 
						|
 | 
						|
                if (category.Equals(Appointment.CategoryGreen))
 | 
						|
                    return (GetCategoryPen(eAppointmentPart.GreenBackground));
 | 
						|
 | 
						|
                if (category.Equals(Appointment.CategoryOrange))
 | 
						|
                    return (GetCategoryPen(eAppointmentPart.OrangeBackground));
 | 
						|
 | 
						|
                if (category.Equals(Appointment.CategoryPurple))
 | 
						|
                    return (GetCategoryPen(eAppointmentPart.PurpleBackground));
 | 
						|
 | 
						|
                if (category.Equals(Appointment.CategoryRed))
 | 
						|
                    return (GetCategoryPen(eAppointmentPart.RedBackground));
 | 
						|
 | 
						|
                if (category.Equals(Appointment.CategoryYellow))
 | 
						|
                    return (GetCategoryPen(eAppointmentPart.YellowBackground));
 | 
						|
            }
 | 
						|
 | 
						|
            return (GetCategoryPen(eAppointmentPart.DefaultBackground));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetCategoryPen
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// GetCategoryPen
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="part"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        private Pen GetCategoryPen(eAppointmentPart part)
 | 
						|
        {
 | 
						|
            ColorDef cdef = _appointmentColor.GetColorDef((int)part);
 | 
						|
 | 
						|
            return (new Pen(cdef.Colors[cdef.Colors.Length - 1], 2));
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region DrawAppointments
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Draws TimeLine appointments
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e"></param>
 | 
						|
        private void DrawAppointments(ItemPaintArgs e)
 | 
						|
        {
 | 
						|
            List<CalendarItem> items = CalendarItems;
 | 
						|
 | 
						|
            if (items.Count > 0)
 | 
						|
            {
 | 
						|
                // Loop through each CalendarItem in the week
 | 
						|
 | 
						|
                int selItem = -1;
 | 
						|
 | 
						|
                for (int i = 0; i < items.Count; i++)
 | 
						|
                {
 | 
						|
                    // If we can display the item, then initiate the paint
 | 
						|
 | 
						|
                    if (items[i].Displayed == true)
 | 
						|
                    {
 | 
						|
                        if (e.ClipRectangle.IsEmpty ||
 | 
						|
                            e.ClipRectangle.IntersectsWith(items[i].DisplayRectangle))
 | 
						|
                        {
 | 
						|
                            if (items[i].IsSelected == true)
 | 
						|
                                selItem = i;
 | 
						|
                            else
 | 
						|
                                items[i].Paint(e);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                if (selItem >= 0)
 | 
						|
                {
 | 
						|
                    for (int i = 0; i < items.Count; i++)
 | 
						|
                    {
 | 
						|
                        // If we can display the item, then initiate the paint
 | 
						|
 | 
						|
                        if (items[i].Displayed == true)
 | 
						|
                        {
 | 
						|
                            if (e.ClipRectangle.IsEmpty ||
 | 
						|
                                e.ClipRectangle.IntersectsWith(items[i].DisplayRectangle))
 | 
						|
                            {
 | 
						|
                                if (items[i].IsSelected == true)
 | 
						|
                                    items[i].Paint(e);
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetColRange
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Calculates the range of columns needed to be drawn
 | 
						|
        /// to satisfy the specified paint request
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="e">ItemPaintArgs</param>
 | 
						|
        /// <param name="colStart">[out] Column start index</param>
 | 
						|
        /// <param name="colEnd">[out] Column end index</param>
 | 
						|
        /// <returns>Column range count (end - start)</returns>
 | 
						|
        private int GetColRange(ItemPaintArgs e, out int colStart, out int colEnd)
 | 
						|
        {
 | 
						|
            // Calc our starting index
 | 
						|
 | 
						|
            int start = -_HScrollPos / ColumnWidth;
 | 
						|
            int x = ClientRect.X + start * ColumnWidth + _HScrollPos;
 | 
						|
 | 
						|
            while (start < TimeLineColumnCount)
 | 
						|
            {
 | 
						|
                if (x + ColumnWidth > e.ClipRectangle.X)
 | 
						|
                    break;
 | 
						|
 | 
						|
                x += ColumnWidth;
 | 
						|
 | 
						|
                start++;
 | 
						|
            }
 | 
						|
 | 
						|
            // Calc our ending index
 | 
						|
 | 
						|
            int end = start;
 | 
						|
 | 
						|
            while (end < TimeLineColumnCount)
 | 
						|
            {
 | 
						|
                if (x >= e.ClipRectangle.Right)
 | 
						|
                    break;
 | 
						|
 | 
						|
                x += ColumnWidth;
 | 
						|
 | 
						|
                end++;
 | 
						|
            }
 | 
						|
 | 
						|
            end++;
 | 
						|
 | 
						|
            // Set the user supplied 'out' values, and
 | 
						|
            // return the range count to the caller
 | 
						|
 | 
						|
            if (end - start == 0)
 | 
						|
            {
 | 
						|
                colStart = 0;
 | 
						|
                colEnd = 0;
 | 
						|
 | 
						|
                return (0);
 | 
						|
            }
 | 
						|
 | 
						|
            colStart = start;
 | 
						|
            colEnd = end;
 | 
						|
 | 
						|
            return (end - start);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetColRect
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the display rectangle for the given column
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">Column</param>
 | 
						|
        /// <returns>Display rectangle</returns>
 | 
						|
        private Rectangle GetColRect(int col)
 | 
						|
        {
 | 
						|
            Rectangle r = ClientRect;
 | 
						|
 | 
						|
            r.X += ((col * ColumnWidth) + _HScrollPos);
 | 
						|
            r.Width = ColumnWidth;
 | 
						|
 | 
						|
            r.Height -= 1;
 | 
						|
 | 
						|
            if (ShowCondensed == true)
 | 
						|
                r.Height -= (CondensedLineHeight - 1);
 | 
						|
 | 
						|
            return (r);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetCondensedRect
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the CondensedView rectangle
 | 
						|
        /// </summary>
 | 
						|
        /// <returns>CondensedView rectangle</returns>
 | 
						|
        private Rectangle GetCondensedRect()
 | 
						|
        {
 | 
						|
            Rectangle r = ClientRect;
 | 
						|
 | 
						|
            r.X += 1;
 | 
						|
            r.Width -= 1;
 | 
						|
 | 
						|
            r.Y = r.Bottom - CondensedLineHeight;
 | 
						|
            r.Height = CondensedLineHeight - 1;
 | 
						|
 | 
						|
            return (r);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDateCol
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the absolute column value for the given date
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="selDate">Selection date</param>
 | 
						|
        /// <returns>Absolute column</returns>
 | 
						|
        private int GetDateCol(DateTime? selDate)
 | 
						|
        {
 | 
						|
            if (selDate.HasValue)
 | 
						|
            {
 | 
						|
                TimeSpan ts = selDate.Value - StartDate;
 | 
						|
 | 
						|
                return (int)(ts.TotalMinutes / CalendarView.BaseInterval);
 | 
						|
            }
 | 
						|
 | 
						|
            return (0);
 | 
						|
        }
 | 
						|
 | 
						|
        #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 (objArg.Button == MouseButtons.Left)
 | 
						|
            {
 | 
						|
                if (IsTabMoving == false)
 | 
						|
                {
 | 
						|
                    // Locate where the event took place
 | 
						|
 | 
						|
                    if (ClientRect.Contains(objArg.Location) == true)
 | 
						|
                    {
 | 
						|
                        if (PointInCondensedView(objArg.Location) == true)
 | 
						|
                        {
 | 
						|
                            // User is mousing in the CondensedView area
 | 
						|
 | 
						|
                            MyCursor = Cursors.Hand;
 | 
						|
 | 
						|
                            ProcessCvlButtonDown(objArg);
 | 
						|
 | 
						|
                            IsCondMoving = true;
 | 
						|
                        }
 | 
						|
                        else
 | 
						|
                        {
 | 
						|
                            int col;
 | 
						|
 | 
						|
                            if (GetPointItem(objArg.Location, out col, true) == true)
 | 
						|
                            {
 | 
						|
                                // User is mouseing in the Content area
 | 
						|
 | 
						|
                                MyCursor = GetContentCursor();
 | 
						|
 | 
						|
                                if (ProcessCilButtonDown(objArg) == false)
 | 
						|
                                    ProcessTvlButtonDown(col);
 | 
						|
 | 
						|
                                IsMouseDown = true;
 | 
						|
                            }
 | 
						|
 | 
						|
                            IsCopyDrag = false;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region CondensedView MouseDown processing
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles CondensedView Left Button Down events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        private void ProcessCvlButtonDown(MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            ProcessCvlPoint(objArg);
 | 
						|
        }
 | 
						|
 | 
						|
        #region ProcessCvlPoint
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes CondensedView point selection
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        private void ProcessCvlPoint(MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            TimeSpan ts0 = EndDate - StartDate;
 | 
						|
 | 
						|
            float scale = (float)((ClientRect.Width + 2) / ts0.TotalMinutes);
 | 
						|
            int width = (int)((BaseInterval * ClientRect.Width) / ColumnWidth * scale);
 | 
						|
 | 
						|
            double x = (objArg.Location.X - ClientRect.X - (width / 2)) / scale;
 | 
						|
            int col = (int)(x / BaseInterval);
 | 
						|
 | 
						|
            // Make sure we stay within our bounds, and
 | 
						|
            // then set our new scroll value accordingly
 | 
						|
 | 
						|
            HScrollBarAdv hScrollBar = CalendarView.TimeLineHScrollPanel.ScrollBar;
 | 
						|
 | 
						|
            if (col < hScrollBar.Minimum)
 | 
						|
                col = hScrollBar.Minimum;
 | 
						|
 | 
						|
            if (col > hScrollBar.Maximum - hScrollBar.LargeChange)
 | 
						|
                col = hScrollBar.Maximum - hScrollBar.LargeChange;
 | 
						|
 | 
						|
            hScrollBar.Value = col;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CalendarItem MouseDown processing
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// CalendarItem left mouseDown processing
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg">MouseEventArgs</param>
 | 
						|
        private bool ProcessCilButtonDown(MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            CalendarItem item = m_HotSubItem as CalendarItem;
 | 
						|
 | 
						|
            if (item != null)
 | 
						|
            {
 | 
						|
                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)
 | 
						|
                    {
 | 
						|
                        _LastBounds = item.Bounds;
 | 
						|
                        _LastPointOffset = objArg.Location;
 | 
						|
                        _LastMovePoint = objArg.Location;
 | 
						|
 | 
						|
                        if (IsResizing == false && IsMoving == false)
 | 
						|
                        {
 | 
						|
                            OldStartTime = item.StartTime;
 | 
						|
                            OldEndTime = item.EndTime;
 | 
						|
                            OldOwnerKey = OwnerKey;
 | 
						|
                        }
 | 
						|
 | 
						|
                        // Flag appropriate action
 | 
						|
 | 
						|
                        if (item.HitArea == CalendarItem.eHitArea.LeftResize)
 | 
						|
                            IsStartResizing = true;
 | 
						|
 | 
						|
                        else if (item.HitArea == CalendarItem.eHitArea.RightResize)
 | 
						|
                            IsEndResizing = true;
 | 
						|
 | 
						|
                        else if (item.HitArea == CalendarItem.eHitArea.Move)
 | 
						|
                            IsMoving = true;
 | 
						|
 | 
						|
                        // Update our initial PosWin display
 | 
						|
 | 
						|
                        UpdatePosWin(ClientRect);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
 | 
						|
                return (true);
 | 
						|
            }
 | 
						|
 | 
						|
            return (false);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region TimeLineView MouseDown processing
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles TimeLineView left MouseDown events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">Column index</param>
 | 
						|
        private void ProcessTvlButtonDown(int col)
 | 
						|
        {
 | 
						|
            DateTime startDate = CalendarView.TimeLineAddInterval(StartDate, col);
 | 
						|
            DateTime endDate = CalendarView.TimeLineAddInterval(startDate, 1);
 | 
						|
 | 
						|
            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);
 | 
						|
 | 
						|
            // Cancel our scroll timer
 | 
						|
 | 
						|
            CancelScrollTimer();
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region MouseMove processing
 | 
						|
 | 
						|
        /// <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 (IsCondMoving == true || PointInCondensedView(objArg.Location) == true)
 | 
						|
                {
 | 
						|
                    // The user in the CondensedView area
 | 
						|
 | 
						|
                    MyCursor = Cursors.Hand;
 | 
						|
 | 
						|
                    if (IsCondMoving == true)
 | 
						|
                        ProcessCvlMouseMove(objArg);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    // The user in the Content area
 | 
						|
 | 
						|
                    MyCursor = GetContentCursor();
 | 
						|
 | 
						|
                    if (objArg.Button == MouseButtons.Left)
 | 
						|
                        ProcessContentMove(objArg);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #region ProcessCvlMouseMove
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles CondensedView mouse moves
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        private void ProcessCvlMouseMove(MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            ProcessCvlPoint(objArg);
 | 
						|
        }
 | 
						|
 | 
						|
        #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;
 | 
						|
 | 
						|
            if (GetPointItem(objArg.Location, out col, false) == true)
 | 
						|
            {
 | 
						|
                // The col is visible, so no need to
 | 
						|
                // enable scrolling - just process the event
 | 
						|
 | 
						|
                EnableViewScrolling(false);
 | 
						|
 | 
						|
                ProcessMouseMove(col, objArg);
 | 
						|
            }
 | 
						|
            else if (IsMouseDown == true)
 | 
						|
            {
 | 
						|
                // Check to see if the user is performing
 | 
						|
                // a "DragDrop" operation
 | 
						|
 | 
						|
                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 cells (auto moving apps is intrusive looking)
 | 
						|
 | 
						|
                    if (DateSelectionAnchor != null)
 | 
						|
                        ProcessMouseMove(col, objArg);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #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);
 | 
						|
                TimeLineView tlv = bv as TimeLineView;
 | 
						|
 | 
						|
                if (tlv != null && tlv != this)
 | 
						|
                {
 | 
						|
                    eViewArea area = bv.GetViewAreaFromPoint(pt);
 | 
						|
 | 
						|
                    if (area == eViewArea.InContent)
 | 
						|
                    {
 | 
						|
                        if (CalendarView.DoAppointmentViewChanging(SelectedItem, tlv.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 (tlv.DragAppointment(this, av));
 | 
						|
 | 
						|
                            CustomCalendarItem ci = SelectedItem as CustomCalendarItem;
 | 
						|
 | 
						|
                            if (ci != null)
 | 
						|
                                return (tlv.DragCustomItem(this, ci));
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return (false);
 | 
						|
        }
 | 
						|
 | 
						|
        #region DragCustomItem
 | 
						|
 | 
						|
        private bool DragCustomItem(TimeLineView pv, CustomCalendarItem ci)
 | 
						|
        {
 | 
						|
            // Set the new owner and selected view, and
 | 
						|
            // recalc the new layout
 | 
						|
 | 
						|
            ci.OwnerKey = OwnerKey;
 | 
						|
 | 
						|
            NeedRecalcLayout = true;
 | 
						|
            RecalcSize();
 | 
						|
 | 
						|
            CalendarView.SelectedOwnerIndex = this.DisplayedOwnerKeyIndex;
 | 
						|
 | 
						|
            // Get the new view
 | 
						|
 | 
						|
            CustomCalendarItem view = GetCustomCalendarItem(ci);
 | 
						|
 | 
						|
            if (view != null)
 | 
						|
                SetNewDragItem(pv, view);
 | 
						|
 | 
						|
            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 drag</param>
 | 
						|
        private bool DragAppointment(TimeLineView pv, AppointmentView av)
 | 
						|
        {
 | 
						|
            // Set the new owner and selected view, and
 | 
						|
            // recalc the new layout
 | 
						|
 | 
						|
            av.Appointment.OwnerKey = OwnerKey;
 | 
						|
 | 
						|
            NeedRecalcLayout = true;
 | 
						|
            RecalcSize();
 | 
						|
 | 
						|
            CalendarView.SelectedOwnerIndex = this.DisplayedOwnerKeyIndex;
 | 
						|
 | 
						|
            // Get the new view
 | 
						|
 | 
						|
            AppointmentView view = GetAppointmentView(av.Appointment);
 | 
						|
 | 
						|
            if (view != null)
 | 
						|
                SetNewDragItem(pv, view);
 | 
						|
 | 
						|
            return (true);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region SetNewDragItem
 | 
						|
 | 
						|
        private void SetNewDragItem(TimeLineView pv, CalendarItem view)
 | 
						|
        {
 | 
						|
            _LastBounds = pv._LastBounds;
 | 
						|
            _LastMovePoint = pv._LastMovePoint;
 | 
						|
            _LastPointOffset = pv._LastPointOffset;
 | 
						|
 | 
						|
            int dx = _LastPointOffset.X - _LastBounds.X;
 | 
						|
 | 
						|
            CalendarView.CalendarPanel.InternalMouseMove(new
 | 
						|
                MouseEventArgs(MouseButtons.None, 0, view.Bounds.X + dx, view.Bounds.Y, 0));
 | 
						|
 | 
						|
            MouseEventArgs args = new
 | 
						|
                MouseEventArgs(MouseButtons.Left, 1, view.Bounds.X + dx, view.Bounds.Y, 0);
 | 
						|
 | 
						|
            IsMoving = true;
 | 
						|
 | 
						|
            InternalMouseMove(args);
 | 
						|
            CalendarView.CalendarPanel.InternalMouseDown(args);
 | 
						|
 | 
						|
            SelectedItem = view;
 | 
						|
 | 
						|
            IsCopyDrag = 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.LeftResize:
 | 
						|
                    case CalendarItem.eHitArea.RightResize:
 | 
						|
                        return (Cursors.SizeWE);
 | 
						|
 | 
						|
                    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="objArg"></param>
 | 
						|
        private void ProcessMouseMove(int col, MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            if (DateSelectionAnchor != null)
 | 
						|
            {
 | 
						|
                ProcessTvMouseMove(col);
 | 
						|
            }
 | 
						|
            else if (SelectedItem != null)
 | 
						|
            {
 | 
						|
                if (objArg.Location.Equals(_LastMovePoint) == false)
 | 
						|
                {
 | 
						|
                    if (IsMoving == true)
 | 
						|
                        ProcessItemMove(col, objArg);
 | 
						|
 | 
						|
                    else if (IsStartResizing == true)
 | 
						|
                        ProcessItemLeftResize(col, objArg);
 | 
						|
 | 
						|
                    else if (IsEndResizing == true)
 | 
						|
                        ProcessItemRightResize(col, objArg);
 | 
						|
 | 
						|
                    _LastMovePoint = objArg.Location;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessTvMouseMove
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes TimeLineView mouseMove events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">Column</param>
 | 
						|
        private void ProcessTvMouseMove(int col)
 | 
						|
        {
 | 
						|
            if (DateSelectionAnchor != null)
 | 
						|
            {
 | 
						|
                DateTime date = CalendarView.TimeLineAddInterval(StartDate, col);
 | 
						|
 | 
						|
                // Let the user select forwards or backwards
 | 
						|
 | 
						|
                if (date >= DateSelectionAnchor)
 | 
						|
                {
 | 
						|
                    CalendarView.DateSelectionStart = DateSelectionAnchor.Value;
 | 
						|
                    CalendarView.DateSelectionEnd = CalendarView.TimeLineAddInterval(date, 1);
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    CalendarView.DateSelectionStart = date;
 | 
						|
                    CalendarView.DateSelectionEnd = CalendarView.TimeLineAddInterval(DateSelectionAnchor.Value, 1);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CalendarItem MouseMove processing
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes CalendarItem mouseMove events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">Column</param>
 | 
						|
        /// <param name="objArg">MouseEventArgs</param>
 | 
						|
        private void ProcessItemMove(int col, MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            // Calculate our new item date
 | 
						|
 | 
						|
            DateTime newDate;
 | 
						|
 | 
						|
            if (CalendarView.TimeLinePeriod == eTimeLinePeriod.Years)
 | 
						|
            {
 | 
						|
                newDate = StartDate.AddYears(
 | 
						|
                    GetDeltaYears(col, true, objArg));
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                newDate = StartDate.AddMinutes(
 | 
						|
                    GetDeltaMinutes(col, true, objArg));
 | 
						|
            }
 | 
						|
 | 
						|
            if (newDate != SelectedItem.StartTime)
 | 
						|
            {
 | 
						|
                if (DragCopy() == false)
 | 
						|
                {
 | 
						|
                    TimeSpan ts = SelectedItem.EndTime - SelectedItem.StartTime;
 | 
						|
 | 
						|
                    try
 | 
						|
                    {
 | 
						|
                        if (SelectedItem is CustomCalendarItem)
 | 
						|
                            CalendarView.CustomItems.BeginUpdate();
 | 
						|
                        else
 | 
						|
                            CalendarModel.BeginUpdate();
 | 
						|
 | 
						|
                        // Make the move
 | 
						|
 | 
						|
                        if (CalendarView.DoAppointmentViewChanging(SelectedItem, null, newDate,
 | 
						|
                            newDate + ts, eViewOperation.AppointmentMove, IsNewCopyDrag) == false)
 | 
						|
                        {
 | 
						|
                            SelectedItem.StartTime = newDate;
 | 
						|
                            SelectedItem.EndTime = newDate + ts;
 | 
						|
 | 
						|
                            NeedRecalcLayout = true;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    finally
 | 
						|
                    {
 | 
						|
                        if (SelectedItem is CustomCalendarItem)
 | 
						|
                            CalendarView.CustomItems.EndUpdate();
 | 
						|
                        else
 | 
						|
                            CalendarModel.EndUpdate();
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region CalendarItem MouseResize processing
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes CalendarItem left resizing
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">Column</param>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        private void ProcessItemLeftResize(int col, MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            DateTime date = (CalendarView.TimeLinePeriod == eTimeLinePeriod.Years) ?
 | 
						|
                StartDate.AddYears(GetDeltaYears(col, true, objArg)) :
 | 
						|
                StartDate.AddMinutes(GetDeltaMinutes(col, true, objArg));
 | 
						|
 | 
						|
            if (date < SelectedItem.EndTime && SelectedItem.StartTime != date)
 | 
						|
                ResizeItem(date, SelectedItem.EndTime);
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes CalendarItem right resizing
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">Column</param>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        private void ProcessItemRightResize(int col, MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            DateTime date = (CalendarView.TimeLinePeriod == eTimeLinePeriod.Years) ?
 | 
						|
                StartDate.AddYears(GetDeltaYears(col, false, objArg)) :
 | 
						|
                StartDate.AddMinutes(GetDeltaMinutes(col, false, objArg));
 | 
						|
 | 
						|
            if (date > SelectedItem.StartTime && SelectedItem.EndTime != date)
 | 
						|
                ResizeItem(SelectedItem.StartTime, date);
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Initiates the resize of the selected item
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="startTime"></param>
 | 
						|
        /// <param name="endTime"></param>
 | 
						|
        private void ResizeItem(DateTime startTime, DateTime endTime)
 | 
						|
        {
 | 
						|
            // Let the user cancel the operation if desired
 | 
						|
 | 
						|
            if (CalendarView.DoAppointmentViewChanging(SelectedItem, null, startTime,
 | 
						|
                endTime, eViewOperation.AppointmentResize, IsNewCopyDrag) == false)
 | 
						|
            {
 | 
						|
                SelectedItem.StartTime = startTime;
 | 
						|
                SelectedItem.EndTime = endTime;
 | 
						|
 | 
						|
                NeedRecalcLayout = true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDeltaMinutes
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the change from the last offset (in minutes)
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">Column</param>
 | 
						|
        /// <param name="left">Are we going left or right</param>
 | 
						|
        /// <param name="objArg">MouseEventArgs</param>
 | 
						|
        /// <returns>Change in mnutes</returns>
 | 
						|
        private double GetDeltaMinutes(int col, bool left, MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            // Calculate our delta minutes
 | 
						|
 | 
						|
            Rectangle r = GetColRect(col);
 | 
						|
 | 
						|
            double dm = (objArg.Location.X - _LastPointOffset.X);
 | 
						|
 | 
						|
            dm += left ? _LastBounds.Left - r.Left
 | 
						|
                       : _LastBounds.Right - r.Right;
 | 
						|
 | 
						|
            dm = BaseInterval * dm / ColumnWidth;
 | 
						|
 | 
						|
            // If the Alt key is not pressed, then round
 | 
						|
            // our value off to the nearest column
 | 
						|
 | 
						|
            if ((Control.ModifierKeys & Keys.Alt) != Keys.Alt)
 | 
						|
            {
 | 
						|
                col += (int)(dm / BaseInterval);
 | 
						|
                dm = 0;
 | 
						|
            }
 | 
						|
 | 
						|
            dm += (col * BaseInterval);
 | 
						|
 | 
						|
            // Make sure we don't cross our day boundaries
 | 
						|
 | 
						|
            if (left == true)
 | 
						|
            {
 | 
						|
                if (dm < 0)
 | 
						|
                    dm = 0;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                dm += BaseInterval;
 | 
						|
            }
 | 
						|
 | 
						|
            return (dm);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetDeltaYears
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the change from the last offset (in years)
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="col">Column</param>
 | 
						|
        /// <param name="left">Are we going left or right</param>
 | 
						|
        /// <param name="objArg">MouseEventArgs</param>
 | 
						|
        /// <returns>Change in years</returns>
 | 
						|
        private int GetDeltaYears(int col, bool left, MouseEventArgs objArg)
 | 
						|
        {
 | 
						|
            // Calculate our delta minutes
 | 
						|
 | 
						|
            Rectangle r = GetColRect(col);
 | 
						|
 | 
						|
            int dm = (objArg.Location.X - _LastPointOffset.X);
 | 
						|
 | 
						|
            dm += left ? _LastBounds.Left - r.Left
 | 
						|
                       : _LastBounds.Right - r.Right;
 | 
						|
 | 
						|
            dm = CalendarView.TimeLineInterval * dm / ColumnWidth;
 | 
						|
 | 
						|
            // If the Alt key is not pressed, then round
 | 
						|
            // our value off to the nearest column
 | 
						|
 | 
						|
            if ((Control.ModifierKeys & Keys.Alt) != Keys.Alt)
 | 
						|
            {
 | 
						|
                col += dm / CalendarView.TimeLineInterval;
 | 
						|
                dm = 0;
 | 
						|
            }
 | 
						|
 | 
						|
            dm += (col * CalendarView.TimeLineInterval);
 | 
						|
 | 
						|
            // Make sure we don't cross our day boundaries
 | 
						|
 | 
						|
            if (left == true)
 | 
						|
            {
 | 
						|
                if (dm < 0)
 | 
						|
                    dm = 0;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                dm += CalendarView.TimeLineInterval;
 | 
						|
            }
 | 
						|
 | 
						|
            return (dm);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region View Scrolling support
 | 
						|
 | 
						|
        /// <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 (_ScrollViewTimer == null)
 | 
						|
                {
 | 
						|
                    _ScrollViewTimer = new Timer();
 | 
						|
 | 
						|
                    _ScrollViewTimer.Interval = 10;
 | 
						|
                    _ScrollViewTimer.Tick += ScrollViewTimerTick;
 | 
						|
                    _ScrollViewTimer.Start();
 | 
						|
                }
 | 
						|
 | 
						|
                _ScrollDwell = 0;
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                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;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        /// <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)
 | 
						|
        {
 | 
						|
            _ScrollDwell++;
 | 
						|
 | 
						|
            int dx = Math.Abs(delta);
 | 
						|
            int n = (dx < 16 ? 8 : dx < 32 ? 4 : 1);
 | 
						|
 | 
						|
            if (_ScrollDwell % n == 0)
 | 
						|
                return (delta < 0 ? -1 : 1);
 | 
						|
 | 
						|
            return (0);
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles view scroll timer ticks
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="sender">object</param>
 | 
						|
        /// <param name="e">EventArgs</param>
 | 
						|
        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 = ClientRect;
 | 
						|
 | 
						|
                int n = r.X + (ClientRect.Width / ColumnWidth) * ColumnWidth;
 | 
						|
 | 
						|
                int dx = (pt.X < r.Left) ? ScrollAmount(pt.X - r.Left) :
 | 
						|
                    (pt.X >= n) ? ScrollAmount(pt.X - n) : 0;
 | 
						|
 | 
						|
                // Make sure we stay within our upper bounds
 | 
						|
 | 
						|
                if (dx < 0)
 | 
						|
                {
 | 
						|
                    if (CalendarView.TimeLineHScrollPanel.ScrollBar.Value + dx < 0)
 | 
						|
                        dx = -CalendarView.TimeLineHScrollPanel.ScrollBar.Value;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    int maxValue = CalendarView.TimeLineHScrollPanel.ScrollBar.Maximum -
 | 
						|
                        CalendarView.TimeLineHScrollPanel.ScrollBar.LargeChange;
 | 
						|
 | 
						|
                    if (CalendarView.TimeLineHScrollPanel.ScrollBar.Value + dx > maxValue)
 | 
						|
                        dx = maxValue - CalendarView.TimeLineHScrollPanel.ScrollBar.Value;
 | 
						|
                }
 | 
						|
 | 
						|
                // Scroll if necessary
 | 
						|
 | 
						|
                if (dx != 0)
 | 
						|
                {
 | 
						|
                    CalendarView.TimeLineHScrollPanel.ScrollBar.Value += dx;
 | 
						|
 | 
						|
                    if (PosWin != null)
 | 
						|
                        PosWin.Hide();
 | 
						|
 | 
						|
                    InternalMouseMove(new
 | 
						|
                        MouseEventArgs(MouseButtons.Left, 0, pt.X, pt.Y, 0));
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region GetPointItem
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Gets the item column at the given point
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pt">Point in question</param>
 | 
						|
        /// <param name="col">[out] Column</param>
 | 
						|
        /// <param name="partial">True if partial hits are ok</param>
 | 
						|
        /// <returns>True if valid item</returns>
 | 
						|
        private bool GetPointItem(Point pt, out int col, bool partial)
 | 
						|
        {
 | 
						|
            int start = -_HScrollPos / ColumnWidth;
 | 
						|
            int end = start + ClientRect.Width / ColumnWidth;
 | 
						|
 | 
						|
            Rectangle r = GetColRect(start);
 | 
						|
 | 
						|
            for (int i = start; i <= end; i++)
 | 
						|
            {
 | 
						|
                if (r.Contains(pt) == true)
 | 
						|
                {
 | 
						|
                    col = i;
 | 
						|
 | 
						|
                    return (IsColVisible(r, partial));
 | 
						|
                }
 | 
						|
 | 
						|
                r.X += ColumnWidth;
 | 
						|
            }
 | 
						|
 | 
						|
            col = (pt.X < ClientRect.X) ? 0 : TimeLineColumnCount;
 | 
						|
 | 
						|
            return (false);
 | 
						|
        }
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Determines if a given column is visible
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="r">Display rectangle</param>
 | 
						|
        /// <param name="partial">True if partial visibility is ok</param>
 | 
						|
        /// <returns>True if visible</returns>
 | 
						|
        private bool IsColVisible(Rectangle r, bool partial)
 | 
						|
        {
 | 
						|
            if (partial == true)
 | 
						|
            {
 | 
						|
                if (r.Right < ClientRect.Left)
 | 
						|
                    return (false);
 | 
						|
 | 
						|
                if (r.Left > ClientRect.Right)
 | 
						|
                    return (false);
 | 
						|
            }
 | 
						|
            else
 | 
						|
            {
 | 
						|
                if (r.Left < ClientRect.Left)
 | 
						|
                    return (false);
 | 
						|
 | 
						|
                if (r.Right > ClientRect.Right)
 | 
						|
                    return (false);
 | 
						|
            }
 | 
						|
 | 
						|
            return (true);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region PointInCondensedView
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Determines if the given point in in
 | 
						|
        /// the CondensedView area
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="pt"></param>
 | 
						|
        /// <returns></returns>
 | 
						|
        private bool PointInCondensedView(Point pt)
 | 
						|
        {
 | 
						|
            if (ShowCondensed == true)
 | 
						|
                return (GetCondensedRect().Contains(pt));
 | 
						|
 | 
						|
            return (false);
 | 
						|
        }
 | 
						|
 | 
						|
        #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:
 | 
						|
                    objArg.Handled = true;
 | 
						|
                    break;
 | 
						|
 | 
						|
                case Keys.Down:
 | 
						|
                case Keys.Down | Keys.Shift:
 | 
						|
                case Keys.Down | Keys.Control:
 | 
						|
                case Keys.Down | Keys.Control | Keys.Shift:
 | 
						|
                    objArg.Handled = true;
 | 
						|
                    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;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        #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 (ValidDateSelection())
 | 
						|
            {
 | 
						|
// ReSharper disable PossibleInvalidOperationException
 | 
						|
 | 
						|
                DateTime startDate = CalendarView.DateSelectionStart.Value;
 | 
						|
                DateTime endDate = CalendarView.DateSelectionEnd.Value;
 | 
						|
 | 
						|
                if (startDate.Equals(DateSelectionAnchor.Value) == true)
 | 
						|
                    startDate = CalendarView.TimeLineAddInterval(endDate, -1);
 | 
						|
 | 
						|
// ReSharper restore PossibleInvalidOperationException
 | 
						|
 | 
						|
                startDate = CalendarView.TimeLineAddInterval(startDate, dx);
 | 
						|
                endDate = CalendarView.TimeLineAddInterval(startDate, 1);
 | 
						|
 | 
						|
                DateTime viewStart = CalendarView.TimeLineViewScrollStartDate;
 | 
						|
                DateTime viewEnd = CalendarView.TimeLineViewScrollEndDate;
 | 
						|
 | 
						|
                if (startDate < viewStart)
 | 
						|
                {
 | 
						|
                    CalendarView.TimeLineViewScrollStartDate = startDate;
 | 
						|
                }
 | 
						|
                else if (endDate > viewEnd)
 | 
						|
                {
 | 
						|
                    CalendarView.TimeLineViewScrollStartDate =
 | 
						|
                        CalendarView.TimeLineAddInterval(CalendarView.TimeLineViewScrollStartDate, 1);
 | 
						|
                }
 | 
						|
 | 
						|
                ExtendSelection(ref startDate, ref endDate);
 | 
						|
 | 
						|
                CalendarView.DateSelectionStart = startDate;
 | 
						|
                CalendarView.DateSelectionEnd = endDate;
 | 
						|
            }
 | 
						|
 | 
						|
            objArg.Handled = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessHomeKey
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Handles Home key events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        protected virtual void ProcessHomeKey(KeyEventArgs objArg)
 | 
						|
        {
 | 
						|
            DateTime startDate = CalendarView.TimeLineViewScrollStartDate;
 | 
						|
            DateTime endDate = CalendarView.TimeLineAddInterval(startDate, 1);
 | 
						|
 | 
						|
            ExtendSelection(ref startDate, ref endDate);
 | 
						|
 | 
						|
            CalendarView.DateSelectionStart = startDate;
 | 
						|
            CalendarView.DateSelectionEnd = endDate;
 | 
						|
 | 
						|
            SelectedItem = null;
 | 
						|
 | 
						|
            objArg.Handled = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region ProcessEndKey
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Processes End key events
 | 
						|
        /// </summary>
 | 
						|
        /// <param name="objArg"></param>
 | 
						|
        protected virtual void ProcessEndKey(KeyEventArgs objArg)
 | 
						|
        {
 | 
						|
            DateTime endDate = CalendarView.TimeLineViewScrollEndDate;
 | 
						|
            DateTime startDate = CalendarView.TimeLineAddInterval(endDate, -1);
 | 
						|
 | 
						|
            ExtendSelection(ref startDate, ref endDate);
 | 
						|
 | 
						|
            CalendarView.DateSelectionStart = startDate;
 | 
						|
            CalendarView.DateSelectionEnd = endDate;
 | 
						|
 | 
						|
            SelectedItem = null;
 | 
						|
 | 
						|
            objArg.Handled = true;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #endregion
 | 
						|
 | 
						|
        #region IDisposable Members
 | 
						|
 | 
						|
        protected override void Dispose(bool disposing)
 | 
						|
        {
 | 
						|
            if (disposing == true && IsDisposed == false)
 | 
						|
            {
 | 
						|
                ResetView();
 | 
						|
 | 
						|
                WorkBrush = null;
 | 
						|
                OffWorkBrush = null;
 | 
						|
                SelectedBrush = null;
 | 
						|
 | 
						|
                HookEvents(false);
 | 
						|
            }
 | 
						|
 | 
						|
            base.Dispose(disposing);
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
    }
 | 
						|
}
 | 
						|
#endif |