Designer, IdeIntf: Update Object Inspector tree after adding/deleting components. Optimize excess updates. Issue #30033

git-svn-id: trunk@52230 -
This commit is contained in:
juha 2016-04-21 20:40:02 +00:00
parent 6d991af10c
commit fa6c3b0d21
5 changed files with 71 additions and 57 deletions

View File

@ -42,8 +42,8 @@ type
FPropertyEditorHook: TPropertyEditorHook;
FImageList: TImageList;
function GetSelection: TPersistentSelectionList;
procedure SetPropertyEditorHook(const AValue: TPropertyEditorHook);
procedure SetSelection(const NewSelection: TPersistentSelectionList);
procedure SetPropertyEditorHook(AValue: TPropertyEditorHook);
procedure SetSelection(NewSelection: TPersistentSelectionList);
procedure UpdateSelected;
protected
procedure DoSelectionChanged; override;
@ -255,9 +255,7 @@ end;
{ TComponentTreeView }
procedure TComponentTreeView.SetSelection(const NewSelection: TPersistentSelectionList);
var
IsNewLookupRoot: Boolean;
procedure TComponentTreeView.SetSelection(NewSelection: TPersistentSelectionList);
begin
if (PropertyEditorHook = nil) then
begin
@ -272,14 +270,14 @@ begin
UpdateComponentNodesValues;
Exit;
end;
IsNewLookupRoot := FComponentList.LookupRoot <> PropertyEditorHook.LookupRoot;
if IsNewLookupRoot then
FComponentList.LookupRoot := PropertyEditorHook.LookupRoot;
FComponentList.LookupRoot := PropertyEditorHook.LookupRoot;
FComponentList.Selection.Assign(NewSelection);
if IsNewLookupRoot then
RebuildComponentNodes
else
UpdateSelected;
if NewSelection.ForceUpdate then
begin
DebugLn('TComponentTreeView.SetSelection: Selection.ForceUpdate encountered.');
NewSelection.ForceUpdate:=false;
end;
UpdateSelected;
end;
procedure TComponentTreeView.DoSelectionChanged;
@ -574,11 +572,11 @@ begin
OnComponentGetImageIndex(APersistent, Result);
end;
procedure TComponentTreeView.SetPropertyEditorHook(const AValue: TPropertyEditorHook);
procedure TComponentTreeView.SetPropertyEditorHook(AValue: TPropertyEditorHook);
begin
if FPropertyEditorHook=AValue then exit;
FPropertyEditorHook:=AValue;
RebuildComponentNodes;
//RebuildComponentNodes;
end;
function TComponentTreeView.GetSelection: TPersistentSelectionList;
@ -681,9 +679,9 @@ var
RootNode: TTreeNode;
Candidate: TComponentCandidate;
begin
DebugLn('TComponentTreeView.RebuildComponentNodes: Updating TreeView with components');
BeginUpdate;
Items.Clear;
RootObject := nil;
if PropertyEditorHook<>nil then
RootObject := PropertyEditorHook.LookupRoot;
@ -738,7 +736,9 @@ procedure TComponentTreeView.UpdateComponentNodesValues;
end;
begin
BeginUpdate;
UpdateComponentNode(Items.GetFirstNode);
EndUpdate;
end;
procedure TComponentTreeView.UpdateSelected;
@ -755,7 +755,10 @@ procedure TComponentTreeView.UpdateSelected;
end;
begin
BeginUpdate;
Selected := Nil;
UpdateComponentNode(Items.GetFirstNode);
EndUpdate;
end;
function TComponentTreeView.CreateNodeCaption(APersistent: TPersistent;

View File

@ -739,6 +739,7 @@ type
private
FEnableHookGetSelection: boolean;
FInSelection: Boolean;
FRefreshingSelectionCount: integer;
FOnAutoShow: TNotifyEvent;
FLastActiveRowName: String;
function GetComponentPanelHeight: integer;
@ -752,6 +753,7 @@ type
procedure OnGridSelectionChange(Sender: TObject);
function OnGridPropertyHint(Sender: TObject; PointedRow: TOIPropertyGridRow;
out AHint: string): boolean;
procedure FillPersistentComboBox;
procedure SetAvailComboBoxText;
procedure HookGetSelection(const ASelection: TPersistentSelectionList);
procedure HookSetSelection(const ASelection: TPersistentSelectionList);
@ -771,7 +773,7 @@ type
procedure SaveChanges;
procedure RefreshPropertyValues;
procedure RebuildPropertyLists;
procedure FillPersistentComboBox;
procedure FillComponentList;
procedure BeginUpdate;
procedure EndUpdate;
function GetActivePropertyGrid: TOICustomPropertyGrid;
@ -4044,10 +4046,8 @@ begin
inherited Create(AnOwner);
FEnableHookGetSelection := true;
FPropertyEditorHook := nil;
FInSelection := False;
FSelection := TPersistentSelectionList.Create;
FAutoShow := True;
FUpdatingAvailComboBox := false;
FDefaultItemHeight := 22;
ComponentPanelHeight := 160;
FShowComponentTree := True;
@ -4297,7 +4297,7 @@ begin
ASelection.Free;
end;
end;
FillPersistentComboBox;
FillComponentList;
ComponentTree.PropertyEditorHook:=FPropertyEditorHook;
RefreshSelection;
end;
@ -4385,7 +4385,15 @@ begin
if GridControl[Page]<>nil then
GridControl[Page].PropEditLookupRootChange;
CompFilterEdit.Filter:='';
FillPersistentComboBox;
FillComponentList;
end;
procedure TObjectInspectorDlg.FillComponentList;
begin
if FShowComponentTree then
ComponentTree.RebuildComponentNodes
else
FillPersistentComboBox;
end;
procedure TObjectInspectorDlg.FillPersistentComboBox;
@ -4395,9 +4403,10 @@ var
OldText: AnsiString;
NewList: TStringList;
begin
//writeln('[TObjectInspectorDlg.FillComponentComboBox] A ',FUpdatingAvailComboBox
//,' ',FPropertyEditorHook<>nil,' ',FPropertyEditorHook.LookupRoot<>nil);
if FUpdatingAvailComboBox then exit;
DebugLn('TObjectInspectorDlg.FillPersistentComboBox: Updating ComboBox with components');
Assert(not FUpdatingAvailComboBox,
'TObjectInspectorDlg.FillPersistentComboBox: Updating Avail ComboBox');
//if FUpdatingAvailComboBox then exit;
FUpdatingAvailComboBox:=true;
NewList:=TStringList.Create;
try
@ -4607,22 +4616,14 @@ begin
end;
procedure TObjectInspectorDlg.SetSelection(const ASelection: TPersistentSelectionList);
var
OldInSelection: Boolean;
begin
if ASelection<>nil then begin
if FSelection.IsEqual(ASelection) then
begin
if FInSelection then
exit; // prevent endless loops
if (not ASelection.ForceUpdate) then
exit; // nothing changed
ASelection.ForceUpdate:=false;
end;
if FSelection.IsEqual(ASelection) then // Nothing changed or endless loop -> quit.
if FInSelection or not ASelection.ForceUpdate then exit;
end else begin
if FSelection.Count=0 then exit;
end;
OldInSelection := FInSelection;
Assert(not FInSelection, 'TObjectInspectorDlg.SetSelection: Already setting selection.');
FInSelection := True;
try
// ToDo: Clear filter only if a selected node is hidden (Visible=False)
@ -4636,7 +4637,7 @@ begin
if Assigned(FOnSelectPersistentsInOI) then
FOnSelectPersistentsInOI(Self);
finally
FInSelection := OldInSelection;
FInSelection := False;
end;
end;
@ -4644,10 +4645,12 @@ procedure TObjectInspectorDlg.RefreshSelection;
var
Page: TObjectInspectorPage;
begin
if FRefreshingSelectionCount > 0 then Exit; // Prevent a recursive loop.
Inc(FRefreshingSelectionCount);
if NoteBook.Page[3].Visible then
begin
DoUpdateRestricted;
// invalidate RestrictedProps
WidgetSetsRestrictedBox.Invalidate;
ComponentRestrictedBox.Invalidate;
@ -4662,6 +4665,7 @@ begin
OnAutoShow(Self)
else
Visible := True;
Dec(FRefreshingSelectionCount);
end;
procedure TObjectInspectorDlg.RefreshComponentTreeSelection;
@ -5046,6 +5050,7 @@ begin
CreateTopSplitter
else
FreeAndNil(Splitter1);
FillComponentList;
finally
EndUpdate;
end;

View File

@ -397,6 +397,7 @@ type
procedure BeginUpdate;
procedure EndUpdate;
procedure DoChange(ForceUpdate: Boolean = False);
procedure IgnoreUpdate;
property UpdateLock: integer read FUpdateLock;
// items
@ -2088,6 +2089,11 @@ begin
end;
end;
procedure TControlSelection.IgnoreUpdate;
begin
FStates := FStates - cssSelectionChangeFlags;
end;
procedure TControlSelection.DoChangeProperties;
begin
if Assigned(OnPropertiesChanged) then OnPropertiesChanged(Self);

View File

@ -200,7 +200,6 @@ type
function DoDeleteSelectedPersistents: boolean;
procedure DoSelectAll;
procedure DoDeletePersistent(APersistent: TPersistent; FreeIt: boolean);
procedure MarkPersistentForDeletion(APersistent: TPersistent);
function GetSelectedComponentClass: TRegisteredComponent;
procedure NudgePosition(DiffX, DiffY: Integer);
procedure NudgeSize(DiffX, DiffY: Integer);
@ -685,7 +684,10 @@ begin
// was FinalizeFreeDesigner
Include(FFlags, dfDestroyingForm);
// free or hide the form
TheControlSelection.BeginUpdate;
TheFormEditor.DeleteComponent(FLookupRoot,AFreeComponent);
TheControlSelection.IgnoreUpdate;
TheControlSelection.EndUpdate;
DisconnectComponent;
Free;
end;
@ -2339,7 +2341,6 @@ var
exit;
end;
ControlSelection.BeginUpdate;
// check if start new selection or add/remove:
NewRubberbandSelection:= (not (ssShift in Shift))
or (ControlSelection.SelectionForm<>Form);
@ -2363,7 +2364,6 @@ var
SelectionChanged:=true;
end;
ControlSelection.RubberbandActive:=false;
ControlSelection.EndUpdate;
{$IFDEF VerboseDesigner}
DebugLn('RubberbandSelect ',DbgS(ControlSelection.Grabbers[0]));
{$ENDIF}
@ -2452,6 +2452,7 @@ begin
if Handled then exit;
end;
ControlSelection.BeginUpdate;
if Button=mbLeft then
begin
if SelectedCompClass = nil then
@ -2520,11 +2521,11 @@ begin
AddComponent;
end;
end
else
if Button=mbRight then
else if Button=mbRight then
begin
// right click -> popup menu
DisableRubberBand;
ControlSelection.EndUpdate;
if EnvironmentOptions.RightClickSelects
and (not ControlSelection.IsSelected(MouseDownComponent))
and (Shift - [ssRight] = []) then
@ -2533,6 +2534,7 @@ begin
BuildPopupMenu;
PopupPos := Form.ClientToScreen(MouseUpPos);
FDesignerPopupMenu.Popup(PopupPos.X, PopupPos.Y);
ControlSelection.BeginUpdate;
end;
DisableRubberBand;
@ -2543,10 +2545,11 @@ begin
Exclude(FFlags,dfHasSized);
MouseDownComponent:=nil;
MouseDownSender:=nil;
if PropertyEditorHook<>nil then
PropertyEditorHook.DesignerMouseUp(Sender, Button, Shift, p.X, p.Y);
ControlSelection.EndUpdate;
{$IFDEF VerboseDesigner}
DebugLn('[TDesigner.MouseUpOnControl] END');
{$ENDIF}
@ -2899,7 +2902,11 @@ begin
// mark selected components for deletion
for i:=0 to ControlSelection.Count-1 do
MarkPersistentForDeletion(ControlSelection[i].Persistent);
begin
APersistent := ControlSelection[i].Persistent;
if DeletingPersistent.IndexOf(APersistent) = -1 then
DeletingPersistent.Add(APersistent);
end;
// clear selection by selecting the LookupRoot
SelectOnlyThisComponent(FLookupRoot);
// delete marked components
@ -2972,12 +2979,6 @@ begin
Hook.PersistentDeleted;
end;
procedure TDesigner.MarkPersistentForDeletion(APersistent: TPersistent);
begin
if DeletingPersistent.IndexOf(APersistent) = -1 then
DeletingPersistent.Add(APersistent);
end;
function TDesigner.GetSelectedComponentClass: TRegisteredComponent;
begin
Result:=nil;

View File

@ -8803,9 +8803,9 @@ procedure TMainIDE.OnDesignerPersistentDeleted(Sender: TObject; APersistent: TPe
// important: APersistent was freed, do not access its content, only the pointer
begin
if dfDestroyingForm in TDesigner(Sender).Flags then exit;
if APersistent=nil then ;
//if APersistent=nil then ;
if ObjectInspector1<>nil then
ObjectInspector1.FillPersistentComboBox;
ObjectInspector1.FillComponentList;
end;
procedure TMainIDE.OnPropHookPersistentDeleting(APersistent: TPersistent);
@ -12613,7 +12613,7 @@ begin
// ToDo: Mark designer as modified with PropName.
if (PropName='') and Assigned(ObjectInspector1) then
// any change of property can cause a change of a display name
ObjectInspector1.FillPersistentComboBox;
ObjectInspector1.FillComponentList;
end;
{-------------------------------------------------------------------------------
@ -12691,14 +12691,13 @@ begin
CodeToolBoss.CompleteComponent(ActiveUnitInfo.Source,ADesigner.LookupRoot,Ancestor);
end;
if ObjectInspector1<>nil then
ObjectInspector1.FillPersistentComboBox;
//debugln('TMainIDE.OnPropHookPersistentAdded D ',AComponent.Name,':',AComponent.ClassName,' ',Select);
// select component
if Select then begin
if Select then
TheControlSelection.AssignPersistent(APersistent);
end;
if ObjectInspector1<>nil then
ObjectInspector1.FillComponentList;
{$IFDEF IDE_DEBUG}
debugln('TMainIDE.OnPropHookPersistentAdded END ',dbgsName(APersistent),' Select=',Select);
{$ENDIF}