mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-15 13:40:48 +02:00
ideintf: apply patches of Alexander S. Klenin (issue #0013326)
- ClassPropEdit: Make subproperties type filter configurable - ClassPropEdit: Refactor TClassPropertyEditor and TPersistentPropertyEditor - Object Inspector: Do not show objects without properties of appropriate kind - Object inspector: Do not show events on Properties page, even for nested objects git-svn-id: trunk@19016 -
This commit is contained in:
parent
d8ead49984
commit
a075ba45c5
@ -392,6 +392,7 @@ type
|
|||||||
procedure SetSubPropertiesColor(const AValue: TColor);
|
procedure SetSubPropertiesColor(const AValue: TColor);
|
||||||
procedure UpdateScrollBar;
|
procedure UpdateScrollBar;
|
||||||
procedure FillComboboxItems;
|
procedure FillComboboxItems;
|
||||||
|
function PropInfoFilter(const APropInfo: PPropInfo): Boolean;
|
||||||
protected
|
protected
|
||||||
procedure CreateParams(var Params: TCreateParams); override;
|
procedure CreateParams(var Params: TCreateParams); override;
|
||||||
procedure CreateWnd; override;
|
procedure CreateWnd; override;
|
||||||
@ -1181,6 +1182,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TOICustomPropertyGrid.PropInfoFilter(
|
||||||
|
const APropInfo: PPropInfo): Boolean;
|
||||||
|
begin
|
||||||
|
Result := HasSubpropertiesInFilter(APropInfo, FFilter);
|
||||||
|
end;
|
||||||
|
|
||||||
function TOICustomPropertyGrid.GetRowByPath(
|
function TOICustomPropertyGrid.GetRowByPath(
|
||||||
const PropPath: string): TOIPropertyGridRow;
|
const PropPath: string): TOIPropertyGridRow;
|
||||||
// searches PropPath. Expands automatically parent rows
|
// searches PropPath. Expands automatically parent rows
|
||||||
@ -1569,8 +1576,9 @@ begin
|
|||||||
for a:=0 to FRows.Count-1 do Rows[a].Free;
|
for a:=0 to FRows.Count-1 do Rows[a].Free;
|
||||||
FRows.Clear;
|
FRows.Clear;
|
||||||
// get properties
|
// get properties
|
||||||
GetPersistentProperties(FSelection, FFilter, FPropertyEditorHook,
|
GetPersistentProperties(
|
||||||
@AddPropertyEditor,nil);
|
FSelection, FFilter, FPropertyEditorHook, @AddPropertyEditor,
|
||||||
|
@PropInfoFilter, nil);
|
||||||
// sort
|
// sort
|
||||||
FRows.Sort(@SortGridRows);
|
FRows.Sort(@SortGridRows);
|
||||||
for a:=0 to FRows.Count-1 do begin
|
for a:=0 to FRows.Count-1 do begin
|
||||||
@ -1627,7 +1635,9 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
NewRow:=TOIPropertyGridRow.Create(Self,PropEditor,nil, WidgetSets);
|
if PropEditor is TClassPropertyEditor then
|
||||||
|
(PropEditor as TClassPropertyEditor).SubPropsTypeFilter := FFilter;
|
||||||
|
NewRow := TOIPropertyGridRow.Create(Self, PropEditor, nil, WidgetSets);
|
||||||
FRows.Add(NewRow);
|
FRows.Add(NewRow);
|
||||||
if FRows.Count>1 then begin
|
if FRows.Count>1 then begin
|
||||||
NewRow.FPriorBrother:=Rows[FRows.Count-2];
|
NewRow.FPriorBrother:=Rows[FRows.Count-2];
|
||||||
@ -1749,6 +1759,8 @@ procedure TOICustomPropertyGrid.AddSubEditor(PropEditor:TPropertyEditor);
|
|||||||
var NewRow:TOIPropertyGridRow;
|
var NewRow:TOIPropertyGridRow;
|
||||||
NewIndex:integer;
|
NewIndex:integer;
|
||||||
begin
|
begin
|
||||||
|
if PropEditor is TClassPropertyEditor then
|
||||||
|
(PropEditor as TClassPropertyEditor).SubPropsTypeFilter := FFilter;
|
||||||
NewRow:=TOIPropertyGridRow.Create(Self,PropEditor,FExpandingRow, []);
|
NewRow:=TOIPropertyGridRow.Create(Self,PropEditor,FExpandingRow, []);
|
||||||
NewIndex:=FExpandingRow.Index+1+FExpandingRow.ChildCount;
|
NewIndex:=FExpandingRow.Index+1+FExpandingRow.ChildCount;
|
||||||
NewRow.Index:=NewIndex;
|
NewRow.Index:=NewIndex;
|
||||||
@ -4635,7 +4647,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
PropertyGrid := CreateGrid(PROPS, oipgpProperties, 0);
|
PropertyGrid := CreateGrid(PROPS, oipgpProperties, 0);
|
||||||
EventGrid := CreateGrid([tkMethod], oipgpEvents, 1);
|
// Nested or referenced objects may have events too.
|
||||||
|
EventGrid := CreateGrid([tkClass, tkMethod], oipgpEvents, 1);
|
||||||
FavouriteGrid := CreateGrid(PROPS + [tkMethod], oipgpFavourite, 2);
|
FavouriteGrid := CreateGrid(PROPS + [tkMethod], oipgpFavourite, 2);
|
||||||
FavouriteGrid.Favourites := FFavourites;
|
FavouriteGrid.Favourites := FFavourites;
|
||||||
RestrictedGrid := CreateGrid(PROPS + [tkMethod], oipgpRestricted, 3);
|
RestrictedGrid := CreateGrid(PROPS + [tkMethod], oipgpRestricted, 3);
|
||||||
|
@ -549,10 +549,22 @@ type
|
|||||||
editing of the object's properties as sub-properties of the property. }
|
editing of the object's properties as sub-properties of the property. }
|
||||||
|
|
||||||
TClassPropertyEditor = class(TPropertyEditor)
|
TClassPropertyEditor = class(TPropertyEditor)
|
||||||
|
private
|
||||||
|
FSubPropsTypeFilter: TTypeKinds;
|
||||||
|
procedure SetSubPropsTypeFilter(const AValue: TTypeKinds);
|
||||||
|
function PropInfoFilter(const APropInfo: PPropInfo): Boolean;
|
||||||
|
protected
|
||||||
|
function GetSelections: TPersistentSelectionList; virtual;
|
||||||
public
|
public
|
||||||
|
constructor Create(
|
||||||
|
Hook: TPropertyEditorHook; APropCount: Integer); override;
|
||||||
|
|
||||||
function GetAttributes: TPropertyAttributes; override;
|
function GetAttributes: TPropertyAttributes; override;
|
||||||
procedure GetProperties(Proc: TGetPropEditProc); override;
|
procedure GetProperties(Proc: TGetPropEditProc); override;
|
||||||
function GetValue: ansistring; override;
|
function GetValue: ansistring; override;
|
||||||
|
|
||||||
|
property SubPropsTypeFilter: TTypeKinds
|
||||||
|
read FSubPropsTypeFilter write SetSubPropsTypeFilter default tkAny;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TMethodPropertyEditor
|
{ TMethodPropertyEditor
|
||||||
@ -580,17 +592,16 @@ type
|
|||||||
in the same form that is type compatible with the property being edited
|
in the same form that is type compatible with the property being edited
|
||||||
(e.g. the ActiveControl property). }
|
(e.g. the ActiveControl property). }
|
||||||
|
|
||||||
TPersistentPropertyEditor = class(TPropertyEditor)
|
TPersistentPropertyEditor = class(TClassPropertyEditor)
|
||||||
protected
|
protected
|
||||||
function FilterFunc(const ATestEditor: TPropertyEditor): Boolean;
|
function FilterFunc(const ATestEditor: TPropertyEditor): Boolean;
|
||||||
function GetPersistentReference: TPersistent; virtual;
|
function GetPersistentReference: TPersistent; virtual;
|
||||||
function GetSelections: TPersistentSelectionList; virtual;
|
function GetSelections: TPersistentSelectionList; override;
|
||||||
function CheckNewValue(APersistent: TPersistent): boolean; virtual;
|
function CheckNewValue(APersistent: TPersistent): boolean; virtual;
|
||||||
public
|
public
|
||||||
function AllEqual: Boolean; override;
|
function AllEqual: Boolean; override;
|
||||||
procedure Edit; override;
|
procedure Edit; override;
|
||||||
function GetAttributes: TPropertyAttributes; override;
|
function GetAttributes: TPropertyAttributes; override;
|
||||||
procedure GetProperties(Proc:TGetPropEditProc); override;
|
|
||||||
function GetEditLimit: Integer; override;
|
function GetEditLimit: Integer; override;
|
||||||
function GetValue: AnsiString; override;
|
function GetValue: AnsiString; override;
|
||||||
procedure GetValues(Proc: TGetStringProc); override;
|
procedure GetValues(Proc: TGetStringProc); override;
|
||||||
@ -1595,6 +1606,11 @@ type
|
|||||||
procedure WritePublishedProperties(Instance: TPersistent);
|
procedure WritePublishedProperties(Instance: TPersistent);
|
||||||
procedure EditCollection(AComponent: TComponent; ACollection: TCollection; APropertyName: String);
|
procedure EditCollection(AComponent: TComponent; ACollection: TCollection; APropertyName: String);
|
||||||
|
|
||||||
|
// Returns true if given property should be displayed on the property list
|
||||||
|
// filtered by AFilter.
|
||||||
|
function HasSubpropertiesInFilter(
|
||||||
|
const APropInfo: PPropInfo; const AFilter: TTypeKinds): Boolean;
|
||||||
|
|
||||||
const
|
const
|
||||||
NoDefaultValue = Longint($80000000);
|
NoDefaultValue = Longint($80000000);
|
||||||
|
|
||||||
@ -4003,6 +4019,13 @@ end;
|
|||||||
|
|
||||||
{ TClassPropertyEditor }
|
{ TClassPropertyEditor }
|
||||||
|
|
||||||
|
constructor TClassPropertyEditor.Create(Hook: TPropertyEditorHook;
|
||||||
|
APropCount: Integer);
|
||||||
|
begin
|
||||||
|
inherited Create(Hook, APropCount);
|
||||||
|
FSubPropsTypeFilter := tkAny;
|
||||||
|
end;
|
||||||
|
|
||||||
function TClassPropertyEditor.GetAttributes: TPropertyAttributes;
|
function TClassPropertyEditor.GetAttributes: TPropertyAttributes;
|
||||||
begin
|
begin
|
||||||
Result := [paMultiSelect, paSubProperties, paReadOnly];
|
Result := [paMultiSelect, paSubProperties, paReadOnly];
|
||||||
@ -4010,26 +4033,48 @@ end;
|
|||||||
|
|
||||||
procedure TClassPropertyEditor.GetProperties(Proc: TGetPropEditProc);
|
procedure TClassPropertyEditor.GetProperties(Proc: TGetPropEditProc);
|
||||||
var
|
var
|
||||||
I: Integer;
|
selection: TPersistentSelectionList;
|
||||||
SubItem: TPersistent;
|
|
||||||
Selection: TPersistentSelectionList;
|
|
||||||
begin
|
begin
|
||||||
Selection := TPersistentSelectionList.Create;
|
selection := GetSelections;
|
||||||
|
if selection = nil then exit;
|
||||||
|
GetPersistentProperties(
|
||||||
|
selection, SubPropsTypeFilter, PropertyHook, Proc, @PropInfoFilter, nil);
|
||||||
|
selection.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TClassPropertyEditor.GetSelections: TPersistentSelectionList;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
subItem: TPersistent;
|
||||||
|
begin
|
||||||
|
Result := TPersistentSelectionList.Create;
|
||||||
try
|
try
|
||||||
for I := 0 to PropCount - 1 do begin
|
for i := 0 to PropCount - 1 do begin
|
||||||
SubItem := TPersistent(GetObjectValueAt(I));
|
subItem := TPersistent(GetObjectValueAt(i));
|
||||||
if SubItem<>nil then
|
if subItem <> nil then
|
||||||
Selection.Add(SubItem);
|
Result.Add(subItem);
|
||||||
end;
|
end;
|
||||||
GetPersistentProperties(Selection,tkProperties,PropertyHook,Proc,nil);
|
except
|
||||||
finally
|
Result.Free;
|
||||||
Selection.Free;
|
raise;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TClassPropertyEditor.GetValue: ansistring;
|
function TClassPropertyEditor.GetValue: ansistring;
|
||||||
begin
|
begin
|
||||||
Result:='('+GetPropType^.Name+')';
|
Result:='(' + GetPropType^.Name + ')';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TClassPropertyEditor.PropInfoFilter(
|
||||||
|
const APropInfo: PPropInfo): Boolean;
|
||||||
|
begin
|
||||||
|
Result := HasSubpropertiesInFilter(APropInfo, SubPropsTypeFilter);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TClassPropertyEditor.SetSubPropsTypeFilter(const AValue: TTypeKinds);
|
||||||
|
begin
|
||||||
|
if FSubPropsTypeFilter = AValue then exit;
|
||||||
|
FSubPropsTypeFilter := AValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TMethodPropertyEditor }
|
{ TMethodPropertyEditor }
|
||||||
@ -4072,7 +4117,7 @@ begin
|
|||||||
NewMethodName := GetFormMethodName;
|
NewMethodName := GetFormMethodName;
|
||||||
DebugLn('### TMethodPropertyEditor.Edit B FormMethodName=',NewMethodName);
|
DebugLn('### TMethodPropertyEditor.Edit B FormMethodName=',NewMethodName);
|
||||||
if not IsValidIdent(NewMethodName) then
|
if not IsValidIdent(NewMethodName) then
|
||||||
raise EPropertyError.Create('Method name '+NewMethodName+' must be an identifier');
|
raise EPropertyError.Create('Method name "'+NewMethodName+'" must be an identifier');
|
||||||
SetValue(NewMethodName); // this will jump to the method
|
SetValue(NewMethodName); // this will jump to the method
|
||||||
PropertyHook.RefreshPropertyValues;
|
PropertyHook.RefreshPropertyValues;
|
||||||
end else
|
end else
|
||||||
@ -4293,18 +4338,12 @@ begin
|
|||||||
Result := TPersistent(GetObjectValue);
|
Result := TPersistent(GetObjectValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPersistentPropertyEditor.GetSelections:
|
function TPersistentPropertyEditor.GetSelections: TPersistentSelectionList;
|
||||||
TPersistentSelectionList;
|
|
||||||
var
|
|
||||||
I: Integer;
|
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
|
||||||
if (GetPersistentReference <> nil) and AllEqual then
|
if (GetPersistentReference <> nil) and AllEqual then
|
||||||
begin
|
Result := inherited GetSelections
|
||||||
Result := TPersistentSelectionList.Create;
|
else
|
||||||
for I := 0 to PropCount - 1 do
|
Result := nil;
|
||||||
Result.Add(TPersistent(GetObjectValueAt(I)));
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPersistentPropertyEditor.CheckNewValue(APersistent: TPersistent): boolean;
|
function TPersistentPropertyEditor.CheckNewValue(APersistent: TPersistent): boolean;
|
||||||
@ -4356,18 +4395,6 @@ begin
|
|||||||
Result := Result + [paSubProperties, paVolatileSubProperties];
|
Result := Result + [paSubProperties, paVolatileSubProperties];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPersistentPropertyEditor.GetProperties(Proc: TGetPropEditProc);
|
|
||||||
var
|
|
||||||
LPersistents: TPersistentSelectionList;
|
|
||||||
begin
|
|
||||||
LPersistents := GetSelections;
|
|
||||||
if LPersistents <> nil then
|
|
||||||
begin
|
|
||||||
GetPersistentProperties(LPersistents, tkAny, PropertyHook, Proc, nil);
|
|
||||||
LPersistents.Free;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPersistentPropertyEditor.GetEditLimit: Integer;
|
function TPersistentPropertyEditor.GetEditLimit: Integer;
|
||||||
begin
|
begin
|
||||||
Result := MaxIdentLength;
|
Result := MaxIdentLength;
|
||||||
@ -4378,19 +4405,18 @@ var
|
|||||||
Component: TComponent;
|
Component: TComponent;
|
||||||
APersistent: TPersistent;
|
APersistent: TPersistent;
|
||||||
begin
|
begin
|
||||||
Result:='';
|
Result := '';
|
||||||
APersistent:=GetPersistentReference;
|
APersistent := GetPersistentReference;
|
||||||
if APersistent is TComponent then begin
|
if APersistent is TComponent then begin
|
||||||
Component:=TComponent(APersistent);
|
Component := TComponent(APersistent);
|
||||||
if Assigned(PropertyHook) then begin
|
if Assigned(PropertyHook) then
|
||||||
Result:=PropertyHook.GetComponentName(Component);
|
Result := PropertyHook.GetComponentName(Component)
|
||||||
end else begin
|
else begin
|
||||||
if Assigned(Component) then
|
if Assigned(Component) then
|
||||||
Result:=Component.Name;
|
Result := Component.Name;
|
||||||
end;
|
|
||||||
end else if APersistent<>nil then begin
|
|
||||||
Result:='('+APersistent.ClassName+')';
|
|
||||||
end;
|
end;
|
||||||
|
end else if APersistent <> nil then
|
||||||
|
Result := inherited GetValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TPersistentPropertyEditor.GetValues(Proc: TGetStringProc);
|
procedure TPersistentPropertyEditor.GetValues(Proc: TGetStringProc);
|
||||||
@ -6742,6 +6768,49 @@ begin
|
|||||||
TCollectionPropertyEditor.ShowCollectionEditor(ACollection, AComponent, APropertyName);
|
TCollectionPropertyEditor.ShowCollectionEditor(ACollection, AComponent, APropertyName);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function HasSubpropertiesInFilter(
|
||||||
|
const APropInfo: PPropInfo; const AFilter: TTypeKinds): Boolean;
|
||||||
|
var
|
||||||
|
visited: TFPList;
|
||||||
|
|
||||||
|
procedure Rec(A: PPropInfo);
|
||||||
|
var
|
||||||
|
propList: PPropList;
|
||||||
|
i: Integer;
|
||||||
|
ti: PTypeInfo;
|
||||||
|
begin
|
||||||
|
ti := A^.PropType;
|
||||||
|
//DebugLn('HasSubpropertiesInFilter: ', ti^.Name);
|
||||||
|
Result :=
|
||||||
|
(ti^.Kind <> tkClass) or
|
||||||
|
// Since components are selectable in the designer,
|
||||||
|
// there is always a possibility that some descendant class may have
|
||||||
|
// properties of the required kind.
|
||||||
|
(GetTypeData(ti)^.ClassType.InheritsFrom(TComponent));
|
||||||
|
// Class properties may directly or indirectly refer to the same class,
|
||||||
|
// so we must avoid infinite recursion.
|
||||||
|
if Result or (visited.IndexOf(ti) >= 0) then exit;
|
||||||
|
visited.Add(ti);
|
||||||
|
for i := 0 to GetPropList(ti, propList) - 1 do begin
|
||||||
|
if propList^[i]^.PropType^.Kind in AFilter then
|
||||||
|
Rec(propList^[i]);
|
||||||
|
if Result then break;
|
||||||
|
end;
|
||||||
|
FreeMem(propList);
|
||||||
|
visited.Delete(visited.Count - 1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
visited := TFPList.Create;
|
||||||
|
try
|
||||||
|
//DebugLn('HasSubpropertiesInFilter -> ', APropInfo^.Name, ': ', APropInfo^.PropType^.Name);
|
||||||
|
Rec(APropInfo);
|
||||||
|
//DebugLn('HasSubpropertiesInFilter <- ', BoolToStr(Result, true));
|
||||||
|
finally
|
||||||
|
visited.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TNoteBookActiveControlPropertyEditor }
|
{ TNoteBookActiveControlPropertyEditor }
|
||||||
|
|
||||||
function TNoteBookActiveControlPropertyEditor.CheckNewValue(
|
function TNoteBookActiveControlPropertyEditor.CheckNewValue(
|
||||||
|
Loading…
Reference in New Issue
Block a user