View Issue Details

IDProjectCategoryView StatusLast Update
0003913JEDI VCL00 JVCL Componentspublic2007-01-22 08:39
ReporterZENsanAssigned Toobones 
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
Product VersionDaily / GIT 
Target VersionFixed in Version3.34 
Summary0003913: TjvScheduledEvents don't saves all information about events
DescriptionTjvScheduledEvents don't saves all information about events. It saves only this information for any type of schedule (using INI or Reg storage:

Eventname=Event
Stamp.Date=732573
Stamp.Time=64800000
TriggerCount=1
DayCount=1
Snooze.Date=0
Snooze.Time=-1
SnoozeInterval.wYear=0
SnoozeInterval.wMonth=0
SnoozeInterval.wDay=0
SnoozeInterval.wHour=0
SnoozeInterval.wMinute=0
SnoozeInterval.wSecond=0
SnoozeInterval.wMilliseconds=0
Additional InformationDamo can be used from my 0003912 previous report
TagsNo tags attached.

Activities

obones

2006-09-19 02:58

administrator   ~0010140

Can't you investigate why it's doing this and propose a workaround/fix ?

ZENsan

2006-09-19 07:22

reporter   ~0010143

Ok, I will try.

ZENsan

2006-09-20 03:01

reporter   ~0010147

Last edited: 2006-09-20 03:03

Here is updated version of unit.
I tested with all combinations of schedules.
Save/Restore works fine.

One minus (from previous version also) is that when retoring events, they are added as new (also when event names is the same) if LoadEventStates(false).

And one my programming minus(maybe more) is that I don't know (have no time to learn) how to save weekdays as "set" with WriteSet method. Here I used bit setting in integer value.

2006-09-20 03:02

 

JvScheduledEvents.zip (10,510 bytes)

obones

2006-09-26 01:22

administrator   ~0010180

Look for JclIntToSet, JclStringToSet

ZENsan

2006-09-26 05:57

reporter   ~0010181

Thanks for hint, I will update my source and then upload new version.

ZENsan

2006-09-26 06:18

reporter   ~0010182

I have already tried this, but some my mistake with that PTypeInfo...
begin
....
  AppStorage.WriteSet(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekDaysOfWeek']), TypeInfo(TScheduleWeekDays), AWeekDaysOfWeek);
... no error, but also nothing happens. What I am doing wrong?

obones

2006-09-29 06:29

administrator   ~0010231

A few comments:

I don't like having dozens of arguments AT ALL. Please find another way.
For the TypeInfo, ensure that the value returned by the call to TypeInfo is not nil. If it is, then there is something weird. And you can always trace what it is doing.

2006-10-11 00:57

 

JvScheduledEvents.patch (23,920 bytes)
Index: JvScheduledEvents.pas
===================================================================
--- JvScheduledEvents.pas	(revision 10965)
+++ JvScheduledEvents.pas	(working copy)
@@ -197,10 +197,66 @@
     constructor Create(Collection: TCollection); override;
     destructor Destroy; override;
     procedure LoadState(const TriggerStamp: TTimeStamp; const TriggerCount, DayCount: Integer;
-      const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime); virtual;
+      const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime;
+    {Common}
+      const ARecurringType: TScheduleRecurringKind;
+      const AStartDate: TTimeStamp;
+      const AEndType: TScheduleEndKind;
+      const AEndDate: TTimeStamp;
+      const AEndCount: Cardinal;
+      const ALastTriggered: TTimeStamp;
+    {DayFrequency}
+      const ADayFrequencyStartTime: Cardinal;
+      const ADayFrequencyEndTime: Cardinal;
+      const ADayFrequencyInterval: Cardinal;
+    {Daily}
+      const ADayEveryWeekDay: Boolean;
+      const ADayInterval: Cardinal;
+    {Weekly}
+      const AWeekInterval: Cardinal;
+      const AWeekDaysOfWeek: TScheduleWeekDays;
+    {Monthly}
+      const AMonthIndexKind: TScheduleIndexKind;
+      const AMonthIndexValue: Cardinal;
+      const AMonthDay: Cardinal;
+      const AMonthInterval: Cardinal;
+    {Yearly}
+      const AYearIndexKind: TScheduleIndexKind;
+      const AYearIndexValue: Cardinal;
+      const AYearDay: Cardinal;
+      const AYearMonth: Cardinal;
+      const AYearInterval: Cardinal); virtual;
     procedure Pause;
     procedure SaveState(out TriggerStamp: TTimeStamp; out TriggerCount, DayCount: Integer;
-      out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime); virtual;
+      out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime;
+    {Common}
+      out ARecurringType: TScheduleRecurringKind;
+      out AStartDate: TTimeStamp;
+      out AEndType: TScheduleEndKind;
+      out AEndDate: TTimeStamp;
+      out AEndCount: Cardinal;
+      out ALastTriggered: TTimeStamp;
+    {DayFrequency}
+      out ADayFrequencyStartTime: Cardinal;
+      out ADayFrequencyEndTime: Cardinal;
+      out ADayFrequencyInterval: Cardinal;
+    {Daily}
+      out ADayEveryWeekDay: Boolean;
+      out ADayInterval: Cardinal;
+    {Weekly}
+      out AWeekInterval: Cardinal;
+      out AWeekDaysOfWeek: TScheduleWeekDays;
+    {Monthly}
+      out AMothIndexKind: TScheduleIndexKind;
+      out AMonthIndexValue: Cardinal;
+      out AMonthDay: Cardinal;
+      out AMonthInterval: Cardinal;
+    {Yearly}
+      out AYearIndexKind: TScheduleIndexKind;
+      out AYearIndexValue: Cardinal;
+      out AYearDay: Cardinal;
+      out AYearMonth: Cardinal;
+      out AYearInterval: Cardinal); virtual;
     procedure Snooze(const MSecs: Word; const Secs: Word = 0; const Mins: Word = 0;
       const Hrs: Word = 0; const Days: Word = 0);
     procedure Start;
@@ -452,20 +508,6 @@
 begin
   inherited Create(AOwner);
   FEvents := TJvEventCollection.Create(Self);
-
-  {$IFDEF VCL}
-  FWnd := AllocateHWndEx(WndProc);
-  {$ENDIF VCL}
-  {$IFDEF VisualCLX}
-  FWnd := QWidgetH(AllocateMessageObject(Self));
-  {$ENDIF VisualCLX}
-  if not (csDesigning in ComponentState) and not (csLoading in ComponentState) then
-  begin
-    if AutoSave then
-      LoadEventStates;
-    InitEvents;
-  end;
-  ScheduleThread.AddEventComponent(Self);
 end;
 
 destructor TJvCustomScheduledEvents.Destroy;
@@ -537,9 +579,16 @@
 begin
   if not (csDesigning in ComponentState) then
   begin
+    {$IFDEF VCL}
+    FWnd := AllocateHWndEx(WndProc);
+    {$ENDIF VCL}
+    {$IFDEF VisualCLX}
+    FWnd := QWidgetH(AllocateMessageObject(Self));
+    {$ENDIF VisualCLX}
     if AutoSave then
       LoadEventStates;
     InitEvents;
+    ScheduleThread.AddEventComponent(Self);
   end;
 end;
 
@@ -553,6 +602,37 @@
   SnoozeInterval: TSystemTime;
   EventName: string;
   Event: TJvEventCollectionItem;
+
+  AInt: Cardinal;
+  {common}
+  ARecurringType: TScheduleRecurringKind;
+  AStartDate: TTimeStamp;
+  AEndType: TScheduleEndKind;
+  AEndDate: TTimeStamp;
+  AEndCount: Cardinal;
+  ALastTriggered: TTimeStamp;
+  {DayFrequency}
+  ADayFrequencyStartTime: Cardinal;
+  ADayFrequencyEndTime: Cardinal;
+  ADayFrequencyInterval: Cardinal;
+  {Daily}
+  ADayEveryWeekDay: Boolean;
+  ADayInterval: Cardinal;
+  {Weekly}
+  AWeekInterval: Cardinal;
+  AWeekDaysOfWeek: TScheduleWeekDays;
+  AWeekDaysBitValue: Cardinal;//bit setting
+  {Monthly}
+  AMothIndexKind: TScheduleIndexKind;
+  AMonthIndexValue: Cardinal;
+  AMonthDay: Cardinal;
+  AMonthInterval: Cardinal;
+  {Yearly}
+  AYearIndexKind: TScheduleIndexKind;
+  AYearIndexValue: Cardinal;
+  AYearDay: Cardinal;
+  AYearMonth: Cardinal;
+  AYearInterval: Cardinal;
 begin
   EventName := Sender.ReadString(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'Eventname']));
   if EventName <> '' then
@@ -570,9 +650,89 @@
     SnoozeInterval.wMinute := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMinute']));
     SnoozeInterval.wSecond := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wSecond']));
     SnoozeInterval.wMilliseconds := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMilliseconds']));
+    {Common}
+    AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'RecurringType']));
+    ARecurringType := TScheduleRecurringKind(AInt);
+    AStartDate.Time := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_time']));
+    AStartDate.Date := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_date']));
+    AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndType']));
+    AEndType := TScheduleEndKind(AInt);
+    AEndDate.Time := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_time']));
+    AEndDate.Date := Sender.readInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_date']));
+    AEndCount := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndCount']));
+    ALastTriggered.Time := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_time']));
+    ALastTriggered.Date := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_date']));
+    {DayFrequency}
+    ADayFrequencyStartTime := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyStartTime']));
+    ADayFrequencyEndTime := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyEndTime']));
+    ADayFrequencyInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyInterval']));
+    {Daily}
+    ADayEveryWeekDay := Sender.ReadBoolean(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayEveryWeekDay']));
+    ADayInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayInterval']));
+    {Weekly}
+    AWeekInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekInterval']));
+//    AppStorage.ReadSet(Sender.ConcatPaths([Path, ItemName + IntToStr(Index),'WeekDays']), TypeInfo(TScheduleWeekDays), [], AWeekDaysOfWeek);
+    {sorry for this code, but for me it is easer then use WriteSet, because I don't have time to learn how it works.}
+    AWeekDaysBitValue:=AppStorage.ReadInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekDaysOfWeek']));
+    AWeekDaysOfWeek:=[];
+    if AWeekDaysBitValue and $40 = $40 then
+      Include(AWeekDaysOfWeek,swdMonday);
+    if AWeekDaysBitValue and $20 = $20 then
+      Include(AWeekDaysOfWeek,swdTuesday);
+    if AWeekDaysBitValue and $10 = $10 then
+      Include(AWeekDaysOfWeek,swdWednesday);
+    if AWeekDaysBitValue and 8 = 8 then
+      Include(AWeekDaysOfWeek,swdThursday);
+    if AWeekDaysBitValue and 4 = 4 then
+      Include(AWeekDaysOfWeek,swdFriday);
+    if AWeekDaysBitValue and 2 = 2 then
+      Include(AWeekDaysOfWeek,swdSaturday);
+    if AWeekDaysBitValue and 1 = 1 then
+      Include(AWeekDaysOfWeek,swdSunday);
+    {Monthly}
+    AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MothIndexKind']));
+    AMothIndexKind := TScheduleIndexKind(AInt);
+    AMonthIndexValue := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthIndexValue']));
+    AMonthDay := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthDay']));
+    AMonthInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthInterval']));
+    {Yearly}
+    AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexKind']));
+    AYearIndexKind := TScheduleIndexKind(AInt);
+    AYearIndexValue := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexValue']));
+    AYearDay := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearDay']));
+    AYearMonth := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearMonth']));
+    AYearInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearInterval']));
     Event := TJvEventCollection(List).Add;
     Event.Name := EventName;
-    Event.LoadState(Stamp, TriggerCount, DayCount, Snooze, SnoozeInterval);
+    Event.LoadState(Stamp, TriggerCount, DayCount, Snooze, SnoozeInterval,
+    {common}
+    ARecurringType,
+    AStartDate,
+    AEndType,
+    AEndDate,
+    AEndCount,
+    ALastTriggered,
+    {DayFrequency}
+    ADayFrequencyStartTime,
+    ADayFrequencyEndTime,
+    ADayFrequencyInterval,
+    {Daily}
+    ADayEveryWeekDay,
+    ADayInterval,
+    {Weekly}
+    AWeekInterval,
+    AWeekDaysOfWeek,
+    {Monthly}
+    AMothIndexKind,
+    AMonthIndexValue,
+    AMonthDay,
+    AMonthInterval,
+    {Yearly}
+    AYearIndexKind,
+    AYearIndexValue,
+    AYearDay,
+    AYearMonth,
+    AYearInterval);
   end;
 end;
 
@@ -597,8 +757,65 @@
   SnoozeInterval: TSystemTime;
   SnoozeDate: Integer;
   SnoozeTime: Integer;
+  {common}
+  ARecurringType: TScheduleRecurringKind;
+  AStartDate: TTimeStamp;
+  AEndType: TScheduleEndKind;
+  AEndDate: TTimeStamp;
+  AEndCount: Cardinal;
+  ALastTriggered: TTimeStamp;
+  {DayFrequency}
+  ADayFrequencyStartTime: Cardinal;
+  ADayFrequencyEndTime: Cardinal;
+  ADayFrequencyInterval: Cardinal;
+  {Daily}
+  ADayEveryWeekDay: Boolean;
+  ADayInterval: Cardinal;
+  {Weekly}
+  AWeekInterval: Cardinal;
+  AWeekDaysOfWeek: TScheduleWeekDays;
+  AWeekDaysBitValue:integer;//bit setting
+  {Monthly}
+  AMothIndexKind: TScheduleIndexKind;
+  AMonthIndexValue: Cardinal;
+  AMonthDay: Cardinal;
+  AMonthInterval: Cardinal;
+  {Yearly}
+  AYearIndexKind: TScheduleIndexKind;
+  AYearIndexValue: Cardinal;
+  AYearDay: Cardinal;
+  AYearMonth: Cardinal;
+  AYearInterval: Cardinal;
 begin
-  TJvEventCollection(List)[Index].SaveState(Stamp, TriggerCount, DayCount, SnoozeStamp, SnoozeInterval);
+  TJvEventCollection(List)[Index].SaveState(Stamp, TriggerCount, DayCount, SnoozeStamp, SnoozeInterval,
+  {Common}
+    ARecurringType,
+    AStartDate,
+    AEndType,
+    AEndDate,
+    AEndCount,
+    ALastTriggered,
+  {DayFrequency}
+    ADayFrequencyStartTime,
+    ADayFrequencyEndTime,
+    ADayFrequencyInterval,
+  {Daily}
+    ADayEveryWeekDay,
+    ADayInterval,
+  {Weekly}
+    AWeekInterval,
+    AWeekDaysOfWeek,
+  {Monthly}
+    AMothIndexKind,
+    AMonthIndexValue,
+    AMonthDay,
+    AMonthInterval,
+  {Yearly}
+    AYearIndexKind,
+    AYearIndexValue,
+    AYearDay,
+    AYearMonth,
+    AYearInterval);
   StampDate := Stamp.Date;
   StampTime := Stamp.Time;
   SnoozeDate := SnoozeStamp.Date;
@@ -617,6 +834,46 @@
   AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMinute']), SnoozeInterval.wMinute);
   AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wSecond']), SnoozeInterval.wSecond);
   AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMilliseconds']), SnoozeInterval.wMilliseconds);
+  {Common}
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'RecurringType']), Integer(ARecurringType));
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_time']), AStartDate.Time);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_date']), AStartDate.Date);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndType']), Integer(AEndType));
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_time']), AEndDate.Time);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_date']), AEndDate.Date);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndCount']), AEndCount);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_time']), ALastTriggered.Time);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_date']), ALastTriggered.Date);
+  {DayFrequency}
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyStartTime']), ADayFrequencyStartTime);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyEndTime']), ADayFrequencyEndTime);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyInterval']), ADayFrequencyInterval);
+  {Daily}
+  AppStorage.WriteBoolean(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayEveryWeekDay']), ADayEveryWeekDay);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayInterval']), ADayInterval);
+  {Weekly}
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekInterval']), AWeekInterval);
+//  AppStorage.WriteSet(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekDaysOfWeek']), TypeInfo(TScheduleWeekDays), AWeekDaysOfWeek);
+  AWeekDaysBitValue:=0 or
+    (Ord(swdMonday in AWeekDaysOfWeek) shl 6) or
+    (Ord(swdTuesday in AWeekDaysOfWeek) shl 5) or
+    (Ord(swdWednesday in AWeekDaysOfWeek) shl 4) or
+    (Ord(swdThursday in AWeekDaysOfWeek) shl 3) or
+    (Ord(swdFriday in AWeekDaysOfWeek) shl 2) or
+    (Ord(swdSaturday in AWeekDaysOfWeek) shl 1) or
+     Ord(swdSunday in AWeekDaysOfWeek);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekDaysOfWeek']),AWeekDaysBitValue);
+  {Monthly}
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MothIndexKind']), Integer(AMothIndexKind));
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthIndexValue']), AMonthIndexValue);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthDay']), AMonthDay);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthInterval']), AMonthInterval);
+  {Yearly}
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexKind']), Integer(AYearIndexKind));
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexValue']), AYearIndexValue);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearDay']), AYearDay);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearMonth']), AYearMonth);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearInterval']), AYearInterval);
 end;
 
 procedure TJvCustomScheduledEvents.DeleteSingleEvent(Sender: TJvCustomAppStorage; const Path: string;
@@ -666,9 +923,6 @@
 
 {$IFDEF VCL}
 procedure TJvCustomScheduledEvents.WndProc(var Msg: TMessage);
-var
-  List: TList;
-  I: Integer;
 begin
   with Msg do
     case Msg of
@@ -676,25 +930,9 @@
         Dispatch(Msg);
       WM_TIMECHANGE:
         begin
-          // Mantis 3355: Time has changed, mark all running schedules as
-          // "to be restarted", stop and then restart them.
-          List := TList.Create;
-          try
-            for I := 0 to FEvents.Count - 1 do
-            begin
-              if FEvents[I].State in [sesTriggered, sesExecuting, sesPaused] then
-              begin
-                List.Add(FEvents[I]);
-                FEvents[I].Stop;
-              end;
-            end;
-            for I := 0 to List.Count - 1 do
-            begin
-              TJvEventCollectionItem(List[I]).Start;
-            end;
-          finally
-            List.Free;
-          end;
+          // Mantis 3355: Time has changed, stop and restart the schedules
+          StopAll;
+          StartAll;
         end;
     else
       Result := DefWindowProc(Handle, Msg, WParam, LParam);
@@ -1208,9 +1446,94 @@
   end;
 end;
 
-procedure TJvEventCollectionItem.LoadState(const TriggerStamp: TTimeStamp; const TriggerCount,
-  DayCount: Integer; const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime);
+procedure TJvEventCollectionItem.LoadState(const TriggerStamp: TTimeStamp; const TriggerCount, DayCount: Integer;
+  const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime;
+  {Common}
+  const ARecurringType: TScheduleRecurringKind;
+  const AStartDate: TTimeStamp;
+  const AEndType: TScheduleEndKind;
+  const AEndDate: TTimeStamp;
+  const AEndCount: Cardinal;
+  const ALastTriggered: TTimeStamp;
+  {DayFrequency}
+  const ADayFrequencyStartTime: Cardinal;
+  const ADayFrequencyEndTime: Cardinal;
+  const ADayFrequencyInterval: Cardinal;
+  {Daily}
+  const ADayEveryWeekDay: Boolean;
+  const ADayInterval: Cardinal;
+  {Weekly}
+  const AWeekInterval: Cardinal;
+  const AWeekDaysOfWeek: TScheduleWeekDays;
+  {Monthly}
+  const AMonthIndexKind: TScheduleIndexKind;
+  const AMonthIndexValue: Cardinal;
+  const AMonthDay: Cardinal;
+  const AMonthInterval: Cardinal;
+  {Yearly}
+  const AYearIndexKind: TScheduleIndexKind;
+  const AYearIndexValue: Cardinal;
+  const AYearDay: Cardinal;
+  const AYearMonth: Cardinal;
+  const AYearInterval: Cardinal);
+var
+  IDayFrequency: IJclScheduleDayFrequency;
+  IDay: IJclDailySchedule;
+  IWeek: IJclWeeklySchedule;
+  IMonth: IJclMonthlySchedule;
+  IYear: IJclYearlySchedule;
 begin
+  Schedule.RecurringType:=ARecurringType;
+  if ARecurringType<>srkOneShot then
+    begin
+      IDayFrequency := Schedule as IJclScheduleDayFrequency;
+      IDayFrequency.StartTime := ADayFrequencyStartTime;
+      IDayFrequency.EndTime := ADayFrequencyEndTime;
+      IDayFrequency.Interval := ADayFrequencyInterval;
+    end;
+  case ARecurringType of
+    srkOneShot:
+      begin
+      end;
+    srkDaily:
+      begin
+        {IJclDailySchedule}
+        IDay := Schedule as IJclDailySchedule;
+        IDay.EveryWeekDay := ADayEveryWeekDay;
+        if not ADayEveryWeekDay then
+          IDay.Interval := ADayInterval;
+      end;
+    srkWeekly:
+      begin
+        {IJclWeeklySchedule}
+        IWeek := Schedule as IJclWeeklySchedule;
+        IWeek.DaysOfWeek := AWeekDaysOfWeek;
+        IWeek.Interval := AWeekInterval;
+      end;
+    srkMonthly:
+      begin
+        {IJclMonthlySchedule}
+        IMonth := Schedule as IJclMonthlySchedule;
+        IMonth.IndexKind := AMonthIndexKind;
+        if AMonthIndexKind <> sikNone then
+          IMonth.IndexValue := AMonthIndexValue;
+        if AMonthIndexKind = sikNone then
+          IMonth.Day := AMonthDay;
+        IMonth.Interval := AMonthInterval;
+      end;
+    srkYearly:
+      begin
+        {IJclYearlySchedule}
+        IYear := Schedule as IJclYearlySchedule;
+        IYear.IndexKind := AYearIndexKind;
+        if AYearIndexKind <> sikNone then
+          IYear.IndexValue := AYearIndexValue
+        else
+          IYear.Day := AYearDay;
+        IYear.Month := AYearMonth;
+        IYear.Interval := AYearInterval;
+      end;
+  end;
   Schedule.InitToSavedState(TriggerStamp, TriggerCount, DayCount);
   FScheduleFire := TriggerStamp;
   FSnoozeFire := SnoozeStamp;
@@ -1230,9 +1553,99 @@
     FState := sesPaused;
 end;
 
-procedure TJvEventCollectionItem.SaveState(out TriggerStamp: TTimeStamp; out TriggerCount,
-  DayCount: Integer; out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime);
+procedure TJvEventCollectionItem.SaveState(out TriggerStamp: TTimeStamp; out TriggerCount, DayCount: Integer;
+  {Common}
+  out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime;
+  out ARecurringType: TScheduleRecurringKind;
+  out AStartDate: TTimeStamp;
+  out AEndType: TScheduleEndKind;
+  out AEndDate: TTimeStamp;
+  out AEndCount: Cardinal;
+  out ALastTriggered: TTimeStamp;
+ {DayFrequency}
+  out ADayFrequencyStartTime: Cardinal;
+  out ADayFrequencyEndTime: Cardinal;
+  out ADayFrequencyInterval: Cardinal;
+ {Daily}
+  out ADayEveryWeekDay: Boolean;
+  out ADayInterval: Cardinal;
+ {Weekly}
+  out AWeekInterval: Cardinal;
+  out AWeekDaysOfWeek: TScheduleWeekDays;
+ {Monthly}
+  out AMothIndexKind: TScheduleIndexKind;
+  out AMonthIndexValue: Cardinal;
+  out AMonthDay: Cardinal;
+  out AMonthInterval: Cardinal;
+ {Yearly}
+  out AYearIndexKind: TScheduleIndexKind;
+  out AYearIndexValue: Cardinal;
+  out AYearDay: Cardinal;
+  out AYearMonth: Cardinal;
+  out AYearInterval: Cardinal);
+var
+  IDayFrequency: IJclScheduleDayFrequency;
+  IDay: IJclDailySchedule;
+  IWeek: IJclWeeklySchedule;
+  IMonth: IJclMonthlySchedule;
+  IYear: IJclYearlySchedule;
 begin
+  {Common properties}
+  AEndType := FSchedule.EndType;
+  AEndDate := FSchedule.EndDate;
+  AEndCount := FSchedule.EndCount;
+  ALastTriggered := Fschedule.LastTriggered;
+  AStartDate := FSchedule.StartDate;
+  ARecurringType := FSchedule.RecurringType;
+  {IJclScheduleDayFrequency}
+  if ARecurringType<>srkOneShot then
+    begin
+      IDayFrequency := FSchedule as IJclScheduleDayFrequency;
+      ADayFrequencyStartTime := IDayFrequency.StartTime;
+      ADayFrequencyEndTime := IDayFrequency.EndTime;
+      ADayFrequencyInterval := IDayFrequency.Interval;
+    end;
+  case ARecurringType of
+    srkOneShot:
+      begin
+      end;
+    srkDaily:
+      begin
+        {IJclDailySchedule}
+        IDay := FSchedule as IJclDailySchedule;
+        ADayInterval := IDay.Interval;
+        ADayEveryWeekDay := IDay.EveryWeekDay;
+      end;
+    srkWeekly:
+      begin
+        {IJclWeeklySchedule}
+        IWeek := FSchedule as IJclWeeklySchedule;
+        AWeekInterval := IWeek.Interval;
+        AWeekDaysOfWeek := IWeek.DaysOfWeek;
+      end;
+    srkMonthly:
+      begin
+        {IJclMonthlySchedule}
+        IMonth := FSchedule as IJclMonthlySchedule;
+        AMothIndexKind := IMonth.IndexKind;
+        if AMothIndexKind <> sikNone then
+          AMonthIndexValue := IMonth.IndexValue;
+        AMonthDay := IMonth.Day;
+        AMonthInterval := IMonth.Interval;
+      end;
+    srkYearly:
+      begin
+        {IJclYearlySchedule}
+        IYear := FSchedule as IJclYearlySchedule;
+        AYearIndexKind := IYear.IndexKind;
+        if AYearIndexKind <> sikNone then
+          AYearIndexValue := IYear.IndexValue;
+        AYearDay := IYear.Day;
+        AYearMonth := IYear.Month;
+        AYearInterval := IYear.Interval;
+      end;
+  end;
+  {Old part}
   TriggerStamp := FScheduleFire;
   TriggerCount := Schedule.TriggerCount;
   DayCount := Schedule.DayCount;
JvScheduledEvents.patch (23,920 bytes)

ZENsan

2006-10-11 00:58

reporter   ~0010341

This works fine. Sorry, but I used Integer to save days of week in weekly shedule - maybe someone will have more time to investigate and change that to WriteSet.

obones

2006-10-11 01:07

administrator   ~0010342

Well, yes, it works fine, of course. But this is not acceptable code as it is not clean by any mean. As it is, I won't accept the proposed patch.

ZENsan

2006-10-12 06:21

reporter   ~0010346

Ok I will investigate and then upload path with WriteSet.. Now it saves (in my version) but not restores..

2006-10-12 06:52

 

JvScheduledEvents1.patch (22,455 bytes)
Index: JvScheduledEvents.pas
===================================================================
--- JvScheduledEvents.pas	(revision 10965)
+++ JvScheduledEvents.pas	(working copy)
@@ -197,10 +197,66 @@
     constructor Create(Collection: TCollection); override;
     destructor Destroy; override;
     procedure LoadState(const TriggerStamp: TTimeStamp; const TriggerCount, DayCount: Integer;
-      const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime); virtual;
+      const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime;
+    {Common}
+      const ARecurringType: TScheduleRecurringKind;
+      const AStartDate: TTimeStamp;
+      const AEndType: TScheduleEndKind;
+      const AEndDate: TTimeStamp;
+      const AEndCount: Cardinal;
+      const ALastTriggered: TTimeStamp;
+    {DayFrequency}
+      const ADayFrequencyStartTime: Cardinal;
+      const ADayFrequencyEndTime: Cardinal;
+      const ADayFrequencyInterval: Cardinal;
+    {Daily}
+      const ADayEveryWeekDay: Boolean;
+      const ADayInterval: Cardinal;
+    {Weekly}
+      const AWeekInterval: Cardinal;
+      const AWeekDaysOfWeek: TScheduleWeekDays;
+    {Monthly}
+      const AMonthIndexKind: TScheduleIndexKind;
+      const AMonthIndexValue: Cardinal;
+      const AMonthDay: Cardinal;
+      const AMonthInterval: Cardinal;
+    {Yearly}
+      const AYearIndexKind: TScheduleIndexKind;
+      const AYearIndexValue: Cardinal;
+      const AYearDay: Cardinal;
+      const AYearMonth: Cardinal;
+      const AYearInterval: Cardinal); virtual;
     procedure Pause;
     procedure SaveState(out TriggerStamp: TTimeStamp; out TriggerCount, DayCount: Integer;
-      out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime); virtual;
+      out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime;
+    {Common}
+      out ARecurringType: TScheduleRecurringKind;
+      out AStartDate: TTimeStamp;
+      out AEndType: TScheduleEndKind;
+      out AEndDate: TTimeStamp;
+      out AEndCount: Cardinal;
+      out ALastTriggered: TTimeStamp;
+    {DayFrequency}
+      out ADayFrequencyStartTime: Cardinal;
+      out ADayFrequencyEndTime: Cardinal;
+      out ADayFrequencyInterval: Cardinal;
+    {Daily}
+      out ADayEveryWeekDay: Boolean;
+      out ADayInterval: Cardinal;
+    {Weekly}
+      out AWeekInterval: Cardinal;
+      out AWeekDaysOfWeek: TScheduleWeekDays;
+    {Monthly}
+      out AMothIndexKind: TScheduleIndexKind;
+      out AMonthIndexValue: Cardinal;
+      out AMonthDay: Cardinal;
+      out AMonthInterval: Cardinal;
+    {Yearly}
+      out AYearIndexKind: TScheduleIndexKind;
+      out AYearIndexValue: Cardinal;
+      out AYearDay: Cardinal;
+      out AYearMonth: Cardinal;
+      out AYearInterval: Cardinal); virtual;
     procedure Snooze(const MSecs: Word; const Secs: Word = 0; const Mins: Word = 0;
       const Hrs: Word = 0; const Days: Word = 0);
     procedure Start;
@@ -452,20 +508,6 @@
 begin
   inherited Create(AOwner);
   FEvents := TJvEventCollection.Create(Self);
-
-  {$IFDEF VCL}
-  FWnd := AllocateHWndEx(WndProc);
-  {$ENDIF VCL}
-  {$IFDEF VisualCLX}
-  FWnd := QWidgetH(AllocateMessageObject(Self));
-  {$ENDIF VisualCLX}
-  if not (csDesigning in ComponentState) and not (csLoading in ComponentState) then
-  begin
-    if AutoSave then
-      LoadEventStates;
-    InitEvents;
-  end;
-  ScheduleThread.AddEventComponent(Self);
 end;
 
 destructor TJvCustomScheduledEvents.Destroy;
@@ -537,9 +579,16 @@
 begin
   if not (csDesigning in ComponentState) then
   begin
+    {$IFDEF VCL}
+    FWnd := AllocateHWndEx(WndProc);
+    {$ENDIF VCL}
+    {$IFDEF VisualCLX}
+    FWnd := QWidgetH(AllocateMessageObject(Self));
+    {$ENDIF VisualCLX}
     if AutoSave then
       LoadEventStates;
     InitEvents;
+    ScheduleThread.AddEventComponent(Self);
   end;
 end;
 
@@ -553,6 +602,36 @@
   SnoozeInterval: TSystemTime;
   EventName: string;
   Event: TJvEventCollectionItem;
+
+  AInt: Cardinal;
+  {common}
+  ARecurringType: TScheduleRecurringKind;
+  AStartDate: TTimeStamp;
+  AEndType: TScheduleEndKind;
+  AEndDate: TTimeStamp;
+  AEndCount: Cardinal;
+  ALastTriggered: TTimeStamp;
+  {DayFrequency}
+  ADayFrequencyStartTime: Cardinal;
+  ADayFrequencyEndTime: Cardinal;
+  ADayFrequencyInterval: Cardinal;
+  {Daily}
+  ADayEveryWeekDay: Boolean;
+  ADayInterval: Cardinal;
+  {Weekly}
+  AWeekInterval: Cardinal;
+  AWeekDaysOfWeek: TScheduleWeekDays;
+  {Monthly}
+  AMothIndexKind: TScheduleIndexKind;
+  AMonthIndexValue: Cardinal;
+  AMonthDay: Cardinal;
+  AMonthInterval: Cardinal;
+  {Yearly}
+  AYearIndexKind: TScheduleIndexKind;
+  AYearIndexValue: Cardinal;
+  AYearDay: Cardinal;
+  AYearMonth: Cardinal;
+  AYearInterval: Cardinal;
 begin
   EventName := Sender.ReadString(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'Eventname']));
   if EventName <> '' then
@@ -570,9 +649,72 @@
     SnoozeInterval.wMinute := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMinute']));
     SnoozeInterval.wSecond := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wSecond']));
     SnoozeInterval.wMilliseconds := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMilliseconds']));
+    {Common}
+    AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'RecurringType']));
+    ARecurringType := TScheduleRecurringKind(AInt);
+    AStartDate.Time := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_time']));
+    AStartDate.Date := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_date']));
+    AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndType']));
+    AEndType := TScheduleEndKind(AInt);
+    AEndDate.Time := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_time']));
+    AEndDate.Date := Sender.readInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_date']));
+    AEndCount := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndCount']));
+    ALastTriggered.Time := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_time']));
+    ALastTriggered.Date := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_date']));
+    {DayFrequency}
+    ADayFrequencyStartTime := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyStartTime']));
+    ADayFrequencyEndTime := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyEndTime']));
+    ADayFrequencyInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyInterval']));
+    {Daily}
+    ADayEveryWeekDay := Sender.ReadBoolean(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayEveryWeekDay']));
+    ADayInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayInterval']));
+    {Weekly}
+    AWeekInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekInterval']));
+    AppStorage.ReadSet(Sender.ConcatPaths([Path, ItemName + IntToStr(Index),'WeekDaysOfWeek']), TypeInfo(TScheduleWeekDays), [], AWeekDaysOfWeek);
+    {Monthly}
+    AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MothIndexKind']));
+    AMothIndexKind := TScheduleIndexKind(AInt);
+    AMonthIndexValue := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthIndexValue']));
+    AMonthDay := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthDay']));
+    AMonthInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthInterval']));
+    {Yearly}
+    AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexKind']));
+    AYearIndexKind := TScheduleIndexKind(AInt);
+    AYearIndexValue := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexValue']));
+    AYearDay := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearDay']));
+    AYearMonth := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearMonth']));
+    AYearInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearInterval']));
     Event := TJvEventCollection(List).Add;
     Event.Name := EventName;
-    Event.LoadState(Stamp, TriggerCount, DayCount, Snooze, SnoozeInterval);
+    Event.LoadState(Stamp, TriggerCount, DayCount, Snooze, SnoozeInterval,
+    {common}
+    ARecurringType,
+    AStartDate,
+    AEndType,
+    AEndDate,
+    AEndCount,
+    ALastTriggered,
+    {DayFrequency}
+    ADayFrequencyStartTime,
+    ADayFrequencyEndTime,
+    ADayFrequencyInterval,
+    {Daily}
+    ADayEveryWeekDay,
+    ADayInterval,
+    {Weekly}
+    AWeekInterval,
+    AWeekDaysOfWeek,
+    {Monthly}
+    AMothIndexKind,
+    AMonthIndexValue,
+    AMonthDay,
+    AMonthInterval,
+    {Yearly}
+    AYearIndexKind,
+    AYearIndexValue,
+    AYearDay,
+    AYearMonth,
+    AYearInterval);
   end;
 end;
 
@@ -597,8 +739,64 @@
   SnoozeInterval: TSystemTime;
   SnoozeDate: Integer;
   SnoozeTime: Integer;
+  {common}
+  ARecurringType: TScheduleRecurringKind;
+  AStartDate: TTimeStamp;
+  AEndType: TScheduleEndKind;
+  AEndDate: TTimeStamp;
+  AEndCount: Cardinal;
+  ALastTriggered: TTimeStamp;
+  {DayFrequency}
+  ADayFrequencyStartTime: Cardinal;
+  ADayFrequencyEndTime: Cardinal;
+  ADayFrequencyInterval: Cardinal;
+  {Daily}
+  ADayEveryWeekDay: Boolean;
+  ADayInterval: Cardinal;
+  {Weekly}
+  AWeekInterval: Cardinal;
+  AWeekDaysOfWeek: TScheduleWeekDays;
+  {Monthly}
+  AMothIndexKind: TScheduleIndexKind;
+  AMonthIndexValue: Cardinal;
+  AMonthDay: Cardinal;
+  AMonthInterval: Cardinal;
+  {Yearly}
+  AYearIndexKind: TScheduleIndexKind;
+  AYearIndexValue: Cardinal;
+  AYearDay: Cardinal;
+  AYearMonth: Cardinal;
+  AYearInterval: Cardinal;
 begin
-  TJvEventCollection(List)[Index].SaveState(Stamp, TriggerCount, DayCount, SnoozeStamp, SnoozeInterval);
+  TJvEventCollection(List)[Index].SaveState(Stamp, TriggerCount, DayCount, SnoozeStamp, SnoozeInterval,
+  {Common}
+    ARecurringType,
+    AStartDate,
+    AEndType,
+    AEndDate,
+    AEndCount,
+    ALastTriggered,
+  {DayFrequency}
+    ADayFrequencyStartTime,
+    ADayFrequencyEndTime,
+    ADayFrequencyInterval,
+  {Daily}
+    ADayEveryWeekDay,
+    ADayInterval,
+  {Weekly}
+    AWeekInterval,
+    AWeekDaysOfWeek,
+  {Monthly}
+    AMothIndexKind,
+    AMonthIndexValue,
+    AMonthDay,
+    AMonthInterval,
+  {Yearly}
+    AYearIndexKind,
+    AYearIndexValue,
+    AYearDay,
+    AYearMonth,
+    AYearInterval);
   StampDate := Stamp.Date;
   StampTime := Stamp.Time;
   SnoozeDate := SnoozeStamp.Date;
@@ -617,6 +815,37 @@
   AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMinute']), SnoozeInterval.wMinute);
   AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wSecond']), SnoozeInterval.wSecond);
   AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMilliseconds']), SnoozeInterval.wMilliseconds);
+  {Common}
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'RecurringType']), Integer(ARecurringType));
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_time']), AStartDate.Time);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_date']), AStartDate.Date);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndType']), Integer(AEndType));
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_time']), AEndDate.Time);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_date']), AEndDate.Date);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndCount']), AEndCount);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_time']), ALastTriggered.Time);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_date']), ALastTriggered.Date);
+  {DayFrequency}
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyStartTime']), ADayFrequencyStartTime);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyEndTime']), ADayFrequencyEndTime);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyInterval']), ADayFrequencyInterval);
+  {Daily}
+  AppStorage.WriteBoolean(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayEveryWeekDay']), ADayEveryWeekDay);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayInterval']), ADayInterval);
+  {Weekly}
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekInterval']), AWeekInterval);
+  AppStorage.WriteSet(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekDaysOfWeek']), TypeInfo(TScheduleWeekDays), AWeekDaysOfWeek);
+  {Monthly}
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MothIndexKind']), Integer(AMothIndexKind));
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthIndexValue']), AMonthIndexValue);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthDay']), AMonthDay);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthInterval']), AMonthInterval);
+  {Yearly}
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexKind']), Integer(AYearIndexKind));
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexValue']), AYearIndexValue);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearDay']), AYearDay);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearMonth']), AYearMonth);
+  AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearInterval']), AYearInterval);
 end;
 
 procedure TJvCustomScheduledEvents.DeleteSingleEvent(Sender: TJvCustomAppStorage; const Path: string;
@@ -666,9 +895,6 @@
 
 {$IFDEF VCL}
 procedure TJvCustomScheduledEvents.WndProc(var Msg: TMessage);
-var
-  List: TList;
-  I: Integer;
 begin
   with Msg do
     case Msg of
@@ -676,25 +902,9 @@
         Dispatch(Msg);
       WM_TIMECHANGE:
         begin
-          // Mantis 3355: Time has changed, mark all running schedules as
-          // "to be restarted", stop and then restart them.
-          List := TList.Create;
-          try
-            for I := 0 to FEvents.Count - 1 do
-            begin
-              if FEvents[I].State in [sesTriggered, sesExecuting, sesPaused] then
-              begin
-                List.Add(FEvents[I]);
-                FEvents[I].Stop;
-              end;
-            end;
-            for I := 0 to List.Count - 1 do
-            begin
-              TJvEventCollectionItem(List[I]).Start;
-            end;
-          finally
-            List.Free;
-          end;
+          // Mantis 3355: Time has changed, stop and restart the schedules
+          StopAll;
+          StartAll;
         end;
     else
       Result := DefWindowProc(Handle, Msg, WParam, LParam);
@@ -1208,9 +1418,94 @@
   end;
 end;
 
-procedure TJvEventCollectionItem.LoadState(const TriggerStamp: TTimeStamp; const TriggerCount,
-  DayCount: Integer; const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime);
+procedure TJvEventCollectionItem.LoadState(const TriggerStamp: TTimeStamp; const TriggerCount, DayCount: Integer;
+  const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime;
+  {Common}
+  const ARecurringType: TScheduleRecurringKind;
+  const AStartDate: TTimeStamp;
+  const AEndType: TScheduleEndKind;
+  const AEndDate: TTimeStamp;
+  const AEndCount: Cardinal;
+  const ALastTriggered: TTimeStamp;
+  {DayFrequency}
+  const ADayFrequencyStartTime: Cardinal;
+  const ADayFrequencyEndTime: Cardinal;
+  const ADayFrequencyInterval: Cardinal;
+  {Daily}
+  const ADayEveryWeekDay: Boolean;
+  const ADayInterval: Cardinal;
+  {Weekly}
+  const AWeekInterval: Cardinal;
+  const AWeekDaysOfWeek: TScheduleWeekDays;
+  {Monthly}
+  const AMonthIndexKind: TScheduleIndexKind;
+  const AMonthIndexValue: Cardinal;
+  const AMonthDay: Cardinal;
+  const AMonthInterval: Cardinal;
+  {Yearly}
+  const AYearIndexKind: TScheduleIndexKind;
+  const AYearIndexValue: Cardinal;
+  const AYearDay: Cardinal;
+  const AYearMonth: Cardinal;
+  const AYearInterval: Cardinal);
+var
+  IDayFrequency: IJclScheduleDayFrequency;
+  IDay: IJclDailySchedule;
+  IWeek: IJclWeeklySchedule;
+  IMonth: IJclMonthlySchedule;
+  IYear: IJclYearlySchedule;
 begin
+  Schedule.RecurringType:=ARecurringType;
+  if ARecurringType<>srkOneShot then
+    begin
+      IDayFrequency := Schedule as IJclScheduleDayFrequency;
+      IDayFrequency.StartTime := ADayFrequencyStartTime;
+      IDayFrequency.EndTime := ADayFrequencyEndTime;
+      IDayFrequency.Interval := ADayFrequencyInterval;
+    end;
+  case ARecurringType of
+    srkOneShot:
+      begin
+      end;
+    srkDaily:
+      begin
+        {IJclDailySchedule}
+        IDay := Schedule as IJclDailySchedule;
+        IDay.EveryWeekDay := ADayEveryWeekDay;
+        if not ADayEveryWeekDay then
+          IDay.Interval := ADayInterval;
+      end;
+    srkWeekly:
+      begin
+        {IJclWeeklySchedule}
+        IWeek := Schedule as IJclWeeklySchedule;
+        IWeek.DaysOfWeek := AWeekDaysOfWeek;
+        IWeek.Interval := AWeekInterval;
+      end;
+    srkMonthly:
+      begin
+        {IJclMonthlySchedule}
+        IMonth := Schedule as IJclMonthlySchedule;
+        IMonth.IndexKind := AMonthIndexKind;
+        if AMonthIndexKind <> sikNone then
+          IMonth.IndexValue := AMonthIndexValue;
+        if AMonthIndexKind = sikNone then
+          IMonth.Day := AMonthDay;
+        IMonth.Interval := AMonthInterval;
+      end;
+    srkYearly:
+      begin
+        {IJclYearlySchedule}
+        IYear := Schedule as IJclYearlySchedule;
+        IYear.IndexKind := AYearIndexKind;
+        if AYearIndexKind <> sikNone then
+          IYear.IndexValue := AYearIndexValue
+        else
+          IYear.Day := AYearDay;
+        IYear.Month := AYearMonth;
+        IYear.Interval := AYearInterval;
+      end;
+  end;
   Schedule.InitToSavedState(TriggerStamp, TriggerCount, DayCount);
   FScheduleFire := TriggerStamp;
   FSnoozeFire := SnoozeStamp;
@@ -1230,9 +1525,99 @@
     FState := sesPaused;
 end;
 
-procedure TJvEventCollectionItem.SaveState(out TriggerStamp: TTimeStamp; out TriggerCount,
-  DayCount: Integer; out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime);
+procedure TJvEventCollectionItem.SaveState(out TriggerStamp: TTimeStamp; out TriggerCount, DayCount: Integer;
+  {Common}
+  out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime;
+  out ARecurringType: TScheduleRecurringKind;
+  out AStartDate: TTimeStamp;
+  out AEndType: TScheduleEndKind;
+  out AEndDate: TTimeStamp;
+  out AEndCount: Cardinal;
+  out ALastTriggered: TTimeStamp;
+ {DayFrequency}
+  out ADayFrequencyStartTime: Cardinal;
+  out ADayFrequencyEndTime: Cardinal;
+  out ADayFrequencyInterval: Cardinal;
+ {Daily}
+  out ADayEveryWeekDay: Boolean;
+  out ADayInterval: Cardinal;
+ {Weekly}
+  out AWeekInterval: Cardinal;
+  out AWeekDaysOfWeek: TScheduleWeekDays;
+ {Monthly}
+  out AMothIndexKind: TScheduleIndexKind;
+  out AMonthIndexValue: Cardinal;
+  out AMonthDay: Cardinal;
+  out AMonthInterval: Cardinal;
+ {Yearly}
+  out AYearIndexKind: TScheduleIndexKind;
+  out AYearIndexValue: Cardinal;
+  out AYearDay: Cardinal;
+  out AYearMonth: Cardinal;
+  out AYearInterval: Cardinal);
+var
+  IDayFrequency: IJclScheduleDayFrequency;
+  IDay: IJclDailySchedule;
+  IWeek: IJclWeeklySchedule;
+  IMonth: IJclMonthlySchedule;
+  IYear: IJclYearlySchedule;
 begin
+  {Common properties}
+  AEndType := FSchedule.EndType;
+  AEndDate := FSchedule.EndDate;
+  AEndCount := FSchedule.EndCount;
+  ALastTriggered := Fschedule.LastTriggered;
+  AStartDate := FSchedule.StartDate;
+  ARecurringType := FSchedule.RecurringType;
+  {IJclScheduleDayFrequency}
+  if ARecurringType<>srkOneShot then
+    begin
+      IDayFrequency := FSchedule as IJclScheduleDayFrequency;
+      ADayFrequencyStartTime := IDayFrequency.StartTime;
+      ADayFrequencyEndTime := IDayFrequency.EndTime;
+      ADayFrequencyInterval := IDayFrequency.Interval;
+    end;
+  case ARecurringType of
+    srkOneShot:
+      begin
+      end;
+    srkDaily:
+      begin
+        {IJclDailySchedule}
+        IDay := FSchedule as IJclDailySchedule;
+        ADayInterval := IDay.Interval;
+        ADayEveryWeekDay := IDay.EveryWeekDay;
+      end;
+    srkWeekly:
+      begin
+        {IJclWeeklySchedule}
+        IWeek := FSchedule as IJclWeeklySchedule;
+        AWeekInterval := IWeek.Interval;
+        AWeekDaysOfWeek := IWeek.DaysOfWeek;
+      end;
+    srkMonthly:
+      begin
+        {IJclMonthlySchedule}
+        IMonth := FSchedule as IJclMonthlySchedule;
+        AMothIndexKind := IMonth.IndexKind;
+        if AMothIndexKind <> sikNone then
+          AMonthIndexValue := IMonth.IndexValue;
+        AMonthDay := IMonth.Day;
+        AMonthInterval := IMonth.Interval;
+      end;
+    srkYearly:
+      begin
+        {IJclYearlySchedule}
+        IYear := FSchedule as IJclYearlySchedule;
+        AYearIndexKind := IYear.IndexKind;
+        if AYearIndexKind <> sikNone then
+          AYearIndexValue := IYear.IndexValue;
+        AYearDay := IYear.Day;
+        AYearMonth := IYear.Month;
+        AYearInterval := IYear.Interval;
+      end;
+  end;
+  {Old part}
   TriggerStamp := FScheduleFire;
   TriggerCount := Schedule.TriggerCount;
   DayCount := Schedule.DayCount;
JvScheduledEvents1.patch (22,455 bytes)

obones

2006-10-12 06:57

administrator   ~0010348

Let me insist:
Saving sets as integer, well, I could live with it.
But having so many arguments to the save and restore function, this is simply NOT acceptable. Pass an object containing the values, even the schedule directly.

ZENsan

2006-10-12 09:50

reporter   ~0010350

Understand, ok. I thought that you are talking about integer as set. Ok I will correct source.

2006-10-12 10:11

 

JvScheduledEvents2.patch (22,935 bytes)
Index: JvScheduledEvents.pas
===================================================================
--- JvScheduledEvents.pas	(revision 10965)
+++ JvScheduledEvents.pas	(working copy)
@@ -58,6 +58,46 @@
 
   TScheduledEventState =
     (sesNotInitialized, sesWaiting, sesTriggered, sesExecuting, sesPaused, sesEnded);
+  TScheduledEventStateInfo = record
+    {Common}
+      ARecurringType: TScheduleRecurringKind;
+      AStartDate: TTimeStamp;
+      AEndType: TScheduleEndKind;
+      AEndDate: TTimeStamp;
+      AEndCount: Cardinal;
+      ALastTriggered: TTimeStamp;
+    {DayFrequency}
+      DayFrequence: record
+        ADayFrequencyStartTime: Cardinal;
+        ADayFrequencyEndTime: Cardinal;
+        ADayFrequencyInterval: Cardinal;
+      end;
+    {Daily}
+      Daily: record
+        ADayEveryWeekDay: Boolean;
+        ADayInterval: Cardinal;
+      end;
+    {Weekly}
+      Weekly: record
+        AWeekInterval: Cardinal;
+        AWeekDaysOfWeek: TScheduleWeekDays;
+      end;
+    {Monthly}
+      Monthly: record
+        AMonthIndexKind: TScheduleIndexKind;
+        AMonthIndexValue: Cardinal;
+        AMonthDay: Cardinal;
+        AMonthInterval: Cardinal;
+      end;
+    {Yearly}
+      Yearly: record
+        AYearIndexKind: TScheduleIndexKind;
+        AYearIndexValue: Cardinal;
+        AYearDay: Cardinal;
+        AYearMonth: Cardinal;
+        AYearInterval: Cardinal;
+      end;
+  end;
   TScheduledEventExecute = procedure(Sender: TJvEventCollectionItem; const IsSnoozeEvent: Boolean) of object;
 
   TJvCustomScheduledEvents = class(TComponent)
@@ -197,10 +237,12 @@
     constructor Create(Collection: TCollection); override;
     destructor Destroy; override;
     procedure LoadState(const TriggerStamp: TTimeStamp; const TriggerCount, DayCount: Integer;
-      const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime); virtual;
+      const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime;
+      const AEventInfo: TScheduledEventStateInfo); virtual;
     procedure Pause;
     procedure SaveState(out TriggerStamp: TTimeStamp; out TriggerCount, DayCount: Integer;
-      out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime); virtual;
+      out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime;
+      out AEventInfo: TScheduledEventStateInfo); virtual;
     procedure Snooze(const MSecs: Word; const Secs: Word = 0; const Mins: Word = 0;
       const Hrs: Word = 0; const Days: Word = 0);
     procedure Start;
@@ -452,20 +494,6 @@
 begin
   inherited Create(AOwner);
   FEvents := TJvEventCollection.Create(Self);
-
-  {$IFDEF VCL}
-  FWnd := AllocateHWndEx(WndProc);
-  {$ENDIF VCL}
-  {$IFDEF VisualCLX}
-  FWnd := QWidgetH(AllocateMessageObject(Self));
-  {$ENDIF VisualCLX}
-  if not (csDesigning in ComponentState) and not (csLoading in ComponentState) then
-  begin
-    if AutoSave then
-      LoadEventStates;
-    InitEvents;
-  end;
-  ScheduleThread.AddEventComponent(Self);
 end;
 
 destructor TJvCustomScheduledEvents.Destroy;
@@ -537,9 +565,16 @@
 begin
   if not (csDesigning in ComponentState) then
   begin
+    {$IFDEF VCL}
+    FWnd := AllocateHWndEx(WndProc);
+    {$ENDIF VCL}
+    {$IFDEF VisualCLX}
+    FWnd := QWidgetH(AllocateMessageObject(Self));
+    {$ENDIF VisualCLX}
     if AutoSave then
       LoadEventStates;
     InitEvents;
+    ScheduleThread.AddEventComponent(Self);
   end;
 end;
 
@@ -553,6 +588,37 @@
   SnoozeInterval: TSystemTime;
   EventName: string;
   Event: TJvEventCollectionItem;
+
+  AInt: Cardinal;
+  {common}
+(*  ARecurringType: TScheduleRecurringKind;
+  AStartDate: TTimeStamp;
+  AEndType: TScheduleEndKind;
+  AEndDate: TTimeStamp;
+  AEndCount: Cardinal;
+  ALastTriggered: TTimeStamp;
+  {DayFrequency}
+  ADayFrequencyStartTime: Cardinal;
+  ADayFrequencyEndTime: Cardinal;
+  ADayFrequencyInterval: Cardinal;
+  {Daily}
+  ADayEveryWeekDay: Boolean;
+  ADayInterval: Cardinal;
+  {Weekly}
+  AWeekInterval: Cardinal;
+  AWeekDaysOfWeek: TScheduleWeekDays;
+  {Monthly}
+  AMothIndexKind: TScheduleIndexKind;
+  AMonthIndexValue: Cardinal;
+  AMonthDay: Cardinal;
+  AMonthInterval: Cardinal;
+  {Yearly}
+  AYearIndexKind: TScheduleIndexKind;
+  AYearIndexValue: Cardinal;
+  AYearDay: Cardinal;
+  AYearMonth: Cardinal;
+  AYearInterval: Cardinal; *)
+  EventInfo: TScheduledEventStateInfo;
 begin
   EventName := Sender.ReadString(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'Eventname']));
   if EventName <> '' then
@@ -570,9 +636,62 @@
     SnoozeInterval.wMinute := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMinute']));
     SnoozeInterval.wSecond := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wSecond']));
     SnoozeInterval.wMilliseconds := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMilliseconds']));
+    {Common}
+    with EventInfo do
+      begin
+        AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'RecurringType']));
+        ARecurringType := TScheduleRecurringKind(AInt);
+        AStartDate.Time := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_time']));
+        AStartDate.Date := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_date']));
+        AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndType']));
+        AEndType := TScheduleEndKind(AInt);
+        AEndDate.Time := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_time']));
+        AEndDate.Date := Sender.readInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_date']));
+        AEndCount := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndCount']));
+        ALastTriggered.Time := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_time']));
+        ALastTriggered.Date := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_date']));
+      end;
+    {DayFrequency}
+    with EventInfo.DayFrequence do
+      begin
+        ADayFrequencyStartTime := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyStartTime']));
+        ADayFrequencyEndTime := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyEndTime']));
+        ADayFrequencyInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyInterval']));
+      end;
+    {Daily}
+    with EventInfo.Daily do
+      begin
+        ADayEveryWeekDay := Sender.ReadBoolean(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayEveryWeekDay']));
+        ADayInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayInterval']));
+      end;
+    {Weekly}
+    with EventInfo.Weekly do
+      begin
+        AWeekInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekInterval']));
+        AppStorage.ReadSet(Sender.ConcatPaths([Path, ItemName + IntToStr(Index),'WeekDaysOfWeek']), TypeInfo(TScheduleWeekDays), [], AWeekDaysOfWeek);
+      end;
+    {Monthly}
+    with EventInfo.Monthly do
+      begin
+        AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MothIndexKind']));
+        AMonthIndexKind := TScheduleIndexKind(AInt);
+        AMonthIndexValue := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthIndexValue']));
+        AMonthDay := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthDay']));
+        AMonthInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthInterval']));
+      end;
+    {Yearly}
+    with EventInfo.Yearly do
+      begin
+        AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexKind']));
+        AYearIndexKind := TScheduleIndexKind(AInt);
+        AYearIndexValue := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexValue']));
+        AYearDay := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearDay']));
+        AYearMonth := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearMonth']));
+        AYearInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearInterval']));
+      end;
     Event := TJvEventCollection(List).Add;
     Event.Name := EventName;
-    Event.LoadState(Stamp, TriggerCount, DayCount, Snooze, SnoozeInterval);
+    Event.LoadState(Stamp, TriggerCount, DayCount, Snooze, SnoozeInterval,EventInfo);
   end;
 end;
 
@@ -597,8 +716,37 @@
   SnoozeInterval: TSystemTime;
   SnoozeDate: Integer;
   SnoozeTime: Integer;
+  {common}
+  ARecurringType: TScheduleRecurringKind;
+  AStartDate: TTimeStamp;
+  AEndType: TScheduleEndKind;
+  AEndDate: TTimeStamp;
+  AEndCount: Cardinal;
+  ALastTriggered: TTimeStamp;
+  {DayFrequency}
+  ADayFrequencyStartTime: Cardinal;
+  ADayFrequencyEndTime: Cardinal;
+  ADayFrequencyInterval: Cardinal;
+  {Daily}
+  ADayEveryWeekDay: Boolean;
+  ADayInterval: Cardinal;
+  {Weekly}
+  AWeekInterval: Cardinal;
+  AWeekDaysOfWeek: TScheduleWeekDays;
+  {Monthly}
+  AMothIndexKind: TScheduleIndexKind;
+  AMonthIndexValue: Cardinal;
+  AMonthDay: Cardinal;
+  AMonthInterval: Cardinal;
+  {Yearly}
+  AYearIndexKind: TScheduleIndexKind;
+  AYearIndexValue: Cardinal;
+  AYearDay: Cardinal;
+  AYearMonth: Cardinal;
+  AYearInterval: Cardinal;
+  EventInfo: TScheduledEventStateInfo;
 begin
-  TJvEventCollection(List)[Index].SaveState(Stamp, TriggerCount, DayCount, SnoozeStamp, SnoozeInterval);
+  TJvEventCollection(List)[Index].SaveState(Stamp, TriggerCount, DayCount, SnoozeStamp, SnoozeInterval, EventInfo);
   StampDate := Stamp.Date;
   StampTime := Stamp.Time;
   SnoozeDate := SnoozeStamp.Date;
@@ -617,6 +765,55 @@
   AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMinute']), SnoozeInterval.wMinute);
   AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wSecond']), SnoozeInterval.wSecond);
   AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMilliseconds']), SnoozeInterval.wMilliseconds);
+  {Common}
+  with EventInfo do
+    begin
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'RecurringType']), Integer(ARecurringType));
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_time']), AStartDate.Time);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_date']), AStartDate.Date);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndType']), Integer(AEndType));
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_time']), AEndDate.Time);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_date']), AEndDate.Date);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndCount']), AEndCount);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_time']), ALastTriggered.Time);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_date']), ALastTriggered.Date);
+    end;
+  {DayFrequency}
+  with EventInfo.DayFrequence do
+    begin
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyStartTime']), ADayFrequencyStartTime);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyEndTime']), ADayFrequencyEndTime);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyInterval']), ADayFrequencyInterval);
+    end;
+  {Daily}
+  with EventInfo.Daily do
+    begin
+      AppStorage.WriteBoolean(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayEveryWeekDay']), ADayEveryWeekDay);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayInterval']), ADayInterval);
+    end;
+  {Weekly}
+  with EventInfo.Weekly do
+    begin
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekInterval']), AWeekInterval);
+      AppStorage.WriteSet(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekDaysOfWeek']), TypeInfo(TScheduleWeekDays), AWeekDaysOfWeek);
+    end;
+  {Monthly}
+  with EventInfo.Monthly do
+    begin
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MothIndexKind']), Integer(AMonthIndexKind));
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthIndexValue']), AMonthIndexValue);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthDay']), AMonthDay);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthInterval']), AMonthInterval);
+    end;
+  {Yearly}
+  with EventInfo.Yearly do
+    begin
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexKind']), Integer(AYearIndexKind));
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexValue']), AYearIndexValue);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearDay']), AYearDay);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearMonth']), AYearMonth);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearInterval']), AYearInterval);
+    end;
 end;
 
 procedure TJvCustomScheduledEvents.DeleteSingleEvent(Sender: TJvCustomAppStorage; const Path: string;
@@ -666,9 +863,6 @@
 
 {$IFDEF VCL}
 procedure TJvCustomScheduledEvents.WndProc(var Msg: TMessage);
-var
-  List: TList;
-  I: Integer;
 begin
   with Msg do
     case Msg of
@@ -676,25 +870,9 @@
         Dispatch(Msg);
       WM_TIMECHANGE:
         begin
-          // Mantis 3355: Time has changed, mark all running schedules as
-          // "to be restarted", stop and then restart them.
-          List := TList.Create;
-          try
-            for I := 0 to FEvents.Count - 1 do
-            begin
-              if FEvents[I].State in [sesTriggered, sesExecuting, sesPaused] then
-              begin
-                List.Add(FEvents[I]);
-                FEvents[I].Stop;
-              end;
-            end;
-            for I := 0 to List.Count - 1 do
-            begin
-              TJvEventCollectionItem(List[I]).Start;
-            end;
-          finally
-            List.Free;
-          end;
+          // Mantis 3355: Time has changed, stop and restart the schedules
+          StopAll;
+          StartAll;
         end;
     else
       Result := DefWindowProc(Handle, Msg, WParam, LParam);
@@ -1208,20 +1386,95 @@
   end;
 end;
 
-procedure TJvEventCollectionItem.LoadState(const TriggerStamp: TTimeStamp; const TriggerCount,
-  DayCount: Integer; const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime);
+procedure TJvEventCollectionItem.LoadState(const TriggerStamp: TTimeStamp; const TriggerCount, DayCount: Integer;
+  const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime; const AEventInfo: TScheduledEventStateInfo);
+var
+  IDayFrequency: IJclScheduleDayFrequency;
+  IDay: IJclDailySchedule;
+  IWeek: IJclWeeklySchedule;
+  IMonth: IJclMonthlySchedule;
+  IYear: IJclYearlySchedule;
 begin
-  Schedule.InitToSavedState(TriggerStamp, TriggerCount, DayCount);
-  FScheduleFire := TriggerStamp;
-  FSnoozeFire := SnoozeStamp;
-  FLastSnoozeInterval := ALastSnoozeInterval;
-  if IsNullTimeStamp(NextFire) or
-    (CompareTimeStamps(NextFire, DateTimeToTimeStamp(Now)) < 0) then
-    Schedule.NextEventFromNow(CountMissedEvents);
-  if IsNullTimeStamp(NextFire) then
-    FState := sesEnded
-  else
-    FState := sesWaiting;
+  with AEventInfo do
+    begin
+      Schedule.RecurringType:=ARecurringType;
+      if ARecurringType<>srkOneShot then
+        begin
+          IDayFrequency := Schedule as IJclScheduleDayFrequency;
+          with AEventInfo.DayFrequence do
+            begin
+              IDayFrequency.StartTime :=ADayFrequencyStartTime;
+              IDayFrequency.EndTime := ADayFrequencyEndTime;
+              IDayFrequency.Interval := ADayFrequencyInterval;
+            end;
+        end;
+      case ARecurringType of
+        srkOneShot:
+          begin
+          end;
+        srkDaily:
+          begin
+            {IJclDailySchedule}
+            IDay := Schedule as IJclDailySchedule;
+            with AEventInfo.Daily do
+              begin
+                IDay.EveryWeekDay := ADayEveryWeekDay;
+                if not ADayEveryWeekDay then
+                  IDay.Interval := ADayInterval;
+              end;
+          end;
+        srkWeekly:
+          begin
+            {IJclWeeklySchedule}
+            IWeek := Schedule as IJclWeeklySchedule;
+            with AEventInfo.Weekly do
+              begin
+                IWeek.DaysOfWeek := AWeekDaysOfWeek;
+                IWeek.Interval := AWeekInterval;
+              end;
+          end;
+        srkMonthly:
+          begin
+            {IJclMonthlySchedule}
+            IMonth := Schedule as IJclMonthlySchedule;
+            with AEventInfo.Monthly do
+              begin
+                IMonth.IndexKind := AMonthIndexKind;
+                if AMonthIndexKind <> sikNone then
+                  IMonth.IndexValue := AMonthIndexValue;
+                if AMonthIndexKind = sikNone then
+                  IMonth.Day := AMonthDay;
+                IMonth.Interval := AMonthInterval;
+              end;
+          end;
+        srkYearly:
+          begin
+            {IJclYearlySchedule}
+            IYear := Schedule as IJclYearlySchedule;
+            with AEventInfo.Yearly do
+              begin
+                IYear.IndexKind := AYearIndexKind;
+                if AYearIndexKind <> sikNone then
+                  IYear.IndexValue := AYearIndexValue
+                else
+                  IYear.Day := AYearDay;
+                IYear.Month := AYearMonth;
+                IYear.Interval := AYearInterval;
+              end;
+          end;
+      end;
+      Schedule.InitToSavedState(TriggerStamp, TriggerCount, DayCount);
+      FScheduleFire := TriggerStamp;
+      FSnoozeFire := SnoozeStamp;
+      FLastSnoozeInterval := ALastSnoozeInterval;
+      if IsNullTimeStamp(NextFire) or
+        (CompareTimeStamps(NextFire, DateTimeToTimeStamp(Now)) < 0) then
+        Schedule.NextEventFromNow(CountMissedEvents);
+      if IsNullTimeStamp(NextFire) then
+        FState := sesEnded
+      else
+        FState := sesWaiting;
+    end;
 end;
 
 procedure TJvEventCollectionItem.Pause;
@@ -1230,14 +1483,95 @@
     FState := sesPaused;
 end;
 
-procedure TJvEventCollectionItem.SaveState(out TriggerStamp: TTimeStamp; out TriggerCount,
-  DayCount: Integer; out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime);
+procedure TJvEventCollectionItem.SaveState(out TriggerStamp: TTimeStamp; out TriggerCount, DayCount: Integer;
+      out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime;
+      out AEventInfo: TScheduledEventStateInfo);
+var
+  IDayFrequency: IJclScheduleDayFrequency;
+  IDay: IJclDailySchedule;
+  IWeek: IJclWeeklySchedule;
+  IMonth: IJclMonthlySchedule;
+  IYear: IJclYearlySchedule;
 begin
-  TriggerStamp := FScheduleFire;
-  TriggerCount := Schedule.TriggerCount;
-  DayCount := Schedule.DayCount;
-  SnoozeStamp := FSnoozeFire;
-  ALastSnoozeInterval := LastSnoozeInterval;
+  {Common properties}
+  with AEventInfo do
+    begin
+      AEndType := FSchedule.EndType;
+      AEndDate := FSchedule.EndDate;
+      AEndCount := FSchedule.EndCount;
+      ALastTriggered := Fschedule.LastTriggered;
+      AStartDate := FSchedule.StartDate;
+      ARecurringType := FSchedule.RecurringType;
+      {IJclScheduleDayFrequency}
+      if ARecurringType<>srkOneShot then
+        begin
+          IDayFrequency := FSchedule as IJclScheduleDayFrequency;
+          with AEventInfo.DayFrequence do
+            begin
+              ADayFrequencyStartTime := IDayFrequency.StartTime;
+              ADayFrequencyEndTime := IDayFrequency.EndTime;
+              ADayFrequencyInterval := IDayFrequency.Interval;
+            end;
+        end;
+      case ARecurringType of
+        srkOneShot:
+          begin
+          end;
+        srkDaily:
+          begin
+            {IJclDailySchedule}
+            IDay := FSchedule as IJclDailySchedule;
+            with AEventInfo.Daily do
+              begin
+                ADayInterval := IDay.Interval;
+                ADayEveryWeekDay := IDay.EveryWeekDay;
+              end;
+          end;
+        srkWeekly:
+          begin
+            {IJclWeeklySchedule}
+            IWeek := FSchedule as IJclWeeklySchedule;
+            with AEventInfo.Weekly do
+              begin
+                AWeekInterval := IWeek.Interval;
+                AWeekDaysOfWeek := IWeek.DaysOfWeek;
+              end;
+          end;
+        srkMonthly:
+          begin
+            {IJclMonthlySchedule}
+            IMonth := FSchedule as IJclMonthlySchedule;
+            with AEventInfo.Monthly do
+              begin
+                AMonthIndexKind := IMonth.IndexKind;
+                if AMonthIndexKind <> sikNone then
+                  AMonthIndexValue := IMonth.IndexValue;
+                AMonthDay := IMonth.Day;
+                AMonthInterval := IMonth.Interval;
+              end;
+          end;
+        srkYearly:
+          begin
+            {IJclYearlySchedule}
+            IYear := FSchedule as IJclYearlySchedule;
+            with AEventInfo.Yearly do
+              begin
+                AYearIndexKind := IYear.IndexKind;
+                if AYearIndexKind <> sikNone then
+                  AYearIndexValue := IYear.IndexValue;
+                AYearDay := IYear.Day;
+                AYearMonth := IYear.Month;
+                AYearInterval := IYear.Interval;
+              end;
+          end;
+      end;
+      {Old part}
+      TriggerStamp := FScheduleFire;
+      TriggerCount := Schedule.TriggerCount;
+      DayCount := Schedule.DayCount;
+      SnoozeStamp := FSnoozeFire;
+      ALastSnoozeInterval := LastSnoozeInterval;
+    end;
 end;
 
 procedure TJvEventCollectionItem.Snooze(const MSecs: Word; const Secs: Word = 0;
JvScheduledEvents2.patch (22,935 bytes)

2006-10-12 10:14

 

JvScheduledEvents3.patch (21,410 bytes)
Index: JvScheduledEvents.pas
===================================================================
--- JvScheduledEvents.pas	(revision 10965)
+++ JvScheduledEvents.pas	(working copy)
@@ -58,6 +58,46 @@
 
   TScheduledEventState =
     (sesNotInitialized, sesWaiting, sesTriggered, sesExecuting, sesPaused, sesEnded);
+  TScheduledEventStateInfo = record
+    {Common}
+      ARecurringType: TScheduleRecurringKind;
+      AStartDate: TTimeStamp;
+      AEndType: TScheduleEndKind;
+      AEndDate: TTimeStamp;
+      AEndCount: Cardinal;
+      ALastTriggered: TTimeStamp;
+    {DayFrequency}
+      DayFrequence: record
+        ADayFrequencyStartTime: Cardinal;
+        ADayFrequencyEndTime: Cardinal;
+        ADayFrequencyInterval: Cardinal;
+      end;
+    {Daily}
+      Daily: record
+        ADayEveryWeekDay: Boolean;
+        ADayInterval: Cardinal;
+      end;
+    {Weekly}
+      Weekly: record
+        AWeekInterval: Cardinal;
+        AWeekDaysOfWeek: TScheduleWeekDays;
+      end;
+    {Monthly}
+      Monthly: record
+        AMonthIndexKind: TScheduleIndexKind;
+        AMonthIndexValue: Cardinal;
+        AMonthDay: Cardinal;
+        AMonthInterval: Cardinal;
+      end;
+    {Yearly}
+      Yearly: record
+        AYearIndexKind: TScheduleIndexKind;
+        AYearIndexValue: Cardinal;
+        AYearDay: Cardinal;
+        AYearMonth: Cardinal;
+        AYearInterval: Cardinal;
+      end;
+  end;
   TScheduledEventExecute = procedure(Sender: TJvEventCollectionItem; const IsSnoozeEvent: Boolean) of object;
 
   TJvCustomScheduledEvents = class(TComponent)
@@ -197,10 +237,12 @@
     constructor Create(Collection: TCollection); override;
     destructor Destroy; override;
     procedure LoadState(const TriggerStamp: TTimeStamp; const TriggerCount, DayCount: Integer;
-      const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime); virtual;
+      const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime;
+      const AEventInfo: TScheduledEventStateInfo); virtual;
     procedure Pause;
     procedure SaveState(out TriggerStamp: TTimeStamp; out TriggerCount, DayCount: Integer;
-      out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime); virtual;
+      out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime;
+      out AEventInfo: TScheduledEventStateInfo); virtual;
     procedure Snooze(const MSecs: Word; const Secs: Word = 0; const Mins: Word = 0;
       const Hrs: Word = 0; const Days: Word = 0);
     procedure Start;
@@ -452,20 +494,6 @@
 begin
   inherited Create(AOwner);
   FEvents := TJvEventCollection.Create(Self);
-
-  {$IFDEF VCL}
-  FWnd := AllocateHWndEx(WndProc);
-  {$ENDIF VCL}
-  {$IFDEF VisualCLX}
-  FWnd := QWidgetH(AllocateMessageObject(Self));
-  {$ENDIF VisualCLX}
-  if not (csDesigning in ComponentState) and not (csLoading in ComponentState) then
-  begin
-    if AutoSave then
-      LoadEventStates;
-    InitEvents;
-  end;
-  ScheduleThread.AddEventComponent(Self);
 end;
 
 destructor TJvCustomScheduledEvents.Destroy;
@@ -537,9 +565,16 @@
 begin
   if not (csDesigning in ComponentState) then
   begin
+    {$IFDEF VCL}
+    FWnd := AllocateHWndEx(WndProc);
+    {$ENDIF VCL}
+    {$IFDEF VisualCLX}
+    FWnd := QWidgetH(AllocateMessageObject(Self));
+    {$ENDIF VisualCLX}
     if AutoSave then
       LoadEventStates;
     InitEvents;
+    ScheduleThread.AddEventComponent(Self);
   end;
 end;
 
@@ -553,6 +588,9 @@
   SnoozeInterval: TSystemTime;
   EventName: string;
   Event: TJvEventCollectionItem;
+
+  AInt: Cardinal;
+  EventInfo: TScheduledEventStateInfo;
 begin
   EventName := Sender.ReadString(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'Eventname']));
   if EventName <> '' then
@@ -570,9 +608,62 @@
     SnoozeInterval.wMinute := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMinute']));
     SnoozeInterval.wSecond := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wSecond']));
     SnoozeInterval.wMilliseconds := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMilliseconds']));
+    {Common}
+    with EventInfo do
+      begin
+        AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'RecurringType']));
+        ARecurringType := TScheduleRecurringKind(AInt);
+        AStartDate.Time := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_time']));
+        AStartDate.Date := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_date']));
+        AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndType']));
+        AEndType := TScheduleEndKind(AInt);
+        AEndDate.Time := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_time']));
+        AEndDate.Date := Sender.readInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_date']));
+        AEndCount := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndCount']));
+        ALastTriggered.Time := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_time']));
+        ALastTriggered.Date := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_date']));
+      end;
+    {DayFrequency}
+    with EventInfo.DayFrequence do
+      begin
+        ADayFrequencyStartTime := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyStartTime']));
+        ADayFrequencyEndTime := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyEndTime']));
+        ADayFrequencyInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyInterval']));
+      end;
+    {Daily}
+    with EventInfo.Daily do
+      begin
+        ADayEveryWeekDay := Sender.ReadBoolean(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayEveryWeekDay']));
+        ADayInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayInterval']));
+      end;
+    {Weekly}
+    with EventInfo.Weekly do
+      begin
+        AWeekInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekInterval']));
+        AppStorage.ReadSet(Sender.ConcatPaths([Path, ItemName + IntToStr(Index),'WeekDaysOfWeek']), TypeInfo(TScheduleWeekDays), [], AWeekDaysOfWeek);
+      end;
+    {Monthly}
+    with EventInfo.Monthly do
+      begin
+        AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MothIndexKind']));
+        AMonthIndexKind := TScheduleIndexKind(AInt);
+        AMonthIndexValue := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthIndexValue']));
+        AMonthDay := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthDay']));
+        AMonthInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthInterval']));
+      end;
+    {Yearly}
+    with EventInfo.Yearly do
+      begin
+        AInt := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexKind']));
+        AYearIndexKind := TScheduleIndexKind(AInt);
+        AYearIndexValue := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexValue']));
+        AYearDay := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearDay']));
+        AYearMonth := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearMonth']));
+        AYearInterval := Sender.ReadInteger(Sender.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearInterval']));
+      end;
     Event := TJvEventCollection(List).Add;
     Event.Name := EventName;
-    Event.LoadState(Stamp, TriggerCount, DayCount, Snooze, SnoozeInterval);
+    Event.LoadState(Stamp, TriggerCount, DayCount, Snooze, SnoozeInterval,EventInfo);
   end;
 end;
 
@@ -597,8 +688,9 @@
   SnoozeInterval: TSystemTime;
   SnoozeDate: Integer;
   SnoozeTime: Integer;
+  EventInfo: TScheduledEventStateInfo;
 begin
-  TJvEventCollection(List)[Index].SaveState(Stamp, TriggerCount, DayCount, SnoozeStamp, SnoozeInterval);
+  TJvEventCollection(List)[Index].SaveState(Stamp, TriggerCount, DayCount, SnoozeStamp, SnoozeInterval, EventInfo);
   StampDate := Stamp.Date;
   StampTime := Stamp.Time;
   SnoozeDate := SnoozeStamp.Date;
@@ -617,6 +709,55 @@
   AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMinute']), SnoozeInterval.wMinute);
   AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wSecond']), SnoozeInterval.wSecond);
   AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'SnoozeInterval.wMilliseconds']), SnoozeInterval.wMilliseconds);
+  {Common}
+  with EventInfo do
+    begin
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'RecurringType']), Integer(ARecurringType));
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_time']), AStartDate.Time);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'StartDate_date']), AStartDate.Date);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndType']), Integer(AEndType));
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_time']), AEndDate.Time);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndDate_date']), AEndDate.Date);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'EndCount']), AEndCount);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_time']), ALastTriggered.Time);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'LastTriggered_date']), ALastTriggered.Date);
+    end;
+  {DayFrequency}
+  with EventInfo.DayFrequence do
+    begin
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyStartTime']), ADayFrequencyStartTime);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyEndTime']), ADayFrequencyEndTime);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayFrequencyInterval']), ADayFrequencyInterval);
+    end;
+  {Daily}
+  with EventInfo.Daily do
+    begin
+      AppStorage.WriteBoolean(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayEveryWeekDay']), ADayEveryWeekDay);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'DayInterval']), ADayInterval);
+    end;
+  {Weekly}
+  with EventInfo.Weekly do
+    begin
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekInterval']), AWeekInterval);
+      AppStorage.WriteSet(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'WeekDaysOfWeek']), TypeInfo(TScheduleWeekDays), AWeekDaysOfWeek);
+    end;
+  {Monthly}
+  with EventInfo.Monthly do
+    begin
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MothIndexKind']), Integer(AMonthIndexKind));
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthIndexValue']), AMonthIndexValue);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthDay']), AMonthDay);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'MonthInterval']), AMonthInterval);
+    end;
+  {Yearly}
+  with EventInfo.Yearly do
+    begin
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexKind']), Integer(AYearIndexKind));
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearIndexValue']), AYearIndexValue);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearDay']), AYearDay);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearMonth']), AYearMonth);
+      AppStorage.WriteInteger(AppStorage.ConcatPaths([Path, ItemName + IntToStr(Index), 'YearInterval']), AYearInterval);
+    end;
 end;
 
 procedure TJvCustomScheduledEvents.DeleteSingleEvent(Sender: TJvCustomAppStorage; const Path: string;
@@ -666,9 +807,6 @@
 
 {$IFDEF VCL}
 procedure TJvCustomScheduledEvents.WndProc(var Msg: TMessage);
-var
-  List: TList;
-  I: Integer;
 begin
   with Msg do
     case Msg of
@@ -676,25 +814,9 @@
         Dispatch(Msg);
       WM_TIMECHANGE:
         begin
-          // Mantis 3355: Time has changed, mark all running schedules as
-          // "to be restarted", stop and then restart them.
-          List := TList.Create;
-          try
-            for I := 0 to FEvents.Count - 1 do
-            begin
-              if FEvents[I].State in [sesTriggered, sesExecuting, sesPaused] then
-              begin
-                List.Add(FEvents[I]);
-                FEvents[I].Stop;
-              end;
-            end;
-            for I := 0 to List.Count - 1 do
-            begin
-              TJvEventCollectionItem(List[I]).Start;
-            end;
-          finally
-            List.Free;
-          end;
+          // Mantis 3355: Time has changed, stop and restart the schedules
+          StopAll;
+          StartAll;
         end;
     else
       Result := DefWindowProc(Handle, Msg, WParam, LParam);
@@ -1208,20 +1330,95 @@
   end;
 end;
 
-procedure TJvEventCollectionItem.LoadState(const TriggerStamp: TTimeStamp; const TriggerCount,
-  DayCount: Integer; const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime);
+procedure TJvEventCollectionItem.LoadState(const TriggerStamp: TTimeStamp; const TriggerCount, DayCount: Integer;
+  const SnoozeStamp: TTimeStamp; const ALastSnoozeInterval: TSystemTime; const AEventInfo: TScheduledEventStateInfo);
+var
+  IDayFrequency: IJclScheduleDayFrequency;
+  IDay: IJclDailySchedule;
+  IWeek: IJclWeeklySchedule;
+  IMonth: IJclMonthlySchedule;
+  IYear: IJclYearlySchedule;
 begin
-  Schedule.InitToSavedState(TriggerStamp, TriggerCount, DayCount);
-  FScheduleFire := TriggerStamp;
-  FSnoozeFire := SnoozeStamp;
-  FLastSnoozeInterval := ALastSnoozeInterval;
-  if IsNullTimeStamp(NextFire) or
-    (CompareTimeStamps(NextFire, DateTimeToTimeStamp(Now)) < 0) then
-    Schedule.NextEventFromNow(CountMissedEvents);
-  if IsNullTimeStamp(NextFire) then
-    FState := sesEnded
-  else
-    FState := sesWaiting;
+  with AEventInfo do
+    begin
+      Schedule.RecurringType:=ARecurringType;
+      if ARecurringType<>srkOneShot then
+        begin
+          IDayFrequency := Schedule as IJclScheduleDayFrequency;
+          with AEventInfo.DayFrequence do
+            begin
+              IDayFrequency.StartTime :=ADayFrequencyStartTime;
+              IDayFrequency.EndTime := ADayFrequencyEndTime;
+              IDayFrequency.Interval := ADayFrequencyInterval;
+            end;
+        end;
+      case ARecurringType of
+        srkOneShot:
+          begin
+          end;
+        srkDaily:
+          begin
+            {IJclDailySchedule}
+            IDay := Schedule as IJclDailySchedule;
+            with AEventInfo.Daily do
+              begin
+                IDay.EveryWeekDay := ADayEveryWeekDay;
+                if not ADayEveryWeekDay then
+                  IDay.Interval := ADayInterval;
+              end;
+          end;
+        srkWeekly:
+          begin
+            {IJclWeeklySchedule}
+            IWeek := Schedule as IJclWeeklySchedule;
+            with AEventInfo.Weekly do
+              begin
+                IWeek.DaysOfWeek := AWeekDaysOfWeek;
+                IWeek.Interval := AWeekInterval;
+              end;
+          end;
+        srkMonthly:
+          begin
+            {IJclMonthlySchedule}
+            IMonth := Schedule as IJclMonthlySchedule;
+            with AEventInfo.Monthly do
+              begin
+                IMonth.IndexKind := AMonthIndexKind;
+                if AMonthIndexKind <> sikNone then
+                  IMonth.IndexValue := AMonthIndexValue;
+                if AMonthIndexKind = sikNone then
+                  IMonth.Day := AMonthDay;
+                IMonth.Interval := AMonthInterval;
+              end;
+          end;
+        srkYearly:
+          begin
+            {IJclYearlySchedule}
+            IYear := Schedule as IJclYearlySchedule;
+            with AEventInfo.Yearly do
+              begin
+                IYear.IndexKind := AYearIndexKind;
+                if AYearIndexKind <> sikNone then
+                  IYear.IndexValue := AYearIndexValue
+                else
+                  IYear.Day := AYearDay;
+                IYear.Month := AYearMonth;
+                IYear.Interval := AYearInterval;
+              end;
+          end;
+      end;
+      Schedule.InitToSavedState(TriggerStamp, TriggerCount, DayCount);
+      FScheduleFire := TriggerStamp;
+      FSnoozeFire := SnoozeStamp;
+      FLastSnoozeInterval := ALastSnoozeInterval;
+      if IsNullTimeStamp(NextFire) or
+        (CompareTimeStamps(NextFire, DateTimeToTimeStamp(Now)) < 0) then
+        Schedule.NextEventFromNow(CountMissedEvents);
+      if IsNullTimeStamp(NextFire) then
+        FState := sesEnded
+      else
+        FState := sesWaiting;
+    end;
 end;
 
 procedure TJvEventCollectionItem.Pause;
@@ -1230,14 +1427,95 @@
     FState := sesPaused;
 end;
 
-procedure TJvEventCollectionItem.SaveState(out TriggerStamp: TTimeStamp; out TriggerCount,
-  DayCount: Integer; out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime);
+procedure TJvEventCollectionItem.SaveState(out TriggerStamp: TTimeStamp; out TriggerCount, DayCount: Integer;
+      out SnoozeStamp: TTimeStamp; out ALastSnoozeInterval: TSystemTime;
+      out AEventInfo: TScheduledEventStateInfo);
+var
+  IDayFrequency: IJclScheduleDayFrequency;
+  IDay: IJclDailySchedule;
+  IWeek: IJclWeeklySchedule;
+  IMonth: IJclMonthlySchedule;
+  IYear: IJclYearlySchedule;
 begin
-  TriggerStamp := FScheduleFire;
-  TriggerCount := Schedule.TriggerCount;
-  DayCount := Schedule.DayCount;
-  SnoozeStamp := FSnoozeFire;
-  ALastSnoozeInterval := LastSnoozeInterval;
+  {Common properties}
+  with AEventInfo do
+    begin
+      AEndType := FSchedule.EndType;
+      AEndDate := FSchedule.EndDate;
+      AEndCount := FSchedule.EndCount;
+      ALastTriggered := Fschedule.LastTriggered;
+      AStartDate := FSchedule.StartDate;
+      ARecurringType := FSchedule.RecurringType;
+      {IJclScheduleDayFrequency}
+      if ARecurringType<>srkOneShot then
+        begin
+          IDayFrequency := FSchedule as IJclScheduleDayFrequency;
+          with AEventInfo.DayFrequence do
+            begin
+              ADayFrequencyStartTime := IDayFrequency.StartTime;
+              ADayFrequencyEndTime := IDayFrequency.EndTime;
+              ADayFrequencyInterval := IDayFrequency.Interval;
+            end;
+        end;
+      case ARecurringType of
+        srkOneShot:
+          begin
+          end;
+        srkDaily:
+          begin
+            {IJclDailySchedule}
+            IDay := FSchedule as IJclDailySchedule;
+            with AEventInfo.Daily do
+              begin
+                ADayInterval := IDay.Interval;
+                ADayEveryWeekDay := IDay.EveryWeekDay;
+              end;
+          end;
+        srkWeekly:
+          begin
+            {IJclWeeklySchedule}
+            IWeek := FSchedule as IJclWeeklySchedule;
+            with AEventInfo.Weekly do
+              begin
+                AWeekInterval := IWeek.Interval;
+                AWeekDaysOfWeek := IWeek.DaysOfWeek;
+              end;
+          end;
+        srkMonthly:
+          begin
+            {IJclMonthlySchedule}
+            IMonth := FSchedule as IJclMonthlySchedule;
+            with AEventInfo.Monthly do
+              begin
+                AMonthIndexKind := IMonth.IndexKind;
+                if AMonthIndexKind <> sikNone then
+                  AMonthIndexValue := IMonth.IndexValue;
+                AMonthDay := IMonth.Day;
+                AMonthInterval := IMonth.Interval;
+              end;
+          end;
+        srkYearly:
+          begin
+            {IJclYearlySchedule}
+            IYear := FSchedule as IJclYearlySchedule;
+            with AEventInfo.Yearly do
+              begin
+                AYearIndexKind := IYear.IndexKind;
+                if AYearIndexKind <> sikNone then
+                  AYearIndexValue := IYear.IndexValue;
+                AYearDay := IYear.Day;
+                AYearMonth := IYear.Month;
+                AYearInterval := IYear.Interval;
+              end;
+          end;
+      end;
+      {Old part}
+      TriggerStamp := FScheduleFire;
+      TriggerCount := Schedule.TriggerCount;
+      DayCount := Schedule.DayCount;
+      SnoozeStamp := FSnoozeFire;
+      ALastSnoozeInterval := LastSnoozeInterval;
+    end;
 end;
 
 procedure TJvEventCollectionItem.Snooze(const MSecs: Word; const Secs: Word = 0;
JvScheduledEvents3.patch (21,410 bytes)

ZENsan

2006-10-12 10:15

reporter   ~0010351

In third patch I think all is ok - I have also removed unusable comments and unused variables.

ZENsan

2006-12-11 07:02

reporter   ~0010464

Maybe it is possibel to apply patch at end?

ZENsan

2007-01-22 06:29

reporter   ~0010574

Hey! Comon! Working fine, integrate! :)
Also uses WriteSet/ReadSet as you wished.

obones

2007-01-22 08:38

administrator   ~0010576

This is now in SVN but your patch had to be fixed because it included removal of some earlier fixes. This takes time and pushes the issue down the list of priorities.

Issue History

Date Modified Username Field Change
2006-09-19 01:40 ZENsan New Issue
2006-09-19 02:58 obones Note Added: 0010140
2006-09-19 02:58 obones Status new => feedback
2006-09-19 07:22 ZENsan Note Added: 0010143
2006-09-20 03:01 ZENsan Note Added: 0010147
2006-09-20 03:02 ZENsan File Added: JvScheduledEvents.zip
2006-09-20 03:03 ZENsan Note Edited: 0010147
2006-09-26 01:22 obones Note Added: 0010180
2006-09-26 05:57 ZENsan Note Added: 0010181
2006-09-26 06:18 ZENsan Note Added: 0010182
2006-09-29 06:29 obones Note Added: 0010231
2006-10-11 00:57 ZENsan File Added: JvScheduledEvents.patch
2006-10-11 00:58 ZENsan Note Added: 0010341
2006-10-11 01:07 obones Note Added: 0010342
2006-10-12 06:21 ZENsan Note Added: 0010346
2006-10-12 06:52 ZENsan File Added: JvScheduledEvents1.patch
2006-10-12 06:57 obones Note Added: 0010348
2006-10-12 09:50 ZENsan Note Added: 0010350
2006-10-12 10:11 ZENsan File Added: JvScheduledEvents2.patch
2006-10-12 10:14 ZENsan File Added: JvScheduledEvents3.patch
2006-10-12 10:15 ZENsan Note Added: 0010351
2006-12-11 07:02 ZENsan Note Added: 0010464
2007-01-22 06:29 ZENsan Note Added: 0010574
2007-01-22 08:38 obones Status feedback => resolved
2007-01-22 08:38 obones Fixed in Version => Daily / SVN
2007-01-22 08:38 obones Resolution open => fixed
2007-01-22 08:38 obones Assigned To => obones
2007-01-22 08:38 obones Note Added: 0010576