diff --git a/components/tvplanit/languages/vpsr.de.po b/components/tvplanit/languages/vpsr.de.po
index 358895be5..8c22f9576 100644
--- a/components/tvplanit/languages/vpsr.de.po
+++ b/components/tvplanit/languages/vpsr.de.po
@@ -9,7 +9,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 3.1\n"
+"X-Generator: Poedit 3.1.1\n"
#: vpsr.rs1day
msgid "1 day"
@@ -47,6 +47,11 @@ msgstr "Fre"
msgid "Age:"
msgstr "Alter:"
+#: vpsr.rsalarmin
+#, object-pascal-format
+msgid "Alarm in %s"
+msgstr "Alarm in %s"
+
#: vpsr.rsalarmset
msgid "&Reminder"
msgstr "E&rinnerung"
@@ -97,7 +102,7 @@ msgstr "Die Ende-Zeit darf nicht vor der Start-Zeit liegen."
#: vpsr.rsbaditemtype
msgid "Invalid item type "
-msgstr "Ungültiger Eintragstyp."
+msgstr "Ungültiger Eintragstyp "
#: vpsr.rsbadmeasurement
msgid "Invalid measurement"
@@ -105,7 +110,7 @@ msgstr "Ungültige Messung"
#: vpsr.rsbadprintformat
msgid "Invalid print format "
-msgstr "Ungültiges Druckformat."
+msgstr "Ungültiges Druckformat "
#: vpsr.rsbadtriggerhandle
msgid "Invalid trigger handle."
@@ -455,6 +460,26 @@ msgctxt "vpsr.rsevent"
msgid "Event"
msgstr "Ereignis"
+#: vpsr.rseverydays
+#, object-pascal-format
+msgid "Every %d days"
+msgstr "Alle %d Tage"
+
+#: vpsr.rseverymonthson
+#, object-pascal-format
+msgid "Every %d months on day %s"
+msgstr "Alle %d Monate am %s-ten"
+
+#: vpsr.rseveryweekson
+#, object-pascal-format
+msgid "Every %d weeks on %s"
+msgstr "Alle %d Wochen am %s"
+
+#: vpsr.rseveryyearson
+#, object-pascal-format
+msgid "Every %d years on %s"
+msgstr "Alle %d Jahre am %s"
+
#: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event."
msgstr "Konflikte mit einem anderen ausschließenden Ereignis."
@@ -675,6 +700,11 @@ msgstr "Monatlich, nach Datum"
msgid "Monthly by day"
msgstr "Monatlich, nach Tag"
+#: vpsr.rsmonthlyon
+#, object-pascal-format
+msgid "Monthly on day %s"
+msgstr "Monatlich am Tag %s"
+
#: vpsr.rsmonths
msgid "Months"
msgstr "Monate"
@@ -697,7 +727,7 @@ msgstr "Bitte geben Sie einen Element-Namen an"
#: vpsr.rsneedformatname
msgid "FormatName cannot be blank"
-msgstr "Der Format-Name muss angegeben sein.."
+msgstr "Der Format-Name muss angegeben sein"
#: vpsr.rsnewbtn
msgid "New"
@@ -729,6 +759,10 @@ msgstr "Nächstes Jahr"
msgid "N"
msgstr "N"
+#: vpsr.rsnoalarm
+msgid "No alarm"
+msgstr "Ohne Alarm"
+
#: vpsr.rsnocanvas
msgid "TCanvas not assigned"
msgstr "TCanvas wurde nicht zugewiesen"
@@ -1088,6 +1122,10 @@ msgstr "Termin-Wiederholung:"
msgid "Reminder"
msgstr "Erinnerung"
+#: vpsr.rsrepeat
+msgid "Repeat:"
+msgstr "Wiederholung:"
+
#: vpsr.rsreportsetup
msgid "Report setup"
msgstr "Ausdruck einrichten"
@@ -1155,6 +1193,10 @@ msgstr "&Später"
msgid "Click &Snooze to be reminded again in:"
msgstr "Auf \"Später\" klicken, um erinnert zu werden in:"
+#: vpsr.rssound
+msgid "Sound"
+msgstr "Alarmton"
+
#: vpsr.rssoundfinder
msgid "Sound Finder"
msgstr "Klang-Suche"
@@ -1328,6 +1370,11 @@ msgstr "Mittwoch"
msgid "Weekly"
msgstr "Wöchentlich"
+#: vpsr.rsweeklyon
+#, object-pascal-format
+msgid "Weekly on %s"
+msgstr "Wöchentlich am %s"
+
#: vpsr.rsweeks
msgid "Weeks"
msgstr "Wochen"
@@ -1385,6 +1432,11 @@ msgstr "Jährlich, nach Datum"
msgid "Yearly by day"
msgstr "Jährlich, nach Wochentag"
+#: vpsr.rsyearlyon
+#, object-pascal-format
+msgid "Yearly on %s"
+msgstr "Jährlich am %s"
+
#: vpsr.rsyears
msgid "Years"
msgstr "Jahre"
@@ -1413,7 +1465,7 @@ msgstr "Attribut %s von Element %s hat keinen ganzzahligen Wert."
#: vpsr.sbadparamentnesting
msgid "Parameter-entity text must be properly nested: "
-msgstr "Parameter-Entity muss richtig eingebettet sein:"
+msgstr "Parameter-Entity muss richtig eingebettet sein: "
#: vpsr.sbadsepinmodel
msgid "Bad separator in content model: "
diff --git a/components/tvplanit/languages/vpsr.en.po b/components/tvplanit/languages/vpsr.en.po
index 4533c6bbc..909876ea7 100644
--- a/components/tvplanit/languages/vpsr.en.po
+++ b/components/tvplanit/languages/vpsr.en.po
@@ -9,7 +9,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 3.1\n"
+"X-Generator: Poedit 3.1.1\n"
#: vpsr.rs1day
msgid "1 day"
@@ -47,6 +47,11 @@ msgstr "Fri"
msgid "Age:"
msgstr "Age:"
+#: vpsr.rsalarmin
+#, object-pascal-format
+msgid "Alarm in %s"
+msgstr "Alarm in %s"
+
#: vpsr.rsalarmset
msgid "&Reminder"
msgstr "&Reminder"
@@ -449,6 +454,26 @@ msgctxt "vpsr.rsevent"
msgid "Event"
msgstr "Event"
+#: vpsr.rseverydays
+#, object-pascal-format
+msgid "Every %d days"
+msgstr "Every %d days"
+
+#: vpsr.rseverymonthson
+#, object-pascal-format
+msgid "Every %d months on day %s"
+msgstr "Every %d months on day %s"
+
+#: vpsr.rseveryweekson
+#, object-pascal-format
+msgid "Every %d weeks on %s"
+msgstr "Every %d weeks on %s"
+
+#: vpsr.rseveryyearson
+#, object-pascal-format
+msgid "Every %d years on %s"
+msgstr "Every %d years on %s"
+
#: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event."
msgstr "Conflicts with another exclusive event."
@@ -669,6 +694,11 @@ msgstr "Monthly by date"
msgid "Monthly by day"
msgstr "Monthly by day"
+#: vpsr.rsmonthlyon
+#, object-pascal-format
+msgid "Monthly on day %s"
+msgstr ""
+
#: vpsr.rsmonths
msgid "Months"
msgstr "Months"
@@ -721,6 +751,10 @@ msgstr "Next year"
msgid "N"
msgstr "N"
+#: vpsr.rsnoalarm
+msgid "No alarm"
+msgstr "No alarm"
+
#: vpsr.rsnocanvas
msgid "TCanvas not assigned"
msgstr "TCanvas not assigned"
@@ -1074,6 +1108,10 @@ msgstr "Appointment recurrence:"
msgid "Reminder"
msgstr "Reminder"
+#: vpsr.rsrepeat
+msgid "Repeat:"
+msgstr "Repeat:"
+
#: vpsr.rsreportsetup
msgid "Report setup"
msgstr "Report setup"
@@ -1141,6 +1179,10 @@ msgstr "&Snooze"
msgid "Click &Snooze to be reminded again in:"
msgstr "Click &Snooze to be reminded again in:"
+#: vpsr.rssound
+msgid "Sound"
+msgstr "Sound"
+
#: vpsr.rssoundfinder
msgid "Sound Finder"
msgstr "Sound Finder"
@@ -1310,6 +1352,11 @@ msgstr "Wednesday"
msgid "Weekly"
msgstr "Weekly"
+#: vpsr.rsweeklyon
+#, object-pascal-format
+msgid "Weekly on %s"
+msgstr "Weekly on %s"
+
#: vpsr.rsweeks
msgid "Weeks"
msgstr "Weeks"
@@ -1367,6 +1414,11 @@ msgstr "Yearly by date"
msgid "Yearly by day"
msgstr "Yearly by day"
+#: vpsr.rsyearlyon
+#, object-pascal-format
+msgid "Yearly on %s"
+msgstr "Yearly on %s"
+
#: vpsr.rsyears
msgid "Years"
msgstr "Years"
diff --git a/components/tvplanit/languages/vpsr.fi.po b/components/tvplanit/languages/vpsr.fi.po
index affab2fcc..f249ac115 100644
--- a/components/tvplanit/languages/vpsr.fi.po
+++ b/components/tvplanit/languages/vpsr.fi.po
@@ -37,6 +37,11 @@ msgstr "Pe"
msgid "Age:"
msgstr "Ikä:"
+#: vpsr.rsalarmin
+#, object-pascal-format
+msgid "Alarm in %s"
+msgstr ""
+
#: vpsr.rsalarmset
msgid "&Reminder"
msgstr ""
@@ -445,6 +450,26 @@ msgctxt "vpsr.rsevent"
msgid "Event"
msgstr ""
+#: vpsr.rseverydays
+#, object-pascal-format
+msgid "Every %d days"
+msgstr ""
+
+#: vpsr.rseverymonthson
+#, object-pascal-format
+msgid "Every %d months on day %s"
+msgstr ""
+
+#: vpsr.rseveryweekson
+#, object-pascal-format
+msgid "Every %d weeks on %s"
+msgstr ""
+
+#: vpsr.rseveryyearson
+#, object-pascal-format
+msgid "Every %d years on %s"
+msgstr ""
+
#: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event."
msgstr ""
@@ -666,6 +691,11 @@ msgstr ""
msgid "Monthly by day"
msgstr ""
+#: vpsr.rsmonthlyon
+#, object-pascal-format
+msgid "Monthly on day %s"
+msgstr ""
+
#: vpsr.rsmonths
msgid "Months"
msgstr "Kuukaudet"
@@ -720,6 +750,10 @@ msgstr "Seuraava vuosi"
msgid "N"
msgstr ""
+#: vpsr.rsnoalarm
+msgid "No alarm"
+msgstr ""
+
#: vpsr.rsnocanvas
msgid "TCanvas not assigned"
msgstr ""
@@ -1079,6 +1113,10 @@ msgstr ""
msgid "Reminder"
msgstr ""
+#: vpsr.rsrepeat
+msgid "Repeat:"
+msgstr ""
+
#: vpsr.rsreportsetup
msgid "Report setup"
msgstr ""
@@ -1146,6 +1184,10 @@ msgstr ""
msgid "Click &Snooze to be reminded again in:"
msgstr ""
+#: vpsr.rssound
+msgid "Sound"
+msgstr ""
+
#: vpsr.rssoundfinder
msgid "Sound Finder"
msgstr ""
@@ -1320,6 +1362,11 @@ msgstr "Keskiviikko"
msgid "Weekly"
msgstr ""
+#: vpsr.rsweeklyon
+#, object-pascal-format
+msgid "Weekly on %s"
+msgstr ""
+
#: vpsr.rsweeks
msgid "Weeks"
msgstr ""
@@ -1377,6 +1424,11 @@ msgstr ""
msgid "Yearly by day"
msgstr ""
+#: vpsr.rsyearlyon
+#, object-pascal-format
+msgid "Yearly on %s"
+msgstr ""
+
#: vpsr.rsyears
msgid "Years"
msgstr ""
diff --git a/components/tvplanit/languages/vpsr.fr.po b/components/tvplanit/languages/vpsr.fr.po
index 87dfb058e..5a1badf59 100644
--- a/components/tvplanit/languages/vpsr.fr.po
+++ b/components/tvplanit/languages/vpsr.fr.po
@@ -53,6 +53,11 @@ msgstr "Ven"
msgid "Age:"
msgstr ""
+#: vpsr.rsalarmin
+#, object-pascal-format
+msgid "Alarm in %s"
+msgstr ""
+
#: vpsr.rsalarmset
msgid "&Reminder"
msgstr "&Rappel"
@@ -461,6 +466,26 @@ msgctxt "vpsr.rsevent"
msgid "Event"
msgstr "Événement"
+#: vpsr.rseverydays
+#, object-pascal-format
+msgid "Every %d days"
+msgstr ""
+
+#: vpsr.rseverymonthson
+#, object-pascal-format
+msgid "Every %d months on day %s"
+msgstr ""
+
+#: vpsr.rseveryweekson
+#, object-pascal-format
+msgid "Every %d weeks on %s"
+msgstr ""
+
+#: vpsr.rseveryyearson
+#, object-pascal-format
+msgid "Every %d years on %s"
+msgstr ""
+
#: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event."
msgstr "Cette événement est en conflit avec une autre événement exclusif"
@@ -681,6 +706,11 @@ msgstr "Mensuel par date"
msgid "Monthly by day"
msgstr "Mensuel par jour"
+#: vpsr.rsmonthlyon
+#, object-pascal-format
+msgid "Monthly on day %s"
+msgstr ""
+
#: vpsr.rsmonths
msgid "Months"
msgstr ""
@@ -735,6 +765,10 @@ msgstr ""
msgid "N"
msgstr ""
+#: vpsr.rsnoalarm
+msgid "No alarm"
+msgstr ""
+
#: vpsr.rsnocanvas
msgid "TCanvas not assigned"
msgstr "TCanvas non spécifié"
@@ -1094,6 +1128,10 @@ msgstr "Rendevous à répéter:"
msgid "Reminder"
msgstr "Rappel"
+#: vpsr.rsrepeat
+msgid "Repeat:"
+msgstr ""
+
#: vpsr.rsreportsetup
msgid "Report setup"
msgstr ""
@@ -1161,6 +1199,10 @@ msgstr "&Sieste"
msgid "Click &Snooze to be reminded again in:"
msgstr "Click &Sieste pour être rappelé à nouveau dans :"
+#: vpsr.rssound
+msgid "Sound"
+msgstr ""
+
#: vpsr.rssoundfinder
msgid "Sound Finder"
msgstr "Trouver le son"
@@ -1336,6 +1378,11 @@ msgstr "Mercredi"
msgid "Weekly"
msgstr "Hebdomadaire"
+#: vpsr.rsweeklyon
+#, object-pascal-format
+msgid "Weekly on %s"
+msgstr ""
+
#: vpsr.rsweeks
msgid "Weeks"
msgstr ""
@@ -1393,6 +1440,11 @@ msgstr "Annuel par date"
msgid "Yearly by day"
msgstr "Annuel par jour"
+#: vpsr.rsyearlyon
+#, object-pascal-format
+msgid "Yearly on %s"
+msgstr ""
+
#: vpsr.rsyears
msgid "Years"
msgstr ""
diff --git a/components/tvplanit/languages/vpsr.nl.po b/components/tvplanit/languages/vpsr.nl.po
index 60ded8800..b2e995fb8 100644
--- a/components/tvplanit/languages/vpsr.nl.po
+++ b/components/tvplanit/languages/vpsr.nl.po
@@ -47,6 +47,11 @@ msgstr "Vr"
msgid "Age:"
msgstr ""
+#: vpsr.rsalarmin
+#, object-pascal-format
+msgid "Alarm in %s"
+msgstr ""
+
#: vpsr.rsalarmset
msgid "&Reminder"
msgstr "He&rinnering"
@@ -455,6 +460,26 @@ msgctxt "vpsr.rsevent"
msgid "Event"
msgstr "Gebeurtenis"
+#: vpsr.rseverydays
+#, object-pascal-format
+msgid "Every %d days"
+msgstr ""
+
+#: vpsr.rseverymonthson
+#, object-pascal-format
+msgid "Every %d months on day %s"
+msgstr ""
+
+#: vpsr.rseveryweekson
+#, object-pascal-format
+msgid "Every %d weeks on %s"
+msgstr ""
+
+#: vpsr.rseveryyearson
+#, object-pascal-format
+msgid "Every %d years on %s"
+msgstr ""
+
#: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event."
msgstr "Conflict met een andere gebeurtenis."
@@ -675,6 +700,11 @@ msgstr "Maandelijks, op Datum"
msgid "Monthly by day"
msgstr "Maandelijks, op Dag"
+#: vpsr.rsmonthlyon
+#, object-pascal-format
+msgid "Monthly on day %s"
+msgstr ""
+
#: vpsr.rsmonths
msgid "Months"
msgstr ""
@@ -729,6 +759,10 @@ msgstr ""
msgid "N"
msgstr "N"
+#: vpsr.rsnoalarm
+msgid "No alarm"
+msgstr ""
+
#: vpsr.rsnocanvas
msgid "TCanvas not assigned"
msgstr "TCanvas is niet toegewezen."
@@ -1088,6 +1122,10 @@ msgstr "Afspraak herhaling:"
msgid "Reminder"
msgstr "Herinnering"
+#: vpsr.rsrepeat
+msgid "Repeat:"
+msgstr ""
+
#: vpsr.rsreportsetup
msgid "Report setup"
msgstr ""
@@ -1155,6 +1193,10 @@ msgstr "&Uitstellen"
msgid "Click &Snooze to be reminded again in:"
msgstr "Klik op \"Uitstellen\" om nogmaals herinnerd te worden in:"
+#: vpsr.rssound
+msgid "Sound"
+msgstr ""
+
#: vpsr.rssoundfinder
msgid "Sound Finder"
msgstr "Geluid Zoeker"
@@ -1330,6 +1372,11 @@ msgstr "Woensdag"
msgid "Weekly"
msgstr "Wekelijks"
+#: vpsr.rsweeklyon
+#, object-pascal-format
+msgid "Weekly on %s"
+msgstr ""
+
#: vpsr.rsweeks
msgid "Weeks"
msgstr ""
@@ -1387,6 +1434,11 @@ msgstr "Jaarlijks, op Datum"
msgid "Yearly by day"
msgstr "Jaarlijks, op dag"
+#: vpsr.rsyearlyon
+#, object-pascal-format
+msgid "Yearly on %s"
+msgstr ""
+
#: vpsr.rsyears
msgid "Years"
msgstr ""
diff --git a/components/tvplanit/languages/vpsr.pl.po b/components/tvplanit/languages/vpsr.pl.po
index 0dd1aef5a..919097bc4 100644
--- a/components/tvplanit/languages/vpsr.pl.po
+++ b/components/tvplanit/languages/vpsr.pl.po
@@ -47,6 +47,11 @@ msgstr "Pią"
msgid "Age:"
msgstr "Wiek:"
+#: vpsr.rsalarmin
+#, object-pascal-format
+msgid "Alarm in %s"
+msgstr ""
+
#: vpsr.rsalarmset
msgid "&Reminder"
msgstr "&Przypomnienie"
@@ -455,6 +460,26 @@ msgctxt "vpsr.rsevent"
msgid "Event"
msgstr "Wydarzenie"
+#: vpsr.rseverydays
+#, object-pascal-format
+msgid "Every %d days"
+msgstr ""
+
+#: vpsr.rseverymonthson
+#, object-pascal-format
+msgid "Every %d months on day %s"
+msgstr ""
+
+#: vpsr.rseveryweekson
+#, object-pascal-format
+msgid "Every %d weeks on %s"
+msgstr ""
+
+#: vpsr.rseveryyearson
+#, object-pascal-format
+msgid "Every %d years on %s"
+msgstr ""
+
#: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event."
msgstr "Konflikt z innym wydarzeniem wyłącznym."
@@ -675,6 +700,11 @@ msgstr "Mieś. wg daty"
msgid "Monthly by day"
msgstr "Mieś. wg dnia"
+#: vpsr.rsmonthlyon
+#, object-pascal-format
+msgid "Monthly on day %s"
+msgstr ""
+
#: vpsr.rsmonths
msgid "Months"
msgstr "Miesiąc"
@@ -729,6 +759,10 @@ msgstr "Następny rok"
msgid "N"
msgstr "N"
+#: vpsr.rsnoalarm
+msgid "No alarm"
+msgstr ""
+
#: vpsr.rsnocanvas
msgid "TCanvas not assigned"
msgstr "TCanvas nie został przypisany."
@@ -1087,6 +1121,10 @@ msgstr "Częstotliwość:"
msgid "Reminder"
msgstr "Przypomnienie"
+#: vpsr.rsrepeat
+msgid "Repeat:"
+msgstr ""
+
#: vpsr.rsreportsetup
msgid "Report setup"
msgstr "Ustawienia Raportu"
@@ -1154,6 +1192,10 @@ msgstr "&Drzemka"
msgid "Click &Snooze to be reminded again in:"
msgstr "Naciśnij \"&Drzemka aby uaktywnić ponownie..."
+#: vpsr.rssound
+msgid "Sound"
+msgstr ""
+
#: vpsr.rssoundfinder
msgid "Sound Finder"
msgstr "Wyszukanie dźwięku"
@@ -1328,6 +1370,11 @@ msgstr "Środa"
msgid "Weekly"
msgstr "Tygodniowo"
+#: vpsr.rsweeklyon
+#, object-pascal-format
+msgid "Weekly on %s"
+msgstr ""
+
#: vpsr.rsweeks
msgid "Weeks"
msgstr "Tygodnie"
@@ -1385,6 +1432,11 @@ msgstr "Rocz. wg daty"
msgid "Yearly by day"
msgstr "Rocz. wg dnia"
+#: vpsr.rsyearlyon
+#, object-pascal-format
+msgid "Yearly on %s"
+msgstr ""
+
#: vpsr.rsyears
msgid "Years"
msgstr "Lata"
diff --git a/components/tvplanit/languages/vpsr.pot b/components/tvplanit/languages/vpsr.pot
index 491db9b65..6ba95cf01 100644
--- a/components/tvplanit/languages/vpsr.pot
+++ b/components/tvplanit/languages/vpsr.pot
@@ -37,6 +37,11 @@ msgstr ""
msgid "Age:"
msgstr ""
+#: vpsr.rsalarmin
+#, object-pascal-format
+msgid "Alarm in %s"
+msgstr ""
+
#: vpsr.rsalarmset
msgid "&Reminder"
msgstr ""
@@ -439,6 +444,26 @@ msgctxt "vpsr.rsevent"
msgid "Event"
msgstr ""
+#: vpsr.rseverydays
+#, object-pascal-format
+msgid "Every %d days"
+msgstr ""
+
+#: vpsr.rseverymonthson
+#, object-pascal-format
+msgid "Every %d months on day %s"
+msgstr ""
+
+#: vpsr.rseveryweekson
+#, object-pascal-format
+msgid "Every %d weeks on %s"
+msgstr ""
+
+#: vpsr.rseveryyearson
+#, object-pascal-format
+msgid "Every %d years on %s"
+msgstr ""
+
#: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event."
msgstr ""
@@ -659,6 +684,11 @@ msgstr ""
msgid "Monthly by day"
msgstr ""
+#: vpsr.rsmonthlyon
+#, object-pascal-format
+msgid "Monthly on day %s"
+msgstr ""
+
#: vpsr.rsmonths
msgid "Months"
msgstr ""
@@ -711,6 +741,10 @@ msgstr ""
msgid "N"
msgstr ""
+#: vpsr.rsnoalarm
+msgid "No alarm"
+msgstr ""
+
#: vpsr.rsnocanvas
msgid "TCanvas not assigned"
msgstr ""
@@ -1064,6 +1098,10 @@ msgstr ""
msgid "Reminder"
msgstr ""
+#: vpsr.rsrepeat
+msgid "Repeat:"
+msgstr ""
+
#: vpsr.rsreportsetup
msgid "Report setup"
msgstr ""
@@ -1131,6 +1169,10 @@ msgstr ""
msgid "Click &Snooze to be reminded again in:"
msgstr ""
+#: vpsr.rssound
+msgid "Sound"
+msgstr ""
+
#: vpsr.rssoundfinder
msgid "Sound Finder"
msgstr ""
@@ -1300,6 +1342,11 @@ msgstr ""
msgid "Weekly"
msgstr ""
+#: vpsr.rsweeklyon
+#, object-pascal-format
+msgid "Weekly on %s"
+msgstr ""
+
#: vpsr.rsweeks
msgid "Weeks"
msgstr ""
@@ -1357,6 +1404,11 @@ msgstr ""
msgid "Yearly by day"
msgstr ""
+#: vpsr.rsyearlyon
+#, object-pascal-format
+msgid "Yearly on %s"
+msgstr ""
+
#: vpsr.rsyears
msgid "Years"
msgstr ""
diff --git a/components/tvplanit/languages/vpsr.ru.po b/components/tvplanit/languages/vpsr.ru.po
index 1bbebb09f..eca1208bc 100644
--- a/components/tvplanit/languages/vpsr.ru.po
+++ b/components/tvplanit/languages/vpsr.ru.po
@@ -47,6 +47,11 @@ msgstr "Пт."
msgid "Age:"
msgstr ""
+#: vpsr.rsalarmin
+#, object-pascal-format
+msgid "Alarm in %s"
+msgstr ""
+
#: vpsr.rsalarmset
msgid "&Reminder"
msgstr "Напоминание"
@@ -455,6 +460,26 @@ msgctxt "vpsr.rsevent"
msgid "Event"
msgstr "Событие"
+#: vpsr.rseverydays
+#, object-pascal-format
+msgid "Every %d days"
+msgstr ""
+
+#: vpsr.rseverymonthson
+#, object-pascal-format
+msgid "Every %d months on day %s"
+msgstr ""
+
+#: vpsr.rseveryweekson
+#, object-pascal-format
+msgid "Every %d weeks on %s"
+msgstr ""
+
+#: vpsr.rseveryyearson
+#, object-pascal-format
+msgid "Every %d years on %s"
+msgstr ""
+
#: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event."
msgstr "Конфликт с другим важным событием."
@@ -675,6 +700,11 @@ msgstr "Ежемесячно"
msgid "Monthly by day"
msgstr "Ежемесячную"
+#: vpsr.rsmonthlyon
+#, object-pascal-format
+msgid "Monthly on day %s"
+msgstr ""
+
#: vpsr.rsmonths
msgid "Months"
msgstr "Месяц"
@@ -729,6 +759,10 @@ msgstr ""
msgid "N"
msgstr ""
+#: vpsr.rsnoalarm
+msgid "No alarm"
+msgstr ""
+
#: vpsr.rsnocanvas
msgid "TCanvas not assigned"
msgstr ""
@@ -1088,6 +1122,10 @@ msgstr "Повторение встречи:"
msgid "Reminder"
msgstr "Напоминание"
+#: vpsr.rsrepeat
+msgid "Repeat:"
+msgstr ""
+
#: vpsr.rsreportsetup
msgid "Report setup"
msgstr ""
@@ -1155,6 +1193,10 @@ msgstr ""
msgid "Click &Snooze to be reminded again in:"
msgstr ""
+#: vpsr.rssound
+msgid "Sound"
+msgstr ""
+
#: vpsr.rssoundfinder
msgid "Sound Finder"
msgstr ""
@@ -1328,6 +1370,11 @@ msgstr "Среда"
msgid "Weekly"
msgstr "Еженедельно"
+#: vpsr.rsweeklyon
+#, object-pascal-format
+msgid "Weekly on %s"
+msgstr ""
+
#: vpsr.rsweeks
msgid "Weeks"
msgstr ""
@@ -1385,6 +1432,11 @@ msgstr "Ежегодно по дате"
msgid "Yearly by day"
msgstr "Ежегодно по дню"
+#: vpsr.rsyearlyon
+#, object-pascal-format
+msgid "Yearly on %s"
+msgstr ""
+
#: vpsr.rsyears
msgid "Years"
msgstr ""
diff --git a/components/tvplanit/laz_visualplanit.lpk b/components/tvplanit/laz_visualplanit.lpk
index 7254b1ccd..b2241e9b6 100644
--- a/components/tvplanit/laz_visualplanit.lpk
+++ b/components/tvplanit/laz_visualplanit.lpk
@@ -32,7 +32,7 @@ Portions created by TurboPower Software Inc. are Copyright (C) 2002 TurboPower S
Contributor(s): "/>
-
+
@@ -281,6 +281,10 @@ Contributor(s): "/>
+
+
+
+
diff --git a/components/tvplanit/source/include/vpsr.inc b/components/tvplanit/source/include/vpsr.inc
index 2da81774f..fc13ec3b5 100644
--- a/components/tvplanit/source/include/vpsr.inc
+++ b/components/tvplanit/source/include/vpsr.inc
@@ -182,6 +182,7 @@ resourcestring
RSOverlayedEvent = 'overlayed';
RSOverlayed = 'Overlayed';
RSICalFilter = 'iCalendar files (*.ical;*.ics)|*.ical;*.ics';
+ RSRepeat = 'Repeat:';
{Task Specific}
RSConfirmDeleteTask = 'Delete this task from your list?';
@@ -321,6 +322,16 @@ resourcestring
RS1Day = '1 day';
RSXDays = '%d days';
RS1Week = '1 week';
+ RSEveryYearsOn = 'Every %d years on %s';
+ RSEveryMonthsOn = 'Every %d months on day %s';
+ RSEveryWeeksOn = 'Every %d weeks on %s';
+ RSEveryDays = 'Every %d days';
+ RSYearlyOn = 'Yearly on %s';
+ RSMonthlyOn = 'Monthly on day %s';
+ RSWeeklyOn = 'Weekly on %s';
+ RSAlarmIn = 'Alarm in %s';
+ RSNoAlarm = 'No alarm';
+ RSSound = 'Sound';
{ Calendar }
RSCalendarRevert = 'Revert';
diff --git a/components/tvplanit/source/vpbase.pas b/components/tvplanit/source/vpbase.pas
index 19047c9ab..587f2e6d2 100644
--- a/components/tvplanit/source/vpbase.pas
+++ b/components/tvplanit/source/vpbase.pas
@@ -247,6 +247,7 @@ type
function GetColor(AIndex: Integer): TColor;
function GetName(AIndex: Integer):string;
function GetCategory(AIndex: Integer): TVpCategoryInfo;
+ function GetCategoryName(AIndex: Integer): String;
function IndexOfCategory(AName: String): Integer;
function IndexOfFirstUnusedCategory: Integer;
procedure SetCategoryName(AIndex: Integer; AName: String);
@@ -741,6 +742,11 @@ begin
Result := FCat[AIndex];
end;
+function TVpCategoryColorMap.GetCategoryName(AIndex: Integer): string;
+begin
+ Result := FCat[AIndex].Description;
+end;
+
function TVpCategoryColorMap.IndexOfCategory(AName: String): Integer;
var
i: Integer;
diff --git a/components/tvplanit/source/vpbaseds.pas b/components/tvplanit/source/vpbaseds.pas
index eca9fe2e0..b25eb6ef3 100644
--- a/components/tvplanit/source/vpbaseds.pas
+++ b/components/tvplanit/source/vpbaseds.pas
@@ -313,6 +313,8 @@ type
procedure DeleteResource(Res: TVpResource);
function FindResource(const AResourceName: String): TVpResource;
+ function FindBestCategory(const ACategoryNames: TStrings): String;
+
property Connected : boolean read FConnected write SetConnected;
property Loading : Boolean read FLoading write FLoading;
property Resource: TVpResource read FResource write SetResource;
@@ -543,7 +545,24 @@ begin
Result := FResources.FindResourceByName(AResourceName);
end;
-{=====}
+{ ACategoryNames is a list of category names, e.g. like in ical files.
+ Searches among the datastore's categories whether there is one which matches
+ an element of the category names and returns its name. }
+function TVpCustomDatastore.FindBestCategory(const ACategoryNames: TStrings): String;
+var
+ i, j: Integer;
+begin
+ Result := '';
+ if ACategoryNames.Count > 0 then begin
+ for i := 0 to ACategoryNames.Count-1 do begin
+ j := CategoryColorMap.IndexOfCategory(ACategoryNames[i]);
+ if j <> -1 then begin
+ Result := CategoryColorMap.GetCategoryName(j);
+ break;
+ end;
+ end;
+ end;
+end;
procedure TVpCustomDataStore.DeregisterAllWatchers;
var
diff --git a/components/tvplanit/source/vpdata.pas b/components/tvplanit/source/vpdata.pas
index 949e13b56..71b247109 100644
--- a/components/tvplanit/source/vpdata.pas
+++ b/components/tvplanit/source/vpdata.pas
@@ -37,7 +37,7 @@ interface
uses
LCLProc, LCLType,
- SysUtils, Classes, Dialogs, Graphics,
+ SysUtils, Classes, Dialogs, Graphics, Forms,
VpSR, VpVCard, VpICal;
type
@@ -241,7 +241,8 @@ type
function EventCountByDay(Value: TDateTime): Integer;
procedure EventsByDate(Date: TDateTime; EventList: TList);
function GetEvent(Index: Integer): TVpEvent;
- function ImportICalFile(const AFileName: String; ADefaultCategory: Integer = -1): TVpEventArr;
+ function ImportICalFile(const AFileName: String; APreview: Boolean = false;
+ ADefaultCategory: Integer = -1): TVpEventArr;
function RepeatsOn(Event: TVpEvent; Day: TDateTime): Boolean;
procedure Sort;
property Owner: TVpResource read FOwner;
@@ -311,8 +312,11 @@ type
function CanEdit: Boolean;
function CopyToSchedule(ASchedule: TVpSchedule): TVpEvent;
function GetResource: TVpResource;
+ class function IsAllDayEvent(AStartTime, AEndTime: TDateTime): Boolean;
function IsOverlayed: Boolean;
procedure LoadFromICalendar(AEntry: TVpICalEvent);
+ class procedure GetAlarmParams(ATrigger: TDateTime; out AdvTime: Integer;
+ out AdvTimeUnits: TVpAlarmAdvType);
property Owner: TVpSchedule read FOwner;
property ResourceID: Integer read FResourceID write FResourceID;
property Loading : Boolean read FLoading write FLoading;
@@ -705,7 +709,7 @@ implementation
uses
Math, DateUtils,
- VpException, VpConst, VpMisc, VpBaseDS;
+ VpException, VpConst, VpMisc, VpBaseDS, VpICalPreview;
const
TIME_EPS = 1.0 / SecondsInDay; // Epsilon for comparing times
@@ -1333,6 +1337,13 @@ begin
Result := FOwner.Owner;
end;
+{ Returns whether the event specified by its start and end time is an all-day
+ event. This is true when the time-part is zero in each case. }
+class function TVpEvent.IsAllDayEvent(AStartTime, AEndTime: TDateTime): Boolean;
+begin
+ Result := (frac(AStartTime) = 0) and (frac(AEndTime) = 0);
+end;
+
{ The event is overlayed if its ResourceID is different from that of the
resource to which it belongs. }
function TVpEvent.IsOverlayed: Boolean;
@@ -1352,9 +1363,27 @@ begin
Result := abs(d - round(d)) < Epsilon;
end;
+class procedure TVpEvent.GetAlarmParams(ATrigger: TDateTime; out AdvTime: Integer;
+ out AdvTimeUnits: TVpAlarmAdvType);
+var
+ dt: TDateTime;
+begin
+ dt := abs(ATrigger);
+ if IsInteger(dt, 1.0 / SecondsInDay) then begin
+ AdvTimeUnits := atDays;
+ AdvTime := round(dt);
+ end else
+ if IsInteger(dt*HoursInDay, HoursInDay / SecondsInDay) then begin
+ AdvTimeUnits := atHours;
+ AdvTime := round(dt * HoursInDay);
+ end else begin
+ AdvTimeUnits := atMinutes;
+ AdvTime := round(dt * MinutesInDay);
+ end;
+end;
+
procedure TVpEvent.LoadFromICalendar(AEntry: TVpICalEvent);
var
- dt: Double;
cat: String;
i, j, k: Integer;
datastore: TVpCustomDatastore;
@@ -1392,23 +1421,12 @@ begin
end;
{ All-day event }
- FAllDayEvent := (frac(FStartTime) = 0) and (frac(FEndTime) = 0);
+ FAllDayEvent := TVpEvent.IsAllDayEvent(FStartTime, FEndTime);
{ Alarm properties }
if AEntry.Alarm <> nil then begin
FAlarmSet := true;
- dt := abs(AEntry.Alarm.Trigger);
- if IsInteger(dt, 1.0 / SecondsInDay) then begin
- FAlarmAdvType := atDays;
- FAlarmAdv := round(dt);
- end else
- if IsInteger(dt*HoursInDay, HoursInDay / SecondsInDay) then begin
- FAlarmAdvType := atHours;
- FAlarmAdv := round(dt * HoursInDay);
- end else begin
- FAlarmAdvType := atMinutes;
- FAlarmAdv := round(dt * MinutesInDay);
- end;
+ GetAlarmParams(AEntry.Alarm.Trigger, FAlarmAdv, FAlarmAdvType);
FDingPath := AEntry.Alarm.AudioSrc;
if not FileExists(FDingPath) then FDingPath := '';
end else
@@ -1722,8 +1740,8 @@ begin
result := TVpEvent(FEventList[Index]);
end;
-function TVpSchedule.ImportICalFile(const AFileName: String;
- ADefaultCategory: Integer = -1): TVpEventArr;
+function TVpSchedule.ImportICalFile(const AFileName: String;
+ APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpEventArr;
const
BLOCK_SIZE = 10;
var
@@ -1734,18 +1752,31 @@ var
event: TVpEvent;
eventCounter: Integer;
datastore: TVpCustomDatastore;
+ previewForm: TVpIcalPreviewForm = nil;
begin
Result := nil;
SetLength(Result, BLOCK_SIZE);
- eventCounter := 0;
-
datastore := Owner.Owner.Owner as TVpCustomDatastore;
-
+ eventCounter := 0;
+
ical := TVpICalendar.Create;
try
ical.LoadFromFile(AFileName);
+ if APreview then
+ begin
+ previewForm := TVpICalPreviewForm.Create(nil);
+ previewForm.Position := poMainFormCenter;
+ previewForm.Kind := icEvent;
+ previewForm.Calendar := ical;
+ previewForm.Datastore := datastore;
+ if ADefaultCategory <> -1 then
+ previewForm.DefaultCategory := datastore.CategoryColorMap.GetCategoryName(ADefaultCategory);
+ if not previewForm.Execute then
+ exit;
+ end;
+
for i := 0 to ical.Count-1 do begin
- if not (ical[i] is TVpICalEvent) then
+ if ical[i].Skip or (not (ical[i] is TVpICalEvent)) then
Continue;
startTime := TVpICalEvent(ical[i]).StartTime[false]; // use local times
endTime := TVpICalEvent(ical[i]).EndTime[false];
@@ -1762,8 +1793,10 @@ begin
if eventCounter mod BLOCK_SIZE = 0 then
SetLength(Result, eventCounter + BLOCK_SIZE);
end;
- SetLength(Result, eventCounter);
finally
+ SetLength(Result, eventCounter);
+ if APreview then
+ previewForm.Free;
ical.Free;
end;
end;
diff --git a/components/tvplanit/source/vpdayview.pas b/components/tvplanit/source/vpdayview.pas
index d8629d80f..3714535e9 100644
--- a/components/tvplanit/source/vpdayview.pas
+++ b/components/tvplanit/source/vpdayview.pas
@@ -447,7 +447,8 @@ type
function BuildEventString(AEvent: TVpEvent; UseAsHint: Boolean): String;
procedure DeleteActiveEvent(Verify: Boolean);
procedure DragDrop(Source: TObject; X, Y: Integer); override;
- function ImportICalFile(const AFileName: String; ADefaultCategory: Integer = -1): TVpEventArr;
+ function ImportICalFile(const AFileName: String; APreview: Boolean = false;
+ ADefaultCategory: Integer = -1): TVpEventArr;
procedure Invalidate; override;
function IsHoliday(ADate: TDate; out AHolidayName: String): Boolean;
procedure LoadLanguage;
@@ -1354,7 +1355,7 @@ begin
try
Application.ProcessMessages;
for fn in dlg.Files do
- ImportICalFile(fn);
+ ImportICalFile(fn, dlg.Files.Count = 1);
finally
Screen.Cursor := crDefault;
end;
@@ -2381,25 +2382,20 @@ end;
If you are not happy with this category replacement you can iterate over the
Result array and change it. }
function TVpDayView.ImportICalFile(const AFileName: String;
- ADefaultCategory: Integer = -1): TVpEventArr;
+ APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpEventArr;
begin
if ReadOnly or (not CheckCreateResource) or
(not Assigned(DataStore)) or (not Assigned(DataStore.Resource))
then
- Exit;
+ Exit(nil);
- Screen.Cursor := crHourglass;
- try
- Result := Datastore.Resource.Schedule.ImportICalFile(AFileName, ADefaultCategory);
- if Length(Result) > 0 then
- begin
- FActiveEvent := Result[High(Result)];
- Datastore.PostEvents;
- Datastore.NotifyDependents;
- Invalidate;
- end;
- finally
- Screen.Cursor := crDefault;
+ Result := Datastore.Resource.Schedule.ImportICalFile(AFileName, APreview, ADefaultCategory);
+ if Length(Result) > 0 then
+ begin
+ FActiveEvent := Result[High(Result)];
+ Datastore.PostEvents;
+ Datastore.NotifyDependents;
+ Invalidate;
end;
end;
diff --git a/components/tvplanit/source/vpical.pas b/components/tvplanit/source/vpical.pas
index 2a3816ea1..8df3c3dfb 100644
--- a/components/tvplanit/source/vpical.pas
+++ b/components/tvplanit/source/vpical.pas
@@ -18,9 +18,11 @@ type
TVpICalEntry = class(TVpFileBlock)
private
FCalendar: TVpICalendar;
+ FSkip: Boolean;
public
constructor Create(ACalendar: TVpICalendar); virtual;
function FindItem(AKey: String): TVpICalItem;
+ property Skip: Boolean read FSkip write FSkip default false;
end;
TVpICalTimeZoneInfo = class(TVpICalEntry)
@@ -73,6 +75,7 @@ type
constructor Create(ACalendar: TVpICalendar); override;
destructor Destroy; override;
procedure Analyze; override;
+ function Categories: TStrings;
procedure UseAlarm;
property Summary: String read FSummary; // is "Description" of tvp
property Description: String read FDescription; // is "Notes" of tvp
@@ -389,6 +392,11 @@ begin
end;
end;
+function TVpICalEvent.Categories: TStrings;
+begin
+ Result := FCategories;
+end;
+
function TVpICalEvent.GetCategory(AIndex: Integer): String;
begin
if (AIndex >= 0) and (AIndex < FCategories.Count) then
diff --git a/components/tvplanit/source/vpicalpreview.pas b/components/tvplanit/source/vpicalpreview.pas
new file mode 100644
index 000000000..8126db6b6
--- /dev/null
+++ b/components/tvplanit/source/vpicalpreview.pas
@@ -0,0 +1,321 @@
+unit VpIcalPreview;
+
+{$mode ObjFPC}{$H+}
+
+interface
+
+uses LazLogger,
+ Classes, SysUtils, Types, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
+ Grids,
+ VpData, VpIcal, VpBaseDS;
+
+type
+
+ TVpIcalItemKind = (icEvent, icToDo);
+
+ { TVpICalPreviewForm }
+
+ TVpICalPreviewForm = class(TForm)
+ Button1: TButton;
+ Button2: TButton;
+ Panel1: TPanel;
+ Grid: TDrawGrid;
+ procedure GridDrawCell(Sender: TObject; aCol, aRow: Integer; aRect: TRect;
+ aState: TGridDrawState);
+ procedure GridGetCheckboxState(Sender: TObject; ACol, ARow: Integer;
+ var Value: TCheckboxState);
+ procedure GridPrepareCanvas(sender: TObject; aCol, aRow: Integer;
+ aState: TGridDrawState);
+ procedure GridSetCheckboxState(Sender: TObject; ACol, ARow: Integer;
+ const Value: TCheckboxState);
+ procedure SetCalendar(const AValue: TVpICalendar);
+ procedure SetKind(const AValue: TVpICalItemKind);
+ private
+ FCalendar: TVpICalendar;
+ FDatastore: TVpCustomDatastore;
+ FDefaultCategory: String;
+ FKind: TVpICalItemKind;
+ FTimeFormat: String;
+ FItems: TFPList;
+ procedure CalcRowHeights;
+ function GetCellText(ACol, ARow: Integer): String;
+ function GetEventText(AEvent: TVpICalEvent): String;
+ function GetToDoText(AToDo: TVpICalToDo): String;
+ procedure PrepareItems;
+
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ function Execute: Boolean;
+ property Calendar: TVpICalendar read FCalendar write SetCalendar;
+ property Datastore: TVpCustomDatastore read FDatastore write FDatastore;
+ property DefaultCategory: String read FDefaultCategory write FDefaultCategory;
+ property Kind: TVpICalItemKind read FKind write SetKind;
+
+ end;
+
+var
+ VpICalPreviewForm: TVpICalPreviewForm;
+
+implementation
+
+{$R *.lfm}
+
+uses
+ LCLIntf, LCLType, vpsr;
+
+constructor TVpICalPreviewForm.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FItems := TFPList.Create;
+ FTimeFormat := 'c'; // short date + long time format
+end;
+
+destructor TVpICalPreviewForm.Destroy;
+begin
+ FItems.Free;
+ inherited Destroy;
+end;
+
+procedure TVpICalPreviewForm.CalcRowHeights;
+var
+ bmp: TBitmap;
+ row: Integer;
+ R: TRect;
+ flags: Integer;
+ s: String;
+begin
+ flags := DT_CALCRECT + DT_WORDBREAK;
+ bmp := TBitmap.Create;
+ try
+ bmp.SetSize(1, 1);
+ bmp.Canvas.Font := Grid.Font;
+ for row := 1 to Grid.RowCount-1 do
+ begin
+ R := Rect(0, 0, MaxInt, 0);
+ s := GetCellText(1, row);
+ DrawText(bmp.Canvas.Handle, PChar(s), Length(s), R, flags);
+ Grid.RowHeights[row] := R.Bottom - R.Top + 2*varCellPadding;
+ end;
+ finally
+ bmp.Free;
+ end;
+end;
+
+function TVpICalPreviewForm.Execute: Boolean;
+begin
+ Result := ShowModal = mrOK;
+end;
+
+function TVpICalPreviewForm.GetCellText(ACol, ARow: Integer): String;
+var
+ item: TVpICalEntry;
+begin
+ Result := '';
+ if ARow < Grid.FixedRows then
+ exit;
+ item := TVpICalEntry(FItems[ARow - Grid.FixedRows]);
+ if item = nil then
+ exit;
+ case ACol of
+ 1: case Kind of
+ icEvent: Result := GetEventText(TVpICalEvent(item));
+ icToDo: Result := GetToDoText(TVpICalToDo(item));
+ end;
+ end;
+end;
+
+function TVpICalPreviewForm.GetEventText(AEvent: TVpICalEvent): String;
+var
+ startTime, endTime: TDateTime;
+ sStartTime, sEndTime: String;
+ advTime: Integer;
+ advTimeUnits: TVpAlarmAdvType;
+ dingPath: String;
+ s: String;
+ cat: String;
+begin
+ startTime := AEvent.StartTime[false];
+ endTime := AEvent.EndTime[false];
+ sStartTime := FormatDateTime(FTimeFormat, startTime);
+ sEndTime := FormatDateTime(FTimeFormat, endTime);
+ if TVpEvent.IsAllDayEvent(startTime, endTime) then
+ begin
+ if trunc(startTime) = trunc(endTime) then
+ Result := Format('%s (%s)', [sStartTime, RSAllDay])
+ else
+ Result := Format('%s - %s (%s)', [sStartTime, sEndTime, RSAllDay]);
+ end else
+ Result :=
+ RSStartTimeLbl + ' ' + sStartTime + LineEnding +
+ RSEndTimeLbl + ' ' + sEndTime;
+
+ Result := Result + LineEnding +
+ RSDescriptionLbl + ' ' + AEvent.Summary + LineEnding +
+ RSCategoryLbl + ' ';
+
+ // Categories
+ if Assigned(FDatastore) then
+ begin
+ cat := FDatastore.FindBestCategory(AEvent.Categories);
+ if cat = '' then cat := FDefaultCategory;
+ Result := Result + cat;
+ end;
+
+ // Recurrence
+ if AEvent.RecurrenceFrequency <> '' then
+ begin
+ s := '';
+ case Uppercase(AEvent.RecurrenceFrequency) of
+ 'YEARLY':
+ if AEvent.RecurrenceInterval in [0, 1] then
+ s := Format(RSYearlyOn, [FormatDateTime('dd/mm',startTime)])
+ else
+ s := Format(RSEveryYearsOn, [AEvent.RecurrenceInterval, FormatDateTime('dd/mm', startTime)]);
+ 'MONTHLY':
+ if AEvent.RecurrenceInterval in [0, 1] then
+ s := Format(RSMonthlyOn, [FormatDateTime('d', startTime)])
+ else
+ s := Format(RSEveryMonthsOn, [AEvent.RecurrenceInterval, FormatDateTime('d', startTime)]);
+ 'WEEKLY':
+ if AEvent.RecurrenceInterval in [0, 1] then
+ s := Format(RSWeeklyOn, [FormatDateTime('dddd',startTime)])
+ else
+ s := Format(RSEveryWeeksOn, [AEvent.RecurrenceInterval, FormatDateTime('ddd', startTime)]);
+ 'DAILY':
+ if AEvent.RecurrenceInterval in [0, 1] then
+ s := RSDaily
+ else
+ s := Format(RSEveryDays, [AEvent.RecurrenceInterval]);
+ end;
+ if s <> '' then
+ Result := Result + LineEnding + RSRepeat + ' ' + s;
+ end;
+
+ // Alarm
+ if AEvent.Alarm <> nil then
+ begin
+ TVpEvent.GetAlarmParams(AEvent.Alarm.Trigger, advTime, advTimeUnits);
+ dingPath := AEvent.Alarm.AudioSrc;
+ if advTime <> 1 then
+ begin
+ case advTimeUnits of
+ atMinutes: s := Format(RSXMinutes, [advTime]);
+ atHours: s := Format(RSXHours, [advTime]);
+ atDays: s := Format(RSXDays, [advTime]);
+ end;
+ s := Format(RSAlarmIn, [s]);
+ end else
+ case advTimeUnits of
+ atMinutes: s := Format(RSAlarmIn, [RS1Minute]);
+ atHours: s := Format(RSAlarmIn, [RS1Hour]);
+ atDays: s := Format(RSAlarmIn, [RS1Day]);
+ end;
+ Result := Result + LineEnding + s;
+ if FileExists(dingPath) then
+ Result := Format('%s, %s: %s', [Result, RSSound, dingPath]);
+ end else
+ Result := Result + LineEnding + RSNoAlarm;
+end;
+
+function TVpICalPreviewForm.GetToDoText(AToDo: TVpICalToDo): String;
+begin
+ Result := '';
+end;
+
+procedure TVpICalPreviewForm.GridDrawCell(Sender: TObject; aCol, aRow: Integer;
+ aRect: TRect; aState: TGridDrawState);
+var
+ s: String;
+ R: TRect;
+begin
+ R := ARect;
+ InflateRect(R, -varCellPadding, - varCellPadding);
+ s := GetCellText(ACol, ARow);
+ Grid.Canvas.TextRect(R, R.Left, R.Top, s);
+end;
+
+procedure TVpICalPreviewForm.GridGetCheckboxState(Sender: TObject; ACol,
+ ARow: Integer; var Value: TCheckboxState);
+var
+ item: TVpICalEntry;
+begin
+ if ARow < Grid.FixedRows then
+ exit;
+ item := TVpICalEntry(FItems[ARow - Grid.FixedRows]);
+ if item = nil then
+ exit;
+ if item.Skip then
+ Value := cbUnchecked
+ else
+ Value := cbChecked;
+end;
+
+procedure TVpICalPreviewForm.GridPrepareCanvas(sender: TObject; aCol,
+ aRow: Integer; aState: TGridDrawState);
+var
+ ts: TTextStyle;
+begin
+ if ACol = 1 then
+ begin
+ ts := Grid.Canvas.TextStyle;
+ ts.SingleLine := false;
+ ts.Wordbreak := true;
+ Grid.Canvas.TextStyle := ts;
+ end;
+end;
+
+procedure TVpICalPreviewForm.GridSetCheckboxState(Sender: TObject; ACol,
+ ARow: Integer; const Value: TCheckboxState);
+var
+ item: TVpICalEntry;
+begin
+ if ARow < Grid.FixedRows then
+ exit;
+ item := TVpICalEntry(FItems[ARow - Grid.FixedRows]);
+ if item = nil then
+ exit;
+ item.Skip := (Value <> cbChecked);
+end;
+
+procedure TVpICalPreviewForm.PrepareItems;
+var
+ i: Integer;
+begin
+ FItems.Clear;
+ if FCalendar <> nil then
+ begin
+ case FKind of
+ icEvent:
+ for i := 0 to FCalendar.Count-1 do
+ if (FCalendar.Entry[i] is TVpICalEvent) then
+ FItems.Add(FCalendar.Entry[i]);
+ icToDo:
+ for i := 0 to FCalendar.Count-1 do
+ if (FCalendar.Entry[i] is TVpICalToDo) then
+ FItems.Add(FCalendar.Entry[i]);
+ end;
+ Grid.RowCount := Grid.FixedRows + FItems.Count;
+ CalcRowHeights;
+ end else
+ Grid.RowCount := Grid.FixedRows;
+end;
+
+procedure TVpICalPreviewForm.SetCalendar(const AValue: TVpICalendar);
+begin
+ if AValue = FCalendar then
+ exit;
+ FCalendar := AValue;
+ PrepareItems;
+end;
+
+procedure TVpICalPreviewForm.SetKind(const AValue: TVpICalItemKind);
+begin
+ if AValue = FKind then
+ exit;
+ FKind := AValue;
+ PrepareItems;
+end;
+
+end.
+
diff --git a/components/tvplanit/source/vpweekview.pas b/components/tvplanit/source/vpweekview.pas
index 1d5f8777f..1e901fd29 100644
--- a/components/tvplanit/source/vpweekview.pas
+++ b/components/tvplanit/source/vpweekview.pas
@@ -272,7 +272,8 @@ type
procedure LoadLanguage;
procedure DeleteActiveEvent(Verify: Boolean);
procedure DragDrop(Source: TObject; X, Y: Integer); override;
- function ImportICalFile(const AFileName: String; ADefaultCategory: Integer = -1): TVpEventArr;
+ function ImportICalFile(const AFileName: String; APreview: Boolean = false;
+ ADefaultCategory: Integer = -1): TVpEventArr;
procedure Invalidate; override;
function IsHoliday(ADate: TDate; out AHolidayName: String): Boolean;
procedure LinkHandler(Sender: TComponent;
@@ -1092,25 +1093,20 @@ end;
If you are not happy with this category replacement you can iterate over the
Result array and change it. }
function TVpWeekView.ImportICalFile(const AFileName: String;
- ADefaultCategory: Integer = -1): TVpEventArr;
+ APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpEventArr;
begin
if ReadOnly or (not CheckCreateResource) or
(not Assigned(DataStore)) or (not Assigned(DataStore.Resource))
then
- Exit;
+ Exit(nil);
- Screen.Cursor := crHourglass;
- try
- Result := Datastore.Resource.Schedule.ImportICalFile(AFileName, ADefaultCategory);
- if Length(Result) > 0 then
- begin
- FActiveEvent := Result[High(Result)];
- Datastore.PostEvents;
- Datastore.NotifyDependents;
- Invalidate;
- end;
- finally
- Screen.Cursor := crDefault;
+ Result := Datastore.Resource.Schedule.ImportICalFile(AFileName, APreview, ADefaultCategory);
+ if Length(Result) > 0 then
+ begin
+ FActiveEvent := Result[High(Result)];
+ Datastore.PostEvents;
+ Datastore.NotifyDependents;
+ Invalidate;
end;
end;
@@ -1339,7 +1335,7 @@ begin
try
Application.ProcessMessages;
for fn in dlg.Files do
- ImportICalFile(fn);
+ ImportICalFile(fn, dlg.Files.Count = 1);
finally
Screen.Cursor := crDefault;
end;