tvplanit: Simplify linking of runtime created datastores to dependent controls.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5121 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2016-09-02 16:31:27 +00:00
parent e45bb283df
commit d582c8663f
3 changed files with 118 additions and 97 deletions

View File

@ -9,7 +9,6 @@
<Title Value="project1"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<Icon Value="0"/>
</General>
<VersionInfo>
<StringTable ProductVersion=""/>

View File

@ -38,8 +38,6 @@ implementation
procedure TForm1.FormCreate(Sender: TObject);
begin
ControlLink := TVpControlLink.Create(self);
Datastore := TVpBufDSDatastore.Create(self);
Datastore.Directory := '.';
Datastore.AutoCreate := true;
@ -48,30 +46,28 @@ begin
DayView := TVpDayview.Create(self);
DayView.Parent := self;
DayView.Align := alLeft;
DayView.ControlLink := ControlLink;
DayView.Datastore := Datastore;
WeekView := TVpWeekView.Create(self);
WeekView.Parent := self;
Weekview.Align := alClient;
WeekView.ControlLink := ControlLink;
WeekView.Datastore := Datastore;
MonthView := TVpMonthView.Create(self);
MonthView.Parent := self;
MonthView.Align := alRight;
MonthView.ControlLink := ControlLink;
MonthView.Datastore := Datastore;
Combo := TVpResourceCombo.Create(Self);
Combo.Parent := Panel1;
Combo.Left := 8;
Combo.Top := 8;
Combo.Width := 200;
Combo.Datastore := Datastore;
ControlLink := TVpControlLink.Create(self);
ControlLink.Datastore := Datastore;
// This establishes the links to all controls that depend on Datastore.
// Must be called when all dependent controls are created.
if Datastore.Resources.Count > 0 then
Datastore.ResourceID := Datastore.Resources.Items[0].ResourceID;
Datastore.Resource := Datastore.Resources.Items[0];
end;
end.

View File

@ -164,7 +164,7 @@ type
{$ENDIF}
public
constructor Create (AOwner : TComponent); override;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
{$IFDEF LCL}
@ -222,6 +222,7 @@ type
FResource : TVpResource;
dsAlertTimer : TTimer; { fires the alerts }
FNotifiers : TList;
FLinkedOwner: TComponent;
{events}
FOnConnect : TNotifyEvent;
@ -242,6 +243,8 @@ type
procedure SetDayBuffer(Value: Integer);
procedure SetRange(StartTime, EndTime: TDateTime);
procedure NotifyLinked;
procedure LinkToControls(AOwner: TComponent);
procedure UnlinkFromControls(AOwner: TComponent);
property AutoConnect: Boolean
read FAutoConnect write SetAutoConnect;
@ -279,6 +282,7 @@ type
procedure PostResources; virtual; abstract;
procedure RegisterWatcher (Watcher : THandle);
procedure PlaySound(const AWavFile: String; APlaySoundMode: TVpPlaySoundMode);
property Loading : Boolean
read FLoading write FLoading;
property Resource: TVpResource
@ -291,6 +295,7 @@ type
read FActiveDate write SetActiveDate;
property TimeRange: TVpTimeRange
read FTimeRange;
published
property CategoryColorMap: TVpCategoryColorMap
read FCategoryColorMap write FCategoryColorMap;
@ -407,6 +412,7 @@ type
end;
implementation
uses
@ -420,8 +426,6 @@ uses
{ TVpCustomDataStore }
constructor TVpCustomDataStore.Create(AOwner: TComponent);
var
I: Integer;
begin
inherited;
@ -452,40 +456,7 @@ begin
{ If the DataStore is being dropped onto a form for the first time... }
if (csDesigning in ComponentState) and not (csLoading in ComponentState) then
begin
I := 0;
{ Auto connect to the first available ControlLink component found }
while (I < Owner.ComponentCount) do begin
if (Owner.Components[I] is TVpControlLink)
and (TVpControlLink(Owner.Components[I]).DataStore = nil) then begin
TVpControlLink(Owner.Components[I]).DataStore := self;
Break;
end;
Inc(I);
end;
I := 0;
{ Then Auto connect to all available LinkableControl components found }
while (I < Owner.ComponentCount) do begin
if (Owner.Components[I] is TVpLinkableControl) then begin
if TVpLinkableControl(Owner.Components[I]).DataStore = nil then
TVpLinkableControl(Owner.Components[I]).DataStore := self;
end
else if (Owner.Components[I] is TVpResourceCombo) then begin
if TVpResourceCombo(Owner.Components[I]).DataStore = nil then
TVpResourceCombo(Owner.Components[I]).DataStore := self;
end
else if (Owner.Components[I] is TVpBaseDialog) then begin
if TVpBaseDialog(Owner.Components[I]).DataStore = nil then
TVpBaseDialog(Owner.Components[I]).DataStore := self;
end
else if (Owner.Components[I] is TVpControlLink) then begin
if TVpControlLink(Owner.Components[I]).DataStore = nil then
TVpControlLink(Owner.Components[I]).DataStore := self;
end;
Inc(I);
end;
end;
LinkToControls(Owner);
{ enable the event timer }
if not (csDesigning in ComponentState) then
@ -494,43 +465,13 @@ end;
{=====}
destructor TVpCustomDataStore.Destroy;
var
I: Integer;
begin
DeregisterAllWatchers;
FNotifiers.Free;
FNotifiers := nil;
{ Remove self from all dependent controls }
if Owner <> nil then begin
I := 0;
{ Remove self from dependent Control Links first }
while (I < Owner.ComponentCount) do begin
if (Owner.Components[I] is TVpControlLink) then begin
if TVpControlLink(Owner.Components[I]).DataStore = self then
TVpControlLink(Owner.Components[I]).DataStore := nil;
end;
Inc(I);
end;
I := 0;
{ Then remove self from dependent controls }
while (I < Owner.ComponentCount) do begin
if (Owner.Components[I] is TVpLinkableControl) then begin
if TVpLinkableControl(Owner.Components[I]).DataStore = self then
TVpLinkableControl(Owner.Components[I]).DataStore := nil;
end
else if (Owner.Components[I] is TVpResourceCombo) then begin
if TVpResourceCombo(Owner.Components[I]).DataStore = self then
TVpResourceCombo(Owner.Components[I]).DataStore := nil;
end
else if (Owner.Components[I] is TVpBaseDialog) then begin
if TVpBaseDialog(Owner.Components[I]).DataStore = self then
TVpBaseDialog(Owner.Components[I]).DataStore := nil;
end;
Inc(I);
end;
end;
UnlinkFromControls(FLinkedOwner);
FResources.Free;
FTimeRange.Free;
@ -545,12 +486,12 @@ end;
procedure TVpCustomDataStore.DeregisterAllWatchers;
var
i : Integer;
i: Integer;
begin
if FNotifiers <> nil then
for i := FNotifiers.Count - 1 downto 0 do
if Assigned (FNotifiers[i]) then begin
FreeMem (FNotifiers[i]);
if Assigned(FNotifiers[i]) then begin
FreeMem(FNotifiers[i]);
FNotifiers.Delete (i);
end;
end;
@ -558,13 +499,13 @@ end;
procedure TVpCustomDataStore.DeregisterWatcher (Watcher : THandle);
var
i : Integer;
i: Integer;
begin
if FNotifiers <> nil then
for i := FNotifiers.Count - 1 downto 0 do
if Assigned (FNotifiers[i]) then
if Assigned(FNotifiers[i]) then
if PVpWatcher (FNotifiers[i]).Handle = Watcher then begin
FreeMem (FNotifiers[i]);
FreeMem(FNotifiers[i]);
FNotifiers.Delete (i);
Exit;
end;
@ -913,8 +854,91 @@ begin
{$ENDIF}
end;
end;
{=====}
{ This code links the datastore to the Datastore property of all dependent
components.
AOwner is normally a TForm and is stored in FLinkedOwner to be unlinked by
destructor.
The method is useful if datastores are created at runtime. }
procedure TVpCustomDatastore.LinkToControls(AOwner: TComponent);
var
i: Integer;
begin
UnlinkFromControls(FLinkedOwner);
if (AOwner = nil) then
exit;
{ Auto connect to the first available ControlLink component found }
for i := 0 to AOwner.ComponentCount - 1 do begin
if (AOwner.Components[I] is TVpControlLink) and
(TVpControlLink(AOwner.Components[I]).DataStore = nil) then
begin
TVpControlLink(AOwner.Components[I]).DataStore := Self;
Break;
end;
end;
{ Then Auto connect to all available LinkableControl components found }
for i := 0 to AOwner.ComponentCount - 1 do begin
if (AOwner.Components[I] is TVpLinkableControl) then begin
if TVpLinkableControl(AOwner.Components[I]).DataStore = nil then
TVpLinkableControl(AOwner.Components[I]).DataStore := Self;
end
else if (AOwner.Components[I] is TVpResourceCombo) then begin
if TVpResourceCombo(AOwner.Components[I]).DataStore = nil then
TVpResourceCombo(AOwner.Components[I]).DataStore := Self;
end
else if (AOwner.Components[I] is TVpBaseDialog) then begin
if TVpBaseDialog(AOwner.Components[I]).DataStore = nil then
TVpBaseDialog(AOwner.Components[I]).DataStore := Self;
end;
{
else if (AOwner.Components[I] is TVpControlLink) then begin
if TVpControlLink(AOwner.Components[I]).DataStore = nil then
TVpControlLink(AOwner.Components[I]).DataStore := Self;
end;
}
end;
FLinkedOwner := AOwner;
end;
{ Removes the "Datastore" links from dependent controls.
Is called automatically by destructor. }
procedure TVpCustomDatastore.UnlinkFromControls(AOwner: TComponent);
var
i: Integer;
begin
if AOwner = nil then
exit;
{ Remove self from dependent Control Links first }
for i:= 0 to AOwner.ComponentCount-1 do begin
if (AOwner.Components[I] is TVpControlLink) then begin
if TVpControlLink(AOwner.Components[I]).DataStore = self then
TVpControlLink(AOwner.Components[I]).DataStore := nil;
end;
end;
{ Then remove self from dependent controls }
for i := 0 to AOwner.ComponentCount-1 do begin
if (AOwner.Components[I] is TVpLinkableControl) then begin
if TVpLinkableControl(AOwner.Components[I]).DataStore = self then
TVpLinkableControl(AOwner.Components[I]).DataStore := nil;
end
else if (AOwner.Components[I] is TVpResourceCombo) then begin
if TVpResourceCombo(AOwner.Components[I]).DataStore = self then
TVpResourceCombo(AOwner.Components[I]).DataStore := nil;
end
else if (AOwner.Components[I] is TVpBaseDialog) then begin
if TVpBaseDialog(AOwner.Components[I]).DataStore = self then
TVpBaseDialog(AOwner.Components[I]).DataStore := nil;
end;
end;
FLinkedOwner := nil;
end;
{ TVpEventDragObject }
@ -1425,8 +1449,10 @@ end;
procedure TVpControlLink.SetDataStore(const Value: TVpCustomDataStore);
begin
if FDataStore <> Value then
if FDataStore <> Value then begin
FDataStore := Value;
if FDatastore <> nil then FDatastore.LinkToControls(Owner);
end;
end;
{=====}
procedure TVpControlLink.SetDefaultCountry (const v : string);