599 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			599 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| #if FRAMEWORK20
 | |
| using System;
 | |
| using System.Collections.Generic;
 | |
| using DevComponents.Schedule.Model;
 | |
| using System.ComponentModel;
 | |
| 
 | |
| namespace DevComponents.DotNetBar.Schedule
 | |
| {
 | |
|     internal class ModelMonthViewConnector : ModelViewConnector
 | |
|     {
 | |
|         #region Constants
 | |
| 
 | |
|         private const int DaysInWeek = 7;
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Private variables
 | |
| 
 | |
|         private CalendarModel _Model;       // The associated CalendarModel
 | |
|         private MonthView _View;            // The associated MonthView
 | |
| 
 | |
|         private bool _IsConnected;          // Connection status
 | |
|         private uint _RefreshCount;
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Constructor
 | |
|         /// </summary>
 | |
|         /// <param name="model">Assoc CalendarModel</param>
 | |
|         /// <param name="monthView">Assoc MonthView</param>
 | |
|         public ModelMonthViewConnector(CalendarModel model, MonthView monthView)
 | |
|         {
 | |
|             _Model = model;
 | |
|             _View = monthView;
 | |
|         }
 | |
| 
 | |
|         #region Public properties
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets the connection status
 | |
|         /// </summary>
 | |
|         public override bool IsConnected
 | |
|         {
 | |
|             get { return _IsConnected; }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Connect
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Performs Model connection processing
 | |
|         /// </summary>
 | |
|         public override void Connect()
 | |
|         {
 | |
|             VerifyModel();
 | |
| 
 | |
|             // Load the connection data
 | |
| 
 | |
|             if (_IsConnected)
 | |
|                 Disconnect();
 | |
| 
 | |
|             LoadData();
 | |
| 
 | |
|             // Get notification on Model property changes
 | |
| 
 | |
|             _Model.PropertyChanged += ModelPropertyChanged;
 | |
|             _Model.SubPropertyChanged += ModelSubPropertyChanged;
 | |
| 
 | |
|             _View.CalendarView.CustomItems.CollectionChanged += CustomItemsCollectionChanged;
 | |
| 
 | |
|             _IsConnected = true;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Disconnect
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Severs the Model/MonthView connection
 | |
|         /// </summary>
 | |
|         public override void Disconnect()
 | |
|         {
 | |
|             VerifyModel();
 | |
| 
 | |
|             if (_IsConnected)
 | |
|             {
 | |
|                 // Loop through each week, clearing each
 | |
|                 // associated view connection
 | |
| 
 | |
|                 for (int i = 0; i < _View.MonthWeeks.Length; i++)
 | |
|                     ClearMonthWeek(_View.MonthWeeks[i]);
 | |
| 
 | |
|                 _View.SubItems.Clear();
 | |
| 
 | |
|                 // Stop notification on Model property changes
 | |
| 
 | |
|                 _Model.PropertyChanged -= ModelPropertyChanged;
 | |
|                 _Model.SubPropertyChanged -= ModelSubPropertyChanged;
 | |
| 
 | |
|                 _View.CalendarView.CustomItems.CollectionChanged -= CustomItemsCollectionChanged;
 | |
| 
 | |
|                 _IsConnected = false;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Clears individual MonthWeek view connections
 | |
|         /// </summary>
 | |
|         /// <param name="monthWeek">MonthWeek</param>
 | |
|         private void ClearMonthWeek(MonthWeek monthWeek)
 | |
|         {
 | |
|             if (monthWeek.CalendarItems.Count > 0)
 | |
|             {
 | |
|                 // Loop through each CalendarItem, resetting
 | |
|                 // it's associated connection
 | |
| 
 | |
|                 for (int i = monthWeek.CalendarItems.Count - 1; i >= 0; i--)
 | |
|                 {
 | |
|                     AppointmentMonthView view =
 | |
|                         monthWeek.CalendarItems[i] as AppointmentMonthView;
 | |
| 
 | |
|                     if (view != null)
 | |
|                     {
 | |
|                         view.IsSelectedChanged -= _View.ItemIsSelectedChanged;
 | |
| 
 | |
|                         view.Appointment = null;
 | |
|                         view.IsSelected = false;
 | |
|                         view.MonthWeek = null;
 | |
|                     }
 | |
| 
 | |
|                     monthWeek.CalendarItems.RemoveAt(i);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region LoadData
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Loads Model/MonthView connection data
 | |
|         /// </summary>
 | |
|         private void LoadData()
 | |
|         {
 | |
|             MonthWeek[] wks = _View.MonthWeeks;
 | |
| 
 | |
|             if (wks.Length > 0)
 | |
|             {
 | |
|                 _RefreshCount++;
 | |
| 
 | |
|                 DateTime startDate = wks[0].FirstDayOfWeek;
 | |
|                 DateTime endDate = DateTimeHelper.EndOfDay(wks[wks.Length - 1].LastDayOfWeek);
 | |
| 
 | |
|                 DateTime appStartDate = startDate.AddMonths(-1);
 | |
| 
 | |
|                 List<Appointment> appts = GetAppointmentList(_Model, appStartDate, endDate);
 | |
| 
 | |
|                 for (int i = 0; i < wks.Length; i++)
 | |
|                 {
 | |
|                     MonthWeek monthWeek = wks[i];
 | |
| 
 | |
|                     startDate = monthWeek.FirstDayOfWeek;
 | |
|                     endDate = DateTimeHelper.EndOfDay(monthWeek.LastDayOfWeek);
 | |
| 
 | |
|                     UpdateWeekView(monthWeek, appts, startDate, endDate);
 | |
|                     UpdateCustomItems(monthWeek, startDate, endDate);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region RefreshData
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Refreshes the data in a previously established
 | |
|         /// and loaded connection
 | |
|         /// </summary>
 | |
|         public void RefreshData()
 | |
|         {
 | |
|             LoadData();
 | |
| 
 | |
|             List<CalendarItem> removedViews = null;
 | |
| 
 | |
|             foreach (MonthWeek monthWeek in _View.MonthWeeks)
 | |
|                 RemoveOutdatedViews(monthWeek, ref removedViews);
 | |
| 
 | |
|             ProcessRemovedData(removedViews);
 | |
|         }
 | |
| 
 | |
|         #region RemoveOutdatedViews
 | |
| 
 | |
|         private void RemoveOutdatedViews(
 | |
|             MonthWeek monthWeek, ref List<CalendarItem> removedViews)
 | |
|         {
 | |
|             for (int i = monthWeek.CalendarItems.Count - 1; i >= 0; i--)
 | |
|             {
 | |
|                 CalendarItem view = monthWeek.CalendarItems[i];
 | |
| 
 | |
|                 if (view != null)
 | |
|                 {
 | |
|                     if (view.RefreshCount != _RefreshCount)
 | |
|                     {
 | |
|                         if (removedViews == null)
 | |
|                             removedViews = new List<CalendarItem>();
 | |
| 
 | |
|                         removedViews.Add(view);
 | |
| 
 | |
|                         _View.SubItems._Remove(view);
 | |
|                         _View.NeedRecalcSize = true;
 | |
| 
 | |
|                         monthWeek.CalendarItems.RemoveAt(i);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ProcessRemovedData
 | |
| 
 | |
|         private void ProcessRemovedData(List<CalendarItem> removedViews)
 | |
|         {
 | |
|             if (removedViews != null && removedViews.Count > 0)
 | |
|             {
 | |
|                 for (int i = 0; i < removedViews.Count; i++)
 | |
|                 {
 | |
|                     CalendarItem item = removedViews[i];
 | |
| 
 | |
|                     item.IsSelectedChanged -= _View.ItemIsSelectedChanged;
 | |
| 
 | |
|                     item.Dispose();
 | |
|                 }
 | |
| 
 | |
|                 _View.NeedRecalcLayout = true;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region UpdateWeekView
 | |
| 
 | |
|         private void UpdateWeekView(MonthWeek monthWeek,
 | |
|             List<Appointment> apps, DateTime startDate, DateTime endDate)
 | |
|         {
 | |
|             // Loop through each appointment
 | |
|             // updating the assoc view accordingly
 | |
| 
 | |
|             foreach (Appointment app in  apps)
 | |
|             {
 | |
|                 if (app.StartTime < endDate && app.EndTime > startDate)
 | |
|                 {
 | |
|                     if (IsAppointmentVisible(app))
 | |
|                     {
 | |
|                         // Get the assoc view
 | |
| 
 | |
|                         AppointmentMonthView view = GetViewFromWeek(monthWeek, app) ??
 | |
|                                                     GetNewView(app);
 | |
| 
 | |
|                         // Set the view start and end times to
 | |
|                         // match the assoc appointment
 | |
| 
 | |
|                         view.StartTime = app.StartTime;
 | |
|                         view.EndTime = app.EndTime;
 | |
| 
 | |
|                         view.RefreshCount = _RefreshCount;
 | |
| 
 | |
|                         // And update the MonthWeek data
 | |
| 
 | |
|                         if (view.MonthWeek == null)
 | |
|                         {
 | |
|                             view.MonthWeek = monthWeek;
 | |
| 
 | |
|                             monthWeek.CalendarItems.Add(view);
 | |
| 
 | |
|                             _View.SubItems.Add(view);
 | |
|                         }
 | |
| 
 | |
|                         view.IsSelected = app.IsSelected;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region UpdateCustomItems
 | |
| 
 | |
|         private void UpdateCustomItems(
 | |
|             MonthWeek monthWeek, DateTime startDate, DateTime endDate)
 | |
|         {
 | |
|             CustomCalendarItemCollection items = _View.CalendarView.CustomItems;
 | |
| 
 | |
|             if (items != null && items.Count > 0)
 | |
|             {
 | |
|                 for (int i = 0; i < items.Count; i++)
 | |
|                 {
 | |
|                     CustomCalendarItem item = items[i];
 | |
| 
 | |
|                     if (IsCustomItemVisible(item) == true &&
 | |
|                         (item.StartTime < endDate && item.EndTime > startDate))
 | |
|                     {
 | |
|                         item.CalendarView = _View.CalendarView;
 | |
| 
 | |
|                         CustomCalendarItem ci = GetItemFromWeek(monthWeek, item);
 | |
| 
 | |
|                         if (ci == null)
 | |
|                         {
 | |
|                             ci = GetNewCustomItem(item);
 | |
| 
 | |
|                             monthWeek.CalendarItems.Add(ci);
 | |
| 
 | |
|                             _View.SubItems.Insert(0, ci);
 | |
|                         }
 | |
| 
 | |
|                         ci.RefreshCount = _RefreshCount;
 | |
| 
 | |
|                         if (ci.BaseCalendarItem != item)
 | |
|                         {
 | |
|                             ci.StartTime = item.StartTime;
 | |
|                             ci.EndTime = item.EndTime;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetViewFrom
 | |
| 
 | |
|         private List<AppointmentMonthView> GetViewsFromAll(Appointment app)
 | |
|         {
 | |
|             List<AppointmentMonthView> list = new List<AppointmentMonthView>();
 | |
| 
 | |
|             for (int i = 0; i < _View.MonthWeeks.Length; i++)
 | |
|             {
 | |
|                 AppointmentMonthView view =
 | |
|                     GetViewFromWeek(_View.MonthWeeks[i], app);
 | |
| 
 | |
|                 if (view != null)
 | |
|                     list.Add(view);
 | |
|             }
 | |
| 
 | |
|             return (list);
 | |
|         }
 | |
| 
 | |
|         private AppointmentMonthView GetViewFromWeek(MonthWeek monthWeek, Appointment appointment)
 | |
|         {
 | |
|             foreach (CalendarItem item in monthWeek.CalendarItems)
 | |
|             {
 | |
|                 AppointmentMonthView view = item as AppointmentMonthView;
 | |
| 
 | |
|                 if (view != null && view.Appointment == appointment)
 | |
|                     return (view);
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetItemFromWeek
 | |
| 
 | |
|         private CustomCalendarItem GetItemFromWeek(MonthWeek monthWeek, CustomCalendarItem item)
 | |
|         {
 | |
|             foreach (CalendarItem citem in monthWeek.CalendarItems)
 | |
|             {
 | |
|                 CustomCalendarItem view = citem as CustomCalendarItem;
 | |
| 
 | |
|                 if (view != null && (view == item || view.BaseCalendarItem == item))
 | |
|                     return (view);
 | |
|             }
 | |
| 
 | |
|             return (null);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetNewView
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets a new appointment view
 | |
|         /// </summary>
 | |
|         /// <param name="appointment">Appointment</param>
 | |
|         /// <returns>New view</returns>
 | |
|         private AppointmentMonthView GetNewView(Appointment appointment)
 | |
|         {
 | |
|             AppointmentMonthView view = new AppointmentMonthView(_View, appointment);
 | |
| 
 | |
|             view.Tooltip = appointment.Tooltip;
 | |
| 
 | |
|             // Set the selected state to match any current
 | |
|             // views that are present for this appointment
 | |
| 
 | |
|             for (int i = 0; i < _View.MonthWeeks.Length; i++)
 | |
|             {
 | |
|                 AppointmentMonthView viewPart =
 | |
|                     GetViewFromWeek(_View.MonthWeeks[i], appointment);
 | |
| 
 | |
|                 if (viewPart != null)
 | |
|                 {
 | |
|                     view.IsSelected = viewPart.IsSelected;
 | |
|                     break;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             view.IsSelectedChanged += _View.ItemIsSelectedChanged;
 | |
| 
 | |
|             return (view);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetNewCustomItem
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets a new CustomItem
 | |
|         /// </summary>
 | |
|         /// <param name="item"></param>
 | |
|         /// <returns></returns>
 | |
|         private CustomCalendarItem GetNewCustomItem(CustomCalendarItem item)
 | |
|         {
 | |
|             CustomCalendarItem ci = (CustomCalendarItem)item.Copy();
 | |
| 
 | |
|             ci.BaseCalendarItem = item;
 | |
|             ci.ModelItem = item;
 | |
| 
 | |
|             // Set the selected state to match any current
 | |
|             // views that are present for this appointment
 | |
| 
 | |
|             for (int i = 0; i < _View.MonthWeeks.Length; i++)
 | |
|             {
 | |
|                 CustomCalendarItem viewPart =
 | |
|                     GetItemFromWeek(_View.MonthWeeks[i], item);
 | |
| 
 | |
|                 if (viewPart != null)
 | |
|                 {
 | |
|                     ci.IsSelected = viewPart.IsSelected;
 | |
|                     break;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             ci.IsSelectedChanged += _View.ItemIsSelectedChanged;
 | |
| 
 | |
|             return (ci);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetView
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Returns the Month view
 | |
|         /// </summary>
 | |
|         /// <returns></returns>
 | |
|         public override eCalendarView GetView()
 | |
|         {
 | |
|             return (eCalendarView.Month);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Verifies the Model and MonthView are valid
 | |
|         /// </summary>
 | |
|         private void VerifyModel()
 | |
|         {
 | |
|             if (_Model == null)
 | |
|                 throw new NullReferenceException("CalendarModel must be set on connector.");
 | |
| 
 | |
|             if (_View == null)
 | |
|                 throw new NullReferenceException("MonthCalendarView must be set on connector.");
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ModelPropertyChanged
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Handles Model property change notifications
 | |
|         /// </summary>
 | |
|         /// <param name="sender"></param>
 | |
|         /// <param name="e"></param>
 | |
|         private void ModelPropertyChanged(object sender, PropertyChangedEventArgs e)
 | |
|         {
 | |
|             if (e.PropertyName == CalendarModel.AppointmentsPropertyName)
 | |
|             {
 | |
|                 RefreshData();
 | |
| 
 | |
|                 _View.NeedRecalcSize = true;
 | |
|                 _View.Refresh();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region ModelSubPropertyChanged
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Handles ModelSubProperty change notifications
 | |
|         /// </summary>
 | |
|         /// <param name="sender">object</param>
 | |
|         /// <param name="e">SubPropertyChangedEventArgs</param>
 | |
|         private void ModelSubPropertyChanged(object sender, SubPropertyChangedEventArgs e)
 | |
|         {
 | |
|             if (e.Source is Owner)
 | |
|             {
 | |
|                 Owner owner = (Owner)e.Source;
 | |
| 
 | |
|                 if (_View.OwnerKey != null && _View.OwnerKey.Equals(owner.Key))
 | |
|                 {
 | |
|                     if (e.PropertyChangedArgs.PropertyName == Owner.DisplayNamePropertyName)
 | |
|                         _View.DisplayName = owner.DisplayName;
 | |
| 
 | |
|                     else if (e.PropertyChangedArgs.PropertyName.Equals("ColorScheme"))
 | |
|                         _View.CalendarColor = owner.ColorScheme;
 | |
|                 }
 | |
|             }
 | |
|             else if (e.Source is Appointment)
 | |
|             {
 | |
|                 Appointment app = e.Source as Appointment;
 | |
|                 List<AppointmentMonthView> list;
 | |
| 
 | |
|                 string name = e.PropertyChangedArgs.PropertyName;
 | |
| 
 | |
|                 if (name.Equals("Tooltip"))
 | |
|                 {
 | |
|                     list = GetViewsFromAll(app);
 | |
| 
 | |
|                     for (int i = 0; i < list.Count; i++)
 | |
|                         list[i].Tooltip = app.Tooltip;
 | |
|                 }
 | |
|                 else if (name.Equals("IsSelected"))
 | |
|                 {
 | |
|                     list = GetViewsFromAll(app);
 | |
| 
 | |
|                     for (int i = 0; i < list.Count; i++)
 | |
|                         list[i].IsSelected = app.IsSelected;
 | |
|                 }
 | |
|                 else if (name.Equals("CategoryColor") || name.Equals("TimeMarkedAs"))
 | |
|                 {
 | |
|                     list = GetViewsFromAll(app);
 | |
| 
 | |
|                     for (int i = 0; i < list.Count; i++)
 | |
|                         list[i].Refresh();
 | |
|                 }
 | |
|                 else if (name.Equals("OwnerKey"))
 | |
|                 {
 | |
|                     if (_View.CalendarView.IsMultiCalendar == true)
 | |
|                     {
 | |
|                         if (_View.OwnerKey == app.OwnerKey)
 | |
|                         {
 | |
|                             RefreshData();
 | |
| 
 | |
|                             _View.NeedRecalcSize = true;
 | |
|                             _View.Refresh();
 | |
|                         }
 | |
|                         else
 | |
|                         {
 | |
|                             list = GetViewsFromAll(app);
 | |
| 
 | |
|                             if (list.Count > 0)
 | |
|                             {
 | |
|                                 RefreshData();
 | |
| 
 | |
|                                 _View.NeedRecalcSize = true;
 | |
|                                 _View.Refresh();
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 else if (name.Equals("Visible"))
 | |
|                 {
 | |
|                     RefreshData();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region CustomItems_CollectionChanged
 | |
| 
 | |
|         void CustomItemsCollectionChanged(object sender, EventArgs e)
 | |
|         {
 | |
|             RefreshData();
 | |
| 
 | |
|             _View.NeedRecalcSize = true;
 | |
|             _View.Refresh();
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|     }
 | |
| }
 | |
| #endif
 | |
| 
 |