uvpvdb.pas
来自「FMA is a free1 powerful phone editing to」· PAS 代码 · 共 517 行
PAS
517 行
unit uVpVDB; // do not localize
{
*******************************************************************************
* Descriptions: vCalendar implementation
* $Source: /cvsroot/fma/fma/uVpVDB.pas,v $
* $Locker: $
*
* Todo:
*
* Change Log:
* $Log: uVpVDB.pas,v $
*
*******************************************************************************
}
interface
uses
Classes, TntClasses, VpBaseDS, VpData, uVCalendar;
type
TVpVDataStore = class(TVpCustomDataStore)
private
function GetEventByID(ID: Integer): TVpEvent;
function GetTaskByID(ID: Integer): TVpTask;
protected
FAutoIncr: Integer;
FCalendar: TVCalendar;
procedure SetConnected(const Value: boolean); override;
procedure SetCalendar(const Value: TVCalendar);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Load; override;
procedure Save;
procedure PostEvents; override;
procedure PostTasks; override;
// Begin -- Override just to avoid warnings
procedure PostResources; override;
procedure PostContacts; override;
procedure PurgeResource(Res: TVpResource); override;
procedure PurgeEvents(Res: TVpResource); override;
procedure PurgeTasks(Res: TVpResource); override;
procedure LoadEvents; override;
procedure LoadContacts; override;
procedure LoadTasks; override;
function GetNextID(TableName: string): integer; override;
procedure SetResourceByName(Value: string); override;
// End -- Override just to avoid warnings
property vCalendar: TVCalendar read FCalendar write SetCalendar;
property vEvent[ID: Integer]: TVpEvent read GetEventByID;
property vTask[ID: Integer]: TVpTask read GetTaskByID;
end;
implementation
uses
Dialogs, TntDialogs, DateUtils, uVBase, SysUtils, TntSysUtils;
constructor TVpVDataStore.Create(AOwner: TComponent);
begin
inherited;
FCalendar := nil;
FAutoIncr := 0;
end;
destructor TVpVDataStore.Destroy;
begin
FCalendar := nil;
inherited;
end;
procedure TVpVDataStore.SetConnected(const Value: boolean);
begin
{ disconnect if destroying }
if csDestroying in ComponentState then begin
Exit;
end;
{ Don't connect at designtime }
if csDesigning in ComponentState then Exit;
{ Don't try to connect until we're all loaded up }
if csLoading in ComponentState then Exit;
if Value then Load;
inherited;
end;
procedure TVpVDataStore.SetCalendar(const Value: TVCalendar);
begin
if Value <> FCalendar then
begin
FCalendar := Value;
if FCalendar <> nil then Load;
end;
end;
procedure TVpVDataStore.Load;
var
I: Integer;
ACalEntity: TVCalEntity;
Event: TVpEvent;
Task: TVpTask;
begin
Loading := true;
try
Resources.ClearResources;
{ Load this resource into memory }
Resource := Resources.AddResource(-1);
if FCalendar <> nil then begin
for I := 0 to FCalendar.Count - 1 do begin
ACalEntity := TVCalEntity(FCalendar[I]);
// TODO: Display item state
if ACalEntity.VType.EntityType = tenVEvent then begin
Event := Resource.Schedule.AddEvent(0, ACalEntity.VDtStart.GetLocal, ACalEntity.VDtEnd.GetLocal);
if Assigned(Event) then begin
Event.Loading := true;
Event.Description := ACalEntity.VSummary.PropertyValue;
// Use UserField0 for location value
Event.UserField0 := ACalEntity.VLocation.PropertyValue;
if ACalEntity.VCategories.IsSet then begin
if tcaAppointment in ACalEntity.VCategories.Categories then Event.Category := 1
else if tcaDate in ACalEntity.VCategories.Categories then Event.Category := 2
else if tcaTravel in ACalEntity.VCategories.Categories then Event.Category := 3
else if tcaVacation in ACalEntity.VCategories.Categories then Event.Category := 4
else if tcaAnniversary in ACalEntity.VCategories.Categories then Event.Category := 5
else Event.Category := 0
end;
if ACalEntity.VAAlarm.IsSet then begin
// Use UserField1 for alarm datetime
Event.UserField1 := ACalEntity.VAAlarm.AsString;
Event.AlarmSet := True;
end;
case ACalEntity.VRRule.Reccurence of
rrNone: Event.RepeatCode := rtNone;
rrDaily: Event.RepeatCode := rtDaily;
rrWeekly: Event.RepeatCode := rtWeekly;
rrMonthly: Event.RepeatCode := rtMonthlyByDay;
rrYearly: Event.RepeatCode := rtYearlyByDay;
end;
// Use UserField2 for Weekly reccurence
Event.UserField2 := ACalEntity.VRRule.WeekDays;
Event.RepeatRangeEnd := ACalEntity.VRRule.EndDate;
Event.AlertDisplayed := ACalEntity.VAlertShown.IsON;
inc(FAutoIncr);
Event.UserField8 := IntToStr(FAutoIncr);
// Use UserField9 for FMA Event State
Event.UserField9 := IntToStr(ACalEntity.VFmaState);
// RecordID 0 means new event
Event.RecordID := ACalEntity.ItemIndex + 1;
Event.Loading := false;
end;
end
else begin
if ACalEntity.VType.EntityType = tenVTodo then
begin
Task := Resource.Tasks.AddTask(0);
if Task <> nil then begin
Task.Loading := true;
Task.Description := ACalEntity.VSummary.PropertyValue;
if tcaPhoneCall in ACalEntity.VCategories.Categories then Task.Category := 1
else Task.Category := 0;
Task.Complete := (ACalEntity.VStatus.Status = tstCompleted);
Task.CompletedOn := ACalEntity.VCompleted.GetLocal;
if ACalEntity.VAAlarm.IsSet then
// Use UserField0 for alarm datetime
Task.UserField0 := ACalEntity.VAAlarm.AsString;
inc(FAutoIncr);
Task.UserField8 := IntToStr(FAutoIncr);
// Use UserField9 for FMA Task State
Task.UserField9 := IntToStr(ACalEntity.VFmaState);
// RecordID 0 means new task
Task.RecordID := ACalEntity.ItemIndex + 1;
Task.Loading := false;
end;
end;
end;
end;
end;
finally
Loading := false;
end;
inherited;
end;
function TVpVDataStore.GetNextID(TableName: string): integer;
begin
// Just to avoid warnings
inherited;
Result := 0;
end;
procedure TVpVDataStore.LoadEvents;
begin
inherited;
end;
procedure TVpVDataStore.LoadContacts;
begin
// Just to avoid warnings
inherited;
end;
procedure TVpVDataStore.LoadTasks;
begin
// Just to avoid warnings
inherited;
end;
procedure TVpVDataStore.SetResourceByName(Value: string);
begin
// Just to avoid warnings
inherited;
end;
procedure TVpVDataStore.PostResources;
begin
// Just to avoid warnings
inherited;
end;
procedure TVpVDataStore.PostContacts;
begin
// Just to avoid warnings
inherited;
end;
procedure TVpVDataStore.PostEvents;
var
I: Integer;
ACalEntity: TVCalEntity;
Event: TVpEvent;
begin
if (Resource <> nil) and Resource.EventsDirty then begin
for I := pred(Resource.Schedule.EventCount) downto 0 do begin
Event := Resource.Schedule.GetEvent(I);
if Event.Deleted then begin
if Event.RecordID <> 0 then begin
ACalEntity := FCalendar.GetCalEntityByItemIndex(Event.RecordID - 1);
if Event.UserField9 = '0' then begin
FCalendar.Remove(ACalEntity);
Event.Free;
end
else begin
ACalEntity.VFmaState := 2;
Event.UserField9 := '2'; // FMA state flag
end;
end
else
Event.Free;
Continue;
end
{ always save FMA specific fields }
else if not Event.Changed then begin
if Event.RecordID <> 0 then begin
ACalEntity := FCalendar.GetCalEntityByItemIndex(Event.RecordID - 1);
if ACalEntity.VIrmcLUID.PropertyValue = '' then
Event.UserField9 := '0'; // No IRMC, so its new event
ACalEntity.VAlertShown.IsON := Event.AlertDisplayed; // save Alerted state
ACalEntity.VFmaState := StrToInt(Event.UserField9); // save FMA state
end;
end
else if Event.Changed then begin
if Event.RecordID = 0 then begin
{ RecordID = 0 => make new entry }
ACalEntity := TVCalEntity.Create;
ACalEntity.VType.EntityType := tenVEvent;
Event.UserField9 := '0'; // FMA state flag
FCalendar.Add(ACalEntity);
Event.RecordID := ACalEntity.ItemIndex + 1;
end
else begin
ACalEntity := FCalendar.GetCalEntityByItemIndex(Event.RecordID - 1);
if ACalEntity.VIrmcLUID.PropertyValue = '' then
Event.UserField9 := '0'; // No IRMC, so its new event
end;
ACalEntity.VDtStart.IsUtc := False;
ACalEntity.VDtStart.DateTime := Event.StartTime;
ACalEntity.VDtStart.LocalToUtc;
ACalEntity.VDtEnd.IsUtc := False;
ACalEntity.VDtEnd.DateTime := Event.EndTime;
ACalEntity.VDtEnd.LocalToUtc;
ACalEntity.VSummary.PropertyValue := Event.Description;
// Use UserField0 for location value
ACalEntity.VLocation.PropertyValue := Event.UserField0;
case Event.Category of
0: ACalEntity.VCategories.Categories := [tcaMiscellaneous];
1: ACalEntity.VCategories.Categories := [tcaAppointment];
2: ACalEntity.VCategories.Categories := [tcaDate];
3: ACalEntity.VCategories.Categories := [tcaTravel];
4: ACalEntity.VCategories.Categories := [tcaVacation];
5: ACalEntity.VCategories.Categories := [tcaAnniversary];
else
ACalEntity.VCategories.Categories := [tcaMiscellaneous];
end;
if Event.AlarmSet then
// Use UserField1 for alarm datetime
ACalEntity.VAAlarm.AsString := Event.UserField1
else
ACalEntity.VAAlarm.IsSet := False;
case Event.RepeatCode of
rtDaily:
ACalEntity.VRRule.Reccurence := rrDaily;
rtWeekly:
ACalEntity.VRRule.Reccurence := rrWeekly;
rtMonthlyByDay:
ACalEntity.VRRule.Reccurence := rrMonthly;
rtYearlyByDay:
ACalEntity.VRRule.Reccurence := rrYearly;
else
ACalEntity.VRRule.Reccurence := rrNone;
end;
// Use UserField2 for Weekly reccurence
ACalEntity.VRRule.WeekDays := Event.UserField2;
ACalEntity.VRRule.EndDate := Event.RepeatRangeEnd;
ACalEntity.VAlertShown.IsON := Event.AlertDisplayed;
ACalEntity.VFmaState := StrToInt(Event.UserField9);
Event.Changed := false;
end;
end;
NotifyDependents;
Resource.Schedule.Sort;
Resource.EventsDirty := false;
end;
end;
procedure TVpVDataStore.PostTasks;
var
I: Integer;
ACalEntity: TVCalEntity;
Task: TVpTask;
begin
if (Resources <> nil) and Resource.TasksDirty then begin
for I := pred(Resource.Tasks.Count) downto 0 do begin
Task := Resource.Tasks.GetTask(I);
if Task.Deleted then begin
if Task.RecordID <> 0 then begin
ACalEntity := FCalendar.GetCalEntityByItemIndex(Task.RecordID - 1);
if Task.UserField9 = '0' then begin
FCalendar.Remove(ACalEntity);
Task.Free;
end
else begin
ACalEntity.VFmaState := 2;
Task.UserField9 := '2'; // FMA state flag
end;
end
else
Task.Free;
Continue;
end
else if Task.Changed then begin
if Task.RecordID = 0 then begin
{ RecordID = 0 => make new entry }
ACalEntity := TVCalEntity.Create;
ACalEntity.VType.EntityType := tenVTodo;
Task.UserField9 := '0'; // FMA state flag
FCalendar.Add(ACalEntity);
Task.RecordID := ACalEntity.ItemIndex + 1;
end
else begin
ACalEntity := FCalendar.GetCalEntityByItemIndex(Task.RecordID - 1);
if ACalEntity.VIrmcLUID.PropertyValue = '' then
Task.UserField9 := '0'; // No IRMC, so its new task
end;
ACalEntity.VSummary.PropertyValue := Task.Description;
if Task.Category = 1 then
ACalEntity.VCategories.Categories := [tcaPhoneCall]
else
ACalEntity.VCategories.Categories := [tcaMiscellaneous];
if Task.Complete then begin
ACalEntity.VStatus.Status := tstCompleted;
ACalEntity.VCompleted.IsUtc := False;
ACalEntity.VCompleted.DateTime := Task.CompletedOn;
ACalEntity.VCompleted.LocalToUtc;
end
else begin
ACalEntity.VStatus.Status := tstNeedsAction;
ACalEntity.VCompleted.Text := '';
end;
if Task.UserField0 <> '' then
// Use UserField0 for alarm datetime
ACalEntity.VAAlarm.AsString := Task.UserField0
else
ACalEntity.VAAlarm.IsSet := False;
ACalEntity.VFmaState := StrToInt(Task.UserField9);
Task.Changed := false;
end;
end;
NotifyDependents;
Resource.TasksDirty := false;
end;
end;
procedure TVpVDataStore.PurgeResource(Res: TVpResource);
begin
inherited;
end;
procedure TVpVDataStore.PurgeEvents(Res: TVpResource);
begin
inherited;
end;
procedure TVpVDataStore.PurgeTasks(Res: TVpResource);
begin
inherited;
end;
function TVpVDataStore.GetEventByID(ID: Integer): TVpEvent;
var
I: Integer;
Event: TVpEvent;
begin
Result := nil;
if Assigned(Resource) then
for I := pred(Resource.Schedule.EventCount) downto 0 do begin
Event := Resource.Schedule.GetEvent(I);
if Event.UserField8 = IntToStr(ID) then begin
Result := Event;
break;
end;
end;
end;
function TVpVDataStore.GetTaskByID(ID: Integer): TVpTask;
var
I: Integer;
Task: TVpTask;
begin
Result := nil;
if Assigned(Resource) then
for I := pred(Resource.Tasks.Count) downto 0 do begin
Task := Resource.Tasks.GetTask(I);
if Task.UserField8 = IntToStr(ID) then begin
Result := Task;
break;
end;
end;
end;
procedure TVpVDataStore.Save;
begin
PostTasks;
PostEvents;
end;
end.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?