home *** CD-ROM | disk | FTP | other *** search
/ Delphi 5 for Professionals / DELPHI5.iso / AddOns / Components / Essentials / SETUP.EXE / %MAINDIR% / EsEdCal.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-11-28  |  22.2 KB  |  796 lines

  1. {*********************************************************}
  2. {*                  ESEDCAL.PAS 1.05                     *}
  3. {*      Copyright (c) 1997-98 TurboPower Software Co     *}
  4. {*                 All rights reserved.                  *}
  5. {*********************************************************}
  6.  
  7. {$I ES.INC}
  8.  
  9. {$B-} {Complete Boolean Evaluation}
  10. {$I+} {Input/Output-Checking}
  11. {$P+} {Open Parameters}
  12. {$T-} {Typed @ Operator}
  13. {$W-} {Windows Stack Frame}
  14. {$X+} {Extended Syntax}
  15.  
  16. {$IFNDEF Win32}
  17.   {$G+} {286 Instructions}
  18.   {$N+} {Numeric Coprocessor}
  19.   {$C MOVEABLE,DEMANDLOAD,DISCARDABLE}
  20. {$ENDIF}
  21.  
  22. unit EsEdCal;
  23.   {-date edit field with popup calendar}
  24.  
  25. interface
  26.  
  27. uses
  28.   {$IFDEF Win32} Windows, {$ELSE} WinTypes, WinProcs, {$ENDIF}
  29.   Buttons, Classes, Controls, Forms, Graphics, Menus, Messages,
  30.   StdCtrls, SysUtils,
  31.   EsBase, EsCal, EsConst, EsEdPop, EsUtil;
  32.  
  33. type
  34.   TEsDateOrder = (doMDY, doDMY, doYMD);
  35.   TEsRequiredField = (rfYear, rfMonth, rfDay);
  36.   TEsRequiredFields = set of TEsRequiredField;
  37.  
  38.   TEsGetDateEvent = procedure(Sender : TObject; var Value : string)
  39.     of object;
  40.  
  41.   TEsCustomDateEdit = class(TEsEdPopup)
  42.   protected {private}
  43.     {.Z+}
  44.     {property variables}
  45.     FAllowIncDec    : Boolean;
  46.     FDate           : TDateTime;
  47.     FEpoch          : Integer;                                         {!!.04}
  48.     FForceCentury   : Boolean;                                         {!!.02}
  49.     FPopupCalColors : TEsCalColors;
  50.     FPopupCalFont   : TFont;
  51.     FPopupCalHeight : Integer;
  52.     FPopupCalWidth  : Integer;
  53.     FRequiredFields : TEsRequiredFields;
  54.     FTodayString    : string;
  55.     FWeekStarts     : TEsDayType;     {the day that begins the week}   {!!.02}
  56.  
  57.     {event variables}
  58.     FOnGetDate      : TEsGetDateEvent;
  59.     FOnSetDate      : TNotifyEvent;
  60.  
  61.     {internal variables}
  62.     Calendar        : TEsCalendar;
  63.     DateOrder       : TEsDateOrder;
  64.     HoldCursor      : TCursor;                                         {!!.04}
  65.     WasAutoScroll   : Boolean;
  66.  
  67.     {property methods}
  68.     function GetDate : TDateTime;                                      {!!.04}
  69.     function GetReadOnly : Boolean;
  70.     procedure SetForceCentury(Value : Boolean);                        {!!.02}
  71.     procedure SetPopupCalFont(Value : TFont);
  72.     procedure SetReadOnly(Value : Boolean);
  73.  
  74.     {internal methods}
  75.     procedure PopupDateChange(Sender : TObject; Date : TDateTime);
  76.     procedure PopupKeyDown(Sender : TObject; var Key : Word; Shift : TShiftState);
  77.     procedure PopupKeyPress(Sender : TObject; var Key : Char);
  78.     procedure PopupMouseDown(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer);
  79.     {.Z-}
  80.  
  81.   protected
  82.     {.Z+}
  83.     procedure DoExit;
  84.       override;
  85.     procedure KeyDown(var Key : Word; Shift : TShiftState);
  86.       override;
  87.     procedure KeyPress(var Key : Char);
  88.       override;
  89.     procedure PopupClose(Sender : TObject);
  90.       override;
  91.     procedure SetDate(Value : TDateTime);
  92.     procedure SetDateText(Value : string);
  93.       dynamic;
  94.     {.Z-}
  95.  
  96.     {protected properties}
  97.     property AllowIncDec : Boolean
  98.       read FAllowIncDec
  99.       write FAllowIncDec
  100.       default True;
  101.  
  102.     property Epoch : Integer                                           {!!.04}
  103.       read FEpoch
  104.       write FEpoch;
  105.  
  106.     property ForceCentury : Boolean                                    {!!.02}
  107.       read FForceCentury
  108.       write SetForceCentury
  109.       default False;
  110.  
  111.     property PopupCalColors : TEsCalColors
  112.       read FPopupCalColors
  113.       write FPopupCalColors;
  114.  
  115.     property PopupCalFont : TFont
  116.       read FPopupCalFont
  117.       write SetPopupCalFont;
  118.  
  119.     property PopupCalHeight : Integer
  120.       read FPopupCalHeight
  121.       write FPopupCalHeight
  122.       default calDefHeight;
  123.  
  124.     property PopupCalWidth : Integer
  125.       read FPopupCalWidth
  126.       write FPopupCalWidth
  127.       default calDefWidth;
  128.  
  129.     property ReadOnly : Boolean
  130.       read GetReadOnly
  131.       write SetReadOnly;
  132.  
  133.     property RequiredFields : TEsRequiredFields
  134.       read FRequiredFields
  135.       write FRequiredFields;
  136.  
  137.     property TodayString : string
  138.       read FTodayString
  139.       write FTodayString;
  140.  
  141.     property WeekStarts : TEsDayType                                   {!!.02}
  142.       read FWeekStarts
  143.       write FWeekStarts
  144.       default calDefWeekStarts;
  145.  
  146.     {protected events}
  147.     property OnGetDate : TEsGetDateEvent
  148.       read FOnGetDate
  149.       write FOnGetDate;
  150.  
  151.     property OnSetDate : TNotifyEvent
  152.       read FOnSetDate
  153.       write FOnSetDate;
  154.  
  155.   public
  156.     {.Z+}
  157.     constructor Create(AOwner : TComponent);
  158.       override;
  159.     destructor Destroy;
  160.       override;
  161.     procedure PopupOpen;
  162.       override;
  163.     {.Z-}
  164.  
  165.     function FormatDate(Value : TDateTime) : string;
  166.       dynamic;
  167.  
  168.     {public properties}
  169.     property Date : TDateTime
  170.       read GetDate                                                     {!!.04}
  171.       write SetDate;
  172.   end;
  173.  
  174.   TEsDateEdit = class(TEsCustomDateEdit)
  175.   published
  176.     {properties}
  177.     property AllowIncDec;
  178.     property AutoSelect;
  179.     property AutoSize;
  180.     property BorderStyle;
  181.     property CharCase;
  182.     property Color;
  183.     property Ctl3D;
  184.     property Cursor;
  185.     property DragCursor;
  186.     property DragMode;
  187.     property Enabled;
  188.     property Epoch;                                                    {!!.04}
  189.     property EsLabelInfo;
  190.     property Font;
  191.     property ForceCentury;                                             {!!.02}
  192.     property HideSelection;
  193.     property ParentColor;
  194.     property ParentCtl3D;
  195.     property ParentFont;
  196.     property ParentShowHint;
  197.     property PopupCalColors;
  198.     property PopupCalFont;
  199.     property PopupCalHeight;
  200.     property PopupCalWidth;
  201.     property PopupMenu;
  202.     property ReadOnly;
  203.     property RequiredFields;
  204.     property ShowHint;
  205.     property ShowButton;
  206.     property TabOrder;
  207.     property TabStop;
  208.     property TodayString;
  209.     property Version;
  210.     property Visible;
  211.     property WeekStarts;                                               {!!.02}
  212.  
  213.     {events}
  214.     property OnChange;
  215.     property OnClick;
  216.     property OnDblClick;
  217.     property OnDragDrop;
  218.     property OnDragOver;
  219.     property OnEndDrag;
  220.     property OnEnter;
  221.     property OnExit;
  222.     property OnGetDate;
  223.     property OnKeyDown;
  224.     property OnKeyPress;
  225.     property OnKeyUp;
  226.     property OnMouseDown;
  227.     property OnMouseMove;
  228.     property OnMouseUp;
  229.     property OnSetDate;
  230.     {$IFDEF Win32}
  231.     property OnStartDrag;
  232.     {$ENDIF Win32}
  233.   end;
  234.  
  235.  
  236. implementation
  237.  
  238.  
  239. {$IFDEF TRIALRUN}
  240. uses
  241.   EsTrial;
  242. {$I ESTRIALF.INC}
  243. {$ENDIF}
  244.  
  245.  
  246. {*** TEsCustomDateEdit ***}
  247.  
  248. constructor TEsCustomDateEdit.Create(AOwner : TComponent);
  249. var
  250.   C : array[0..1] of Char;
  251. {$IFDEF TRIALRUN}
  252.   X : Integer;
  253. {$ENDIF}
  254. begin
  255.   inherited Create(AOwner);
  256.  
  257.   ControlStyle := ControlStyle - [csSetCaption];
  258.  
  259.   FAllowIncDec := True;
  260.   FEpoch := DefaultEpoch;
  261.   FForceCentury := False;                                              {!!.02}
  262.   FRequiredFields := [rfMonth, rfDay];
  263.   FTodayString := DateSeparator;
  264.   FPopupCalHeight := calDefHeight;
  265.   FPopupCalWidth := calDefWidth;
  266.   FPopupCalFont := TFont.Create;
  267.   FPopupCalFont.Assign(Font);
  268.  
  269.   {get the date order from windows}
  270.   C[0] := '0'; {default}
  271.   GetProfileString('intl', 'iDate', '0', C, 2);
  272.   DateOrder := TEsDateOrder(Ord(C[0])-Ord('0'));
  273.  
  274.   {load button glyph}
  275.   FButton.Glyph.Handle := LoadBitmap(HInstance, 'ESSMALLDOWNARROW');
  276.  
  277.   {create color class}
  278.   FPopupCalColors := TEsCalColors.Create;
  279.   {assign default color scheme}
  280.   FPopupCalColors.FCalColors := CalScheme[csWindows];
  281.   FPopupCalColors.FColorScheme := csWindows;
  282.  
  283. {$IFDEF TRIALRUN}
  284.   X := _CC_;
  285.   if (X < ccRangeLow) or (X > ccRangeHigh) then Halt;
  286.   X := _VC_;
  287.   if (X < ccRangeLow) or (X > ccRangeHigh) then Halt;
  288. {$ENDIF}
  289. end;
  290.  
  291. destructor TEsCustomDateEdit.Destroy;
  292. begin
  293.   FPopupCalColors.Free;
  294.   FPopupCalColors := nil;
  295.  
  296.   FPopupCalFont.Free;
  297.   FPopupCalFont := nil;
  298.  
  299.   inherited Destroy;
  300. end;
  301.  
  302. procedure TEsCustomDateEdit.DoExit;
  303. begin
  304.   try
  305.     SetDateText(Text);
  306.   except
  307.     SetFocus;
  308.     raise;
  309.   end;
  310.  
  311.   if not PopupActive then
  312.     inherited DoExit;
  313. end;
  314.  
  315. {!!.04}
  316. function TEsCustomDateEdit.GetDate : TDateTime;
  317. begin
  318.   SetDateText(Text);
  319.   Result := FDate;
  320. end;
  321.  
  322. function TEsCustomDateEdit.GetReadOnly : Boolean;
  323. begin
  324.   Result := inherited ReadOnly;
  325. end;
  326.  
  327. procedure TEsCustomDateEdit.KeyDown(var Key : Word; Shift : TShiftState);
  328. begin
  329.   inherited KeyDown(Key, Shift);
  330.  
  331.   if (Key = VK_DOWN) and (ssAlt in Shift) then
  332.     PopupOpen;
  333. end;
  334.  
  335. procedure TEsCustomDateEdit.KeyPress(var Key : Char);
  336. var
  337.   D : Word;
  338.   M : Word;
  339.   Y : Word;
  340. begin
  341.   inherited KeyPress(Key);
  342.  
  343.   if FAllowIncDec  and (Key in ['+', '-']) then begin
  344.     DoExit; {accept current date}
  345.     if FDate = 0 then
  346.       DecodeDate(SysUtils.Date, Y, M, D)
  347.     else
  348.       DecodeDate(FDate, Y, M, D);
  349.     if Key = '+' then begin
  350.       Inc(D);
  351.       if D > DaysInMonth(Y, M) then begin
  352.         D := 1;
  353.         Inc(M);
  354.         if M > 12 then begin
  355.           Inc(Y);
  356.           M := 1;
  357.         end;
  358.       end;
  359.     end else {'-'} begin
  360.       Dec(D);
  361.       if D < 1 then begin
  362.         Dec(M);
  363.         if M < 1 then begin
  364.           M := 12;
  365.           Dec(Y);
  366.         end;
  367.         D := DaysInMonth(Y, M);
  368.       end;
  369.     end;
  370.     SetDate(EncodeDate(Y, M, D));
  371.     Modified := True;                                                  {!!.05}
  372.  
  373.     Key := #0; {clear}
  374.   end;
  375. end;
  376.  
  377. {!!.02} {revised}
  378. function TEsCustomDateEdit.FormatDate(Value : TDateTime) : string;
  379. var
  380.   S : string;
  381. begin
  382.   S := ShortDateFormat;
  383.   if FForceCentury then
  384.     if Pos('yyyy', S) = 0 then
  385.       Insert('yy', S, Pos('yy', S));
  386.   Result := FormatDateTime(S, FDate)
  387. end;
  388.  
  389. procedure TEsCustomDateEdit.PopupClose(Sender : TObject);
  390. begin
  391.   inherited PopupClose(Sender);
  392.  
  393.   if GetCapture = Calendar.Handle then
  394.     ReleaseCapture;
  395.  
  396.   SetFocus;                                                            {!!.05}
  397.   Calendar.Hide;  {hide the Calendar}
  398.   if (Calendar.Parent <> nil) and (Calendar.Parent is TForm) then      {!!.05}
  399.     TForm(Calendar.Parent).AutoScroll := WasAutoScroll;
  400.   Cursor := HoldCursor;                                                {!!.04}
  401.  
  402.   {change parentage so that we control the window handle destruction}  {!!.04}
  403.   Calendar.Parent := Self;                                             {!!.04}
  404. end;
  405.  
  406. procedure TEsCustomDateEdit.PopupKeyDown(Sender : TObject; var Key : Word; Shift : TShiftState);
  407. var
  408.   X : Integer;
  409. begin
  410.   case Key of
  411.     VK_UP : if Shift = [ssAlt] then begin
  412.               PopupClose(Sender);
  413.               X := SelStart;
  414.               SetFocus;
  415.               SelStart := X;
  416.               SelLength := 0;
  417.             end;
  418.   end;
  419. end;
  420.  
  421. procedure TEsCustomDateEdit.PopupKeyPress(Sender : TObject; var Key : Char);
  422. var
  423.   X : Integer;
  424. begin
  425.   case Key of
  426.     #27 :
  427.       begin
  428.         PopupClose(Sender);
  429.         X := SelStart;
  430.         SetFocus;
  431.         SelStart := X;
  432.         SelLength := 0;
  433.       end;
  434.   end;
  435. end;
  436.  
  437. procedure TEsCustomDateEdit.PopupMouseDown(Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer);
  438. var
  439.   P : TPoint;
  440.   I : Integer;
  441. begin
  442.   P := Point(X,Y);
  443.   if not PtInRect(Calendar.ClientRect, P) then
  444.     PopUpClose(Sender);
  445.  
  446.   {convert to our coordinate system}
  447.   P := ScreenToClient(Calendar.ClientToScreen(P));
  448.  
  449.   if PtInRect(ClientRect, P) then begin
  450.     I := SelStart;
  451.     SetFocus;
  452.     SelStart := I;
  453.     SelLength := 0;
  454.   end;
  455. end;
  456.  
  457. procedure TEsCustomDateEdit.PopupOpen;
  458. var
  459.   P : TPoint;
  460.   {$IFDEF Win32}
  461.   R : TRect;                                                           {!!.04}
  462.   {$ENDIF}
  463. begin
  464.   inherited PopupOpen;
  465.  
  466.   DoExit;    {force update of date}
  467.  
  468.   if not Assigned(Calendar) then begin
  469.     Calendar := TEsCalendar.CreateEx(Self, True);
  470.     Calendar.OnChange := PopupDateChange;
  471.     Calendar.OnExit := PopupClose;
  472.     Calendar.OnKeyDown := PopupKeyDown;
  473.     Calendar.OnKeyPress := PopupKeyPress;
  474.     Calendar.OnMouseDown := PopupMouseDown;
  475.     Calendar.Visible := False; {to avoid flash at 0,0}
  476.     Calendar.BorderStyle := bsSingle;
  477.     Calendar.Height := FPopupCalHeight;
  478.     Calendar.Width := FPopupCalWidth;
  479.     Calendar.WeekStarts := FWeekStarts;                                {!!.02}
  480.     Calendar.ParentCtl3D := False;                                     {!!.02}
  481.     Calendar.Ctl3D := Ctl3D;                                           {!!.02}
  482.     Calendar.Font.Assign(FPopupCalFont);
  483.   end;
  484.   {!!.05}
  485.   if Parent <> nil then
  486.     Calendar.Parent := Parent
  487.   else
  488.     Calendar.Parent := GetParentForm(Self);
  489.  
  490.   if (Calendar.Parent <> nil) and (Calendar.Parent is TForm) then begin{!!.05}
  491.     WasAutoScroll := TForm(Calendar.Parent).AutoScroll;
  492.     TForm(Calendar.Parent).AutoScroll := False;
  493.   end;                                                                 {!!.05}
  494.  
  495.   {set colors}
  496.   Calendar.Colors.Assign(FPopupCalColors);
  497.   {determine the proper position}
  498.   {$IFDEF Win32}
  499.   P := ClientToScreen(Point(-2, Height-2));
  500.   {$ELSE}
  501.   P := ClientToScreen(Point(0, Height));
  502.   {$ENDIF}
  503.  
  504.   {!!.04}
  505.   {$IFDEF Win32}
  506.   SystemParametersInfo(SPI_GETWORKAREA, 0, @R, 0);
  507.   if P.Y + Calendar.Height >= R.Bottom then
  508.     P.Y := P.Y - Calendar.Height - Height - 2;
  509.   if P.X + Calendar.Width >= R.Right then
  510.     P.X := R.Right - Calendar.Width - 1;
  511.   {$ELSE}
  512.   if P.Y + Calendar.Height >= Screen.Height then
  513.     P.Y := P.Y - Calendar.Height - Height - 2;
  514.   if P.X + Calendar.Width >= Screen.Width then
  515.     P.X := Screen.Width - Calendar.Width - 1;
  516.   {$ENDIF}
  517.  
  518.   MoveWindow(Calendar.Handle, P.X, P.Y, Calendar.Width, Calendar.Height, False);
  519.  
  520.   if Text = '' then
  521.     Calendar.Date := SysUtils.Date
  522.   else
  523.     Calendar.Date := FDate;
  524.  
  525.   HoldCursor := Cursor;                                                {!!.04}
  526.   Cursor := crArrow;                                                   {!!.04}
  527.   Calendar.Show;
  528.   Calendar.SetFocus;
  529.   SetCapture(Calendar.Handle);
  530. end;
  531.  
  532. procedure TEsCustomDateEdit.PopupDateChange(Sender : TObject; Date : TDateTime);
  533. begin
  534.   {get the current value}
  535.   SetDate(Calendar.Date);
  536.   Modified := True;                                                    {!!.04}
  537.  
  538.   if Calendar.Browsing then                                            {!!.04}
  539.     Exit;                                                              {!!.04}
  540.  
  541.   {hide the Calendar}
  542.   PopupClose(Sender);
  543.   SetFocus;
  544.   SelStart := Length(Text);
  545.   SelLength := 0;
  546. end;
  547.  
  548. procedure TEsCustomDateEdit.SetDate(Value : TDateTime);
  549. begin
  550.   FDate := Value;
  551.   Modified := True;
  552.  
  553.   if FDate = 0 then
  554.     Text := ''
  555.   else
  556.     Text := FormatDate(FDate);
  557.  
  558.   if Assigned(FOnSetDate) then
  559.     FOnSetDate(Self);
  560. end;
  561.  
  562. procedure TEsCustomDateEdit.SetDateText(Value : string);
  563. var
  564.   Field      : Integer;
  565.   I1         : Integer;
  566.   I2         : Integer;
  567.   Error      : Integer;
  568.   ThisYear   : Word;
  569.   ThisMonth  : Word;
  570.   ThisDay    : Word;
  571.   Year       : Word;
  572.   Month      : Word;
  573.   Day        : Word;
  574.   EpochYear  : Integer;                                                {!!.04}
  575.   EpochCent  : Integer;                                                {!!.04}
  576.   StringList : TStringList;
  577.   FieldOrder : string[3];
  578.   S          : string;
  579. begin
  580.   if Assigned(FOnGetDate) then
  581.     FOnGetDate(Self, Value);
  582.  
  583.   if (Value = '') and (RequiredFields <> []) then begin
  584.     FDate := 0;
  585.     Text := '';
  586.     Exit;
  587.   end;
  588.  
  589.   if AnsiCompareText(Value, TodayString) = 0 then begin
  590.     FDate := SysUtils.Date;
  591.     Text := FormatDate(FDate);
  592.   end else begin
  593.     DecodeDate(SysUtils.Date, ThisYear, ThisMonth, ThisDay);
  594.     Value := UpperCase(Value);
  595.     StringList := TStringList.Create;
  596.     try
  597.       {parse the string into subfields using a string list to hold the parts}
  598.       I1 := 1;
  599.       while (I1 <= Length(Value)) and not (Value[I1] in ['0'..'9', 'A'..'Z']) do
  600.         Inc(I1);
  601.       while I1 <= Length(Value) do begin
  602.         I2 := I1;
  603.         while (I2 <= Length(Value)) and (Value[I2] in ['0'..'9', 'A'..'Z']) do
  604.           Inc(I2);
  605.         StringList.Add(Copy(Value, I1, I2-I1));
  606.         while (I2 <= Length(Value)) and not (Value[I2] in ['0'..'9', 'A'..'Z']) do
  607.           Inc(I2);
  608.         I1 := I2;
  609.       end;
  610.  
  611.       case DateOrder of
  612.         doMDY : FieldOrder := 'MDY';
  613.         doDMY : FieldOrder := 'DMY';
  614.         doYMD : FieldOrder := 'YMD';
  615.       end;
  616.  
  617.       Year := 0;
  618.       Month := 0;
  619.       Day := 0;
  620.       Error := 0;
  621.       for Field := 1 to Length(FieldOrder) do begin
  622.         if StringList.Count > 0 then
  623.           S := StringList[0]
  624.         else
  625.           S := '';
  626.  
  627.         case FieldOrder[Field] of
  628.           'M' :
  629.             begin
  630.               if (S = '') or (S[1] in ['0'..'9']) then begin {numeric month}
  631.                 try
  632.                   if S = '' then
  633.                     Month := 0
  634.                   else
  635.                     Month := StrToInt(S);
  636.                 except
  637.                   Month := 0;
  638.                   Error := SCEsMonthConvertError; {error converting month number}
  639.                 end;
  640.                 if not (Month in [1..12]) then
  641.                   Month := 0;
  642.               end else begin {one or more letters in month}
  643.                 Month := 0;
  644.                 I1 := 1;
  645.                 S := Copy(S, 1, 3);
  646.                 Error := SCEsMonthNameConvertError; {error converting month name}
  647.                 repeat
  648.                   if S = UpperCase(Copy(ShortMonthNames[I1], 1, Length(S))) then begin
  649.                     Month := I1;
  650.                     I1 := 13;
  651.                     Error := 0;
  652.                   end else
  653.                     Inc(I1);
  654.                 until I1 = 13;
  655.               end;
  656.  
  657.               if Month = 0 then begin
  658.                 if rfMonth in FRequiredFields then
  659.                   Error := SCEsMonthRequired {month required}
  660.                 else
  661.                   Month := ThisMonth;
  662.               end else if StringList.Count > 0 then
  663.                 StringList.Delete(0);
  664.  
  665.               if Error > 0 then
  666.                 Break;
  667.             end;
  668.           'Y' :
  669.             begin
  670.               try
  671.                 if S = '' then
  672.                   Year := 0
  673.                 else
  674.                   Year := StrToInt(S);
  675.               except
  676.                 Year := 0;
  677.                 Error := SCEsYearConvertError; {error converting year}
  678.               end;
  679.               {!!.04}
  680.               if (FEpoch = 0) and (Year < 100) and (S <> '') then
  681.                 {default to current century if Epoch is zero}
  682.                 Year := Year + (ThisYear div 100 * 100)
  683.               else if (FEpoch > 0) and (Year < 100) and (S <> '') then begin
  684.                 {use epoch}
  685.                 EpochYear := FEpoch mod 100;
  686.                 EpochCent := (FEpoch div 100) * 100;
  687.                 if (Year < EpochYear) then
  688.                   Inc(Year,EpochCent+100)
  689.                 else
  690.                   Inc(Year,EpochCent);
  691.               end;
  692.               if Year = 0 then begin
  693.                 if rfYear in FRequiredFields then
  694.                   Error := SCEsYearRequired {year is required}
  695.                 else
  696.                   Year := ThisYear;
  697.               end else if StringList.Count > 0 then
  698.                 StringList.Delete(0);
  699.  
  700.               if Error > 0 then
  701.                 Break;
  702.             end;
  703.           'D' :
  704.             begin
  705.               try
  706.                 if S = '' then
  707.                   Day := 0
  708.                 else
  709.                   Day := StrToInt(S);
  710.               except
  711.                 Day := 0;
  712.                 Error := SCEsDayConvertError; {error converting day}
  713.               end;
  714.               if not (Day in [1..31]) then
  715.                 Day := 0;
  716.               if Day = 0 then begin
  717.                 if rfDay in FRequiredFields then
  718.                   Error := SCEsDayRequired {day is required}
  719.                 else
  720.                   Day := ThisDay;
  721.                 end
  722.               else if StringList.Count > 0 then
  723.                 StringList.Delete(0);
  724.  
  725.               if Error > 0 then
  726.                 Break;
  727.             end;
  728.         end;
  729.       end;
  730.  
  731.       case Error of
  732.         SCEsDayConvertError :
  733.           if S = '' then
  734.             raise EEssentialsError.Create(StrRes[SCEsInvalidDay] + ' "' + Value + '"')
  735.           else
  736.             raise EEssentialsError.Create(StrRes[SCEsInvalidDay] + ' "' + S + '"');
  737.         SCEsMonthConvertError :
  738.           if S = '' then
  739.             raise EEssentialsError.Create(StrRes[SCEsInvalidMonth] + ' "' + Value + '"')
  740.           else
  741.             raise EEssentialsError.Create(StrRes[SCEsInvalidMonth] + ' "' + S + '"');
  742.         SCEsMonthNameConvertError :
  743.           if S = '' then
  744.             raise EEssentialsError.Create(StrRes[SCEsInvalidMonthName] + ' "' + Value + '"')
  745.           else
  746.             raise EEssentialsError.Create(StrRes[SCEsInvalidMonthName] + ' "' + S + '"');
  747.         SCEsYearConvertError :
  748.           if S = '' then
  749.             raise EEssentialsError.Create(StrRes[SCEsInvalidYear] + ' "' + Value + '"')
  750.           else
  751.             raise EEssentialsError.Create(StrRes[SCEsInvalidYear] + ' "' + S + '"');
  752.         SCEsDayRequired :
  753.           raise EEssentialsError.Create(StrRes[SCEsDayIsRequired]);
  754.         SCEsMonthRequired :
  755.           raise EEssentialsError.Create(StrRes[SCEsMonthIsRequired]);
  756.         SCEsYearRequired :
  757.           raise EEssentialsError.Create(StrRes[SCEsYearIsRequired]);
  758.       end;
  759.  
  760.       try
  761.         FDate := EncodeDate(Year, Month, Day);
  762.         Text := FormatDate(FDate);
  763.       except
  764.         raise EEssentialsError.Create(StrRes[SCEsInvalidDate] + ' "' + Value + '"');
  765.       end;
  766.  
  767.     finally
  768.       StringList.Free;
  769.     end;
  770.   end;
  771. end;
  772.  
  773. {!!.02}
  774. procedure TEsCustomDateEdit.SetForceCentury(Value : Boolean);
  775. begin
  776.   if Value <> FForceCentury then begin
  777.     FForceCentury := Value;
  778.     if Assigned(Calendar) then                                         {!!.03}
  779.       SetDate(Calendar.Date);
  780.   end;
  781. end;
  782.  
  783. procedure TEsCustomDateEdit.SetPopupCalFont(Value : TFont);
  784. begin
  785.   if Assigned(Value) then
  786.     FPopupCalFont.Assign(Value);
  787. end;
  788.  
  789. procedure TEsCustomDateEdit.SetReadOnly(Value : Boolean);
  790. begin
  791.   inherited ReadOnly := Value;
  792.   FButton.Enabled := not ReadOnly;
  793. end;
  794.  
  795. end.
  796.