diff --git a/components/tvplanit/source/vpdata.pas b/components/tvplanit/source/vpdata.pas index cc0bfaee2..81efcfc69 100644 --- a/components/tvplanit/source/vpdata.pas +++ b/components/tvplanit/source/vpdata.pas @@ -76,6 +76,8 @@ type TVpContact = class; TVpTask = class; + TVpEvents = array of TVpEvent; + TVpResources = class private FOwner: TObject; // This is the Datastore. diff --git a/components/tvplanit/source/vpdayview.pas b/components/tvplanit/source/vpdayview.pas index 90bd3143b..b68cfdd4f 100644 --- a/components/tvplanit/source/vpdayview.pas +++ b/components/tvplanit/source/vpdayview.pas @@ -447,6 +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; procedure Invalidate; override; function IsHoliday(ADate: TDate; out AHolidayName: String): Boolean; procedure LoadLanguage; @@ -1354,29 +1355,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; @@ -1393,7 +1376,6 @@ begin if FActiveEvent <> nil then DeleteActiveEvent (True); end; -{=====} procedure TVpDayView.PopupEditEvent(Sender: TObject); begin @@ -1404,49 +1386,41 @@ begin { edit this Event } dvSpawnEventEditDialog(False); end; -{=====} procedure TVpDayView.PopupToday(Sender: TObject); begin Date := Now; end; -{=====} procedure TVpDayView.PopupTomorrow(Sender: TObject); begin Date := Now + 1; end; -{=====} procedure TVpDayView.PopupYesterday(Sender: TObject); begin Date := Now - 1; end; -{=====} procedure TVpDayView.PopupNextDay(Sender: TObject); begin Date := Date + 1; end; -{=====} procedure TVpDayView.PopupPrevDay(Sender: TObject); begin Date := Date - 1; end; -{=====} procedure TVpDayView.PopupNextWeek(Sender: TObject); begin Date := Date + 7; end; -{=====} procedure TVpDayView.PopupPrevWeek(Sender: TObject); begin Date := Date - 7; end; -{=====} procedure TVpDayView.PopupNextMonth(Sender: TObject); var @@ -1463,7 +1437,6 @@ begin Date := EncodeDate(Y, M, D); end; -{=====} procedure TVpDayView.PopupPrevMonth(Sender: TObject); var @@ -1480,7 +1453,6 @@ begin Date := EncodeDate(Y, M, D); end; -{=====} procedure TVpDayView.PopupNextYear(Sender: TObject); var @@ -1489,7 +1461,6 @@ begin DecodeDate(Date, Y, M, D); Date := EncodeDate(Y + 1, M, 1); end; -{=====} procedure TVpDayView.PopupPrevYear(Sender: TObject); var @@ -2406,7 +2377,65 @@ begin dvEndingEditing := False; 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 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; +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; + 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 + FActiveEvent := Result[High(Result)]; + Datastore.PostEvents; + Datastore.NotifyDependents; + Invalidate; + finally + ical.Free; + Screen.Cursor := crDefault; + end; +end; procedure TVpDayView.KeyDown(var Key: Word; Shift: TShiftState); var