#if FRAMEWORK20 using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; namespace DevComponents.Schedule.Model { /// /// Represents an appointment reminder. /// public class Reminder { #region Private variables private bool _NotificationRequestRegistered = false; #endregion #region Constructors /// /// Initializes a new instance of the Reminder class. /// public Reminder() { } /// /// Initializes a new instance of the Reminder class. /// /// public Reminder(DateTime reminderTime) { ReminderTime = reminderTime; } /// /// Initializes a new instance of the Reminder class. /// /// /// public Reminder(string description, DateTime reminderTime) { Description = description; ReminderTime = reminderTime; } #endregion #region Events /// /// 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. /// [Description("Occurs when ReminderTime has been reached.")] public event ReminderEventHandler ReminderNotification; #endregion #region Internal Implementation private bool _IsActiveForPastAppointments = true; /// /// 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. /// 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 = ""; /// /// Gets or sets the reminder description. /// 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; /// /// Gets or sets additional data associated with the object. /// [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) { } /// /// Gets or sets the date and time reminder will be executed at. /// /// 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. /// /// 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; } } /// /// Gets or sets the action performed when reminder time is reached. Default value is Event and Command. /// 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; /// /// Gets the Appointment reminder is attached to. /// [Browsable(false)] public Appointment Appointment { get { return _Appointment; } internal set { if (_Appointment != value) { _Appointment = value; if (NeedsNotification) UpdateNotifications(); } } } private bool _IsActive = true; /// /// 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. /// [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; /// /// Gets or sets the next snooze time for the reminder. Use the Snooze method if you want to snooze the reminder correctly. /// 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")); } /// /// 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. /// /// Next reminder notification time. 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(); } } /// /// Runs the ReminderNotification as if the reminder time has been reached. /// This method is automatically called by reminder once ReminderTime has been reached. /// 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(); } } /// /// Raises the ReminderNotification event. /// /// protected virtual void OnReminderNotification(ReminderEventArgs eventArgs) { ReminderEventHandler h = ReminderNotification; if (h != null) h(this, eventArgs); } /// /// Creates an copy of the reminder. /// /// Reminder copy. 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; /// /// Gets or sets whether this reminder is snooze reminder usually created by Reminder dialog when user hits the Snooze button. /// Default value is false. /// 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); /// /// Defines arguments for reminder related events. /// public class ReminderEventArgs : EventArgs { /// /// Gets the reminder referenced by this event. /// public Reminder Reminder = null; /// /// Initializes a new instance of the ReminderEventArgs class. /// /// public ReminderEventArgs(Reminder reminder) { Reminder = reminder; } } #endregion } #endif