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
|
|
|