Componentes.Terceros.DevExp.../internal/x.44/1/ExpressScheduler/Sources/cxSchedulerRecurrenceEditor.pas
2009-06-29 12:09:02 +00:00

1106 lines
33 KiB
ObjectPascal

{********************************************************************}
{ }
{ Developer Express Visual Component Library }
{ ExpressScheduler }
{ }
{ Copyright (c) 2003-2009 Developer Express Inc. }
{ ALL RIGHTS RESERVED }
{ }
{ The entire contents of this file is protected by U.S. and }
{ International Copyright Laws. Unauthorized reproduction, }
{ reverse-engineering, and distribution of all or any portion of }
{ the code contained in this file is strictly prohibited and may }
{ result in severe civil and criminal penalties and will be }
{ prosecuted to the maximum extent possible under the law. }
{ }
{ RESTRICTIONS }
{ }
{ THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES }
{ (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE }
{ SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS }
{ LICENSED TO DISTRIBUTE THE EXPRESSSCHEDULER AND ALL ACCOMPANYING }
{ VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. }
{ }
{ THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED }
{ FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE }
{ COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE }
{ AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT }
{ AND PERMISSION FROM DEVELOPER EXPRESS INC. }
{ }
{ CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON }
{ ADDITIONAL RESTRICTIONS. }
{ }
{********************************************************************}
unit cxSchedulerRecurrenceEditor;
{$I cxVer.inc}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, cxStyles, cxGraphics, cxEdit, cxControls,
cxContainer, cxTextEdit, cxMaskEdit, cxDropDownEdit, cxCalendar,
ComCtrls, cxLookAndFeelPainters, cxButtons, cxCheckBox, cxRadioGroup,
cxSpinEdit, cxTimeEdit, cxGroupBox, cxSchedulerStorage, cxLookAndFeels,
cxSchedulerUtils, cxDateUtils, cxSchedulerEventEditor, Menus;
type
{ TcxSchedulerCustomRecurrenceEventEditor }
TcxSchedulerCustomRecurrenceEventEditor = class(TcxSchedulerCustomEditorForm)
private
FNeedCheckLossOfExceptions: Boolean;
procedure SetNeedCheckLossOfExceptions(AValue: Boolean);
protected
procedure SaveChanges; virtual;
public
constructor CreateEx(AEvent: TcxSchedulerControlEvent); override;
property NeedCheckLossOfExceptions: Boolean read FNeedCheckLossOfExceptions write SetNeedCheckLossOfExceptions;
end;
{ TcxSchedulerRecurrenceEventEditor }
TcxSchedulerRecurrenceEventEditorForm = class(TcxSchedulerCustomRecurrenceEventEditor)
gbTime: TcxGroupBox;
lbStart: TLabel;
lbEnd: TLabel;
teStart: TcxTimeEdit;
teEnd: TcxTimeEdit;
gbPattern: TcxGroupBox;
Bevel1: TBevel;
pnlPeriodicity: TPanel;
rbDaily: TcxRadioButton;
rbWeekly: TcxRadioButton;
rbMonthly: TcxRadioButton;
rbYearly: TcxRadioButton;
lbOfEvery: TLabel;
lbMonths: TLabel;
lbOfEvery1: TLabel;
lbMonths1: TLabel;
rbDay: TcxRadioButton;
rbThe: TcxRadioButton;
cbWeek: TcxComboBox;
cbDay: TcxComboBox;
lbWeeksOn: TLabel;
lbRecurEvery: TLabel;
cbDayOfWeek1: TcxCheckBox;
cbDayOfWeek2: TcxCheckBox;
cbDayOfWeek3: TcxCheckBox;
cbDayOfWeek4: TcxCheckBox;
cbDayOfWeek5: TcxCheckBox;
cbDayOfWeek6: TcxCheckBox;
cbDayOfWeek7: TcxCheckBox;
lbOf: TLabel;
rbEvery1: TcxRadioButton;
rbThe1: TcxRadioButton;
cbMonths: TcxComboBox;
cbWeek1: TcxComboBox;
cbDay1: TcxComboBox;
cbMonths1: TcxComboBox;
rbEvery: TcxRadioButton;
rbEveryWeekday: TcxRadioButton;
gbRange: TcxGroupBox;
lbStart1: TLabel;
lbOccurrences: TLabel;
deStart: TcxDateEdit;
rbNoEndDate: TcxRadioButton;
rbEndAfter: TcxRadioButton;
rbEndBy: TcxRadioButton;
deEndBy: TcxDateEdit;
btnOk: TcxButton;
btnCancel: TcxButton;
btnRemove: TcxButton;
pcPattern: TPageControl;
tsDaily: TTabSheet;
lbDay: TLabel;
tsYearly: TTabSheet;
tsWeekly: TTabSheet;
tsMonthly: TTabSheet;
meDay: TcxMaskEdit;
meNumOfWeek: TcxMaskEdit;
meNumMonth1: TcxMaskEdit;
meNumMonth: TcxMaskEdit;
meDayOfMonth: TcxMaskEdit;
meEndAfter: TcxMaskEdit;
meNumOfDay: TcxMaskEdit;
procedure SelectPeriodicityClick(Sender: TObject);
procedure meEndAfterPropertiesChange(Sender: TObject);
procedure deEndByPropertiesChange(Sender: TObject);
procedure rbNoEndDateClick(Sender: TObject);
procedure meEndAfterExit(Sender: TObject);
procedure ValidateNumber(Sender: TObject);
procedure meDayPropertiesChange(Sender: TObject);
procedure rbEveryWeekdayClick(Sender: TObject);
procedure SetDayRadioButtonChecked(Sender: TObject);
procedure SetTheRadioButtonChecked(Sender: TObject);
procedure deStartPropertiesEditValueChanged(Sender: TObject);
procedure DoChange(Sender: TObject);
procedure cbMonthsPropertiesChange(Sender: TObject);
procedure cbWeek1PropertiesChange(Sender: TObject);
procedure btnOkClick(Sender: TObject);
procedure deEndByPropertiesEditValueChanged(Sender: TObject);
procedure meEndAfterPropertiesEditValueChanged(Sender: TObject);
private
FLocked: Boolean;
procedure FillDays;
procedure FillMonths;
procedure FillWeeks;
function GetActivePattern: TcxRecurrence;
function GetRecurrenceInfo: TcxSchedulerEventRecurrenceInfo;
function GetDayOfWeekIndex: Integer;
function GetMonthIndex: Integer;
function GetNumber(const S: string): Integer;
function GetWeekIndex: Integer;
function IsValidDailyPattern: Boolean;
function IsValidMonthlyPattern: Boolean;
function IsValidWeeklyPattern: Boolean;
function IsValidYearlyPattern: Boolean;
procedure ResetDailyTab;
procedure ResetMonthlyTab;
procedure ResetWeeklyTab;
procedure ResetYearlyTab;
procedure SelectDaysOfWeek(ADays: TDays);
procedure SetActivePattern(Value: TcxRecurrence);
procedure SetDailyPatternFromEvent;
procedure SetDateWithoutChangeEvent(AEdit: TcxDateEdit; ADate: TDateTime);
procedure SetItemIndexWithoutChangeEvent(AEdit: TcxComboBox; AIndex: Integer);
procedure SetMonthlyPatternFromEvent;
procedure SetPatternFromEvent;
procedure SetTextWithoutChangeEvent(AEdit: TcxMaskEdit; const AText: string);
procedure SetupDaysOfWeek;
procedure SetWeeklyPatternFromEvent;
procedure SetYearlyPatternFromEvent;
protected
procedure ApplyChanges; override;
function CheckLostExceptions: Boolean;
procedure FillCombos; virtual;
function GetFormColor: TColor; override;
function GetRecurrenceInfoValidStatus: TcxRecurrenceValidStatus;
procedure InitializeControls; override;
function IsValid: Boolean;
procedure LoadEventValuesIntoControls; override;
procedure SaveEvent(AEvent: TcxSchedulerControlEvent);
procedure SaveRecurrenceInfo(AInfo: TcxSchedulerEventRecurrenceInfo); virtual;
procedure SaveDailyParams(AInfo: TcxSchedulerEventRecurrenceInfo);
procedure SaveWeeklyParams(AInfo: TcxSchedulerEventRecurrenceInfo);
procedure SaveMonthlyParams(AInfo: TcxSchedulerEventRecurrenceInfo);
procedure SaveYearlyParams(AInfo: TcxSchedulerEventRecurrenceInfo);
procedure SetCaptions; virtual;
procedure SetEndAfter;
procedure SetEndDate;
procedure SetEventRecurrenceFinish;
procedure SetReadOnly(AValue: Boolean); override;
procedure UpdateEventValuesFromControls; override;
procedure UpdateRange;
property ActivePattern: TcxRecurrence read GetActivePattern write SetActivePattern;
property Info: TcxSchedulerEventRecurrenceInfo read GetRecurrenceInfo;
property Locked: Boolean read FLocked write FLocked;
public
property Event;
property Modified;
property NeedCheckLossOfExceptions;
property ReadOnly;
end;
TcxSchedulerRecurrenceEventEditor = TcxSchedulerRecurrenceEventEditorForm; //workaround for Delphi 2005
TcxSchedulerRecurrenceEventEditorClass = class of TcxSchedulerCustomRecurrenceEventEditor;
implementation
uses
cxSchedulerStrs, cxClasses, {$IFDEF DELPHI6}Variants, DateUtils, {$ENDIF} cxSchedulerDialogs;
{$R *.dfm}
function cxDayTypeFromType(AIndex: Integer): TcxDayType;
begin
if AIndex < 0 then AIndex := 0;
Inc(AIndex);
if AIndex >= Byte(cxdtSaturday) then
Result := cxdtSaturday
else
Result := TcxDayType(AIndex);
end;
function cxDayNumberFromRange(AIndex: Integer): Integer;
begin
Result := AIndex + 1;
end;
{ TcxSchedulerCustomRecurrenceEventEditor }
constructor TcxSchedulerCustomRecurrenceEventEditor.CreateEx(
AEvent: TcxSchedulerControlEvent);
begin
inherited CreateEx(AEvent);
FNeedCheckLossOfExceptions := (Event.Pattern <> nil) and Event.Pattern.HasExceptions;
end;
procedure TcxSchedulerCustomRecurrenceEventEditor.SaveChanges;
begin
if Event.Pattern = nil then
begin
Event.EventType := etPattern;
FModified := True;
end
else
Event.EventType := etCustom;
UpdateEventValuesFromControls;
end;
procedure TcxSchedulerCustomRecurrenceEventEditor.SetNeedCheckLossOfExceptions(
AValue: Boolean);
begin
FNeedCheckLossOfExceptions := FNeedCheckLossOfExceptions and AValue;
end;
{ TcxSchedulerRecurrenceEventEditor }
procedure TcxSchedulerRecurrenceEventEditorForm.SelectPeriodicityClick(
Sender: TObject);
begin
ActivePattern := TcxRecurrence(TcxRadioButton(Sender).Tag);
end;
procedure TcxSchedulerRecurrenceEventEditorForm.ApplyChanges;
begin
case ModalResult of
mrOk:
if not ReadOnly then
SaveChanges;
mrAbort:
begin
if not IsInternalActivate and (Event.Pattern <> nil) then
Event.Pattern.DeleteExceptions;
Event.EventType := etNone;
FModified := True;
end;
mrCancel:
if Event.Source = nil then
Event.EventType := etNone;
end;
end;
function TcxSchedulerRecurrenceEventEditorForm.CheckLostExceptions: Boolean;
begin
Result := not FNeedCheckLossOfExceptions or
(MessageDlg(cxGetResourceString(@scxConfirmLostExceptions), mtWarning, [mbOK, mbCancel], 0) = mrOk);
end;
procedure TcxSchedulerRecurrenceEventEditorForm.FillCombos;
begin
FillDays;
FillMonths;
FillWeeks;
end;
function TcxSchedulerRecurrenceEventEditorForm.GetFormColor: TColor;
begin
Result := teStart.Style.LookAndFeel.Painter.DefaultSchedulerControlColor;
end;
function TcxSchedulerRecurrenceEventEditorForm.GetRecurrenceInfoValidStatus: TcxRecurrenceValidStatus;
var
AEvent: TcxSchedulerControlEvent;
begin
AEvent := TcxSchedulerControlEvent.Create(Event.Storage);
try
SaveEvent(AEvent);
AEvent.EventType := etPattern;
Result := AEvent.RecurrenceInfo.GetValidStatus;
finally
AEvent.Free;
end;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.InitializeControls;
begin
SetCaptions;
FillCombos;
FLocked := True;
LoadEventValuesIntoControls;
FLocked := False;
end;
function TcxSchedulerRecurrenceEventEditorForm.IsValid: Boolean;
begin
case ActivePattern of
cxreDaily:
Result := IsValidDailyPattern;
cxreWeekly:
Result := IsValidWeeklyPattern;
cxreMonthly:
Result := IsValidMonthlyPattern;
else //cxreYearly
Result := IsValidYearlyPattern;
end;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.LoadEventValuesIntoControls;
function GetRecurrenceStartTime: TDateTime;
begin
if Event.Pattern <> nil then
Result := TimeOf(Event.Pattern.Start)
else
Result := TimeOf(Event.Start);
end;
function GetRecurrenceEndTime: TDateTime;
begin
if Event.Pattern <> nil then
Result := TimeOf(Event.Pattern.Finish)
else
Result := TimeOf(Event.Finish);
end;
function GetRecurrenceStartDate: TDateTime;
begin
if Event.Pattern <> nil then
Result := DateOf(Event.Pattern.RecurrenceInfo.Start)
else
Result := DateOf(Event.RecurrenceInfo.Start);
end;
begin
teStart.Time := GetRecurrenceStartTime;
teEnd.Time := GetRecurrenceEndTime;
SetDateWithoutChangeEvent(deStart, GetRecurrenceStartDate);
SetPatternFromEvent;
SetEventRecurrenceFinish;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SaveEvent(
AEvent: TcxSchedulerControlEvent);
begin
if AEvent <> Event then
AEvent.Assign(Event);
SaveRecurrenceInfo(AEvent.RecurrenceInfo);
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SaveRecurrenceInfo(
AInfo: TcxSchedulerEventRecurrenceInfo);
begin
AInfo.Start := deStart.Date + teStart.Time;
//correct finish time
with AInfo.Event do Finish := DateOf(Finish) + teEnd.Time;
AInfo.Recurrence := ActivePattern;
if rbNoEndDate.Checked then
AInfo.Count := -1
else if rbEndAfter.Checked then
AInfo.Count := GetNumber(meEndAfter.Text)
else
begin
AInfo.Count := 0;
AInfo.Finish := deEndBy.Date;
end;
case ActivePattern of
cxreDaily: SaveDailyParams(AInfo);
cxreWeekly: SaveWeeklyParams(AInfo);
cxreMonthly: SaveMonthlyParams(AInfo);
cxreYearly: SaveYearlyParams(AInfo);
end;
if not Locked then
AInfo.Validate;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SaveDailyParams(
AInfo: TcxSchedulerEventRecurrenceInfo);
begin
if rbEvery.Checked then
begin
AInfo.DayType := cxdtEveryDay;
AInfo.Periodicity := GetNumber(meDay.Text);
end
else
begin
AInfo.DayType := cxdtWeekDay;
AInfo.Periodicity := 1;
end;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SaveWeeklyParams(
AInfo: TcxSchedulerEventRecurrenceInfo);
procedure Check(ACheckBox: TcxCheckBox; var AOccurDays: TDays);
begin
if ACheckBox.Checked then
Include(AOccurDays, TDay(ACheckBox.Tag - 1));
end;
var
AOccurDays: TDays;
begin
AInfo.Periodicity := GetNumber(meNumOfWeek.Text);
AOccurDays := [];
Check(cbDayOfWeek1, AOccurDays);
Check(cbDayOfWeek2, AOccurDays);
Check(cbDayOfWeek3, AOccurDays);
Check(cbDayOfWeek4, AOccurDays);
Check(cbDayOfWeek5, AOccurDays);
Check(cbDayOfWeek6, AOccurDays);
Check(cbDayOfWeek7, AOccurDays);
AInfo.OccurDays := AOccurDays;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SaveMonthlyParams(
AInfo: TcxSchedulerEventRecurrenceInfo);
begin
if rbDay.Checked then
begin
AInfo.DayType := cxdtDay;
AInfo.DayNumber := GetNumber(meNumOfDay.Text);
AInfo.Periodicity := GetNumber(meNumMonth.Text);;
end
else
begin
AInfo.DayType := cxDayTypeFromType(cbDay.ItemIndex);
AInfo.DayNumber := cxDayNumberFromRange(cbWeek.ItemIndex);
AInfo.Periodicity := GetNumber(meNumMonth1.Text);
end;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SaveYearlyParams(
AInfo: TcxSchedulerEventRecurrenceInfo);
begin
if rbEvery1.Checked then
begin
AInfo.DayType := cxdtDay;
AInfo.Periodicity := cbMonths.ItemIndex + 1;
AInfo.DayNumber := GetNumber(meDayOfMonth.Text);
end
else
begin
AInfo.DayType := cxDayTypeFromType(cbDay1.ItemIndex);
AInfo.DayNumber := cxDayNumberFromRange(cbWeek1.ItemIndex);
AInfo.Periodicity := cbMonths1.ItemIndex + 1;
end;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetCaptions;
begin
Caption := cxGetResourceString(@scxRecurrenceCaption);
// time
gbTime.Caption := cxGetResourceString(@scxEventTime);
lbStart.Caption := cxGetResourceString(@scxStart);
lbEnd.Caption := cxGetResourceString(@scxEnd);
// pattern
gbPattern.Caption := cxGetResourceString(@scxRecurrencePattern);
rbDaily.Caption := cxGetResourceString(@scxDaily);
rbWeekly.Caption := cxGetResourceString(@scxWeekly);
rbMonthly.Caption := cxGetResourceString(@scxMonthly);
rbYearly.Caption := cxGetResourceString(@scxYearly);
// daily
rbEvery.Caption := cxGetResourceString(@scxEvery);
rbEveryWeekday.Caption := cxGetResourceString(@scxEveryWeekDay);
lbDay.Caption := cxGetResourceString(@scxDay1);
// weekly
lbRecurEvery.Caption := cxGetResourceString(@scxRecurEvery);
lbWeeksOn.Caption := cxGetResourceString(@scxWeeksOn);
SetupDaysOfWeek;
// mothly
lbOfEvery.Caption := cxGetResourceString(@scxOfEvery);
lbOfEvery1.Caption := lbOfEvery.Caption;
lbMonths.Caption := cxGetResourceString(@scxMonths);
lbMonths1.Caption := lbMonths.Caption;
rbDay.Caption := cxGetResourceString(@scxDay);
rbThe.Caption := cxGetResourceString(@scxThe);
// yearly
rbEvery1.Caption := rbEvery.Caption;
rbThe1.Caption := rbThe.Caption;
lbOf.Caption := cxGetResourceString(@scxOf);
// range of recurrence
gbRange.Caption := cxGetResourceString(@scxRangeOfRecurrence);
lbStart1.Caption := cxGetResourceString(@scxStart1);
rbNoEndDate.Caption := cxGetResourceString(@scxNoEndDate);
rbEndAfter.Caption := cxGetResourceString(@scxEndAfter);
rbEndBy.Caption := cxGetResourceString(@scxEndBy);
lbOccurrences.Caption := cxGetResourceString(@scxOccurences);
// buttons
btnOk.Caption := cxGetResourceString(@scxOk);
btnCancel.Caption := cxGetResourceString(@scxCancel);
btnRemove.Caption := cxGetResourceString(@scxRemoveRecur);
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetEndAfter;
var
ACount: Integer;
AEvent: TcxSchedulerControlEvent;
begin
AEvent := TcxSchedulerControlEvent.Create(Event.Storage);
try
SaveEvent(AEvent);
with TcxSchedulerOccurrenceCalculator.Create(AEvent, 0, 0) do
try
ACount := GetOccurrenceCount(deEndBy.Date + TimeOf(teEnd.Time));
finally
Free;
end;
finally
AEvent.Free;
end;
if ACount < 1 then
ACount := 1;
SetTextWithoutChangeEvent(meEndAfter, IntToStr(ACount));
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetEndDate;
var
ADate: TDateTime;
AEvent: TcxSchedulerControlEvent;
begin
AEvent := TcxSchedulerControlEvent.Create(Event.Storage);
try
SaveEvent(AEvent);
with TcxSchedulerOccurrenceCalculator.Create(AEvent, 0, 0) do
try
CalcOccurrence(GetNumber(meEndAfter.Text));
ADate := DateOf(OccurrenceFinish);
finally
Free;
end;
finally
AEvent.Free;
end;
SetDateWithoutChangeEvent(deEndBy, ADate);
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetEventRecurrenceFinish;
var
ACount: Integer;
begin
with TcxSchedulerOccurrenceCalculator.Create(Event, 0, 0) do
try
ACount := Info.Count;
if ACount < 0 then ACount := 10;
if ACount > 0 then
begin
if Info.Count < 0 then
rbNoEndDate.Checked := True
else
rbEndAfter.Checked := True;
CalcOccurrence(ACount);
SetDateWithoutChangeEvent(deEndBy, DateOf(OccurrenceFinish));
end
else
begin
rbEndBy.Checked := True;
SetDateWithoutChangeEvent(deEndBy, DateOf(Info.Finish));
ACount := GetOccurrenceCount(Info.Finish);
if ACount < 1 then ACount := 1;
end;
SetTextWithoutChangeEvent(meEndAfter, IntToStr(ACount));
finally
Free;
end;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetReadOnly(
AValue: Boolean);
begin
inherited;
gbTime.Enabled := not AValue;
gbPattern.Enabled := not AValue;
gbRange.Enabled := not AValue;
btnCancel.Enabled := not AValue;
btnRemove.Enabled := not AValue;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.UpdateEventValuesFromControls;
begin
SaveEvent(Event);
end;
procedure TcxSchedulerRecurrenceEventEditorForm.UpdateRange;
begin
if rbEndBy.Checked then
SetEndAfter
else
SetEndDate;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.FillDays;
var
S: TStrings;
I: Integer;
begin
S := cbDay.Properties.Items;
S.BeginUpdate;
try
S.Add(cxGetResourceString(@scxDay1));
S.Add(cxGetResourceString(@scxWeekday));
S.Add(cxGetResourceString(@scxWeekendday));
for I := 1 to 7 do
S.Add(LongDayNames[I]);
finally
S.EndUpdate;
end;
cbDay1.Properties.Items.Assign(S);
end;
procedure TcxSchedulerRecurrenceEventEditorForm.FillMonths;
var
S: TStrings;
I: Integer;
begin
S := cbMonths.Properties.Items;
S.BeginUpdate;
try
for I := 1 to 12 do
S.Add(LongMonthNames[I]);
finally
S.EndUpdate;
end;
cbMonths1.Properties.Items.Assign(S);
end;
procedure TcxSchedulerRecurrenceEventEditorForm.FillWeeks;
var
S: TStrings;
I: Integer;
begin
S := cbWeek.Properties.Items;
S.BeginUpdate;
try
for I := 0 to 4 do
S.Add(cxGetResourceString(sRangeNames[I]));
finally
S.EndUpdate;
end;
cbWeek1.Properties.Items.Assign(S);
end;
function TcxSchedulerRecurrenceEventEditorForm.GetActivePattern: TcxRecurrence;
begin
Result := TcxRecurrence(pcPattern.ActivePageIndex);
end;
function TcxSchedulerRecurrenceEventEditorForm.GetRecurrenceInfo: TcxSchedulerEventRecurrenceInfo;
begin
Result := Event.RecurrenceInfo;
end;
function TcxSchedulerRecurrenceEventEditorForm.GetDayOfWeekIndex: Integer;
begin
Result := DayOfWeek(Info.Start) + 2;
end;
function TcxSchedulerRecurrenceEventEditorForm.GetMonthIndex: Integer;
begin
Result := MonthOf(Info.Start) - 1;
end;
function TcxSchedulerRecurrenceEventEditorForm.GetNumber(const S: string): Integer;
begin
Result := StrToIntDef(Trim(S), 1);
end;
function TcxSchedulerRecurrenceEventEditorForm.GetWeekIndex: Integer;
var
Y, M, D: Word;
begin
DecodeDate(Info.Start, Y, M, D);
Result := D div 7;
end;
function TcxSchedulerRecurrenceEventEditorForm.IsValidDailyPattern: Boolean;
begin
Result := GetNumber(meDay.Text) >= 1;
if not Result then
begin
ActiveControl := meDay;
Exit;
end;
end;
function TcxSchedulerRecurrenceEventEditorForm.IsValidMonthlyPattern: Boolean;
begin
Result := False;
if not GetNumber(meNumOfDay.Text) in [1..31] then
begin
ActiveControl := meNumOfDay;
Exit;
end;
if GetNumber(meNumMonth.Text) < 1 then
begin
ActiveControl := meNumMonth;
Exit;
end;
if GetNumber(meNumMonth1.Text) < 1 then
begin
ActiveControl := meNumMonth1;
Exit;
end;
Result := True;
end;
function TcxSchedulerRecurrenceEventEditorForm.IsValidWeeklyPattern: Boolean;
begin
Result := False;
if GetNumber(meNumOfWeek.Text) < 1 then
begin
ActiveControl := meNumOfWeek;
Exit;
end;
if not (cbDayOfWeek1.Checked or cbDayOfWeek2.Checked or
cbDayOfWeek3.Checked or cbDayOfWeek4.Checked or cbDayOfWeek5.Checked or
cbDayOfWeek6.Checked or cbDayOfWeek7.Checked) then
begin
ActiveControl := cbDayOfWeek1;
Exit;
end;
Result := True;
end;
function TcxSchedulerRecurrenceEventEditorForm.IsValidYearlyPattern: Boolean;
var
ADay: Integer;
begin
ADay := GetNumber(meDayOfMonth.Text);
Result := (ADay >=1) and (ADay <= DaysPerMonth(2000, cbMonths.ItemIndex + 1));
if not Result then
ActiveControl := meDayOfMonth;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.ResetDailyTab;
begin
SetTextWithoutChangeEvent(meDay, '1');
rbEvery.Checked := True;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.ResetMonthlyTab;
begin
SetTextWithoutChangeEvent(meNumOfDay, IntToStr(DayOf(Info.Start)));
SetTextWithoutChangeEvent(meNumMonth, '1');
SetTextWithoutChangeEvent(meNumMonth1, '1');
cbWeek.ItemIndex := GetWeekIndex;
cbDay.ItemIndex := GetDayOfWeekIndex;
rbDay.Checked := True;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.ResetWeeklyTab;
begin
SetTextWithoutChangeEvent(meNumOfWeek, '1');
SelectDaysOfWeek([TDay(DayOfWeek(Info.Start) - 1)]);
end;
procedure TcxSchedulerRecurrenceEventEditorForm.ResetYearlyTab;
begin
cbDay1.ItemIndex := GetDayOfWeekIndex;
meDayOfMonth.Text := IntToStr(DayOf(Info.Start));
cbWeek1.ItemIndex := GetWeekIndex;
cbMonths.ItemIndex := GetMonthIndex;
cbMonths1.ItemIndex := GetMonthIndex;
rbEvery1.Checked := True;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SelectDaysOfWeek(ADays: TDays);
procedure Check(ACheckBox: TcxCheckBox);
begin
ACheckBox.Checked := TDay(ACheckBox.Tag - 1) in ADays;
end;
begin
Check(cbDayOfWeek1);
Check(cbDayOfWeek2);
Check(cbDayOfWeek3);
Check(cbDayOfWeek4);
Check(cbDayOfWeek5);
Check(cbDayOfWeek6);
Check(cbDayOfWeek7);
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetActivePattern(
Value: TcxRecurrence);
begin
pcPattern.ActivePageIndex := Integer(Value);
case Value of
cxreDaily: ResetDailyTab;
cxreWeekly: ResetWeeklyTab;
cxreMonthly: ResetMonthlyTab;
cxreYearly: ResetYearlyTab;
end;
UpdateRange;
FModified := True;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetDailyPatternFromEvent;
begin
rbDaily.Checked := True;
if Info.DayType = cxdtWeekDay then
begin
rbEveryWeekday.Checked := True;
SetTextWithoutChangeEvent(meDay, '1');
end
else
begin
rbEvery.Checked := True;
SetTextWithoutChangeEvent(meDay, IntToStr(Info.Periodicity));
end;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetDateWithoutChangeEvent(
AEdit: TcxDateEdit; ADate: TDateTime);
var
AOnChange, AOnEditValueChanged: TNotifyEvent;
begin
AOnChange := AEdit.Properties.OnChange;
AOnEditValueChanged := AEdit.Properties.OnEditValueChanged;
AEdit.Properties.OnChange := nil;
AEdit.Properties.OnEditValueChanged := nil;
AEdit.Date := ADate;
AEdit.Properties.OnChange := AOnChange;
AEdit.Properties.OnEditValueChanged := AOnEditValueChanged;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetItemIndexWithoutChangeEvent(
AEdit: TcxComboBox; AIndex: Integer);
var
AOnChange: TNotifyEvent;
begin
AOnChange := AEdit.Properties.OnChange;
AEdit.Properties.OnChange := nil;
AEdit.ItemIndex := AIndex;
AEdit.Properties.OnChange := AOnChange;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetMonthlyPatternFromEvent;
var
AType: TcxDayType;
ANum: Integer;
begin
rbMonthly.Checked := True;
AType := Info.DayType;
if AType = cxdtDay then
begin
rbDay.Checked := True;
SetTextWithoutChangeEvent(meNumOfDay, IntToStr(Info.DayNumber));
SetTextWithoutChangeEvent(meNumMonth, IntToStr(Info.Periodicity));
end
else
begin
rbThe.Checked := True;
SetTextWithoutChangeEvent(meNumMonth1, IntToStr(Info.Periodicity));
ANum := Info.DayNumber;
if Integer(AType) >= 1 then Dec(Byte(AType));
SetItemIndexWithoutChangeEvent(cbWeek, ANum - 1);
SetItemIndexWithoutChangeEvent(cbDay, Byte(AType));
end;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetPatternFromEvent;
begin
ActivePattern := Info.Recurrence;
case Info.Recurrence of
cxreDaily: SetDailyPatternFromEvent;
cxreWeekly: SetWeeklyPatternFromEvent;
cxreMonthly: SetMonthlyPatternFromEvent;
cxreYearly: SetYearlyPatternFromEvent;
end;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetupDaysOfWeek;
procedure SetDayCheckBox(ACheck: TcxCheckBox);
var
AIndex: Integer;
begin
AIndex := ACheck.Tag;
Inc(AIndex, TcxSchedulerDateTimeHelper.StartOfWeek);
if AIndex > 7 then Dec(AIndex, 7);
ACheck.Caption := LongDayNames[AIndex];
ACheck.Tag := AIndex;
end;
begin
SetDayCheckBox(cbDayOfWeek1);
SetDayCheckBox(cbDayOfWeek2);
SetDayCheckBox(cbDayOfWeek3);
SetDayCheckBox(cbDayOfWeek4);
SetDayCheckBox(cbDayOfWeek5);
SetDayCheckBox(cbDayOfWeek6);
SetDayCheckBox(cbDayOfWeek7);
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetTextWithoutChangeEvent(
AEdit: TcxMaskEdit; const AText: string);
var
AOnChange, AOnEditValueChanged: TNotifyEvent;
begin
AOnChange := AEdit.Properties.OnChange;
AOnEditValueChanged := AEdit.Properties.OnEditValueChanged;
AEdit.Properties.OnChange := nil;
AEdit.Properties.OnEditValueChanged := nil;
AEdit.Text := AText;
AEdit.Properties.OnChange := AOnChange;
AEdit.Properties.OnEditValueChanged := AOnEditValueChanged;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetWeeklyPatternFromEvent;
begin
rbWeekly.Checked := True;
meNumOfWeek.Text := IntToStr(Info.Periodicity);
if Event.IsRecurring and (Event.Source <> nil) then
SelectDaysOfWeek(Info.OccurDays)
else
SelectDaysOfWeek([TDay(DayOfWeek(Event.Start) - 1)]);
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetYearlyPatternFromEvent;
var
AType: TcxDayType;
ANum: Integer;
begin
rbYearly.Checked := True;
AType := Info.DayType;
ANum := Info.DayNumber;
if AType = cxdtDay then
begin
rbEvery1.Checked := True;
cbMonths.ItemIndex := Info.Periodicity - 1;
SetTextWithoutChangeEvent(meDayOfMonth, IntToStr(ANum));
end
else
begin
rbThe1.Checked := True;
cbMonths1.ItemIndex := Info.Periodicity - 1;
if Integer(AType) >= 1 then Dec(Byte(AType));
SetItemIndexWithoutChangeEvent(cbWeek1, ANum - 1);
SetItemIndexWithoutChangeEvent(cbDay1, Byte(AType));
end;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.meEndAfterPropertiesChange(
Sender: TObject);
begin
rbEndAfter.Checked := True;
FModified := True;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.deEndByPropertiesChange(
Sender: TObject);
begin
rbEndBy.Checked := True;
FModified := True;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.rbNoEndDateClick(
Sender: TObject);
begin
meEndAfter.Text := '10';
SetEndDate;
FModified := True;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.meEndAfterExit(
Sender: TObject);
begin
ValidateNumber(Sender);
SetEndDate;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.ValidateNumber(
Sender: TObject);
begin
with TcxMaskEdit(Sender) do
Text := IntToStr(GetNumber(Text));
end;
procedure TcxSchedulerRecurrenceEventEditorForm.meDayPropertiesChange(
Sender: TObject);
begin
rbEvery.Checked := True;
FModified := True;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.rbEveryWeekdayClick(
Sender: TObject);
begin
SetTextWithoutChangeEvent(meDay, '1');
FModified := True;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetDayRadioButtonChecked(
Sender: TObject);
begin
rbDay.Checked := True;
FModified := True;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.SetTheRadioButtonChecked(
Sender: TObject);
begin
rbThe.Checked := True;
FModified := True;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.deStartPropertiesEditValueChanged(
Sender: TObject);
begin
UpdateRange;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.DoChange(Sender: TObject);
begin
FModified := True;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.cbMonthsPropertiesChange(
Sender: TObject);
begin
rbEvery1.Checked := True;
FModified := True;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.cbWeek1PropertiesChange(
Sender: TObject);
begin
rbThe1.Checked := True;
FModified := True;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.btnOkClick(Sender: TObject);
begin
if IsValid then
begin
case GetRecurrenceInfoValidStatus of
rvsValid:
if CheckLostExceptions then
ModalResult := mrOk;
rvsReplaceOccurrenceDate:
if CheckLostExceptions and (MessageDlg(Format(cxGetResourceString(@scxReplaceOccurrenceDate),
[meNumOfDay.Text]), mtWarning, [mbOK,mbCancel], 0) = mrOk) then ModalResult := mrOk;
rvsInvalidDuration:
MessageDlg(cxGetResourceString(@scxInvalidRecurrenceDuration), mtWarning, [mbOK], 0);
else
MessageDlg(cxGetResourceString(@scxWrongPattern), mtWarning, [mbOK], 0);
end
end
else
MessageDlg(cxGetResourceString(@scxWrongPattern), mtWarning, [mbOK], 0);
end;
procedure TcxSchedulerRecurrenceEventEditorForm.deEndByPropertiesEditValueChanged(
Sender: TObject);
begin
if Locked then Exit;
SetEndAfter;
end;
procedure TcxSchedulerRecurrenceEventEditorForm.meEndAfterPropertiesEditValueChanged(
Sender: TObject);
begin
if Locked then Exit;
SetEndDate;
end;
end.