StableVersion4.3/HL_FristAidPlatform_PreHosp.../CustomAppointmentForm1.cs

469 lines
23 KiB
C#
Raw Normal View History

2024-03-11 09:47:34 +08:00
using DevExpress.Utils;
using DevExpress.Utils.Controls;
using DevExpress.Utils.Internal;
using DevExpress.Utils.Menu;
using DevExpress.Utils.Svg;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraEditors.Native;
using DevExpress.XtraScheduler;
using DevExpress.XtraScheduler.Internal;
using DevExpress.XtraScheduler.Localization;
using DevExpress.XtraScheduler.Native;
using DevExpress.XtraScheduler.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
namespace HL_FristAidPlatform_PreHospitalEmergency
{
public partial class CustomAppointmentForm1 : XtraForm, IDXManagerPopupMenu
{
bool openRecurrenceForm;
readonly ISchedulerStorage storage;
readonly SchedulerControl control;
SvgImage recurringSvgImage;
SvgImage normalSvgImage;
readonly AppointmentFormController controller;
IDXMenuManager menuManager;
[EditorBrowsable(EditorBrowsableState.Never)]
public CustomAppointmentForm1()
{
InitializeComponent();
}
public CustomAppointmentForm1(SchedulerControl control, Appointment apt)
: this(control, apt, false)
{
}
public CustomAppointmentForm1(SchedulerControl control, Appointment apt, bool openRecurrenceForm)
{
Guard.ArgumentNotNull(control, "control");
Guard.ArgumentNotNull(control.DataStorage, "control.DataStorage");
Guard.ArgumentNotNull(apt, "apt");
this.openRecurrenceForm = openRecurrenceForm;
this.controller = CreateController(control, apt);
//
// Required for Windows Form Designer support
//
InitializeComponent();
SetupPredefinedConstraints();
LoadIcons();
this.control = control;
this.storage = control.DataStorage;
this.edtShowTimeAs.Storage = this.storage;
this.edtLabel.Storage = this.storage;
this.edtResource.SchedulerControl = control;
this.edtResource.Storage = this.storage;
this.edtResources.SchedulerControl = control;
SubscribeControllerEvents(Controller);
SubscribeEditorsEvents();
BindControllerToControls();
}
protected override FormShowMode ShowMode { get { return FormShowMode.AfterInitialization; } }
[Browsable(false)]
public IDXMenuManager MenuManager { get { return this.menuManager; } private set { this.menuManager = value; } }
protected internal AppointmentFormController Controller { get { return this.controller; } }
protected internal SchedulerControl Control { get { return this.control; } }
protected internal ISchedulerStorage Storage { get { return this.storage; } }
protected internal bool IsNewAppointment { get { return this.controller != null ? this.controller.IsNewAppointment : true; } }
protected internal SvgImage RecurringSvgImage { get { return this.recurringSvgImage; } }
protected internal SvgImage NormalSvgImage { get { return this.normalSvgImage; } }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public SvgImage SvgImage { get { return IconOptions.SvgImage; } set { IconOptions.SvgImage = value; } }
protected internal bool OpenRecurrenceForm { get { return this.openRecurrenceForm; } }
[DXDescription("DevExpress.XtraScheduler.UI.AppointmentForm,ReadOnly")]
[DXCategory(CategoryName.Behavior)]
[DefaultValue(false)]
public bool ReadOnly
{
get { return Controller != null && Controller.ReadOnly; }
set
{
if (Controller.ReadOnly == value)
return;
Controller.ReadOnly = value;
}
}
public virtual void LoadFormData(Appointment appointment)
{
//do nothing
}
public virtual bool SaveFormData(Appointment appointment)
{
return true;
}
public virtual bool IsAppointmentChanged(Appointment appointment)
{
return false;
}
public virtual void SetMenuManager(IDXMenuManager menuManager)
{
MenuManagerUtils.SetMenuManager(Controls, menuManager);
this.menuManager = menuManager;
}
protected internal virtual void SetupPredefinedConstraints()
{
this.tbProgress.Properties.Minimum = AppointmentProcessValues.Min;
this.tbProgress.Properties.Maximum = AppointmentProcessValues.Max;
this.tbProgress.Properties.SmallChange = AppointmentProcessValues.Step;
this.edtResources.Visible = true;
}
protected virtual void BindControllerToControls()
{
BindControllerToIcon();
BindProperties(this.tbSubject, "Text", "Subject");
BindProperties(this.tbLocation, "Text", "Location");
BindProperties(this.tbDescription, "Text", "Description");
BindProperties(this.edtShowTimeAs, "Status", "Status");
BindProperties(this.edtStartDate, "EditValue", "DisplayStartDate");
BindProperties(this.edtStartDate, "Enabled", "IsDateTimeEditable");
BindProperties(this.edtStartTime, "EditValue", "DisplayStartTime");
BindProperties(this.edtStartTime, "Visible", "IsTimeVisible");
BindProperties(this.edtStartTime, "Enabled", "IsTimeVisible");
BindProperties(this.edtEndDate, "EditValue", "DisplayEndDate", DataSourceUpdateMode.Never);
BindProperties(this.edtEndDate, "Enabled", "IsDateTimeEditable", DataSourceUpdateMode.Never);
BindProperties(this.edtEndTime, "EditValue", "DisplayEndTime", DataSourceUpdateMode.Never);
BindProperties(this.edtEndTime, "Visible", "IsTimeVisible", DataSourceUpdateMode.Never);
BindProperties(this.edtEndTime, "Enabled", "IsTimeVisible", DataSourceUpdateMode.Never);
BindProperties(this.chkAllDay, "Checked", "AllDay");
BindProperties(this.chkAllDay, "Enabled", "IsDateTimeEditable");
BindProperties(this.edtResource, "ResourceId", "ResourceId");
BindProperties(this.edtResource, "Enabled", "CanEditResource");
BindToBoolPropertyAndInvert(this.edtResource, "Visible", "ResourceSharing");
BindProperties(this.edtResources, "ResourceIds", "ResourceIds");
BindProperties(this.edtResources, "Visible", "ResourceSharing");
BindProperties(this.edtResources, "Enabled", "CanEditResource");
BindProperties(this.lblResource, "Enabled", "CanEditResource");
BindProperties(this.edtLabel, "Label", "Label");
BindProperties(this.chkReminder, "Enabled", "ReminderVisible");
BindProperties(this.chkReminder, "Visible", "ReminderVisible");
BindProperties(this.chkReminder, "Checked", "HasReminder");
BindProperties(this.cbReminder, "Enabled", "HasReminder");
BindProperties(this.cbReminder, "Visible", "ReminderVisible");
BindProperties(this.cbReminder, "Duration", "ReminderTimeBeforeStart");
BindProperties(this.tbProgress, "Value", "PercentComplete");
BindProperties(this.lblPercentCompleteValue, "Text", "PercentComplete", ObjectToStringConverter);
BindProperties(this.progressPanel, "Visible", "ShouldEditTaskProgress");
BindToBoolPropertyAndInvert(this.btnOk, "Enabled", "ReadOnly");
BindToBoolPropertyAndInvert(this.btnRecurrence, "Enabled", "ReadOnly");
BindProperties(this.btnDelete, "Enabled", "CanDeleteAppointment");
BindProperties(this.btnRecurrence, "Visible", "ShouldShowRecurrenceButton");
}
protected virtual void BindControllerToIcon()
{
Binding binding = new Binding("SvgImage", Controller, "AppointmentType");
binding.Format += AppointmentTypeToIconConverter;
DataBindings.Add(binding);
}
protected virtual void ObjectToStringConverter(object o, ConvertEventArgs e)
{
e.Value = e.Value.ToString();
}
protected virtual void AppointmentTypeToIconConverter(object o, ConvertEventArgs e)
{
AppointmentType type = (AppointmentType)e.Value;
if (type == AppointmentType.Pattern)
e.Value = RecurringSvgImage;
else
e.Value = NormalSvgImage;
}
protected virtual void BindProperties(Control target, string targetProperty, string sourceProperty)
{
BindProperties(target, targetProperty, sourceProperty, DataSourceUpdateMode.OnPropertyChanged);
}
protected virtual void BindProperties(Control target, string targetProperty, string sourceProperty, DataSourceUpdateMode updateMode)
{
target.DataBindings.Add(targetProperty, Controller, sourceProperty, true, updateMode);
}
protected virtual void BindProperties(Control target, string targetProperty, string sourceProperty, ConvertEventHandler objectToStringConverter)
{
Binding binding = new Binding(targetProperty, Controller, sourceProperty, true);
binding.Format += objectToStringConverter;
target.DataBindings.Add(binding);
}
protected virtual void BindToBoolPropertyAndInvert(Control target, string targetProperty, string sourceProperty)
{
target.DataBindings.Add(new BoolInvertBinding(targetProperty, Controller, sourceProperty));
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (Controller == null)
return;
DataBindings.Add("Text", Controller, "Caption");
SubscribeControlsEvents();
LoadFormData(Controller.EditedAppointmentCopy);
RecalculateLayoutOfControlsAffectedByProgressPanel();
}
protected virtual AppointmentFormController CreateController(SchedulerControl control, Appointment apt)
{
return new AppointmentFormController(control, apt);
}
void SubscribeEditorsEvents()
{
this.cbReminder.EditValueChanging += OnCbReminderEditValueChanging;
}
void SubscribeControllerEvents(AppointmentFormController controller)
{
if (controller == null)
return;
controller.PropertyChanged += OnControllerPropertyChanged;
}
void OnControllerPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "ReadOnly")
UpdateReadonly();
}
protected virtual void UpdateReadonly()
{
if (Controller == null)
return;
IList<Control> controls = GetAllControls(this);
foreach (Control control in controls)
{
BaseEdit editor = control as BaseEdit;
if (editor == null)
continue;
editor.ReadOnly = Controller.ReadOnly;
}
this.btnOk.Enabled = !Controller.ReadOnly;
this.btnRecurrence.Enabled = !Controller.ReadOnly;
}
List<Control> GetAllControls(Control rootControl)
{
List<Control> result = new List<Control>();
foreach (Control control in rootControl.Controls)
{
result.Add(control);
IList<Control> childControls = GetAllControls(control);
result.AddRange(childControls);
}
return result;
}
protected internal virtual void LoadIcons()
{
Assembly asm = typeof(Appointment).Assembly;
this.recurringSvgImage = ResourceImageHelper.CreateSvgImageFromResources(SchedulerSvgImageNames.NewRecurringAppointment, asm);
this.normalSvgImage = ResourceImageHelper.CreateSvgImageFromResources(SchedulerSvgImageNames.NewAppointment, asm);
}
protected internal virtual void SubscribeControlsEvents()
{
this.edtEndDate.Validating += new CancelEventHandler(OnEdtEndDateValidating);
this.edtEndDate.InvalidValue += new InvalidValueExceptionEventHandler(OnEdtEndDateInvalidValue);
this.edtEndTime.Validating += new CancelEventHandler(OnEdtEndTimeValidating);
this.edtEndTime.InvalidValue += new InvalidValueExceptionEventHandler(OnEdtEndTimeInvalidValue);
this.cbReminder.InvalidValue += new InvalidValueExceptionEventHandler(OnCbReminderInvalidValue);
this.cbReminder.Validating += new CancelEventHandler(OnCbReminderValidating);
this.edtStartDate.Validating += new CancelEventHandler(OnEdtStartDateValidating);
this.edtStartDate.InvalidValue += new InvalidValueExceptionEventHandler(OnEdtStartDateInvalidValue);
this.edtStartTime.Validating += new CancelEventHandler(OnEdtStartTimeValidating);
this.edtStartTime.InvalidValue += new InvalidValueExceptionEventHandler(OnEdtStartTimeInvalidValue);
}
protected internal virtual void UnsubscribeControlsEvents()
{
this.edtEndDate.Validating -= new CancelEventHandler(OnEdtEndDateValidating);
this.edtEndDate.InvalidValue -= new InvalidValueExceptionEventHandler(OnEdtEndDateInvalidValue);
this.edtEndTime.Validating -= new CancelEventHandler(OnEdtEndTimeValidating);
this.edtEndTime.InvalidValue -= new InvalidValueExceptionEventHandler(OnEdtEndTimeInvalidValue);
this.cbReminder.InvalidValue -= new InvalidValueExceptionEventHandler(OnCbReminderInvalidValue);
this.cbReminder.Validating -= new CancelEventHandler(OnCbReminderValidating);
this.edtStartDate.Validating -= new CancelEventHandler(OnEdtStartDateValidating);
this.edtStartDate.InvalidValue -= new InvalidValueExceptionEventHandler(OnEdtStartDateInvalidValue);
this.edtStartTime.Validating -= new CancelEventHandler(OnEdtStartTimeValidating);
this.edtStartTime.InvalidValue -= new InvalidValueExceptionEventHandler(OnEdtStartTimeInvalidValue);
}
void OnBtnOkClick(object sender, EventArgs e)
{
OnOkButton();
}
protected internal virtual void OnEdtStartTimeInvalidValue(object sender, InvalidValueExceptionEventArgs e)
{
e.ErrorText = SchedulerLocalizer.GetString(SchedulerStringId.Msg_DateOutsideLimitInterval);
}
protected internal virtual void OnEdtStartTimeValidating(object sender, CancelEventArgs e)
{
e.Cancel = !Controller.ValidateLimitInterval(this.edtStartDate.DateTime.Date, this.edtStartTime.Time.TimeOfDay, this.edtEndDate.DateTime.Date, this.edtEndTime.Time.TimeOfDay);
}
protected internal virtual void OnEdtStartDateInvalidValue(object sender, InvalidValueExceptionEventArgs e)
{
e.ErrorText = SchedulerLocalizer.GetString(SchedulerStringId.Msg_DateOutsideLimitInterval);
}
protected internal virtual void OnEdtStartDateValidating(object sender, CancelEventArgs e)
{
e.Cancel = !Controller.ValidateLimitInterval(this.edtStartDate.DateTime.Date, this.edtStartTime.Time.TimeOfDay, this.edtEndDate.DateTime.Date, this.edtEndTime.Time.TimeOfDay);
}
protected internal virtual void OnEdtEndDateValidating(object sender, CancelEventArgs e)
{
e.Cancel = !IsValidInterval();
if (!e.Cancel)
this.edtEndDate.DataBindings["EditValue"].WriteValue();
}
protected internal virtual void OnEdtEndDateInvalidValue(object sender, InvalidValueExceptionEventArgs e)
{
if (!AppointmentFormControllerBase.ValidateInterval(this.edtStartDate.DateTime.Date, this.edtStartTime.Time.TimeOfDay, this.edtEndDate.DateTime.Date, this.edtEndTime.Time.TimeOfDay))
e.ErrorText = SchedulerLocalizer.GetString(SchedulerStringId.Msg_InvalidEndDate);
else
e.ErrorText = SchedulerLocalizer.GetString(SchedulerStringId.Msg_DateOutsideLimitInterval);
}
protected internal virtual void OnEdtEndTimeValidating(object sender, CancelEventArgs e)
{
e.Cancel = !IsValidInterval();
if (!e.Cancel)
this.edtEndTime.DataBindings["EditValue"].WriteValue();
}
protected internal virtual void OnEdtEndTimeInvalidValue(object sender, InvalidValueExceptionEventArgs e)
{
if (!AppointmentFormControllerBase.ValidateInterval(this.edtStartDate.DateTime.Date, this.edtStartTime.Time.TimeOfDay, this.edtEndDate.DateTime.Date, this.edtEndTime.Time.TimeOfDay))
e.ErrorText = SchedulerLocalizer.GetString(SchedulerStringId.Msg_InvalidEndDate);
else
e.ErrorText = SchedulerLocalizer.GetString(SchedulerStringId.Msg_DateOutsideLimitInterval);
}
protected internal virtual bool IsValidInterval()
{
return AppointmentFormControllerBase.ValidateInterval(this.edtStartDate.DateTime.Date, this.edtStartTime.Time.TimeOfDay, this.edtEndDate.DateTime.Date, this.edtEndTime.Time.TimeOfDay) &&
Controller.ValidateLimitInterval(this.edtStartDate.DateTime.Date, this.edtStartTime.Time.TimeOfDay, this.edtEndDate.DateTime.Date, this.edtEndTime.Time.TimeOfDay);
}
protected internal virtual void OnOkButton()
{
if (!ValidateDateAndTime())
return;
if (!SaveFormData(Controller.EditedAppointmentCopy))
return;
if (!Controller.IsConflictResolved())
{
ShowMessageBox(SchedulerLocalizer.GetString(SchedulerStringId.Msg_Conflict), Controller.GetMessageBoxCaption(SchedulerStringId.Msg_Conflict), MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
if (!Controller.IsTimeValid())
{
ShowMessageBox(SchedulerLocalizer.GetString(SchedulerStringId.Msg_InvalidAppointmentTime), Controller.GetMessageBoxCaption(SchedulerStringId.Msg_InvalidAppointmentTime), MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return;
}
if (IsAppointmentChanged(Controller.EditedAppointmentCopy) || Controller.IsAppointmentChanged() || Controller.IsNewAppointment)
Controller.ApplyChanges();
DialogResult = DialogResult.OK;
}
private bool ValidateDateAndTime()
{
this.edtEndDate.DoValidate();
this.edtEndTime.DoValidate();
this.edtStartDate.DoValidate();
this.edtStartTime.DoValidate();
return String.IsNullOrEmpty(this.edtEndTime.ErrorText) && String.IsNullOrEmpty(this.edtEndDate.ErrorText) && String.IsNullOrEmpty(this.edtStartDate.ErrorText) && String.IsNullOrEmpty(this.edtStartTime.ErrorText);
}
protected internal virtual DialogResult ShowMessageBox(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon)
{
return XtraMessageBox.Show(this, text, caption, buttons, icon);
}
void OnBtnDeleteClick(object sender, EventArgs e)
{
OnDeleteButton();
}
protected internal virtual void OnDeleteButton()
{
if (IsNewAppointment)
return;
Controller.DeleteAppointment();
DialogResult = DialogResult.Abort;
Close();
}
void OnBtnRecurrenceClick(object sender, EventArgs e)
{
OnRecurrenceButton();
}
protected internal virtual void OnRecurrenceButton()
{
if (!Controller.ShouldShowRecurrenceButton)
return;
Appointment patternCopy = Controller.PrepareToRecurrenceEdit();
DialogResult result;
using (Form form = CreateAppointmentRecurrenceForm(patternCopy, Control.OptionsView.FirstDayOfWeek))
{
result = ShowRecurrenceForm(form);
}
if (result == DialogResult.Abort)
{
Controller.RemoveRecurrence();
}
else if (result == DialogResult.OK)
{
Controller.ApplyRecurrence(patternCopy);
}
}
protected virtual DialogResult ShowRecurrenceForm(Form form)
{
return FormTouchUIAdapter.ShowDialog(form, this);
}
protected internal virtual Form CreateAppointmentRecurrenceForm(Appointment patternCopy, FirstDayOfWeek firstDayOfWeek)
{
AppointmentRecurrenceForm form = new AppointmentRecurrenceForm(patternCopy, firstDayOfWeek, Controller);
form.SetMenuManager(MenuManager);
form.LookAndFeel.ParentLookAndFeel = LookAndFeel;
form.ShowExceptionsRemoveMsgBox = this.controller.AreExceptionsPresent();
return form;
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
if (this.openRecurrenceForm)
{
this.openRecurrenceForm = false;
OnRecurrenceButton();
}
}
protected internal virtual void OnCbReminderValidating(object sender, CancelEventArgs e)
{
TimeSpan span = this.cbReminder.Duration;
e.Cancel = (span == TimeSpan.MinValue) || (span.Ticks < 0);
if (!e.Cancel)
this.cbReminder.DataBindings["Duration"].WriteValue();
}
protected internal virtual void OnCbReminderInvalidValue(object sender, InvalidValueExceptionEventArgs e)
{
e.ErrorText = SchedulerLocalizer.GetString(SchedulerStringId.Msg_InvalidReminderTimeBeforeStart);
}
protected internal virtual void RecalculateLayoutOfControlsAffectedByProgressPanel()
{
if (this.progressPanel.Visible)
return;
int intDeltaY = this.progressPanel.Height;
this.tbDescription.Location = new Point(this.tbDescription.Location.X, this.tbDescription.Location.Y - intDeltaY);
this.tbDescription.Size = new Size(this.tbDescription.Size.Width, this.tbDescription.Size.Height + intDeltaY);
}
void OnCbReminderEditValueChanging(object sender, ChangingEventArgs e)
{
if (e.NewValue is TimeSpan)
return;
string stringValue = e.NewValue as String;
TimeSpan duration = HumanReadableTimeSpanHelper.Parse(stringValue);
if (duration.Ticks < 0)
e.NewValue = TimeSpan.FromTicks(0);
}
}
}