tvplanit: Add preview form for ical import of event items.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8376 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2022-08-10 10:20:56 +00:00
parent b7a192a723
commit a2ba5cddc7
17 changed files with 874 additions and 64 deletions

View File

@ -9,7 +9,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.1\n" "X-Generator: Poedit 3.1.1\n"
#: vpsr.rs1day #: vpsr.rs1day
msgid "1 day" msgid "1 day"
@ -47,6 +47,11 @@ msgstr "Fre"
msgid "Age:" msgid "Age:"
msgstr "Alter:" msgstr "Alter:"
#: vpsr.rsalarmin
#, object-pascal-format
msgid "Alarm in %s"
msgstr "Alarm in %s"
#: vpsr.rsalarmset #: vpsr.rsalarmset
msgid "&Reminder" msgid "&Reminder"
msgstr "E&rinnerung" msgstr "E&rinnerung"
@ -97,7 +102,7 @@ msgstr "Die Ende-Zeit darf nicht vor der Start-Zeit liegen."
#: vpsr.rsbaditemtype #: vpsr.rsbaditemtype
msgid "Invalid item type " msgid "Invalid item type "
msgstr "Ungültiger Eintragstyp." msgstr "Ungültiger Eintragstyp "
#: vpsr.rsbadmeasurement #: vpsr.rsbadmeasurement
msgid "Invalid measurement" msgid "Invalid measurement"
@ -105,7 +110,7 @@ msgstr "Ungültige Messung"
#: vpsr.rsbadprintformat #: vpsr.rsbadprintformat
msgid "Invalid print format " msgid "Invalid print format "
msgstr "Ungültiges Druckformat." msgstr "Ungültiges Druckformat "
#: vpsr.rsbadtriggerhandle #: vpsr.rsbadtriggerhandle
msgid "Invalid trigger handle." msgid "Invalid trigger handle."
@ -455,6 +460,26 @@ msgctxt "vpsr.rsevent"
msgid "Event" msgid "Event"
msgstr "Ereignis" 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 #: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event." msgid "Conflicts with another exclusive event."
msgstr "Konflikte mit einem anderen ausschließenden Ereignis." msgstr "Konflikte mit einem anderen ausschließenden Ereignis."
@ -675,6 +700,11 @@ msgstr "Monatlich, nach Datum"
msgid "Monthly by day" msgid "Monthly by day"
msgstr "Monatlich, nach Tag" msgstr "Monatlich, nach Tag"
#: vpsr.rsmonthlyon
#, object-pascal-format
msgid "Monthly on day %s"
msgstr "Monatlich am Tag %s"
#: vpsr.rsmonths #: vpsr.rsmonths
msgid "Months" msgid "Months"
msgstr "Monate" msgstr "Monate"
@ -697,7 +727,7 @@ msgstr "Bitte geben Sie einen Element-Namen an"
#: vpsr.rsneedformatname #: vpsr.rsneedformatname
msgid "FormatName cannot be blank" msgid "FormatName cannot be blank"
msgstr "Der Format-Name muss angegeben sein.." msgstr "Der Format-Name muss angegeben sein"
#: vpsr.rsnewbtn #: vpsr.rsnewbtn
msgid "New" msgid "New"
@ -729,6 +759,10 @@ msgstr "Nächstes Jahr"
msgid "N" msgid "N"
msgstr "N" msgstr "N"
#: vpsr.rsnoalarm
msgid "No alarm"
msgstr "Ohne Alarm"
#: vpsr.rsnocanvas #: vpsr.rsnocanvas
msgid "TCanvas not assigned" msgid "TCanvas not assigned"
msgstr "TCanvas wurde nicht zugewiesen" msgstr "TCanvas wurde nicht zugewiesen"
@ -1088,6 +1122,10 @@ msgstr "Termin-Wiederholung:"
msgid "Reminder" msgid "Reminder"
msgstr "Erinnerung" msgstr "Erinnerung"
#: vpsr.rsrepeat
msgid "Repeat:"
msgstr "Wiederholung:"
#: vpsr.rsreportsetup #: vpsr.rsreportsetup
msgid "Report setup" msgid "Report setup"
msgstr "Ausdruck einrichten" msgstr "Ausdruck einrichten"
@ -1155,6 +1193,10 @@ msgstr "&Später"
msgid "Click &Snooze to be reminded again in:" msgid "Click &Snooze to be reminded again in:"
msgstr "Auf \"Später\" klicken, um erinnert zu werden in:" msgstr "Auf \"Später\" klicken, um erinnert zu werden in:"
#: vpsr.rssound
msgid "Sound"
msgstr "Alarmton"
#: vpsr.rssoundfinder #: vpsr.rssoundfinder
msgid "Sound Finder" msgid "Sound Finder"
msgstr "Klang-Suche" msgstr "Klang-Suche"
@ -1328,6 +1370,11 @@ msgstr "Mittwoch"
msgid "Weekly" msgid "Weekly"
msgstr "Wöchentlich" msgstr "Wöchentlich"
#: vpsr.rsweeklyon
#, object-pascal-format
msgid "Weekly on %s"
msgstr "Wöchentlich am %s"
#: vpsr.rsweeks #: vpsr.rsweeks
msgid "Weeks" msgid "Weeks"
msgstr "Wochen" msgstr "Wochen"
@ -1385,6 +1432,11 @@ msgstr "Jährlich, nach Datum"
msgid "Yearly by day" msgid "Yearly by day"
msgstr "Jährlich, nach Wochentag" msgstr "Jährlich, nach Wochentag"
#: vpsr.rsyearlyon
#, object-pascal-format
msgid "Yearly on %s"
msgstr "Jährlich am %s"
#: vpsr.rsyears #: vpsr.rsyears
msgid "Years" msgid "Years"
msgstr "Jahre" msgstr "Jahre"
@ -1413,7 +1465,7 @@ msgstr "Attribut %s von Element %s hat keinen ganzzahligen Wert."
#: vpsr.sbadparamentnesting #: vpsr.sbadparamentnesting
msgid "Parameter-entity text must be properly nested: " msgid "Parameter-entity text must be properly nested: "
msgstr "Parameter-Entity muss richtig eingebettet sein:" msgstr "Parameter-Entity muss richtig eingebettet sein: "
#: vpsr.sbadsepinmodel #: vpsr.sbadsepinmodel
msgid "Bad separator in content model: " msgid "Bad separator in content model: "

View File

@ -9,7 +9,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.1\n" "X-Generator: Poedit 3.1.1\n"
#: vpsr.rs1day #: vpsr.rs1day
msgid "1 day" msgid "1 day"
@ -47,6 +47,11 @@ msgstr "Fri"
msgid "Age:" msgid "Age:"
msgstr "Age:" msgstr "Age:"
#: vpsr.rsalarmin
#, object-pascal-format
msgid "Alarm in %s"
msgstr "Alarm in %s"
#: vpsr.rsalarmset #: vpsr.rsalarmset
msgid "&Reminder" msgid "&Reminder"
msgstr "&Reminder" msgstr "&Reminder"
@ -449,6 +454,26 @@ msgctxt "vpsr.rsevent"
msgid "Event" msgid "Event"
msgstr "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 #: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event." msgid "Conflicts with another exclusive event."
msgstr "Conflicts with another exclusive event." msgstr "Conflicts with another exclusive event."
@ -669,6 +694,11 @@ msgstr "Monthly by date"
msgid "Monthly by day" msgid "Monthly by day"
msgstr "Monthly by day" msgstr "Monthly by day"
#: vpsr.rsmonthlyon
#, object-pascal-format
msgid "Monthly on day %s"
msgstr ""
#: vpsr.rsmonths #: vpsr.rsmonths
msgid "Months" msgid "Months"
msgstr "Months" msgstr "Months"
@ -721,6 +751,10 @@ msgstr "Next year"
msgid "N" msgid "N"
msgstr "N" msgstr "N"
#: vpsr.rsnoalarm
msgid "No alarm"
msgstr "No alarm"
#: vpsr.rsnocanvas #: vpsr.rsnocanvas
msgid "TCanvas not assigned" msgid "TCanvas not assigned"
msgstr "TCanvas not assigned" msgstr "TCanvas not assigned"
@ -1074,6 +1108,10 @@ msgstr "Appointment recurrence:"
msgid "Reminder" msgid "Reminder"
msgstr "Reminder" msgstr "Reminder"
#: vpsr.rsrepeat
msgid "Repeat:"
msgstr "Repeat:"
#: vpsr.rsreportsetup #: vpsr.rsreportsetup
msgid "Report setup" msgid "Report setup"
msgstr "Report setup" msgstr "Report setup"
@ -1141,6 +1179,10 @@ msgstr "&Snooze"
msgid "Click &Snooze to be reminded again in:" msgid "Click &Snooze to be reminded again in:"
msgstr "Click &Snooze to be reminded again in:" msgstr "Click &Snooze to be reminded again in:"
#: vpsr.rssound
msgid "Sound"
msgstr "Sound"
#: vpsr.rssoundfinder #: vpsr.rssoundfinder
msgid "Sound Finder" msgid "Sound Finder"
msgstr "Sound Finder" msgstr "Sound Finder"
@ -1310,6 +1352,11 @@ msgstr "Wednesday"
msgid "Weekly" msgid "Weekly"
msgstr "Weekly" msgstr "Weekly"
#: vpsr.rsweeklyon
#, object-pascal-format
msgid "Weekly on %s"
msgstr "Weekly on %s"
#: vpsr.rsweeks #: vpsr.rsweeks
msgid "Weeks" msgid "Weeks"
msgstr "Weeks" msgstr "Weeks"
@ -1367,6 +1414,11 @@ msgstr "Yearly by date"
msgid "Yearly by day" msgid "Yearly by day"
msgstr "Yearly by day" msgstr "Yearly by day"
#: vpsr.rsyearlyon
#, object-pascal-format
msgid "Yearly on %s"
msgstr "Yearly on %s"
#: vpsr.rsyears #: vpsr.rsyears
msgid "Years" msgid "Years"
msgstr "Years" msgstr "Years"

View File

@ -37,6 +37,11 @@ msgstr "Pe"
msgid "Age:" msgid "Age:"
msgstr "Ikä:" msgstr "Ikä:"
#: vpsr.rsalarmin
#, object-pascal-format
msgid "Alarm in %s"
msgstr ""
#: vpsr.rsalarmset #: vpsr.rsalarmset
msgid "&Reminder" msgid "&Reminder"
msgstr "" msgstr ""
@ -445,6 +450,26 @@ msgctxt "vpsr.rsevent"
msgid "Event" msgid "Event"
msgstr "" 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 #: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event." msgid "Conflicts with another exclusive event."
msgstr "" msgstr ""
@ -666,6 +691,11 @@ msgstr ""
msgid "Monthly by day" msgid "Monthly by day"
msgstr "" msgstr ""
#: vpsr.rsmonthlyon
#, object-pascal-format
msgid "Monthly on day %s"
msgstr ""
#: vpsr.rsmonths #: vpsr.rsmonths
msgid "Months" msgid "Months"
msgstr "Kuukaudet" msgstr "Kuukaudet"
@ -720,6 +750,10 @@ msgstr "Seuraava vuosi"
msgid "N" msgid "N"
msgstr "" msgstr ""
#: vpsr.rsnoalarm
msgid "No alarm"
msgstr ""
#: vpsr.rsnocanvas #: vpsr.rsnocanvas
msgid "TCanvas not assigned" msgid "TCanvas not assigned"
msgstr "" msgstr ""
@ -1079,6 +1113,10 @@ msgstr ""
msgid "Reminder" msgid "Reminder"
msgstr "" msgstr ""
#: vpsr.rsrepeat
msgid "Repeat:"
msgstr ""
#: vpsr.rsreportsetup #: vpsr.rsreportsetup
msgid "Report setup" msgid "Report setup"
msgstr "" msgstr ""
@ -1146,6 +1184,10 @@ msgstr ""
msgid "Click &Snooze to be reminded again in:" msgid "Click &Snooze to be reminded again in:"
msgstr "" msgstr ""
#: vpsr.rssound
msgid "Sound"
msgstr ""
#: vpsr.rssoundfinder #: vpsr.rssoundfinder
msgid "Sound Finder" msgid "Sound Finder"
msgstr "" msgstr ""
@ -1320,6 +1362,11 @@ msgstr "Keskiviikko"
msgid "Weekly" msgid "Weekly"
msgstr "" msgstr ""
#: vpsr.rsweeklyon
#, object-pascal-format
msgid "Weekly on %s"
msgstr ""
#: vpsr.rsweeks #: vpsr.rsweeks
msgid "Weeks" msgid "Weeks"
msgstr "" msgstr ""
@ -1377,6 +1424,11 @@ msgstr ""
msgid "Yearly by day" msgid "Yearly by day"
msgstr "" msgstr ""
#: vpsr.rsyearlyon
#, object-pascal-format
msgid "Yearly on %s"
msgstr ""
#: vpsr.rsyears #: vpsr.rsyears
msgid "Years" msgid "Years"
msgstr "" msgstr ""

View File

@ -53,6 +53,11 @@ msgstr "Ven"
msgid "Age:" msgid "Age:"
msgstr "" msgstr ""
#: vpsr.rsalarmin
#, object-pascal-format
msgid "Alarm in %s"
msgstr ""
#: vpsr.rsalarmset #: vpsr.rsalarmset
msgid "&Reminder" msgid "&Reminder"
msgstr "&Rappel" msgstr "&Rappel"
@ -461,6 +466,26 @@ msgctxt "vpsr.rsevent"
msgid "Event" msgid "Event"
msgstr "Événement" 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 #: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event." msgid "Conflicts with another exclusive event."
msgstr "Cette événement est en conflit avec une autre événement exclusif" 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" msgid "Monthly by day"
msgstr "Mensuel par jour" msgstr "Mensuel par jour"
#: vpsr.rsmonthlyon
#, object-pascal-format
msgid "Monthly on day %s"
msgstr ""
#: vpsr.rsmonths #: vpsr.rsmonths
msgid "Months" msgid "Months"
msgstr "" msgstr ""
@ -735,6 +765,10 @@ msgstr ""
msgid "N" msgid "N"
msgstr "" msgstr ""
#: vpsr.rsnoalarm
msgid "No alarm"
msgstr ""
#: vpsr.rsnocanvas #: vpsr.rsnocanvas
msgid "TCanvas not assigned" msgid "TCanvas not assigned"
msgstr "TCanvas non spécifié" msgstr "TCanvas non spécifié"
@ -1094,6 +1128,10 @@ msgstr "Rendevous à répéter:"
msgid "Reminder" msgid "Reminder"
msgstr "Rappel" msgstr "Rappel"
#: vpsr.rsrepeat
msgid "Repeat:"
msgstr ""
#: vpsr.rsreportsetup #: vpsr.rsreportsetup
msgid "Report setup" msgid "Report setup"
msgstr "" msgstr ""
@ -1161,6 +1199,10 @@ msgstr "&Sieste"
msgid "Click &Snooze to be reminded again in:" msgid "Click &Snooze to be reminded again in:"
msgstr "Click &Sieste pour être rappelé à nouveau dans :" msgstr "Click &Sieste pour être rappelé à nouveau dans :"
#: vpsr.rssound
msgid "Sound"
msgstr ""
#: vpsr.rssoundfinder #: vpsr.rssoundfinder
msgid "Sound Finder" msgid "Sound Finder"
msgstr "Trouver le son" msgstr "Trouver le son"
@ -1336,6 +1378,11 @@ msgstr "Mercredi"
msgid "Weekly" msgid "Weekly"
msgstr "Hebdomadaire" msgstr "Hebdomadaire"
#: vpsr.rsweeklyon
#, object-pascal-format
msgid "Weekly on %s"
msgstr ""
#: vpsr.rsweeks #: vpsr.rsweeks
msgid "Weeks" msgid "Weeks"
msgstr "" msgstr ""
@ -1393,6 +1440,11 @@ msgstr "Annuel par date"
msgid "Yearly by day" msgid "Yearly by day"
msgstr "Annuel par jour" msgstr "Annuel par jour"
#: vpsr.rsyearlyon
#, object-pascal-format
msgid "Yearly on %s"
msgstr ""
#: vpsr.rsyears #: vpsr.rsyears
msgid "Years" msgid "Years"
msgstr "" msgstr ""

View File

@ -47,6 +47,11 @@ msgstr "Vr"
msgid "Age:" msgid "Age:"
msgstr "" msgstr ""
#: vpsr.rsalarmin
#, object-pascal-format
msgid "Alarm in %s"
msgstr ""
#: vpsr.rsalarmset #: vpsr.rsalarmset
msgid "&Reminder" msgid "&Reminder"
msgstr "He&rinnering" msgstr "He&rinnering"
@ -455,6 +460,26 @@ msgctxt "vpsr.rsevent"
msgid "Event" msgid "Event"
msgstr "Gebeurtenis" 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 #: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event." msgid "Conflicts with another exclusive event."
msgstr "Conflict met een andere gebeurtenis." msgstr "Conflict met een andere gebeurtenis."
@ -675,6 +700,11 @@ msgstr "Maandelijks, op Datum"
msgid "Monthly by day" msgid "Monthly by day"
msgstr "Maandelijks, op Dag" msgstr "Maandelijks, op Dag"
#: vpsr.rsmonthlyon
#, object-pascal-format
msgid "Monthly on day %s"
msgstr ""
#: vpsr.rsmonths #: vpsr.rsmonths
msgid "Months" msgid "Months"
msgstr "" msgstr ""
@ -729,6 +759,10 @@ msgstr ""
msgid "N" msgid "N"
msgstr "N" msgstr "N"
#: vpsr.rsnoalarm
msgid "No alarm"
msgstr ""
#: vpsr.rsnocanvas #: vpsr.rsnocanvas
msgid "TCanvas not assigned" msgid "TCanvas not assigned"
msgstr "TCanvas is niet toegewezen." msgstr "TCanvas is niet toegewezen."
@ -1088,6 +1122,10 @@ msgstr "Afspraak herhaling:"
msgid "Reminder" msgid "Reminder"
msgstr "Herinnering" msgstr "Herinnering"
#: vpsr.rsrepeat
msgid "Repeat:"
msgstr ""
#: vpsr.rsreportsetup #: vpsr.rsreportsetup
msgid "Report setup" msgid "Report setup"
msgstr "" msgstr ""
@ -1155,6 +1193,10 @@ msgstr "&Uitstellen"
msgid "Click &Snooze to be reminded again in:" msgid "Click &Snooze to be reminded again in:"
msgstr "Klik op \"Uitstellen\" om nogmaals herinnerd te worden in:" msgstr "Klik op \"Uitstellen\" om nogmaals herinnerd te worden in:"
#: vpsr.rssound
msgid "Sound"
msgstr ""
#: vpsr.rssoundfinder #: vpsr.rssoundfinder
msgid "Sound Finder" msgid "Sound Finder"
msgstr "Geluid Zoeker" msgstr "Geluid Zoeker"
@ -1330,6 +1372,11 @@ msgstr "Woensdag"
msgid "Weekly" msgid "Weekly"
msgstr "Wekelijks" msgstr "Wekelijks"
#: vpsr.rsweeklyon
#, object-pascal-format
msgid "Weekly on %s"
msgstr ""
#: vpsr.rsweeks #: vpsr.rsweeks
msgid "Weeks" msgid "Weeks"
msgstr "" msgstr ""
@ -1387,6 +1434,11 @@ msgstr "Jaarlijks, op Datum"
msgid "Yearly by day" msgid "Yearly by day"
msgstr "Jaarlijks, op dag" msgstr "Jaarlijks, op dag"
#: vpsr.rsyearlyon
#, object-pascal-format
msgid "Yearly on %s"
msgstr ""
#: vpsr.rsyears #: vpsr.rsyears
msgid "Years" msgid "Years"
msgstr "" msgstr ""

View File

@ -47,6 +47,11 @@ msgstr "Pią"
msgid "Age:" msgid "Age:"
msgstr "Wiek:" msgstr "Wiek:"
#: vpsr.rsalarmin
#, object-pascal-format
msgid "Alarm in %s"
msgstr ""
#: vpsr.rsalarmset #: vpsr.rsalarmset
msgid "&Reminder" msgid "&Reminder"
msgstr "&Przypomnienie" msgstr "&Przypomnienie"
@ -455,6 +460,26 @@ msgctxt "vpsr.rsevent"
msgid "Event" msgid "Event"
msgstr "Wydarzenie" 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 #: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event." msgid "Conflicts with another exclusive event."
msgstr "Konflikt z innym wydarzeniem wyłącznym." msgstr "Konflikt z innym wydarzeniem wyłącznym."
@ -675,6 +700,11 @@ msgstr "Mieś. wg daty"
msgid "Monthly by day" msgid "Monthly by day"
msgstr "Mieś. wg dnia" msgstr "Mieś. wg dnia"
#: vpsr.rsmonthlyon
#, object-pascal-format
msgid "Monthly on day %s"
msgstr ""
#: vpsr.rsmonths #: vpsr.rsmonths
msgid "Months" msgid "Months"
msgstr "Miesiąc" msgstr "Miesiąc"
@ -729,6 +759,10 @@ msgstr "Następny rok"
msgid "N" msgid "N"
msgstr "N" msgstr "N"
#: vpsr.rsnoalarm
msgid "No alarm"
msgstr ""
#: vpsr.rsnocanvas #: vpsr.rsnocanvas
msgid "TCanvas not assigned" msgid "TCanvas not assigned"
msgstr "TCanvas nie został przypisany." msgstr "TCanvas nie został przypisany."
@ -1087,6 +1121,10 @@ msgstr "Częstotliwość:"
msgid "Reminder" msgid "Reminder"
msgstr "Przypomnienie" msgstr "Przypomnienie"
#: vpsr.rsrepeat
msgid "Repeat:"
msgstr ""
#: vpsr.rsreportsetup #: vpsr.rsreportsetup
msgid "Report setup" msgid "Report setup"
msgstr "Ustawienia Raportu" msgstr "Ustawienia Raportu"
@ -1154,6 +1192,10 @@ msgstr "&Drzemka"
msgid "Click &Snooze to be reminded again in:" msgid "Click &Snooze to be reminded again in:"
msgstr "Naciśnij \"&Drzemka aby uaktywnić ponownie..." msgstr "Naciśnij \"&Drzemka aby uaktywnić ponownie..."
#: vpsr.rssound
msgid "Sound"
msgstr ""
#: vpsr.rssoundfinder #: vpsr.rssoundfinder
msgid "Sound Finder" msgid "Sound Finder"
msgstr "Wyszukanie dźwięku" msgstr "Wyszukanie dźwięku"
@ -1328,6 +1370,11 @@ msgstr "Środa"
msgid "Weekly" msgid "Weekly"
msgstr "Tygodniowo" msgstr "Tygodniowo"
#: vpsr.rsweeklyon
#, object-pascal-format
msgid "Weekly on %s"
msgstr ""
#: vpsr.rsweeks #: vpsr.rsweeks
msgid "Weeks" msgid "Weeks"
msgstr "Tygodnie" msgstr "Tygodnie"
@ -1385,6 +1432,11 @@ msgstr "Rocz. wg daty"
msgid "Yearly by day" msgid "Yearly by day"
msgstr "Rocz. wg dnia" msgstr "Rocz. wg dnia"
#: vpsr.rsyearlyon
#, object-pascal-format
msgid "Yearly on %s"
msgstr ""
#: vpsr.rsyears #: vpsr.rsyears
msgid "Years" msgid "Years"
msgstr "Lata" msgstr "Lata"

View File

@ -37,6 +37,11 @@ msgstr ""
msgid "Age:" msgid "Age:"
msgstr "" msgstr ""
#: vpsr.rsalarmin
#, object-pascal-format
msgid "Alarm in %s"
msgstr ""
#: vpsr.rsalarmset #: vpsr.rsalarmset
msgid "&Reminder" msgid "&Reminder"
msgstr "" msgstr ""
@ -439,6 +444,26 @@ msgctxt "vpsr.rsevent"
msgid "Event" msgid "Event"
msgstr "" 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 #: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event." msgid "Conflicts with another exclusive event."
msgstr "" msgstr ""
@ -659,6 +684,11 @@ msgstr ""
msgid "Monthly by day" msgid "Monthly by day"
msgstr "" msgstr ""
#: vpsr.rsmonthlyon
#, object-pascal-format
msgid "Monthly on day %s"
msgstr ""
#: vpsr.rsmonths #: vpsr.rsmonths
msgid "Months" msgid "Months"
msgstr "" msgstr ""
@ -711,6 +741,10 @@ msgstr ""
msgid "N" msgid "N"
msgstr "" msgstr ""
#: vpsr.rsnoalarm
msgid "No alarm"
msgstr ""
#: vpsr.rsnocanvas #: vpsr.rsnocanvas
msgid "TCanvas not assigned" msgid "TCanvas not assigned"
msgstr "" msgstr ""
@ -1064,6 +1098,10 @@ msgstr ""
msgid "Reminder" msgid "Reminder"
msgstr "" msgstr ""
#: vpsr.rsrepeat
msgid "Repeat:"
msgstr ""
#: vpsr.rsreportsetup #: vpsr.rsreportsetup
msgid "Report setup" msgid "Report setup"
msgstr "" msgstr ""
@ -1131,6 +1169,10 @@ msgstr ""
msgid "Click &Snooze to be reminded again in:" msgid "Click &Snooze to be reminded again in:"
msgstr "" msgstr ""
#: vpsr.rssound
msgid "Sound"
msgstr ""
#: vpsr.rssoundfinder #: vpsr.rssoundfinder
msgid "Sound Finder" msgid "Sound Finder"
msgstr "" msgstr ""
@ -1300,6 +1342,11 @@ msgstr ""
msgid "Weekly" msgid "Weekly"
msgstr "" msgstr ""
#: vpsr.rsweeklyon
#, object-pascal-format
msgid "Weekly on %s"
msgstr ""
#: vpsr.rsweeks #: vpsr.rsweeks
msgid "Weeks" msgid "Weeks"
msgstr "" msgstr ""
@ -1357,6 +1404,11 @@ msgstr ""
msgid "Yearly by day" msgid "Yearly by day"
msgstr "" msgstr ""
#: vpsr.rsyearlyon
#, object-pascal-format
msgid "Yearly on %s"
msgstr ""
#: vpsr.rsyears #: vpsr.rsyears
msgid "Years" msgid "Years"
msgstr "" msgstr ""

View File

@ -47,6 +47,11 @@ msgstr "Пт."
msgid "Age:" msgid "Age:"
msgstr "" msgstr ""
#: vpsr.rsalarmin
#, object-pascal-format
msgid "Alarm in %s"
msgstr ""
#: vpsr.rsalarmset #: vpsr.rsalarmset
msgid "&Reminder" msgid "&Reminder"
msgstr "Напоминание" msgstr "Напоминание"
@ -455,6 +460,26 @@ msgctxt "vpsr.rsevent"
msgid "Event" msgid "Event"
msgstr "Событие" 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 #: vpsr.rsexclusiveeventconflict
msgid "Conflicts with another exclusive event." msgid "Conflicts with another exclusive event."
msgstr "Конфликт с другим важным событием." msgstr "Конфликт с другим важным событием."
@ -675,6 +700,11 @@ msgstr "Ежемесячно"
msgid "Monthly by day" msgid "Monthly by day"
msgstr "Ежемесячную" msgstr "Ежемесячную"
#: vpsr.rsmonthlyon
#, object-pascal-format
msgid "Monthly on day %s"
msgstr ""
#: vpsr.rsmonths #: vpsr.rsmonths
msgid "Months" msgid "Months"
msgstr "Месяц" msgstr "Месяц"
@ -729,6 +759,10 @@ msgstr ""
msgid "N" msgid "N"
msgstr "" msgstr ""
#: vpsr.rsnoalarm
msgid "No alarm"
msgstr ""
#: vpsr.rsnocanvas #: vpsr.rsnocanvas
msgid "TCanvas not assigned" msgid "TCanvas not assigned"
msgstr "" msgstr ""
@ -1088,6 +1122,10 @@ msgstr "Повторение встречи:"
msgid "Reminder" msgid "Reminder"
msgstr "Напоминание" msgstr "Напоминание"
#: vpsr.rsrepeat
msgid "Repeat:"
msgstr ""
#: vpsr.rsreportsetup #: vpsr.rsreportsetup
msgid "Report setup" msgid "Report setup"
msgstr "" msgstr ""
@ -1155,6 +1193,10 @@ msgstr ""
msgid "Click &Snooze to be reminded again in:" msgid "Click &Snooze to be reminded again in:"
msgstr "" msgstr ""
#: vpsr.rssound
msgid "Sound"
msgstr ""
#: vpsr.rssoundfinder #: vpsr.rssoundfinder
msgid "Sound Finder" msgid "Sound Finder"
msgstr "" msgstr ""
@ -1328,6 +1370,11 @@ msgstr "Среда"
msgid "Weekly" msgid "Weekly"
msgstr "Еженедельно" msgstr "Еженедельно"
#: vpsr.rsweeklyon
#, object-pascal-format
msgid "Weekly on %s"
msgstr ""
#: vpsr.rsweeks #: vpsr.rsweeks
msgid "Weeks" msgid "Weeks"
msgstr "" msgstr ""
@ -1385,6 +1432,11 @@ msgstr "Ежегодно по дате"
msgid "Yearly by day" msgid "Yearly by day"
msgstr "Ежегодно по дню" msgstr "Ежегодно по дню"
#: vpsr.rsyearlyon
#, object-pascal-format
msgid "Yearly on %s"
msgstr ""
#: vpsr.rsyears #: vpsr.rsyears
msgid "Years" msgid "Years"
msgstr "" msgstr ""

View File

@ -32,7 +32,7 @@ Portions created by TurboPower Software Inc. are Copyright (C) 2002 TurboPower S
Contributor(s): "/> Contributor(s): "/>
<Version Major="1" Minor="7"/> <Version Major="1" Minor="7"/>
<Files Count="62"> <Files Count="63">
<Item1> <Item1>
<Filename Value="source\vpbase.pas"/> <Filename Value="source\vpbase.pas"/>
<UnitName Value="VpBase"/> <UnitName Value="VpBase"/>
@ -281,6 +281,10 @@ Contributor(s): "/>
<Filename Value="source\vpfileds.pas"/> <Filename Value="source\vpfileds.pas"/>
<UnitName Value="VpFileDS"/> <UnitName Value="VpFileDS"/>
</Item62> </Item62>
<Item63>
<Filename Value="source\vpicalpreview.pas"/>
<UnitName Value="VpIcalPreview"/>
</Item63>
</Files> </Files>
<CompatibilityMode Value="True"/> <CompatibilityMode Value="True"/>
<i18n> <i18n>

View File

@ -182,6 +182,7 @@ resourcestring
RSOverlayedEvent = 'overlayed'; RSOverlayedEvent = 'overlayed';
RSOverlayed = 'Overlayed'; RSOverlayed = 'Overlayed';
RSICalFilter = 'iCalendar files (*.ical;*.ics)|*.ical;*.ics'; RSICalFilter = 'iCalendar files (*.ical;*.ics)|*.ical;*.ics';
RSRepeat = 'Repeat:';
{Task Specific} {Task Specific}
RSConfirmDeleteTask = 'Delete this task from your list?'; RSConfirmDeleteTask = 'Delete this task from your list?';
@ -321,6 +322,16 @@ resourcestring
RS1Day = '1 day'; RS1Day = '1 day';
RSXDays = '%d days'; RSXDays = '%d days';
RS1Week = '1 week'; 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 } { Calendar }
RSCalendarRevert = 'Revert'; RSCalendarRevert = 'Revert';

View File

@ -247,6 +247,7 @@ type
function GetColor(AIndex: Integer): TColor; function GetColor(AIndex: Integer): TColor;
function GetName(AIndex: Integer):string; function GetName(AIndex: Integer):string;
function GetCategory(AIndex: Integer): TVpCategoryInfo; function GetCategory(AIndex: Integer): TVpCategoryInfo;
function GetCategoryName(AIndex: Integer): String;
function IndexOfCategory(AName: String): Integer; function IndexOfCategory(AName: String): Integer;
function IndexOfFirstUnusedCategory: Integer; function IndexOfFirstUnusedCategory: Integer;
procedure SetCategoryName(AIndex: Integer; AName: String); procedure SetCategoryName(AIndex: Integer; AName: String);
@ -741,6 +742,11 @@ begin
Result := FCat[AIndex]; Result := FCat[AIndex];
end; end;
function TVpCategoryColorMap.GetCategoryName(AIndex: Integer): string;
begin
Result := FCat[AIndex].Description;
end;
function TVpCategoryColorMap.IndexOfCategory(AName: String): Integer; function TVpCategoryColorMap.IndexOfCategory(AName: String): Integer;
var var
i: Integer; i: Integer;

View File

@ -313,6 +313,8 @@ type
procedure DeleteResource(Res: TVpResource); procedure DeleteResource(Res: TVpResource);
function FindResource(const AResourceName: String): TVpResource; function FindResource(const AResourceName: String): TVpResource;
function FindBestCategory(const ACategoryNames: TStrings): String;
property Connected : boolean read FConnected write SetConnected; property Connected : boolean read FConnected write SetConnected;
property Loading : Boolean read FLoading write FLoading; property Loading : Boolean read FLoading write FLoading;
property Resource: TVpResource read FResource write SetResource; property Resource: TVpResource read FResource write SetResource;
@ -543,7 +545,24 @@ begin
Result := FResources.FindResourceByName(AResourceName); Result := FResources.FindResourceByName(AResourceName);
end; 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; procedure TVpCustomDataStore.DeregisterAllWatchers;
var var

View File

@ -37,7 +37,7 @@ interface
uses uses
LCLProc, LCLType, LCLProc, LCLType,
SysUtils, Classes, Dialogs, Graphics, SysUtils, Classes, Dialogs, Graphics, Forms,
VpSR, VpVCard, VpICal; VpSR, VpVCard, VpICal;
type type
@ -241,7 +241,8 @@ type
function EventCountByDay(Value: TDateTime): Integer; function EventCountByDay(Value: TDateTime): Integer;
procedure EventsByDate(Date: TDateTime; EventList: TList); procedure EventsByDate(Date: TDateTime; EventList: TList);
function GetEvent(Index: Integer): TVpEvent; 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; function RepeatsOn(Event: TVpEvent; Day: TDateTime): Boolean;
procedure Sort; procedure Sort;
property Owner: TVpResource read FOwner; property Owner: TVpResource read FOwner;
@ -311,8 +312,11 @@ type
function CanEdit: Boolean; function CanEdit: Boolean;
function CopyToSchedule(ASchedule: TVpSchedule): TVpEvent; function CopyToSchedule(ASchedule: TVpSchedule): TVpEvent;
function GetResource: TVpResource; function GetResource: TVpResource;
class function IsAllDayEvent(AStartTime, AEndTime: TDateTime): Boolean;
function IsOverlayed: Boolean; function IsOverlayed: Boolean;
procedure LoadFromICalendar(AEntry: TVpICalEvent); procedure LoadFromICalendar(AEntry: TVpICalEvent);
class procedure GetAlarmParams(ATrigger: TDateTime; out AdvTime: Integer;
out AdvTimeUnits: TVpAlarmAdvType);
property Owner: TVpSchedule read FOwner; property Owner: TVpSchedule read FOwner;
property ResourceID: Integer read FResourceID write FResourceID; property ResourceID: Integer read FResourceID write FResourceID;
property Loading : Boolean read FLoading write FLoading; property Loading : Boolean read FLoading write FLoading;
@ -705,7 +709,7 @@ implementation
uses uses
Math, DateUtils, Math, DateUtils,
VpException, VpConst, VpMisc, VpBaseDS; VpException, VpConst, VpMisc, VpBaseDS, VpICalPreview;
const const
TIME_EPS = 1.0 / SecondsInDay; // Epsilon for comparing times TIME_EPS = 1.0 / SecondsInDay; // Epsilon for comparing times
@ -1333,6 +1337,13 @@ begin
Result := FOwner.Owner; Result := FOwner.Owner;
end; 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 { The event is overlayed if its ResourceID is different from that of the
resource to which it belongs. } resource to which it belongs. }
function TVpEvent.IsOverlayed: Boolean; function TVpEvent.IsOverlayed: Boolean;
@ -1352,9 +1363,27 @@ begin
Result := abs(d - round(d)) < Epsilon; Result := abs(d - round(d)) < Epsilon;
end; 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); procedure TVpEvent.LoadFromICalendar(AEntry: TVpICalEvent);
var var
dt: Double;
cat: String; cat: String;
i, j, k: Integer; i, j, k: Integer;
datastore: TVpCustomDatastore; datastore: TVpCustomDatastore;
@ -1392,23 +1421,12 @@ begin
end; end;
{ All-day event } { All-day event }
FAllDayEvent := (frac(FStartTime) = 0) and (frac(FEndTime) = 0); FAllDayEvent := TVpEvent.IsAllDayEvent(FStartTime, FEndTime);
{ Alarm properties } { Alarm properties }
if AEntry.Alarm <> nil then begin if AEntry.Alarm <> nil then begin
FAlarmSet := true; FAlarmSet := true;
dt := abs(AEntry.Alarm.Trigger); GetAlarmParams(AEntry.Alarm.Trigger, FAlarmAdv, FAlarmAdvType);
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;
FDingPath := AEntry.Alarm.AudioSrc; FDingPath := AEntry.Alarm.AudioSrc;
if not FileExists(FDingPath) then FDingPath := ''; if not FileExists(FDingPath) then FDingPath := '';
end else end else
@ -1723,7 +1741,7 @@ begin
end; end;
function TVpSchedule.ImportICalFile(const AFileName: String; function TVpSchedule.ImportICalFile(const AFileName: String;
ADefaultCategory: Integer = -1): TVpEventArr; APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpEventArr;
const const
BLOCK_SIZE = 10; BLOCK_SIZE = 10;
var var
@ -1734,18 +1752,31 @@ var
event: TVpEvent; event: TVpEvent;
eventCounter: Integer; eventCounter: Integer;
datastore: TVpCustomDatastore; datastore: TVpCustomDatastore;
previewForm: TVpIcalPreviewForm = nil;
begin begin
Result := nil; Result := nil;
SetLength(Result, BLOCK_SIZE); SetLength(Result, BLOCK_SIZE);
eventCounter := 0;
datastore := Owner.Owner.Owner as TVpCustomDatastore; datastore := Owner.Owner.Owner as TVpCustomDatastore;
eventCounter := 0;
ical := TVpICalendar.Create; ical := TVpICalendar.Create;
try try
ical.LoadFromFile(AFileName); 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 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; Continue;
startTime := TVpICalEvent(ical[i]).StartTime[false]; // use local times startTime := TVpICalEvent(ical[i]).StartTime[false]; // use local times
endTime := TVpICalEvent(ical[i]).EndTime[false]; endTime := TVpICalEvent(ical[i]).EndTime[false];
@ -1762,8 +1793,10 @@ begin
if eventCounter mod BLOCK_SIZE = 0 then if eventCounter mod BLOCK_SIZE = 0 then
SetLength(Result, eventCounter + BLOCK_SIZE); SetLength(Result, eventCounter + BLOCK_SIZE);
end; end;
SetLength(Result, eventCounter);
finally finally
SetLength(Result, eventCounter);
if APreview then
previewForm.Free;
ical.Free; ical.Free;
end; end;
end; end;

View File

@ -447,7 +447,8 @@ type
function BuildEventString(AEvent: TVpEvent; UseAsHint: Boolean): String; function BuildEventString(AEvent: TVpEvent; UseAsHint: Boolean): String;
procedure DeleteActiveEvent(Verify: Boolean); procedure DeleteActiveEvent(Verify: Boolean);
procedure DragDrop(Source: TObject; X, Y: Integer); override; 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; procedure Invalidate; override;
function IsHoliday(ADate: TDate; out AHolidayName: String): Boolean; function IsHoliday(ADate: TDate; out AHolidayName: String): Boolean;
procedure LoadLanguage; procedure LoadLanguage;
@ -1354,7 +1355,7 @@ begin
try try
Application.ProcessMessages; Application.ProcessMessages;
for fn in dlg.Files do for fn in dlg.Files do
ImportICalFile(fn); ImportICalFile(fn, dlg.Files.Count = 1);
finally finally
Screen.Cursor := crDefault; Screen.Cursor := crDefault;
end; end;
@ -2381,25 +2382,20 @@ end;
If you are not happy with this category replacement you can iterate over the If you are not happy with this category replacement you can iterate over the
Result array and change it. } Result array and change it. }
function TVpDayView.ImportICalFile(const AFileName: String; function TVpDayView.ImportICalFile(const AFileName: String;
ADefaultCategory: Integer = -1): TVpEventArr; APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpEventArr;
begin begin
if ReadOnly or (not CheckCreateResource) or if ReadOnly or (not CheckCreateResource) or
(not Assigned(DataStore)) or (not Assigned(DataStore.Resource)) (not Assigned(DataStore)) or (not Assigned(DataStore.Resource))
then then
Exit; Exit(nil);
Screen.Cursor := crHourglass; Result := Datastore.Resource.Schedule.ImportICalFile(AFileName, APreview, ADefaultCategory);
try if Length(Result) > 0 then
Result := Datastore.Resource.Schedule.ImportICalFile(AFileName, ADefaultCategory); begin
if Length(Result) > 0 then FActiveEvent := Result[High(Result)];
begin Datastore.PostEvents;
FActiveEvent := Result[High(Result)]; Datastore.NotifyDependents;
Datastore.PostEvents; Invalidate;
Datastore.NotifyDependents;
Invalidate;
end;
finally
Screen.Cursor := crDefault;
end; end;
end; end;

View File

@ -18,9 +18,11 @@ type
TVpICalEntry = class(TVpFileBlock) TVpICalEntry = class(TVpFileBlock)
private private
FCalendar: TVpICalendar; FCalendar: TVpICalendar;
FSkip: Boolean;
public public
constructor Create(ACalendar: TVpICalendar); virtual; constructor Create(ACalendar: TVpICalendar); virtual;
function FindItem(AKey: String): TVpICalItem; function FindItem(AKey: String): TVpICalItem;
property Skip: Boolean read FSkip write FSkip default false;
end; end;
TVpICalTimeZoneInfo = class(TVpICalEntry) TVpICalTimeZoneInfo = class(TVpICalEntry)
@ -73,6 +75,7 @@ type
constructor Create(ACalendar: TVpICalendar); override; constructor Create(ACalendar: TVpICalendar); override;
destructor Destroy; override; destructor Destroy; override;
procedure Analyze; override; procedure Analyze; override;
function Categories: TStrings;
procedure UseAlarm; procedure UseAlarm;
property Summary: String read FSummary; // is "Description" of tvp property Summary: String read FSummary; // is "Description" of tvp
property Description: String read FDescription; // is "Notes" of tvp property Description: String read FDescription; // is "Notes" of tvp
@ -389,6 +392,11 @@ begin
end; end;
end; end;
function TVpICalEvent.Categories: TStrings;
begin
Result := FCategories;
end;
function TVpICalEvent.GetCategory(AIndex: Integer): String; function TVpICalEvent.GetCategory(AIndex: Integer): String;
begin begin
if (AIndex >= 0) and (AIndex < FCategories.Count) then if (AIndex >= 0) and (AIndex < FCategories.Count) then

View File

@ -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.

View File

@ -272,7 +272,8 @@ type
procedure LoadLanguage; procedure LoadLanguage;
procedure DeleteActiveEvent(Verify: Boolean); procedure DeleteActiveEvent(Verify: Boolean);
procedure DragDrop(Source: TObject; X, Y: Integer); override; 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; procedure Invalidate; override;
function IsHoliday(ADate: TDate; out AHolidayName: String): Boolean; function IsHoliday(ADate: TDate; out AHolidayName: String): Boolean;
procedure LinkHandler(Sender: TComponent; procedure LinkHandler(Sender: TComponent;
@ -1092,25 +1093,20 @@ end;
If you are not happy with this category replacement you can iterate over the If you are not happy with this category replacement you can iterate over the
Result array and change it. } Result array and change it. }
function TVpWeekView.ImportICalFile(const AFileName: String; function TVpWeekView.ImportICalFile(const AFileName: String;
ADefaultCategory: Integer = -1): TVpEventArr; APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpEventArr;
begin begin
if ReadOnly or (not CheckCreateResource) or if ReadOnly or (not CheckCreateResource) or
(not Assigned(DataStore)) or (not Assigned(DataStore.Resource)) (not Assigned(DataStore)) or (not Assigned(DataStore.Resource))
then then
Exit; Exit(nil);
Screen.Cursor := crHourglass; Result := Datastore.Resource.Schedule.ImportICalFile(AFileName, APreview, ADefaultCategory);
try if Length(Result) > 0 then
Result := Datastore.Resource.Schedule.ImportICalFile(AFileName, ADefaultCategory); begin
if Length(Result) > 0 then FActiveEvent := Result[High(Result)];
begin Datastore.PostEvents;
FActiveEvent := Result[High(Result)]; Datastore.NotifyDependents;
Datastore.PostEvents; Invalidate;
Datastore.NotifyDependents;
Invalidate;
end;
finally
Screen.Cursor := crDefault;
end; end;
end; end;
@ -1339,7 +1335,7 @@ begin
try try
Application.ProcessMessages; Application.ProcessMessages;
for fn in dlg.Files do for fn in dlg.Files do
ImportICalFile(fn); ImportICalFile(fn, dlg.Files.Count = 1);
finally finally
Screen.Cursor := crDefault; Screen.Cursor := crDefault;
end; end;