mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-21 22:59:27 +02:00
MenuDesigner: BeginUpdate and EndUpdate methods to prevent AV. Related changes in menushadows.pp inside method TShadowMenu.DeleteChildlessShadowAndItem
(operation ownsIt.RemoveComponent(mi) was the starting point for many TMenuDesigner.OnDesignerSetSelection calls, especially visible with Sparta package. During execution OnDesignerSetSelection, caller object TShadowMenu was destroyed after RemoveComponent operation, before end of DeleteChildlessShadowAndItem). Issue #29328, from Maciej. git-svn-id: trunk@51212 -
This commit is contained in:
parent
8663e9c084
commit
d5272def5e
@ -73,6 +73,7 @@ type
|
||||
FTemplatesSaved: boolean;
|
||||
FTotalMenuItemsCount: integer;
|
||||
FVariableGlyphsInMenuBar: boolean;
|
||||
FUpdateCount: integer;
|
||||
function GetItemCounts(out aCaptionedItemCount, aShortcutItemCount,
|
||||
anIconCount, anAccelCount: integer): integer;
|
||||
function GetPopupAssignmentCount: integer;
|
||||
@ -94,6 +95,8 @@ type
|
||||
procedure UpdateShortcutList(includeAccelerators: boolean=False);
|
||||
procedure UpdateStatistics;
|
||||
procedure UpdateTemplatesCount;
|
||||
procedure BeginUpdate;
|
||||
procedure EndUpdate;
|
||||
property AcceleratorMenuItemsCount: integer read FAcceleratorMenuItemsCount;
|
||||
property EditedMenu: TMenu read FEditedMenu;
|
||||
property SavedTemplatesCount: integer read FSavedTemplatesCount;
|
||||
@ -203,6 +206,9 @@ var
|
||||
isTMenu: boolean;
|
||||
persist: TPersistent;
|
||||
begin
|
||||
if FUpdateCount > 0 then
|
||||
Exit; // This event will be executed after all updates, look at EndUpdate
|
||||
|
||||
persist:=GetSelectedMenuComponent(ASelection, isTMenu, selCount);
|
||||
if (persist <> nil) then
|
||||
begin
|
||||
@ -571,6 +577,20 @@ begin
|
||||
else FSavedTemplatesCount:=GetSavedTemplatesCount;
|
||||
end;
|
||||
|
||||
procedure TMenuDesigner.BeginUpdate;
|
||||
begin
|
||||
Inc(FUpdateCount);
|
||||
end;
|
||||
|
||||
procedure TMenuDesigner.EndUpdate;
|
||||
begin
|
||||
if FUpdateCount<=0 then
|
||||
RaiseGDBException('');
|
||||
Dec(FUpdateCount);
|
||||
if FUpdateCount = 0 then
|
||||
OnDesignerSetSelection(FormEditingHook.GetCurrentObjectInspector.Selection);
|
||||
end;
|
||||
|
||||
{ TMainMenuComponentEditor}
|
||||
|
||||
procedure TMainMenuComponentEditor.Edit;
|
||||
|
@ -5017,41 +5017,47 @@ var
|
||||
box: TShadowBox;
|
||||
ownsIt: TComponent;
|
||||
begin
|
||||
mi:=anExistingSI.RealItem;
|
||||
if (mi.Count > 0) then
|
||||
DeleteShadowAndItemAndChildren(anExistingSI)
|
||||
else begin
|
||||
HideFakes;
|
||||
if (mi = FSelectedMenuItem) then
|
||||
FSelectedMenuItem:=nil;
|
||||
nearestMI:=GetNextNonSepItem(mi);
|
||||
if (nearestMI = nil) then
|
||||
nearestMI:=GetPreviousNonSepItem(mi);
|
||||
if (nearestMI = nil) then
|
||||
nearestMI:=mi.Parent;
|
||||
box:=anExistingSI.ParentBox;
|
||||
box.ParentMenuItem.Remove(mi);
|
||||
ownsIt:=mi.Owner;
|
||||
if (ownsIt <> nil) then
|
||||
ownsIt.RemoveComponent(mi);
|
||||
anExistingSI.RealItem:=nil;
|
||||
box.ShadowList.Remove(anExistingSI);
|
||||
anExistingSI.Parent:=nil;
|
||||
box.RemoveComponent(anExistingSI);
|
||||
FreeAndNil(anExistingSI);
|
||||
FEditorDesigner.PropertyEditorHook.PersistentDeleting(TPersistent(mi));
|
||||
FreeAndNil(mi);
|
||||
FEditorDesigner.Modified;
|
||||
MenuDesigner.BeginUpdate;
|
||||
try
|
||||
mi:=anExistingSI.RealItem;
|
||||
if (mi.Count > 0) then
|
||||
DeleteShadowAndItemAndChildren(anExistingSI)
|
||||
else begin
|
||||
HideFakes;
|
||||
if (mi = FSelectedMenuItem) then
|
||||
FSelectedMenuItem:=nil;
|
||||
nearestMI:=GetNextNonSepItem(mi);
|
||||
if (nearestMI = nil) then
|
||||
nearestMI:=GetPreviousNonSepItem(mi);
|
||||
if (nearestMI = nil) then
|
||||
nearestMI:=mi.Parent;
|
||||
box:=anExistingSI.ParentBox;
|
||||
box.ParentMenuItem.Remove(mi);
|
||||
ownsIt:=mi.Owner;
|
||||
if (ownsIt <> nil) then
|
||||
ownsIt.RemoveComponent(mi);
|
||||
anExistingSI.RealItem:=nil;
|
||||
box.ShadowList.Remove(anExistingSI);
|
||||
anExistingSI.Parent:=nil;
|
||||
box.RemoveComponent(anExistingSI);
|
||||
FreeAndNil(anExistingSI);
|
||||
FEditorDesigner.PropertyEditorHook.PersistentDeleting(TPersistent(mi));
|
||||
FreeAndNil(mi);
|
||||
FEditorDesigner.PropertyEditorHook.PersistentDeleted;
|
||||
FEditorDesigner.Modified;
|
||||
|
||||
if (box.ShadowCount = 0) then begin
|
||||
FBoxList.Remove(box);
|
||||
box.Parent:=nil;
|
||||
RemoveComponent(box);
|
||||
FreeAndNil(box);
|
||||
if (box.ShadowCount = 0) then begin
|
||||
FBoxList.Remove(box);
|
||||
box.Parent:=nil;
|
||||
RemoveComponent(box);
|
||||
FreeAndNil(box);
|
||||
end;
|
||||
UpdateBoxLocationsAndSizes;
|
||||
SetSelectedMenuItem(nearestMI, False, True);
|
||||
MenuDesigner.UpdateStatistics;
|
||||
end;
|
||||
UpdateBoxLocationsAndSizes;
|
||||
SetSelectedMenuItem(nearestMI, False, True);
|
||||
MenuDesigner.UpdateStatistics;
|
||||
finally
|
||||
MenuDesigner.EndUpdate;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user