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; TVpContact = class;
TVpTask = class; TVpTask = class;
TVpEvents = array of TVpEvent; TVpEventArr = array of TVpEvent;
TVpTaskArr = array of TVpTask;
TVpResources = class TVpResources = class
private private
@ -240,6 +241,7 @@ 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 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;
@ -378,6 +380,7 @@ 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 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;
@ -1719,6 +1722,52 @@ begin
result := TVpEvent(FEventList[Index]); result := TVpEvent(FEventList[Index]);
end; 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; function TVpSchedule.RepeatsOn(Event: TVpEvent; Day: TDateTime): Boolean;
var var
EY, EM, ED: Word; EY, EM, ED: Word;
@ -2903,6 +2952,47 @@ begin
result := FTaskList.Count; result := FTaskList.Count;
end; 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; function TVpTasks.IndexOf(ATask: TVpTask): Integer;
begin begin
Result := FTaskList.IndexOf(ATask); Result := FTaskList.IndexOf(ATask);

View File

@ -447,7 +447,7 @@ 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(AFileName: String; ADefaultCategory: Integer = 0): TVpEvents; function ImportICalFile(const AFileName: String; 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;
@ -546,7 +546,7 @@ uses
DateUtils, DateUtils,
{$ENDIF} {$ENDIF}
SysUtils, StrUtils, Math, Dialogs, SysUtils, StrUtils, Math, Dialogs,
VpEvntEditDlg, VpDayViewPainter, VpICal; VpEvntEditDlg, VpDayViewPainter;
(*****************************************************************************) (*****************************************************************************)
{ TVpTGInPlaceEdit } { TVpTGInPlaceEdit }
@ -1336,11 +1336,7 @@ end;
procedure TVpDayView.PopupAddFromICalFile(Sender: TObject); procedure TVpDayView.PopupAddFromICalFile(Sender: TObject);
var var
dlg: TOpenDialog; dlg: TOpenDialog;
ical: TVpICalendar;
fn: String; fn: String;
i: Integer;
id: Integer;
startTime, endTime: TDateTime;
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))
@ -2384,55 +2380,25 @@ end;
category has been found in the ical, i.e. when the event's category is 0. 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 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(AFileName: String; function TVpDayView.ImportICalFile(const AFileName: String;
ADefaultCategory: Integer = 0): TVpEvents; ADefaultCategory: Integer = -1): TVpEventArr;
const
BLOCK_SIZE = 10;
var
ical: TVpICalendar;
startTime, endTime: TDateTime;
i: Integer;
id: Integer;
event: TVpEvent;
eventCounter: Integer;
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;
SetLength(Result, BLOCK_SIZE); Screen.Cursor := crHourglass;
eventCounter := 0;
ical := TVpICalendar.Create;
try try
ical.LoadFromFile(AFileName); Result := Datastore.Resource.Schedule.ImportICalFile(AFileName, ADefaultCategory);
for i := 0 to ical.Count-1 do begin if Length(Result) > 0 then
if not (ical[i] is TVpICalEvent) then begin
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
FActiveEvent := Result[High(Result)]; FActiveEvent := Result[High(Result)];
Datastore.PostEvents; Datastore.PostEvents;
Datastore.NotifyDependents; Datastore.NotifyDependents;
Invalidate; Invalidate;
end;
finally finally
ical.Free;
Screen.Cursor := crDefault; Screen.Cursor := crDefault;
end; end;
end; end;

View File

@ -216,6 +216,7 @@ 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;
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;
@ -613,13 +614,34 @@ begin
inherited; inherited;
tlLoaded := true; tlLoaded := true;
end; end;
{=====}
function TVpTaskList.GetControlType: TVpItemType; function TVpTaskList.GetControlType: TVpItemType;
begin begin
Result := itTasks; Result := itTasks;
end; 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; procedure TVpTaskList.Paint;
begin begin
@ -902,10 +924,7 @@ end;
procedure TVpTaskList.PopupAddFromICalFile(Sender: TObject); procedure TVpTaskList.PopupAddFromICalFile(Sender: TObject);
var var
dlg: TOpenDialog; dlg: TOpenDialog;
ical: TVpICalendar;
fn: String; fn: String;
i: Integer;
id: Integer;
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))
@ -920,24 +939,11 @@ begin
dlg.Options := dlg.Options + [ofAllowMultiSelect, ofFileMustExist]; dlg.Options := dlg.Options + [ofAllowMultiSelect, ofFileMustExist];
if dlg.Execute then begin if dlg.Execute then begin
Screen.Cursor := crHourGlass; Screen.Cursor := crHourGlass;
Application.ProcessMessages;
ical := TVpICalendar.Create;
try try
for fn in dlg.Files do begin for fn in dlg.Files do
ical.LoadFromFile(fn); Datastore.Resource.Tasks.ImportICalFile(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;
Invalidate; Invalidate;
finally finally
ical.Free;
Screen.Cursor := crDefault; Screen.Cursor := crDefault;
end; end;
end; end;

View File

@ -272,6 +272,7 @@ 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;
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;
@ -341,7 +342,7 @@ uses
DateUtils, DateUtils,
{$ENDIF} {$ENDIF}
SysUtils, StrUtils, LazUTF8, Dialogs, SysUtils, StrUtils, LazUTF8, Dialogs,
VpEvntEditDlg, VpWeekViewPainter, VpICal; VpEvntEditDlg, VpWeekViewPainter;
(*****************************************************************************) (*****************************************************************************)
{ TVpTGInPlaceEdit } { TVpTGInPlaceEdit }
@ -1084,6 +1085,36 @@ begin
end; end;
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 } { Hints }
procedure TVpWeekView.ShowHintWindow(APoint: TPoint; AEvent: TVpEvent); procedure TVpWeekView.ShowHintWindow(APoint: TPoint; AEvent: TVpEvent);
@ -1290,11 +1321,7 @@ end;
procedure TVpWeekView.PopupAddFromICalFile(Sender: TObject); procedure TVpWeekView.PopupAddFromICalFile(Sender: TObject);
var var
dlg: TOpenDialog; dlg: TOpenDialog;
ical: TVpICalendar;
fn: String; fn: String;
i: Integer;
id: Integer;
startTime, endTime: TDateTime;
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))
@ -1309,29 +1336,11 @@ begin
dlg.Options := dlg.Options + [ofAllowMultiSelect, ofFileMustExist]; dlg.Options := dlg.Options + [ofAllowMultiSelect, ofFileMustExist];
if dlg.Execute then begin if dlg.Execute then begin
Screen.Cursor := crHourGlass; Screen.Cursor := crHourGlass;
Application.ProcessMessages;
ical := TVpICalendar.Create;
try try
for fn in dlg.Files do begin Application.ProcessMessages;
ical.LoadFromFile(fn); for fn in dlg.Files do
for i := 0 to ical.Count-1 do begin ImportICalFile(fn);
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;
finally finally
ical.Free;
Screen.Cursor := crDefault; Screen.Cursor := crDefault;
end; end;
end; end;