483 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			483 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| #if FRAMEWORK20
 | |
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Text;
 | |
| using System.ComponentModel;
 | |
| 
 | |
| namespace DevComponents.Schedule.Model
 | |
| {
 | |
|     /// <summary>
 | |
|     /// Represents an appointment reminder.
 | |
|     /// </summary>
 | |
|     public class Reminder
 | |
|     {
 | |
|         #region Private variables
 | |
|         private bool _NotificationRequestRegistered = false;
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Constructors
 | |
|         /// <summary>
 | |
|         /// Initializes a new instance of the Reminder class.
 | |
|         /// </summary>
 | |
|         public Reminder()
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Initializes a new instance of the Reminder class.
 | |
|         /// </summary>
 | |
|         /// <param name="reminderTime"></param>
 | |
|         public Reminder(DateTime reminderTime)
 | |
|         {
 | |
|             ReminderTime = reminderTime;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Initializes a new instance of the Reminder class.
 | |
|         /// </summary>
 | |
|         /// <param name="description"></param>
 | |
|         /// <param name="reminderTime"></param>
 | |
|         public Reminder(string description, DateTime reminderTime)
 | |
|         {
 | |
|             Description = description;
 | |
|             ReminderTime = reminderTime;
 | |
|         }
 | |
|         #endregion
 | |
| 
 | |
|         #region Events
 | |
|         /// <summary>
 | |
|         /// Occurs when ReminderTime has been reached. Note that event handler will be called on the thread of System.Timer which is different
 | |
|         /// than UI thread. You should use BeginInvoke calls to marshal the calls to your UI thread.
 | |
|         /// </summary>
 | |
|         [Description("Occurs when ReminderTime has been reached.")]
 | |
|         public event ReminderEventHandler ReminderNotification;
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Internal Implementation
 | |
|         private bool _IsActiveForPastAppointments = true;
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether reminder will be active for appointments that are in the past. Default value is true.
 | |
|         /// This property is useful if you are creating recurring appointments with reminders that start in past but don't want reminders
 | |
|         /// for past instances of appointment to be active.
 | |
|         /// </summary>
 | |
|         public bool IsActiveForPastAppointments
 | |
|         {
 | |
|             get { return _IsActiveForPastAppointments; }
 | |
|             set
 | |
|             {
 | |
|                 if (value != _IsActiveForPastAppointments)
 | |
|                 {
 | |
|                     bool oldValue = _IsActiveForPastAppointments;
 | |
|                     _IsActiveForPastAppointments = value;
 | |
|                     OnIsActiveForPastAppointmentsChanged(oldValue, value);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void OnIsActiveForPastAppointmentsChanged(bool oldValue, bool newValue)
 | |
|         {
 | |
|             //OnPropertyChanged(new PropertyChangedEventArgs("IsActiveForPastAppointments"));
 | |
|             ReminderCollection parentCollection = this.ParentCollection;
 | |
|             
 | |
|             if (parentCollection != null)
 | |
|             {
 | |
|                 Appointment app = this.ParentCollection.Appointment;
 | |
|                 if (app != null)
 | |
|                 {
 | |
|                     UpdateNotifications();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private string _Description = "";
 | |
|         /// <summary>
 | |
|         /// Gets or sets the reminder description.
 | |
|         /// </summary>
 | |
|         public string Description
 | |
|         {
 | |
|             get { return _Description; }
 | |
|             set
 | |
|             {
 | |
|                 if (value != _Description)
 | |
|                 {
 | |
|                     string oldValue = _Description;
 | |
|                     _Description = value;
 | |
|                     OnDescriptionChanged(oldValue, _Description);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void OnDescriptionChanged(string oldValue, string newValue)
 | |
|         {
 | |
| 
 | |
|         }
 | |
| 
 | |
|         private object _Tag = null;
 | |
|         /// <summary>
 | |
|         /// Gets or sets additional data associated with the object.
 | |
|         /// </summary>
 | |
|         [DefaultValue(null)]
 | |
|         public object Tag
 | |
|         {
 | |
|             get { return _Tag; }
 | |
|             set
 | |
|             {
 | |
|                 if (value != _Tag)
 | |
|                 {
 | |
|                     object oldValue = _Tag;
 | |
|                     _Tag = value;
 | |
|                     OnTagChanged(oldValue, value);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void OnTagChanged(object oldValue, object newValue)
 | |
|         {
 | |
| 
 | |
|         }
 | |
| 
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the date and time reminder will be executed at.
 | |
|         /// <remarks>
 | |
|         /// Unless you mark reminder as inactive by setting the IsActive=false the reminder will occur next time
 | |
|         /// notifications are updated or when appointment data is loaded.
 | |
|         /// </remarks>
 | |
|         /// </summary>
 | |
|         private DateTime _ReminderTime = DateTime.MinValue;
 | |
|         public DateTime ReminderTime
 | |
|         {
 | |
|             get { return GetTimeZoneDateTime(_ReminderTime); }
 | |
|             set
 | |
|             {
 | |
|                 value = GetUTCDateTime(CalendarModel.GetCalendarDateTime(value));
 | |
|                 if (_ReminderTime != value)
 | |
|                 {
 | |
|                     DateTime oldValue = _ReminderTime;
 | |
|                     _ReminderTime = value;
 | |
|                     OnReminderTimeChanged(oldValue, _ReminderTime);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private DateTime GetUTCDateTime(DateTime date)
 | |
|         {
 | |
|             if (date == DateTime.MinValue || date == DateTime.MaxValue || date.Kind == DateTimeKind.Utc)
 | |
|                 return date;
 | |
|             return TimeZoneInfo.ConvertTimeToUtc(date);
 | |
|         }
 | |
| 
 | |
|         private DateTime GetTimeZoneDateTime(DateTime date)
 | |
|         {
 | |
|             if (date.Kind != DateTimeKind.Utc) return date;
 | |
|             TimeZoneInfo zone = TimeZoneInfo.Local;
 | |
|             return TimeZoneInfo.ConvertTimeFromUtc(date, zone);
 | |
|         }
 | |
| 
 | |
|         private void OnReminderTimeChanged(DateTime oldValue, DateTime newValue)
 | |
|         {
 | |
|             if (NeedsNotification)
 | |
|                 UpdateNotifications();
 | |
|         }
 | |
| 
 | |
|         private bool NeedsNotification
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 return _ReminderAction != eReminderAction.None && _IsActive;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Gets or sets the action performed when reminder time is reached. Default value is Event and Command.
 | |
|         /// </summary>
 | |
|         private eReminderAction _ReminderAction = eReminderAction.EventAndCommand;
 | |
|         [DefaultValue(eReminderAction.EventAndCommand)]
 | |
|         public eReminderAction ReminderAction
 | |
|         {
 | |
|             get { return _ReminderAction; }
 | |
|             set
 | |
|             {
 | |
|                 if (_ReminderAction != value)
 | |
|                 {
 | |
|                     eReminderAction oldValue = _ReminderAction;
 | |
|                     _ReminderAction = value;
 | |
|                     OnReminderActionChanged(oldValue, _ReminderAction);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void OnReminderActionChanged(eReminderAction oldValue, eReminderAction newValue)
 | |
|         {
 | |
|             if (oldValue == eReminderAction.None || newValue == eReminderAction.None)
 | |
|                 UpdateNotifications();
 | |
|         }
 | |
| 
 | |
|         internal void UpdateNotifications()
 | |
|         {
 | |
|             if (_Appointment != null && !_IsActiveForPastAppointments && _Appointment.StartTime.Date < DateTime.Today)
 | |
|             {
 | |
|                 UnregisterNotification();
 | |
|                 return;
 | |
|             }
 | |
| 
 | |
|             if ((_Appointment != null && _Appointment.Calendar != null || _Parent != null && _Parent.ParentModel != null) &&
 | |
|                 _IsActive && _ReminderTime > DateTime.MinValue && _ReminderAction != eReminderAction.None)
 | |
|             {
 | |
|                 NotificationRequest request = this.NotificationRequest;
 | |
|                 RegisterNotification(request);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 UnregisterNotification();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void RegisterNotification(NotificationRequest request)
 | |
|         {
 | |
|             if (_NotificationRequestRegistered)
 | |
|                 NotificationServer.UpdateNotification(request);
 | |
|             else
 | |
|                 NotificationServer.Register(request);
 | |
|             _NotificationRequestRegistered = true;
 | |
|         }
 | |
| 
 | |
|         private Appointment _Appointment;
 | |
|         /// <summary>
 | |
|         /// Gets the Appointment reminder is attached to.
 | |
|         /// </summary>
 | |
|         [Browsable(false)]
 | |
|         public Appointment Appointment
 | |
|         {
 | |
|             get { return _Appointment; }
 | |
|             internal set
 | |
|             {
 | |
|                 if (_Appointment != value)
 | |
|                 {
 | |
|                     _Appointment = value;
 | |
|                     if (NeedsNotification) UpdateNotifications();
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private bool _IsActive = true;
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether reminder is active. Active reminders fire events or execute commands when 
 | |
|         /// reminder time has been reached. Set this value to false to dismiss the reminder.
 | |
|         /// </summary>
 | |
|         [DefaultValue(true)]
 | |
|         public bool IsActive
 | |
|         {
 | |
|             get { return _IsActive; }
 | |
|             set
 | |
|             {
 | |
|                 if (_IsActive != value)
 | |
|                 {
 | |
|                     bool oldValue = _IsActive;
 | |
|                     _IsActive = value;
 | |
|                     OnIsActiveChanged(oldValue, _IsActive);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void OnIsActiveChanged(bool oldValue, bool newValue)
 | |
|         {
 | |
|             UpdateNotifications();
 | |
|         }
 | |
| 
 | |
|         private NotificationRequest _NotificationRequest = null;
 | |
|         private NotificationRequest NotificationRequest
 | |
|         {
 | |
|             get
 | |
|             {
 | |
|                 if (_NotificationRequest == null)
 | |
|                 {
 | |
|                     _NotificationRequest = new NotificationRequest(((_IsSnoozeReminder && _SnoozeDateTime != DateTime.MinValue) ? _SnoozeDateTime : _ReminderTime), new NotificationServerEventHandler(OnReminderNotification));
 | |
|                 }
 | |
|                 else
 | |
|                     _NotificationRequest.NotificationTime = ((_IsSnoozeReminder && _SnoozeDateTime != DateTime.MinValue) ? _SnoozeDateTime : _ReminderTime);
 | |
|                 return _NotificationRequest;
 | |
|             }
 | |
|             set
 | |
|             {
 | |
|                 _NotificationRequest = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private DateTime _SnoozeDateTime = DateTime.MinValue;
 | |
|         /// <summary>
 | |
|         /// Gets or sets the next snooze time for the reminder. Use the Snooze method if you want to snooze the reminder correctly.
 | |
|         /// </summary>
 | |
|         public DateTime SnoozeDateTime
 | |
|         {
 | |
|             get { return _SnoozeDateTime; }
 | |
|             set
 | |
|             {
 | |
|                 value = CalendarModel.GetCalendarDateTime(value);
 | |
|                 value = value.Kind == DateTimeKind.Utc ? value : GetUTCDateTime(value);
 | |
|                 if (value != _SnoozeDateTime)
 | |
|                 {
 | |
|                     DateTime oldValue = _SnoozeDateTime;
 | |
|                     _SnoozeDateTime = value;
 | |
|                     if (_SnoozeDateTime == DateTime.MinValue)
 | |
|                     {
 | |
|                         this.IsSnoozeReminder = false;
 | |
|                         UnregisterNotification();
 | |
|                     }
 | |
|                     OnSnoozeDateTimeChanged(oldValue, value);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void OnSnoozeDateTimeChanged(DateTime oldValue, DateTime newValue)
 | |
|         {
 | |
|             //OnPropertyChanged(new PropertyChangedEventArgs("SnoozeDateTime"));
 | |
| 
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Snoozes reminder so it occurs at specified notification time. This method should be used instead of the SnoozeDateTime property and it will
 | |
|         /// set the SnoozeDateTime property to the next notification time.
 | |
|         /// </summary>
 | |
|         /// <param name="nextNotificationTime">Next reminder notification time.</param>
 | |
|         public void Snooze(DateTime nextNotificationTime)
 | |
|         {
 | |
|             nextNotificationTime = CalendarModel.GetCalendarDateTime(nextNotificationTime);
 | |
|             DateTime utcTime = nextNotificationTime.Kind == DateTimeKind.Utc ? nextNotificationTime : GetUTCDateTime(nextNotificationTime);
 | |
|             UnregisterNotification();
 | |
|             this.SnoozeDateTime = nextNotificationTime;
 | |
|             this.IsSnoozeReminder = true;
 | |
|             NotificationRequest request = this.NotificationRequest;
 | |
|             request.NotificationTime = utcTime;
 | |
|             RegisterNotification(request);
 | |
|         }
 | |
| 
 | |
|         private void UnregisterNotification()
 | |
|         {
 | |
|             if (_NotificationRequestRegistered)
 | |
|             {
 | |
|                 NotificationServer.Unregister(this.NotificationRequest);
 | |
|                 _NotificationRequestRegistered = false;
 | |
|                 this.NotificationRequest = null;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private void OnReminderNotification(NotificationRequest request, NotificationServerEventArgs e)
 | |
|         {
 | |
|             if (_ReminderAction != eReminderAction.None)
 | |
|             {
 | |
|                 this.NotificationRequest = null;
 | |
|                 ProcessNotification();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Runs the ReminderNotification as if the reminder time has been reached.
 | |
|         /// <remarks>This method is automatically called by reminder once ReminderTime has been reached.</remarks>
 | |
|         /// </summary>
 | |
|         public void ProcessNotification()
 | |
|         {
 | |
|             if (_Appointment != null && _Appointment.Calendar != null)
 | |
|                 _Appointment.Calendar.InvokeReminderNotification(this);
 | |
|             else if (_Parent != null && _Parent.ParentModel != null)
 | |
|                 _Parent.ParentModel.InvokeReminderNotification(this);
 | |
| 
 | |
|             if (_ReminderAction == eReminderAction.None) return;
 | |
| 
 | |
|             if ((_ReminderAction & eReminderAction.Event) != 0)
 | |
|             {
 | |
|                 OnReminderNotification(new ReminderEventArgs(this));
 | |
|             }
 | |
| 
 | |
|             if ((_ReminderAction & eReminderAction.Command) != 0)
 | |
|             {
 | |
|                 //throw new NotImplementedException();
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Raises the ReminderNotification event.
 | |
|         /// </summary>
 | |
|         /// <param name="eventArgs"></param>
 | |
|         protected virtual void OnReminderNotification(ReminderEventArgs eventArgs)
 | |
|         {
 | |
|             ReminderEventHandler h = ReminderNotification;
 | |
|             if (h != null)
 | |
|                 h(this, eventArgs);
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates an copy of the reminder.
 | |
|         /// </summary>
 | |
|         /// <returns>Reminder copy.</returns>
 | |
|         public Reminder Copy()
 | |
|         {
 | |
|             Reminder copy = new Reminder();
 | |
|             copy.Description = _Description;
 | |
|             copy.Tag = _Tag;
 | |
|             copy.IsActive = _IsActive;
 | |
|             copy.ReminderAction = _ReminderAction;
 | |
|             copy.IsActiveForPastAppointments = this.IsActiveForPastAppointments;
 | |
|             if (ReminderNotification != null)
 | |
|                 copy.ReminderNotification = (ReminderEventHandler)ReminderNotification.Clone();
 | |
|             copy.ReminderTime = ReminderTime;
 | |
|             copy.IsSnoozeReminder = _IsSnoozeReminder;
 | |
|             return copy;
 | |
|         }
 | |
| 
 | |
|         private bool _IsSnoozeReminder = false;
 | |
|         /// <summary>
 | |
|         /// Gets or sets whether this reminder is snooze reminder usually created by Reminder dialog when user hits the Snooze button.
 | |
|         /// Default value is false.
 | |
|         /// </summary>
 | |
|         public bool IsSnoozeReminder
 | |
|         {
 | |
|             get { return _IsSnoozeReminder; }
 | |
|             set
 | |
|             {
 | |
|                 _IsSnoozeReminder = value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         private ReminderCollection _Parent = null;
 | |
|         internal ReminderCollection ParentCollection
 | |
|         {
 | |
|             get { return _Parent; }
 | |
|             set
 | |
|             {
 | |
|                 _Parent = value;
 | |
|                 if (NeedsNotification)
 | |
|                     UpdateNotifications();
 | |
|             }
 | |
|         }
 | |
|         #endregion
 | |
|     }
 | |
| 
 | |
|     #region Events Support
 | |
|     public delegate void ReminderEventHandler(object sender, ReminderEventArgs e);
 | |
|     /// <summary>
 | |
|     /// Defines arguments for reminder related events.
 | |
|     /// </summary>
 | |
|     public class ReminderEventArgs : EventArgs
 | |
|     {
 | |
|         /// <summary>
 | |
|         /// Gets the reminder referenced by this event.
 | |
|         /// </summary>
 | |
|         public Reminder Reminder = null;
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Initializes a new instance of the ReminderEventArgs class.
 | |
|         /// </summary>
 | |
|         /// <param name="appointment"></param>
 | |
|         public ReminderEventArgs(Reminder reminder)
 | |
|         {
 | |
|             Reminder = reminder;
 | |
|         }
 | |
|     }
 | |
|     #endregion
 | |
| }
 | |
| #endif
 | |
| 
 |