From deede7b75258806dc399f2b24acf79cc3be55460 Mon Sep 17 00:00:00 2001 From: wp_xxyyzz Date: Sun, 11 Dec 2022 13:08:39 +0000 Subject: [PATCH] TvPlanIt: Fix ical import (issue #39047) git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8643 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- components/tvplanit/languages/vpsr.de.po | 21 ++-- components/tvplanit/languages/vpsr.en.po | 19 ++-- components/tvplanit/languages/vpsr.fi.po | 4 +- components/tvplanit/languages/vpsr.fr.po | 4 +- components/tvplanit/languages/vpsr.nl.po | 4 +- components/tvplanit/languages/vpsr.pl.po | 4 +- components/tvplanit/languages/vpsr.ru.po | 4 +- components/tvplanit/source/vpdata.pas | 46 +++++---- components/tvplanit/source/vpical.pas | 2 +- components/tvplanit/source/vpinids.pas | 6 +- .../tvplanit/source/vpweekviewpainter.pas | 95 ++++++++++--------- 11 files changed, 117 insertions(+), 92 deletions(-) diff --git a/components/tvplanit/languages/vpsr.de.po b/components/tvplanit/languages/vpsr.de.po index 2646ee71d..3e843839e 100644 --- a/components/tvplanit/languages/vpsr.de.po +++ b/components/tvplanit/languages/vpsr.de.po @@ -471,13 +471,16 @@ msgid "Edit shape" msgstr "Form bearbeiten" #: vpsr.rselementalreadyexists -#, object-pascal-format +#, object-pascal-format,fuzzy +#| msgid "" +#| "An element named %s already exists.\n" +#| "Please use a different name.\n" msgid "" "An element named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" msgstr "" "Ein Element mit Namen %s existiert bereits.\n" -"Bitte einen anderen Namen verwenden." +"Bitte einen anderen Namen verwenden.\n" #: vpsr.rselements msgid "Elements:" @@ -1128,13 +1131,16 @@ msgid "&Print" msgstr "&Drucken" #: vpsr.rsprintformatalreadyexists -#, object-pascal-format +#, object-pascal-format,fuzzy +#| msgid "" +#| "A print template named %s already exists.\n" +#| "Please use a different name.\n" msgid "" "A print template named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" msgstr "" "Eine Druckvorlage mit Namen %s existiert bereits.\n" -"Bitte einen anderen Namen verwenden." +"Bitte einen anderen Namen verwenden.\n" #: vpsr.rsprintformatdesigner msgid "Print template designer" @@ -1144,7 +1150,7 @@ msgstr "Druckvorlagen-Designer" msgid "Print order" msgstr "" "Druck-\n" -"Reihenfolge" +"Reihenfolge\n" #: vpsr.rsprintprvcancel msgctxt "vpsr.rsprintprvcancel" @@ -1858,3 +1864,4 @@ msgstr "Unbekannte Achsen-Spezifikation: %s" #: vpsr.sxmldecnotatbeg msgid "The XML declaration must appear before the first element" msgstr "Die XML-Deklaration muss vor dem ersten Element erscheinen" + diff --git a/components/tvplanit/languages/vpsr.en.po b/components/tvplanit/languages/vpsr.en.po index 2e66db9dc..6b3d7b0fa 100644 --- a/components/tvplanit/languages/vpsr.en.po +++ b/components/tvplanit/languages/vpsr.en.po @@ -466,13 +466,16 @@ msgid "Edit shape" msgstr "Edit shape" #: vpsr.rselementalreadyexists -#, object-pascal-format +#, object-pascal-format,fuzzy +#| msgid "" +#| "An element named %s already exists.\n" +#| "Please use a different name.\n" msgid "" "An element named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" msgstr "" "An element named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" #: vpsr.rselements msgid "Elements:" @@ -1115,13 +1118,16 @@ msgid "&Print" msgstr "&Print" #: vpsr.rsprintformatalreadyexists -#, object-pascal-format +#, object-pascal-format,fuzzy +#| msgid "" +#| "A print template named %s already exists.\n" +#| "Please use a different name.\n" msgid "" "A print template named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" msgstr "" "A print template named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" #: vpsr.rsprintformatdesigner msgid "Print template designer" @@ -1838,3 +1844,4 @@ msgstr "Unknown axis specifier: %s" #: vpsr.sxmldecnotatbeg msgid "The XML declaration must appear before the first element" msgstr "The XML declaration must appear before the first element" + diff --git a/components/tvplanit/languages/vpsr.fi.po b/components/tvplanit/languages/vpsr.fi.po index 7e62fcb95..ad45e75ba 100644 --- a/components/tvplanit/languages/vpsr.fi.po +++ b/components/tvplanit/languages/vpsr.fi.po @@ -464,7 +464,7 @@ msgstr "" #, object-pascal-format msgid "" "An element named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" msgstr "" #: vpsr.rselements @@ -1122,7 +1122,7 @@ msgstr "" #, object-pascal-format msgid "" "A print template named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" msgstr "" #: vpsr.rsprintformatdesigner diff --git a/components/tvplanit/languages/vpsr.fr.po b/components/tvplanit/languages/vpsr.fr.po index c47be6e99..d73cb14a2 100644 --- a/components/tvplanit/languages/vpsr.fr.po +++ b/components/tvplanit/languages/vpsr.fr.po @@ -484,7 +484,7 @@ msgstr "" #, object-pascal-format msgid "" "An element named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" msgstr "" #: vpsr.rselements @@ -1139,7 +1139,7 @@ msgstr "&Imprimer" #, object-pascal-format msgid "" "A print template named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" msgstr "" #: vpsr.rsprintformatdesigner diff --git a/components/tvplanit/languages/vpsr.nl.po b/components/tvplanit/languages/vpsr.nl.po index 0127420da..adb59aa56 100644 --- a/components/tvplanit/languages/vpsr.nl.po +++ b/components/tvplanit/languages/vpsr.nl.po @@ -478,7 +478,7 @@ msgstr "" #, object-pascal-format msgid "" "An element named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" msgstr "" #: vpsr.rselements @@ -1133,7 +1133,7 @@ msgstr "&Printen" #, object-pascal-format msgid "" "A print template named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" msgstr "" #: vpsr.rsprintformatdesigner diff --git a/components/tvplanit/languages/vpsr.pl.po b/components/tvplanit/languages/vpsr.pl.po index 4d551e42c..cb23bdc97 100644 --- a/components/tvplanit/languages/vpsr.pl.po +++ b/components/tvplanit/languages/vpsr.pl.po @@ -480,7 +480,7 @@ msgstr "Edycja kształtu" #, object-pascal-format msgid "" "An element named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" msgstr "" #: vpsr.rselements @@ -1143,7 +1143,7 @@ msgstr "&Drukuj" #, object-pascal-format msgid "" "A print template named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" msgstr "" #: vpsr.rsprintformatdesigner diff --git a/components/tvplanit/languages/vpsr.ru.po b/components/tvplanit/languages/vpsr.ru.po index 4246420df..0050d9eda 100644 --- a/components/tvplanit/languages/vpsr.ru.po +++ b/components/tvplanit/languages/vpsr.ru.po @@ -480,7 +480,7 @@ msgstr "" #, object-pascal-format msgid "" "An element named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" msgstr "" #: vpsr.rselements @@ -1139,7 +1139,7 @@ msgstr "Печать" #, object-pascal-format msgid "" "A print template named %s already exists.\n" -"Please use a different name." +"Please use a different name.\n" msgstr "" #: vpsr.rsprintformatdesigner diff --git a/components/tvplanit/source/vpdata.pas b/components/tvplanit/source/vpdata.pas index 4e7e26804..b7375e648 100644 --- a/components/tvplanit/source/vpdata.pas +++ b/components/tvplanit/source/vpdata.pas @@ -245,6 +245,7 @@ type function GetEvent(Index: Integer): TVpEvent; function ImportICalFile(const AFileName: String; APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpEventArr; + function IsEventOfThisDate(ADate: TDateTime; AEvent: TVpEvent): Boolean; function RepeatsOn(Event: TVpEvent; Day: TDateTime): Boolean; procedure Sort; property Owner: TVpResource read FOwner; @@ -1927,7 +1928,10 @@ begin if (not ical[i].Checked) or (not (ical[i] is TVpICalEvent)) then Continue; startTime := TVpICalEvent(ical[i]).StartTime[false]; // use local times - endTime := TVpICalEvent(ical[i]).EndTime[false]; + if TVpICalEvent(ical[i]).IsAllDayEvent then + endTime := trunc(startTime) + 1 - OneSecond + else + endTime := TVpICalEvent(ical[i]).EndTime[false]; if startTime = NO_DATE then continue; id := dataStore.GetNextID(EventsTableName); @@ -2048,16 +2052,11 @@ var I: Integer; Event: TVpEvent; begin - result := 0; + Result := 0; for I := 0 to pred(EventCount) do begin Event := GetEvent(I); - // If this is a repeating event and it falls on today then inc result - if (Event.RepeatCode > rtNone) and RepeatsOn(Event, Value) then - Inc(Result) - // Otherwise if it is an event that naturally falls on today, then inc result - else - if DateInRange(Value, Event.StartTime, Event.EndTime, true) then - Inc(Result); + if IsEventOfThisDate(Value, Event) then + inc(Result); end; end; @@ -2068,18 +2067,13 @@ var begin if EventCountByDay(Date) = 0 then EventList.Clear - - else begin + else + begin // Add this day's events to the Event List. - for I := 0 to pred(EventCount) do begin + for I := 0 to pred(EventCount) do + begin Event := GetEvent(I); - - // If this is a repeating event and it falls on "Date" then add it to the list. - if (Event.RepeatCode > rtNone) and RepeatsOn(Event, Date) then - EventList.Add(Event) - else - // otherwise if this event naturally falls on "Date" then add it to the list. - if DateInRange(Date, Event.StartTime, Event.EndTime, true) then + if IsEventOfThisDate(Date, Event) then EventList.Add(Event); end; end; @@ -2190,6 +2184,20 @@ begin result := FEventList.Count; end; +function TVpSchedule.IsEventOfThisDate(ADate: TDateTime; AEvent: TVpEvent): Boolean; +begin + Result := false; + // Is is a non-repeating event that naturally falls on the given day? + if (AEvent.RepeatCode = rtNone) then + begin + if (AEvent.EndTime <> FOREVER_DATE) and DateInRange(ADate, AEvent.Starttime, AEvent.EndTime, true) then + Result := true; + end else + // Is it a repeating event that falls on the given day? + if RepeatsOn(AEvent, ADate) then + Result := true; +end; + (*****************************************************************************) { TVpContact } diff --git a/components/tvplanit/source/vpical.pas b/components/tvplanit/source/vpical.pas index b841f2efe..9653296d1 100644 --- a/components/tvplanit/source/vpical.pas +++ b/components/tvplanit/source/vpical.pas @@ -588,7 +588,7 @@ begin lValue := 'FREQ=' + RecurrenceFrequency; if RecurrenceInterval > 0 then lValue := lValue + ';INTERVAL=' + IntToStr(RecurrenceInterval); - if RecurrenceEndDate <> 0 then + if (RecurrenceEndDate <> 0) and (RecurrenceEndDate <> FOREVER_DATE) then lValue := lValue + ';UNTIL=' + FormatDateTime(TIME_FORMAT, RecurrenceEndDate); if RecurrenceCount > 0 then lValue := lValue + ';COUNT=' + IntToStr(RecurrenceCount); diff --git a/components/tvplanit/source/vpinids.pas b/components/tvplanit/source/vpinids.pas index 582e2ee9f..11accd11f 100644 --- a/components/tvplanit/source/vpinids.pas +++ b/components/tvplanit/source/vpinids.pas @@ -335,7 +335,8 @@ begin L.AddField('AlarmAdvanceType', GetEnumName(TypeInfo(TVpAlarmAdvType), ord(AEvent.AlarmAdvanceType))); L.AddDateTimeField('SnoozeTime', AEvent.SnoozeTime, 'tt'); // long time format L.AddField('RepeatCode', GetEnumName(TypeInfo(TVpRepeatType), ord(AEvent.RepeatCode))); - L.AddDateTimeField('RepeatRangeEnd', AEvent.RepeatRangeEnd, 'ddddd'); // short date format + if (AEvent.RepeatRangeEnd <> 0) and (AEvent.RepeatRangeEnd <> FOREVER_DATE) then + L.AddDateTimeField('RepeatRangeEnd', AEvent.RepeatRangeEnd, 'ddddd'); // short date format L.AddField('CustomInterval', IntToStr(AEvent.CustomInterval)); L.AddField('UserField0', AEvent.UserField0); // 15 L.AddField('UserField1', AEvent.UserField1); @@ -802,7 +803,8 @@ begin AEvent.SnoozeTime := StrToTime(L.Extract(11)); AEvent.RepeatCode := TVpRepeatType(GetEnumValue(TypeInfo(TVpRepeatType), L.Extract(12))); if L[13] = '' then - AEvent.RepeatRangeEnd := 0 else + AEvent.RepeatRangeEnd := FOREVER_DATE + else AEvent.RepeatRangeEnd := StrToDate(L.Extract(13), FFormatSettings); AEvent.CustomInterval := StrToInt(L.Extract(14)); AEvent.UserField0 := L.Extract(15); diff --git a/components/tvplanit/source/vpweekviewpainter.pas b/components/tvplanit/source/vpweekviewpainter.pas index 4ac812df8..94bcf1458 100644 --- a/components/tvplanit/source/vpweekviewpainter.pas +++ b/components/tvplanit/source/vpweekviewpainter.pas @@ -294,63 +294,64 @@ begin DrawDayHeader(ADayIndex, holiday, TextRect); if (FWeekView.DataStore <> nil) and (FWeekView.DataStore.Resource <> nil) and - (FWeekView.DataStore.Resource.Schedule.EventCountByDay(StartDate + ADayIndex) > 0) and + // (FWeekView.DataStore.Resource.Schedule.EventCountByDay(StartDate + ADayIndex) > 0) and (HeightOf(DayRect) >= FWeekView.TextMargin * 2 + FDayHeadHeight) then begin - // Events exist for this day + // EventList is supposesd to collect the events for the day handled in this procedure EventList := TList.Create; try // Populate the event list with events for this day FWeekView.DataStore.Resource.Schedule.EventsByDate(StartDate + ADayIndex, EventList); - - { Now sort times in ascending order. This must be done because the event - list can contain recurring events which have the wrong date part } - EventList.Sort(CompareEventsByTimeOnly); - - // Initialize TextRect for this day - TextRect := DayRect; - TextRect.Top := DayRect.Top + FDayHeadHeight + 1; - TextRect.Bottom := TextRect.Top + rowHeight; - - // Handle all-day events - tmpRect := TextRect; - tmpRect.Bottom := DayRect.Bottom; - if DrawAllDayEvents(StartDate + ADayIndex, tmpRect, EAIndex) then + if EventList.Count > 0 then begin - TextRect.Bottom := TextRect.Bottom + ADEventsRect.Bottom - TextRect.Top; - TextRect.Top := ADEventsRect.Bottom; - end; + { Now sort times in ascending order. This must be done because the event + list can contain recurring events which have the wrong date part } + EventList.Sort(CompareEventsByTimeOnly); - // Discard AllDayEvents, because they are drawn above. - for J := pred(EventList.Count) downto 0 do - if TVpEvent(EventList[J]).AllDayEvent then - EventList.Delete(J); - - // Iterate the events, painting them one by one - for J := 0 to pred(EventList.Count) do begin - { if the TextRect extends below the available space then draw a } - { dot dot dot to indicate there are more events than can be drawn } - { in the available space } - if TextRect.Bottom - FWeekView.TextMargin > DayRect.Bottom then begin - { Draw ". . ." } - DrawDotDotDot(DayRect, DotDotDotColor); - break; - end; - - // Write the event text - DrawEvent(TVpEvent(EventList.List^[J]), TextRect, ADayIndex); - - // Update the EventArray - with TVpWeekViewOpener(FWeekView).wvEventArray[EAIndex] do begin - Rec := TextRect; - Event := TVpEvent(EventList[J]); - end; - Inc(EAIndex); - - TextRect.Top := TextRect.Bottom; + // Initialize TextRect for this day + TextRect := DayRect; + TextRect.Top := DayRect.Top + FDayHeadHeight + 1; TextRect.Bottom := TextRect.Top + rowHeight; - end; { for loop } + // Handle all-day events + tmpRect := TextRect; + tmpRect.Bottom := DayRect.Bottom; + if DrawAllDayEvents(StartDate + ADayIndex, tmpRect, EAIndex) then + begin + TextRect.Bottom := TextRect.Bottom + ADEventsRect.Bottom - TextRect.Top; + TextRect.Top := ADEventsRect.Bottom; + end; + + // Discard AllDayEvents, because they are drawn above. + for J := pred(EventList.Count) downto 0 do + if TVpEvent(EventList[J]).AllDayEvent then + EventList.Delete(J); + + // Iterate the events, painting them one by one + for J := 0 to pred(EventList.Count) do begin + { if the TextRect extends below the available space then draw a } + { dot dot dot to indicate there are more events than can be drawn } + { in the available space } + if TextRect.Bottom - FWeekView.TextMargin > DayRect.Bottom then begin + { Draw ". . ." } + DrawDotDotDot(DayRect, DotDotDotColor); + break; + end; + + // Write the event text + DrawEvent(TVpEvent(EventList.List^[J]), TextRect, ADayIndex); + + // Update the EventArray + with TVpWeekViewOpener(FWeekView).wvEventArray[EAIndex] do begin + Rec := TextRect; + Event := TVpEvent(EventList[J]); + end; + Inc(EAIndex); + + TextRect.Top := TextRect.Bottom; + TextRect.Bottom := TextRect.Top + rowHeight; + end; { for loop } + end; finally EventList.Free; end;