tvplanit: Extract ImportICalFile also for TVpWeekView and TVpTaskList. Move the essential code into TVpSchedule and TVpTaskList to avoid too much duplication.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@8370 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2022-08-05 20:12:52 +00:00
parent d553c35eb5
commit 080f303cd1
4 changed files with 164 additions and 93 deletions

View File

@ -76,7 +76,8 @@ type
TVpContact = class;
TVpTask = class;
TVpEvents = array of TVpEvent;
TVpEventArr = array of TVpEvent;
TVpTaskArr = array of TVpTask;
TVpResources = class
private
@ -240,6 +241,7 @@ 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 RepeatsOn(Event: TVpEvent; Day: TDateTime): Boolean;
procedure Sort;
property Owner: TVpResource read FOwner;
@ -378,6 +380,7 @@ type
procedure DeleteTask(Task: TVpTask);
function First: TVpTask;
function FirstByDay(Date: TDateTime): TVpTask;
function ImportICalFile(const AFileName: String; ADefaultCategory: Integer = -1): TVpTaskArr;
function IndexOf(ATask: TVpTask): Integer;
function Last: TVpTask;
function LastByDay(Date: TDateTime): TVpTask;
@ -1719,6 +1722,52 @@ begin
result := TVpEvent(FEventList[Index]);
end;
function TVpSchedule.ImportICalFile(const AFileName: String;
ADefaultCategory: Integer = -1): TVpEventArr;
const
BLOCK_SIZE = 10;
var
ical: TVpICalendar;
startTime, endTime: TDateTime;
i: Integer;
id: Integer;
event: TVpEvent;
eventCounter: Integer;
datastore: TVpCustomDatastore;
begin
Result := nil;
SetLength(Result, BLOCK_SIZE);
eventCounter := 0;
datastore := Owner.Owner.Owner as TVpCustomDatastore;
ical := TVpICalendar.Create;
try
ical.LoadFromFile(AFileName);
for i := 0 to ical.Count-1 do begin
if not (ical[i] is TVpICalEvent) then
Continue;
startTime := TVpICalEvent(ical[i]).StartTime[false]; // use local times
endTime := TVpICalEvent(ical[i]).EndTime[false];
if (startTime = 0) and (endTime = 0) then
continue;
id := dataStore.GetNextID(EventsTableName);
event := AddEvent(id, starttime, endtime);
event.Changed := true;
event.LoadFromICalendar(TVpICalEvent(ical[i]));
if (event.Category = 0) and (ADefaultCategory <> -1) then
event.Category := ADefaultCategory;
Result[eventCounter] := event;
inc(eventCounter);
if eventCounter mod BLOCK_SIZE = 0 then
SetLength(Result, eventCounter + BLOCK_SIZE);
end;
SetLength(Result, eventCounter);
finally
ical.Free;
end;
end;
function TVpSchedule.RepeatsOn(Event: TVpEvent; Day: TDateTime): Boolean;
var
EY, EM, ED: Word;
@ -2903,6 +2952,47 @@ begin
result := FTaskList.Count;
end;
function TVpTasks.ImportICalFile(const AFileName: String;
ADefaultCategory: Integer = -1): TVpTaskArr;
const
BLOCK_SIZE = 10;
var
ical: TVpICalendar;
i: Integer;
id: Integer;
task: TVpTask;
taskCounter: Integer;
datastore: TVpCustomDatastore;
begin
Result := nil;
SetLength(Result, BLOCK_SIZE);
taskCounter := 0;
datastore := Owner.Owner.Owner as TVpCustomDatastore;
ical := TVpICalendar.Create;
try
ical.LoadFromFile(AFileName);
for i := 0 to ical.Count-1 do begin
if not (ical[i] is TVpICalToDo) then
Continue;
id := dataStore.GetNextID(TasksTableName);
task := AddTask(id);
task.Changed := true;
task.LoadFromICalendar(TVpICalToDo(ical[i]));
if (task.Category = ord(ctOther)) and (ADefaultCategory <> -1) then
task.Category := ADefaultCategory;
Result[taskCounter] := task;
inc(taskCounter);
if taskCounter mod BLOCK_SIZE = 0 then
SetLength(Result, taskCounter + BLOCK_SIZE);
end;
SetLength(Result, taskCounter);
finally
ical.Free;
end;
end;
function TVpTasks.IndexOf(ATask: TVpTask): Integer;
begin
Result := FTaskList.IndexOf(ATask);

View File

@ -447,7 +447,7 @@ type
function BuildEventString(AEvent: TVpEvent; UseAsHint: Boolean): String;
procedure DeleteActiveEvent(Verify: Boolean);
procedure DragDrop(Source: TObject; X, Y: Integer); override;
function ImportICalFile(AFileName: String; ADefaultCategory: Integer = 0): TVpEvents;
function ImportICalFile(const AFileName: String; ADefaultCategory: Integer = -1): TVpEventArr;
procedure Invalidate; override;
function IsHoliday(ADate: TDate; out AHolidayName: String): Boolean;
procedure LoadLanguage;
@ -546,7 +546,7 @@ uses
DateUtils,
{$ENDIF}
SysUtils, StrUtils, Math, Dialogs,
VpEvntEditDlg, VpDayViewPainter, VpICal;
VpEvntEditDlg, VpDayViewPainter;
(*****************************************************************************)
{ TVpTGInPlaceEdit }
@ -1336,11 +1336,7 @@ end;
procedure TVpDayView.PopupAddFromICalFile(Sender: TObject);
var
dlg: TOpenDialog;
ical: TVpICalendar;
fn: String;
i: Integer;
id: Integer;
startTime, endTime: TDateTime;
begin
if ReadOnly or (not CheckCreateResource) or
(not Assigned(DataStore)) or (not Assigned(DataStore.Resource))
@ -2384,55 +2380,25 @@ end;
category has been found in the ical, i.e. when the event's category is 0.
If you are not happy with this category replacement you can iterate over the
Result array and change it. }
function TVpDayView.ImportICalFile(AFileName: String;
ADefaultCategory: Integer = 0): TVpEvents;
const
BLOCK_SIZE = 10;
var
ical: TVpICalendar;
startTime, endTime: TDateTime;
i: Integer;
id: Integer;
event: TVpEvent;
eventCounter: Integer;
function TVpDayView.ImportICalFile(const AFileName: String;
ADefaultCategory: Integer = -1): TVpEventArr;
begin
if ReadOnly or (not CheckCreateResource) or
(not Assigned(DataStore)) or (not Assigned(DataStore.Resource))
then
Exit;
SetLength(Result, BLOCK_SIZE);
eventCounter := 0;
ical := TVpICalendar.Create;
Screen.Cursor := crHourglass;
try
ical.LoadFromFile(AFileName);
for i := 0 to ical.Count-1 do begin
if not (ical[i] is TVpICalEvent) then
Continue;
startTime := TVpICalEvent(ical[i]).StartTime[false]; // use local times
endTime := TVpICalEvent(ical[i]).EndTime[false];
if (startTime = 0) and (endTime = 0) then
continue;
id := DataStore.GetNextID(EventsTableName);
event := Datastore.Resource.Schedule.AddEvent(id, starttime, endtime);
event.Changed := true;
event.LoadFromICalendar(TVpICalEvent(ical[i]));
if (event.Category = 0) and (ADefaultCategory <> 0) then
event.Category := ADefaultCategory;
Result[eventCounter] := event;
inc(eventCounter);
if eventCounter mod BLOCK_SIZE = 0 then
SetLength(Result, eventCounter + BLOCK_SIZE);
end;
SetLength(Result, eventCounter);
if eventCounter > 0 then
Result := Datastore.Resource.Schedule.ImportICalFile(AFileName, ADefaultCategory);
if Length(Result) > 0 then
begin
FActiveEvent := Result[High(Result)];
Datastore.PostEvents;
Datastore.NotifyDependents;
Invalidate;
Datastore.PostEvents;
Datastore.NotifyDependents;
Invalidate;
end;
finally
ical.Free;
Screen.Cursor := crDefault;
end;
end;

View File

@ -216,6 +216,7 @@ type
procedure LinkHandler(Sender: TComponent; NotificationType: TVpNotificationType;
const Value: Variant); override;
function GetControlType: TVpItemType; override;
function ImportICalFile(const AFileName: String; ADefaultCategory: Integer = -1): TVpTaskArr;
procedure PaintToCanvas(ACanvas: TCanvas; ARect: TRect; Angle: TVpRotationAngle);
procedure RenderToCanvas(RenderCanvas: TCanvas; RenderIn: TRect;
Angle: TVpRotationAngle; Scale: Extended; RenderDate: TDateTime;
@ -613,14 +614,35 @@ begin
inherited;
tlLoaded := true;
end;
{=====}
function TVpTaskList.GetControlType: TVpItemType;
begin
Result := itTasks;
end;
{=====}
function TVpTaskList.ImportICalFile(const AFileName: String;
ADefaultCategory: Integer = -1): TVpTaskArr;
begin
if ReadOnly or (not CheckCreateResource) or
(not Assigned(DataStore)) or (not Assigned(DataStore.Resource))
then
Exit;
Screen.Cursor := crHourglass;
try
Result := Datastore.Resource.Tasks.ImportICalFile(AFileName, ADefaultCategory);
if Length(Result) > 0 then
begin
FActiveTask := Result[High(Result)];
Datastore.PostTasks;
Datastore.NotifyDependents;
Invalidate;
end;
finally
Screen.Cursor := crDefault;
end;
end;
procedure TVpTaskList.Paint;
begin
{ paint simply calls RenderToCanvas and passes in the screen canvas. }
@ -902,10 +924,7 @@ end;
procedure TVpTaskList.PopupAddFromICalFile(Sender: TObject);
var
dlg: TOpenDialog;
ical: TVpICalendar;
fn: String;
i: Integer;
id: Integer;
begin
if ReadOnly or (not CheckCreateResource) or
(not Assigned(DataStore)) or (not Assigned(DataStore.Resource))
@ -920,24 +939,11 @@ begin
dlg.Options := dlg.Options + [ofAllowMultiSelect, ofFileMustExist];
if dlg.Execute then begin
Screen.Cursor := crHourGlass;
Application.ProcessMessages;
ical := TVpICalendar.Create;
try
for fn in dlg.Files do begin
ical.LoadFromFile(fn);
for i := 0 to ical.Count-1 do begin
if not (ical[i] is TVpICalToDo) then
Continue;
id := DataStore.GetNextID(EventsTableName);
FActiveTask := Datastore.Resource.Tasks.AddTask(id);
FActiveTask.LoadFromICalendar(TVpICalToDo(ical[i]));
Datastore.PostTasks;
Datastore.NotifyDependents;
end;
end;
for fn in dlg.Files do
Datastore.Resource.Tasks.ImportICalFile(fn);
Invalidate;
finally
ical.Free;
Screen.Cursor := crDefault;
end;
end;

View File

@ -272,6 +272,7 @@ type
procedure LoadLanguage;
procedure DeleteActiveEvent(Verify: Boolean);
procedure DragDrop(Source: TObject; X, Y: Integer); override;
function ImportICalFile(const AFileName: String; ADefaultCategory: Integer = -1): TVpEventArr;
procedure Invalidate; override;
function IsHoliday(ADate: TDate; out AHolidayName: String): Boolean;
procedure LinkHandler(Sender: TComponent;
@ -341,7 +342,7 @@ uses
DateUtils,
{$ENDIF}
SysUtils, StrUtils, LazUTF8, Dialogs,
VpEvntEditDlg, VpWeekViewPainter, VpICal;
VpEvntEditDlg, VpWeekViewPainter;
(*****************************************************************************)
{ TVpTGInPlaceEdit }
@ -1084,6 +1085,36 @@ begin
end;
end;
{ Reads the events listed in the specified ical file and adds them to the
day view control. All events imported are collected in the Result array.
ADefaultCategory is the category to which the event is assigned if no fitting
category has been found in the ical, i.e. when the event's category is 0.
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;
begin
if ReadOnly or (not CheckCreateResource) or
(not Assigned(DataStore)) or (not Assigned(DataStore.Resource))
then
Exit;
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;
end;
end;
{ Hints }
procedure TVpWeekView.ShowHintWindow(APoint: TPoint; AEvent: TVpEvent);
@ -1290,11 +1321,7 @@ end;
procedure TVpWeekView.PopupAddFromICalFile(Sender: TObject);
var
dlg: TOpenDialog;
ical: TVpICalendar;
fn: String;
i: Integer;
id: Integer;
startTime, endTime: TDateTime;
begin
if ReadOnly or (not CheckCreateResource) or
(not Assigned(DataStore)) or (not Assigned(DataStore.Resource))
@ -1309,29 +1336,11 @@ begin
dlg.Options := dlg.Options + [ofAllowMultiSelect, ofFileMustExist];
if dlg.Execute then begin
Screen.Cursor := crHourGlass;
Application.ProcessMessages;
ical := TVpICalendar.Create;
try
for fn in dlg.Files do begin
ical.LoadFromFile(fn);
for i := 0 to ical.Count-1 do begin
if not (ical[i] is TVpICalEvent) then
Continue;
startTime := TVpICalEvent(ical[i]).StartTime[false]; // use local times
endTime := TVpICalEvent(ical[i]).EndTime[false];
if (startTime = 0) and (endTime = 0) then
continue;
id := DataStore.GetNextID(EventsTableName);
FActiveEvent := Datastore.Resource.Schedule.AddEvent(id, starttime, endtime);
FActiveEvent.Changed := true;
FActiveEvent.LoadFromICalendar(TVpICalEvent(ical[i]));
Datastore.PostEvents;
Datastore.NotifyDependents;
end;
end;
Invalidate;
Application.ProcessMessages;
for fn in dlg.Files do
ImportICalFile(fn);
finally
ical.Free;
Screen.Cursor := crDefault;
end;
end;