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

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8377 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2022-08-10 21:21:17 +00:00
parent a2ba5cddc7
commit 47dcca9bed
14 changed files with 248 additions and 56 deletions

View File

@ -775,6 +775,11 @@ msgstr "Komponente muss mit einem TVpControlLink verbunden sein"
msgid "Day increment unit not specified." msgid "Day increment unit not specified."
msgstr "Intervall nicht angegeben." msgstr "Intervall nicht angegeben."
#: vpsr.rsnoeventitemsfoundinical
#, object-pascal-format
msgid "No event items found in \"%s\"."
msgstr "Keine Termine gefunden in \"%s\"."
#: vpsr.rsnofilenamespecified #: vpsr.rsnofilenamespecified
msgid "Error: No datastore filename specified." msgid "Error: No datastore filename specified."
msgstr "Fehler: Datastore-Dateiname nicht angegeben." msgstr "Fehler: Datastore-Dateiname nicht angegeben."
@ -811,6 +816,11 @@ msgstr "Es sind keine Druckformate definiert"
msgid "Normal" msgid "Normal"
msgstr "Normal" msgstr "Normal"
#: vpsr.rsnotaskitemsfoundinical
#, object-pascal-format
msgid "No task items found in \"%s\"."
msgstr "Keine Aufgaben gefunden in \"%s\"."
#: vpsr.rsnotdoneyet #: vpsr.rsnotdoneyet
msgid "This feature is not implemented at this time." msgid "This feature is not implemented at this time."
msgstr "Dieses Feature ist zur Zeit nicht implementiert." msgstr "Dieses Feature ist zur Zeit nicht implementiert."

View File

@ -697,7 +697,7 @@ msgstr "Monthly by day"
#: vpsr.rsmonthlyon #: vpsr.rsmonthlyon
#, object-pascal-format #, object-pascal-format
msgid "Monthly on day %s" msgid "Monthly on day %s"
msgstr "" msgstr "Monthly on day %s"
#: vpsr.rsmonths #: vpsr.rsmonths
msgid "Months" msgid "Months"
@ -767,6 +767,11 @@ msgstr "Component must be linked to a TVpControlLink"
msgid "Day increment unit not specified." msgid "Day increment unit not specified."
msgstr "Day increment unit not specified." msgstr "Day increment unit not specified."
#: vpsr.rsnoeventitemsfoundinical
#, object-pascal-format
msgid "No event items found in \"%s\"."
msgstr "No event items found in \"%s\"."
#: vpsr.rsnofilenamespecified #: vpsr.rsnofilenamespecified
msgid "Error: No datastore filename specified." msgid "Error: No datastore filename specified."
msgstr "Error: No datastore filename specified." msgstr "Error: No datastore filename specified."
@ -803,6 +808,11 @@ msgstr "No print formats have been defined"
msgid "Normal" msgid "Normal"
msgstr "Normal" msgstr "Normal"
#: vpsr.rsnotaskitemsfoundinical
#, object-pascal-format
msgid "No task items found in \"%s\"."
msgstr "No task items found in \"%s\"."
#: vpsr.rsnotdoneyet #: vpsr.rsnotdoneyet
msgid "This feature is not implemented at this time." msgid "This feature is not implemented at this time."
msgstr "This feature is not implemented at this time." msgstr "This feature is not implemented at this time."

View File

@ -766,6 +766,11 @@ msgstr ""
msgid "Day increment unit not specified." msgid "Day increment unit not specified."
msgstr "" msgstr ""
#: vpsr.rsnoeventitemsfoundinical
#, object-pascal-format
msgid "No event items found in \"%s\"."
msgstr ""
#: vpsr.rsnofilenamespecified #: vpsr.rsnofilenamespecified
msgid "Error: No datastore filename specified." msgid "Error: No datastore filename specified."
msgstr "" msgstr ""
@ -802,6 +807,11 @@ msgstr ""
msgid "Normal" msgid "Normal"
msgstr "" msgstr ""
#: vpsr.rsnotaskitemsfoundinical
#, object-pascal-format
msgid "No task items found in \"%s\"."
msgstr ""
#: vpsr.rsnotdoneyet #: vpsr.rsnotdoneyet
msgid "This feature is not implemented at this time." msgid "This feature is not implemented at this time."
msgstr "" msgstr ""

View File

@ -781,6 +781,11 @@ msgstr "Le composant doit être lié à un TVpControlLink"
msgid "Day increment unit not specified." msgid "Day increment unit not specified."
msgstr "" msgstr ""
#: vpsr.rsnoeventitemsfoundinical
#, object-pascal-format
msgid "No event items found in \"%s\"."
msgstr ""
#: vpsr.rsnofilenamespecified #: vpsr.rsnofilenamespecified
msgid "Error: No datastore filename specified." msgid "Error: No datastore filename specified."
msgstr "" msgstr ""
@ -817,6 +822,11 @@ msgstr "Formats d'impression non-défini"
msgid "Normal" msgid "Normal"
msgstr "" msgstr ""
#: vpsr.rsnotaskitemsfoundinical
#, object-pascal-format
msgid "No task items found in \"%s\"."
msgstr ""
#: vpsr.rsnotdoneyet #: vpsr.rsnotdoneyet
msgid "This feature is not implemented at this time." msgid "This feature is not implemented at this time."
msgstr "Cette fonctionnalité n'est pas mise en œuvre à ce moment" msgstr "Cette fonctionnalité n'est pas mise en œuvre à ce moment"

View File

@ -775,6 +775,11 @@ msgstr "Component moet moet met een TVpControlLink verbonden zijn"
msgid "Day increment unit not specified." msgid "Day increment unit not specified."
msgstr "" msgstr ""
#: vpsr.rsnoeventitemsfoundinical
#, object-pascal-format
msgid "No event items found in \"%s\"."
msgstr ""
#: vpsr.rsnofilenamespecified #: vpsr.rsnofilenamespecified
msgid "Error: No datastore filename specified." msgid "Error: No datastore filename specified."
msgstr "" msgstr ""
@ -811,6 +816,11 @@ msgstr "Er zijn geen afdrukformaten gedefinieerd."
msgid "Normal" msgid "Normal"
msgstr "" msgstr ""
#: vpsr.rsnotaskitemsfoundinical
#, object-pascal-format
msgid "No task items found in \"%s\"."
msgstr ""
#: vpsr.rsnotdoneyet #: vpsr.rsnotdoneyet
msgid "This feature is not implemented at this time." msgid "This feature is not implemented at this time."
msgstr "Dit onderdeel is nog niet geimplementeerd." msgstr "Dit onderdeel is nog niet geimplementeerd."

View File

@ -775,6 +775,11 @@ msgstr "Komponent musi być przypisany do TVpControlLink."
msgid "Day increment unit not specified." msgid "Day increment unit not specified."
msgstr "Nie określono interwału dnia." msgstr "Nie określono interwału dnia."
#: vpsr.rsnoeventitemsfoundinical
#, object-pascal-format
msgid "No event items found in \"%s\"."
msgstr ""
#: vpsr.rsnofilenamespecified #: vpsr.rsnofilenamespecified
msgid "Error: No datastore filename specified." msgid "Error: No datastore filename specified."
msgstr "Błąd: Brak nazwy datastore." msgstr "Błąd: Brak nazwy datastore."
@ -811,6 +816,11 @@ msgstr "Nie zdefiniowano formatu wydruku"
msgid "Normal" msgid "Normal"
msgstr "Normalny" msgstr "Normalny"
#: vpsr.rsnotaskitemsfoundinical
#, object-pascal-format
msgid "No task items found in \"%s\"."
msgstr ""
#: vpsr.rsnotdoneyet #: vpsr.rsnotdoneyet
msgid "This feature is not implemented at this time." msgid "This feature is not implemented at this time."
msgstr "Brak implementacji funkcji." msgstr "Brak implementacji funkcji."

View File

@ -757,6 +757,11 @@ msgstr ""
msgid "Day increment unit not specified." msgid "Day increment unit not specified."
msgstr "" msgstr ""
#: vpsr.rsnoeventitemsfoundinical
#, object-pascal-format
msgid "No event items found in \"%s\"."
msgstr ""
#: vpsr.rsnofilenamespecified #: vpsr.rsnofilenamespecified
msgid "Error: No datastore filename specified." msgid "Error: No datastore filename specified."
msgstr "" msgstr ""
@ -793,6 +798,11 @@ msgstr ""
msgid "Normal" msgid "Normal"
msgstr "" msgstr ""
#: vpsr.rsnotaskitemsfoundinical
#, object-pascal-format
msgid "No task items found in \"%s\"."
msgstr ""
#: vpsr.rsnotdoneyet #: vpsr.rsnotdoneyet
msgid "This feature is not implemented at this time." msgid "This feature is not implemented at this time."
msgstr "" msgstr ""

View File

@ -775,6 +775,11 @@ msgstr ""
msgid "Day increment unit not specified." msgid "Day increment unit not specified."
msgstr "" msgstr ""
#: vpsr.rsnoeventitemsfoundinical
#, object-pascal-format
msgid "No event items found in \"%s\"."
msgstr ""
#: vpsr.rsnofilenamespecified #: vpsr.rsnofilenamespecified
msgid "Error: No datastore filename specified." msgid "Error: No datastore filename specified."
msgstr "" msgstr ""
@ -811,6 +816,11 @@ msgstr "Не определён формат печати"
msgid "Normal" msgid "Normal"
msgstr "" msgstr ""
#: vpsr.rsnotaskitemsfoundinical
#, object-pascal-format
msgid "No task items found in \"%s\"."
msgstr ""
#: vpsr.rsnotdoneyet #: vpsr.rsnotdoneyet
msgid "This feature is not implemented at this time." msgid "This feature is not implemented at this time."
msgstr "Эта возможность не рализована." msgstr "Эта возможность не рализована."

View File

@ -183,6 +183,8 @@ resourcestring
RSOverlayed = 'Overlayed'; RSOverlayed = 'Overlayed';
RSICalFilter = 'iCalendar files (*.ical;*.ics)|*.ical;*.ics'; RSICalFilter = 'iCalendar files (*.ical;*.ics)|*.ical;*.ics';
RSRepeat = 'Repeat:'; RSRepeat = 'Repeat:';
RSNoEventItemsFoundInICAL = 'No event items found in "%s".';
RSNoTaskItemsFoundInICAL = 'No task items found in "%s".';
{Task Specific} {Task Specific}
RSConfirmDeleteTask = 'Delete this task from your list?'; RSConfirmDeleteTask = 'Delete this task from your list?';

View File

@ -313,7 +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; function FindBestEventCategory(const ACategoryNames: TStrings): String;
function FindBestTaskCategory(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;
@ -548,12 +549,12 @@ end;
{ ACategoryNames is a list of category names, e.g. like in ical files. { 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 Searches among the datastore's categories whether there is one which matches
an element of the category names and returns its name. } an element of the category names and returns its name. }
function TVpCustomDatastore.FindBestCategory(const ACategoryNames: TStrings): String; function TVpCustomDatastore.FindBestEventCategory(const ACategoryNames: TStrings): String;
var var
i, j: Integer; i, j: Integer;
begin begin
Result := ''; Result := '';
if ACategoryNames.Count > 0 then begin if Assigned(ACategoryNames) and (ACategoryNames.Count > 0) then begin
for i := 0 to ACategoryNames.Count-1 do begin for i := 0 to ACategoryNames.Count-1 do begin
j := CategoryColorMap.IndexOfCategory(ACategoryNames[i]); j := CategoryColorMap.IndexOfCategory(ACategoryNames[i]);
if j <> -1 then begin if j <> -1 then begin
@ -564,6 +565,31 @@ begin
end; end;
end; end;
function TVpCustomDatastore.FindBestTaskCategory(const ACategoryNames: TStrings): String;
const
CAT_NAMES: array[TVpCategoryType] of string = ('BUSINESS', 'CLIENTS', 'FAMILY', 'OTHER', 'PERSONAL');
var
i: Integer;
catName: String;
ct: TVpCategoryType;
begin
Result := '';
if (ACategoryNames <> nil) then
begin
for i := 0 to ACategoryNames.Count-1 do
begin
catName := Uppercase(ACategoryNames[i]);
for ct in TVpCategoryType do
if catName = CAT_NAMES[ct] then
begin
Result := CategoryLabel(ct);
exit;
end;
end;
end;
Result := CategoryLabel(ctOther);
end;
procedure TVpCustomDataStore.DeregisterAllWatchers; procedure TVpCustomDataStore.DeregisterAllWatchers;
var var
i: Integer; i: Integer;

View File

@ -384,7 +384,8 @@ type
procedure DeleteTask(Task: TVpTask); procedure DeleteTask(Task: TVpTask);
function First: TVpTask; function First: TVpTask;
function FirstByDay(Date: TDateTime): TVpTask; function FirstByDay(Date: TDateTime): TVpTask;
function ImportICalFile(const AFileName: String; ADefaultCategory: Integer = -1): TVpTaskArr; function ImportICalFile(const AFileName: String; APreview: Boolean = false;
ADefaultCategory: Integer = -1): TVpTaskArr;
function IndexOf(ATask: TVpTask): Integer; function IndexOf(ATask: TVpTask): Integer;
function Last: TVpTask; function Last: TVpTask;
function LastByDay(Date: TDateTime): TVpTask; function LastByDay(Date: TDateTime): TVpTask;
@ -436,6 +437,7 @@ type
constructor Create(Owner: TVpTasks); constructor Create(Owner: TVpTasks);
destructor Destroy; override; destructor Destroy; override;
procedure LoadFromICalendar(AEntry: TVpICalToDo); procedure LoadFromICalendar(AEntry: TVpICalToDo);
class function GetTaskPriority(APriority:Integer): TVpTaskPriority;
property Loading: Boolean read FLoading write FLoading; property Loading: Boolean read FLoading write FLoading;
property Changed: Boolean read FChanged write SetChanged; property Changed: Boolean read FChanged write SetChanged;
property Deleted: Boolean read FDeleted write FDeleted; property Deleted: Boolean read FDeleted write FDeleted;
@ -1404,7 +1406,7 @@ begin
datastore := TVpCustomDatastore(Owner.Owner.Owner.Owner); datastore := TVpCustomDatastore(Owner.Owner.Owner.Owner);
k := -1; k := -1;
for i := 0 to AEntry.CategoryCount-1 do begin for i := 0 to AEntry.CategoryCount-1 do begin
cat := AEntry.category[i]; cat := AEntry.Category[i];
j := datastore.CategoryColorMap.IndexOfCategory(cat); j := datastore.CategoryColorMap.IndexOfCategory(cat);
if j <> -1 then begin if j <> -1 then begin
k := j; k := j;
@ -1762,6 +1764,11 @@ begin
ical := TVpICalendar.Create; ical := TVpICalendar.Create;
try try
ical.LoadFromFile(AFileName); ical.LoadFromFile(AFileName);
if ical.EventCount = 0 then
begin
MessageDlg(Format(RSNoEventItemsFoundInICAL, [AFileName]), mtInformation, [mbOK], 0);
exit;
end;
if APreview then if APreview then
begin begin
previewForm := TVpICalPreviewForm.Create(nil); previewForm := TVpICalPreviewForm.Create(nil);
@ -1772,8 +1779,11 @@ begin
if ADefaultCategory <> -1 then if ADefaultCategory <> -1 then
previewForm.DefaultCategory := datastore.CategoryColorMap.GetCategoryName(ADefaultCategory); previewForm.DefaultCategory := datastore.CategoryColorMap.GetCategoryName(ADefaultCategory);
if not previewForm.Execute then if not previewForm.Execute then
begin
SetLength(Result, 0);
exit; exit;
end; end;
end;
for i := 0 to ical.Count-1 do begin for i := 0 to ical.Count-1 do begin
if ical[i].Skip or (not (ical[i] is TVpICalEvent)) then if ical[i].Skip or (not (ical[i] is TVpICalEvent)) then
@ -1793,8 +1803,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;
finally
SetLength(Result, eventCounter); SetLength(Result, eventCounter);
if Length(Result) = 0 then
MessageDlg(Format(RSNoEventItemsFoundInICAL, [AFileName]), mtInformation, [mbOK], 0);
finally
if APreview then if APreview then
previewForm.Free; previewForm.Free;
ical.Free; ical.Free;
@ -2808,6 +2820,18 @@ begin
inherited; inherited;
end; end;
{ Converts the priority numbers from ical files (1=highest ... 9=lowest) to the
TvPlanit type TVpTaskPriority. }
class function TVpTask.GetTaskPriority(APriority:Integer): TVpTaskPriority;
begin
if APriority <= 3 then
Result := tpHigh
else if APriority >= 7 then
Result := tpLow
else
Result := tpNormal;
end;
function TVpTask.IsOverdue: Boolean; function TVpTask.IsOverdue: Boolean;
begin begin
result := (Trunc(DueDate) < now + 1); result := (Trunc(DueDate) < now + 1);
@ -2816,9 +2840,8 @@ end;
procedure TVpTask.LoadFromICalendar(AEntry: TVpICalToDo); procedure TVpTask.LoadFromICalendar(AEntry: TVpICalToDo);
var var
cat: String; cat: String;
i: Integer;
ct: TVpCategoryType; ct: TVpCategoryType;
catFound: Boolean; datastore: TVpCustomDatastore;
begin begin
if AEntry = nil then if AEntry = nil then
exit; exit;
@ -2834,32 +2857,21 @@ begin
FComplete := SameText(AEntry.Status, 'COMPLETED'); FComplete := SameText(AEntry.Status, 'COMPLETED');
{ Priority } { Priority }
case AEntry.Priority of FPriority := ord(GetTaskPriority(AEntry.Priority));
1, 2, 3: FPriority := ord(tpHigh);
4, 5, 6: FPriority := ord(tpNormal);
7, 8, 9: FPriority := ord(tpLow);
else FPriority := ord(tpNormal);
end;
{ Category } { Category }
{ tvplanit has only 1 category, ical may have several. We pick the first one { tvplanit has only 1 category, ical may have several. We pick the first one
defined by TVpCategorytype. If none is found we select ctOther. } defined by TVpCategorytype. If none is found we select ctOther. }
FCategory :=ord(ctOther); FCategory :=ord(ctOther);
catFound := false; datastore := TVpCustomDatastore(Owner.Owner.Owner.Owner);
if AEntry.CategoryCount > 0 then begin cat := datastore.FindBestTaskCategory(AEntry.Categories);
for i := 0 to AEntry.CategoryCount-1 do begin for ct in TVpCategoryType do
cat := AEntry.category[i]; if cat = CategoryLabel(ct) then
for ct in TVpCategoryType do begin begin
if cat = CategoryLabel(ct) then begin
FCategory := ord(ct); FCategory := ord(ct);
catFound := true;
break; break;
end; end;
end; end;
if catFound then break;
end;
end;
end;
procedure TVpTask.SetCategory(const Value: Integer); procedure TVpTask.SetCategory(const Value: Integer);
begin begin
@ -2986,7 +2998,7 @@ begin
end; end;
function TVpTasks.ImportICalFile(const AFileName: String; function TVpTasks.ImportICalFile(const AFileName: String;
ADefaultCategory: Integer = -1): TVpTaskArr; APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpTaskArr;
const const
BLOCK_SIZE = 10; BLOCK_SIZE = 10;
var var
@ -2996,6 +3008,7 @@ var
task: TVpTask; task: TVpTask;
taskCounter: Integer; taskCounter: Integer;
datastore: TVpCustomDatastore; datastore: TVpCustomDatastore;
previewForm: TVpICalPreviewForm = nil;
begin begin
Result := nil; Result := nil;
SetLength(Result, BLOCK_SIZE); SetLength(Result, BLOCK_SIZE);
@ -3006,9 +3019,31 @@ begin
ical := TVpICalendar.Create; ical := TVpICalendar.Create;
try try
ical.LoadFromFile(AFileName); ical.LoadFromFile(AFileName);
if ical.ToDoCount = 0 then
begin
MessageDlg(Format(RSNoTaskItemsFoundInICAL, [AFileName]), mtInformation, [mbOK], 0);
exit;
end;
if APreview then
begin
previewForm := TVpICalPreviewForm.Create(nil);
previewForm.Position := poMainFormCenter;
previewForm.Kind := icToDo;
previewForm.Calendar := ical;
previewForm.Datastore := datastore;
if ADefaultCategory <> -1 then
previewForm.DefaultCategory := CategoryLabel(TVpCategoryType(ADefaultCategory));
if not previewForm.Execute then
begin
SetLength(Result, 0);
exit;
end;
end;
for i := 0 to ical.Count-1 do begin for i := 0 to ical.Count-1 do begin
if not (ical[i] is TVpICalToDo) then if ical[i].Skip or (not (ical[i] is TVpICalToDo)) then
Continue; Continue;
id := dataStore.GetNextID(TasksTableName); id := dataStore.GetNextID(TasksTableName);
task := AddTask(id); task := AddTask(id);
task.Changed := true; task.Changed := true;
@ -3021,7 +3056,11 @@ begin
SetLength(Result, taskCounter + BLOCK_SIZE); SetLength(Result, taskCounter + BLOCK_SIZE);
end; end;
SetLength(Result, taskCounter); SetLength(Result, taskCounter);
if Length(Result) = 0 then
MessageDlg(Format(RSNoTaskItemsFoundInICAL, [AFileName]), mtInformation, [mbOK], 0);
finally finally
if APreview then
previewForm.Free;
ical.Free; ical.Free;
end; end;
end; end;

View File

@ -10,6 +10,8 @@ uses
type type
TVpICalendar = class; TVpICalendar = class;
TVpIcalItemKind = (icEvent, icToDo);
TVpICalItem = class(TVpFileItem) TVpICalItem = class(TVpFileItem)
public public
function GetAttribute(AName: String): string; function GetAttribute(AName: String): string;
@ -115,6 +117,7 @@ type
constructor Create(AOwner: TVpICalendar); override; constructor Create(AOwner: TVpICalendar); override;
destructor Destroy; override; destructor Destroy; override;
procedure Analyze; override; procedure Analyze; override;
function Categories: TStrings;
property Summary: String read FSummary; property Summary: String read FSummary;
property Comment: String read FComment; property Comment: String read FComment;
property StartTime[UTC: Boolean]: TDateTime read GetStartTime; property StartTime[UTC: Boolean]: TDateTime read GetStartTime;
@ -132,6 +135,8 @@ type
FVersion: String; FVersion: String;
function GetCount: Integer; function GetCount: Integer;
function GetEntry(AIndex: Integer): TVpICalEntry; function GetEntry(AIndex: Integer): TVpICalEntry;
function GetEventCount: Integer;
function GetToDoCount: Integer;
protected protected
// Reading // Reading
procedure LoadFromStrings(const AStrings: TStrings); procedure LoadFromStrings(const AStrings: TStrings);
@ -146,6 +151,8 @@ type
procedure LoadFromFile(const AFileName: String); procedure LoadFromFile(const AFileName: String);
procedure LoadFromStream(const AStream: TStream); procedure LoadFromStream(const AStream: TStream);
property Count: Integer read GetCount; property Count: Integer read GetCount;
property EventCount: Integer read GetEventCount;
property TodoCount: Integer read GetToDoCount;
property Entry[AIndex: Integer]: TVpICalEntry read GetEntry; default; property Entry[AIndex: Integer]: TVpICalEntry read GetEntry; default;
end; end;
@ -443,7 +450,7 @@ constructor TVpICalToDo.Create(AOwner: TVpICalendar);
begin begin
inherited; inherited;
FCategories := TStringList.Create; FCategories := TStringList.Create;
FCategories.Delimiter := VALUE_DELIMITER; FCategories.Delimiter := ','; // ToDo categories are separated by comma in ical file.
FCategories.StrictDelimiter := true; FCategories.StrictDelimiter := true;
end; end;
@ -501,6 +508,11 @@ begin
end; end;
end; end;
function TVpICalToDo.Categories: TStrings;
begin
Result := FCategories;
end;
function TVpICalToDo.GetCategory(AIndex: Integer): String; function TVpICalToDo.GetCategory(AIndex: Integer): String;
begin begin
if (AIndex >= 0) and (AIndex < FCategories.Count) then if (AIndex >= 0) and (AIndex < FCategories.Count) then
@ -576,6 +588,26 @@ begin
Result := FEntries[AIndex]; Result := FEntries[AIndex];
end; end;
function TVpICalendar.GetEventCount: Integer;
var
i: Integer;
begin
Result := 0;
for i := 0 to High(FEntries) do
if (FEntries[i] is TVpICalEvent) then
inc(Result);
end;
function TVpICalendar.GetToDoCount: Integer;
var
i: Integer;
begin
Result := 0;
for i := 0 to High(FEntries) do
if (FEntries[i] is TVpICalToDo) then
inc(Result);
end;
procedure TVpICalendar.LoadFromFile(const AFilename: String); procedure TVpICalendar.LoadFromFile(const AFilename: String);
var var
L: TStrings; L: TStrings;

View File

@ -11,8 +11,6 @@ uses LazLogger,
type type
TVpIcalItemKind = (icEvent, icToDo);
{ TVpICalPreviewForm } { TVpICalPreviewForm }
TVpICalPreviewForm = class(TForm) TVpICalPreviewForm = class(TForm)
@ -157,7 +155,7 @@ begin
// Categories // Categories
if Assigned(FDatastore) then if Assigned(FDatastore) then
begin begin
cat := FDatastore.FindBestCategory(AEvent.Categories); cat := FDatastore.FindBestEventCategory(AEvent.Categories);
if cat = '' then cat := FDefaultCategory; if cat = '' then cat := FDefaultCategory;
Result := Result + cat; Result := Result + cat;
end; end;
@ -219,8 +217,27 @@ begin
end; end;
function TVpICalPreviewForm.GetToDoText(AToDo: TVpICalToDo): String; function TVpICalPreviewForm.GetToDoText(AToDo: TVpICalToDo): String;
var
s: String;
cat: String;
begin begin
Result := ''; Result := RSDescriptionLbl + ' ' + AToDo.Summary + LineEnding +
RSDueDateLabel + ' ' + FormatDateTime(FTimeFormat, AToDo.DueTime[false]) + LineEnding +
RSCreatedOn + ' ' + FormatDateTime(FTimeFormat, AToDo.StartTime[false]);
case TVpTask.GetTaskPriority(AToDo.Priority) of
tpLow: s := RSLow;
tpNormal: s := RSNormal;
tpHigh: s := RSHigh;
end;
Result := Result + LineEnding + RSPriorityLabel + ' ' + s + LineEnding + RSCategoryLabel + ' ';
if Assigned(FDatastore) then
begin
cat := FDatastore.FindBestTaskCategory(AToDo.Categories);
if cat = '' then cat := FDefaultCategory;
Result := Result + cat;
end;
end; end;
procedure TVpICalPreviewForm.GridDrawCell(Sender: TObject; aCol, aRow: Integer; procedure TVpICalPreviewForm.GridDrawCell(Sender: TObject; aCol, aRow: Integer;

View File

@ -216,7 +216,8 @@ type
procedure LinkHandler(Sender: TComponent; NotificationType: TVpNotificationType; procedure LinkHandler(Sender: TComponent; NotificationType: TVpNotificationType;
const Value: Variant); override; const Value: Variant); override;
function GetControlType: TVpItemType; override; function GetControlType: TVpItemType; override;
function ImportICalFile(const AFileName: String; ADefaultCategory: Integer = -1): TVpTaskArr; function ImportICalFile(const AFileName: String; APreview: Boolean = false;
ADefaultCategory: Integer = -1): TVpTaskArr;
procedure PaintToCanvas(ACanvas: TCanvas; ARect: TRect; Angle: TVpRotationAngle); procedure PaintToCanvas(ACanvas: TCanvas; ARect: TRect; Angle: TVpRotationAngle);
procedure RenderToCanvas(RenderCanvas: TCanvas; RenderIn: TRect; procedure RenderToCanvas(RenderCanvas: TCanvas; RenderIn: TRect;
Angle: TVpRotationAngle; Scale: Extended; RenderDate: TDateTime; Angle: TVpRotationAngle; Scale: Extended; RenderDate: TDateTime;
@ -621,16 +622,14 @@ begin
end; end;
function TVpTaskList.ImportICalFile(const AFileName: String; function TVpTaskList.ImportICalFile(const AFileName: String;
ADefaultCategory: Integer = -1): TVpTaskArr; APreview: Boolean = false; ADefaultCategory: Integer = -1): TVpTaskArr;
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;
Screen.Cursor := crHourglass; Result := Datastore.Resource.Tasks.ImportICalFile(AFileName, APreview, ADefaultCategory);
try
Result := Datastore.Resource.Tasks.ImportICalFile(AFileName, ADefaultCategory);
if Length(Result) > 0 then if Length(Result) > 0 then
begin begin
FActiveTask := Result[High(Result)]; FActiveTask := Result[High(Result)];
@ -638,9 +637,6 @@ begin
Datastore.NotifyDependents; Datastore.NotifyDependents;
Invalidate; Invalidate;
end; end;
finally
Screen.Cursor := crDefault;
end;
end; end;
procedure TVpTaskList.Paint; procedure TVpTaskList.Paint;