LazMapViewer: TMapEditMark observing deletions of map items. Issue #39089.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9549 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
alpine-a110 2024-12-23 14:10:45 +00:00
parent 7b9236498a
commit 0b8056db78

View File

@ -613,7 +613,6 @@ type
procedure UpdateLayers; procedure UpdateLayers;
procedure CreateEditor; procedure CreateEditor;
procedure DoneEditor;
function EditingEnabled: Boolean; inline; function EditingEnabled: Boolean; inline;
function DraggingEnabled: Boolean; inline; function DraggingEnabled: Boolean; inline;
@ -800,7 +799,7 @@ type
{ TMapEditMark } { TMapEditMark }
TMapEditMark = class(TGPSObj) TMapEditMark = class(TGPSObj, IFPObserver)
private private
FMapView: TMapView; FMapView: TMapView;
FOnDirty: TNotifyEvent; FOnDirty: TNotifyEvent;
@ -811,6 +810,7 @@ type
FRealPt: TRealPoint; FRealPt: TRealPoint;
FPt: TPoint; FPt: TPoint;
FSelection: TMapObjectList; FSelection: TMapObjectList;
FObservedColls: TMapObjectList;
FLit: TMapObjectList; FLit: TMapObjectList;
FOrigins: TRealPointArray; FOrigins: TRealPointArray;
FDragStarted: Boolean; FDragStarted: Boolean;
@ -826,6 +826,10 @@ type
function GetCursorShape: TCursor; function GetCursorShape: TCursor;
function GetHasSelection: Boolean; function GetHasSelection: Boolean;
procedure FPOObservedChanged(ASender: TObject;
Operation: TFPObservedOperation; Data: Pointer);
procedure ObserveItemColl(AItem: TObject);
function AroundPt(X, Y: Integer; APt: TPoint): Boolean; function AroundPt(X, Y: Integer; APt: TPoint): Boolean;
procedure SelectFromMarquee; procedure SelectFromMarquee;
procedure MarkDirty; procedure MarkDirty;
@ -3375,13 +3379,13 @@ var
I: Integer; I: Integer;
begin begin
Active := False; Active := False;
DoneEditor;
Engine.Jobqueue.RemoveAsyncCalls(Self); Engine.Jobqueue.RemoveAsyncCalls(Self);
FFont.Free; FFont.Free;
FreeAndNil(FPOIImage); FreeAndNil(FPOIImage);
FLayers.Free; FLayers.Free;
for I := 0 to High(FGPSItems) do for I := 0 to High(FGPSItems) do
FreeAndNil(FGPSItems[I]); FreeAndNil(FGPSItems[I]);
FDragger.Free;
FCenter.Free; FCenter.Free;
inherited Destroy; inherited Destroy;
end; end;
@ -3702,7 +3706,7 @@ end;
procedure TMapView.CreateEditor; procedure TMapView.CreateEditor;
begin begin
if Assigned(FEditMark) then if Assigned(FEditMark) then
DoneEditor; Exit;
FEditMark := TMapEditMark.Create(Self); FEditMark := TMapEditMark.Create(Self);
FEditMark.UpdateFrom(Nil); FEditMark.UpdateFrom(Nil);
@ -3720,15 +3724,6 @@ begin
FDragger.OnEndDrag := @FEditMark.DoEndDrag; FDragger.OnEndDrag := @FEditMark.DoEndDrag;
end; end;
procedure TMapView.DoneEditor;
begin
if not Assigned(FEditMark) then
Exit;
FDragger.Free;
FGPSItems[High(FGPSItems)].Delete(FEditMark);
FEditMark := Nil;
end;
function TMapView.EditingEnabled: Boolean; function TMapView.EditingEnabled: Boolean;
begin begin
Result := IsActive and (mvoEditorEnabled in Options); Result := IsActive and (mvoEditorEnabled in Options);
@ -4103,6 +4098,7 @@ begin
if ClearFirst then if ClearFirst then
FSelection.Clear; FSelection.Clear;
FSelection.Insert(0, APoint); FSelection.Insert(0, APoint);
ObserveItemColl(APoint);
FMapView.Invalidate; FMapView.Invalidate;
end; end;
@ -4129,7 +4125,8 @@ begin
if Assigned(Hits) then if Assigned(Hits) then
try try
for O in Hits do for O in Hits do
FSelection.AddIfNotPresent(O); if FSelection.AddIfNotPresent(O) then
ObserveItemColl(O);
FMapView.Invalidate; FMapView.Invalidate;
finally finally
Hits.Free; Hits.Free;
@ -4146,14 +4143,44 @@ begin
end; end;
end; end;
procedure TMapEditMark.FPOObservedChanged(ASender: TObject;
Operation: TFPObservedOperation; Data: Pointer);
var
Item: TMapItem;
begin
if (Operation <> ooDeleteItem) or not Assigned(Data) or
not (TObject(Data) is TMapItem)
then
Exit;
// Item has been deleted from its parent collection,
// delete it from the current selection if present.
Item := TMapItem(Data);
FSelection.DelIfPresent(Item);
end;
procedure TMapEditMark.ObserveItemColl(AItem: TObject);
var
ObservedColl: TCollection;
begin
if not (AItem is TMapItem) or not Assigned(TMapItem(AItem).Collection) then
Exit;
// Start observing the item parent collection for deletions
ObservedColl := TMapItem(AItem).Collection;
if FObservedColls.AddIfNotPresent(ObservedColl) then
ObservedColl.FPOAttachObserver(Self);
end;
constructor TMapEditMark.Create(AMapView: TMapView); constructor TMapEditMark.Create(AMapView: TMapView);
begin begin
FMapView := AMapView; FMapView := AMapView;
FSelection := TMapObjectList.Create; FSelection := TMapObjectList.Create;
FObservedColls := TMapObjectList.Create;
FObservedColls.FreeObjects := False;
end; end;
destructor TMapEditMark.Destroy; destructor TMapEditMark.Destroy;
begin begin
FObservedColls.Free;
FSelection.Free; FSelection.Free;
inherited Destroy; inherited Destroy;
end; end;
@ -4266,8 +4293,11 @@ begin
H := FSelection.DelIfPresent(FLit[0]); H := FSelection.DelIfPresent(FLit[0]);
FTruncSelection := not H and FTruncSelection; FTruncSelection := not H and FTruncSelection;
FSelection.Insert(0, FLit[0]); FSelection.Insert(0, FLit[0]);
if not H then
ObserveItemColl(FLit[0]);
for O in FLit do for O in FLit do
FSelection.AddIfNotPresent(O); if FSelection.AddIfNotPresent(O) then
ObserveItemColl(O);
FreeAndNil(FLit); FreeAndNil(FLit);
end end
else else