diff --git a/.gitattributes b/.gitattributes index 68dc0f4d50..791b0403e7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,6 +4,10 @@ /COPYING.modifiedLGPL.txt -text svneol=unset#application/octet-stream /COPYING.txt svneol=native#text/plain /README.txt svneol=native#text/plain +components/IdeInspector/ideinspector.lpk svneol=native#text/xml +components/IdeInspector/ideinspector.pas svneol=native#text/pascal +components/IdeInspector/maininspector.lfm svneol=native#text/plain +components/IdeInspector/maininspector.pas svneol=native#text/pascal components/README.txt svneol=native#text/plain components/aggpas/Agg2DDemo.dpr svneol=native#text/plain components/aggpas/aa_demo.dpr svneol=native#text/plain diff --git a/components/IdeInspector/ideinspector.lpk b/components/IdeInspector/ideinspector.lpk new file mode 100644 index 0000000000..f7d7becdd5 --- /dev/null +++ b/components/IdeInspector/ideinspector.lpk @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/IdeInspector/ideinspector.pas b/components/IdeInspector/ideinspector.pas new file mode 100644 index 0000000000..c443d974ef --- /dev/null +++ b/components/IdeInspector/ideinspector.pas @@ -0,0 +1,21 @@ +{ This file was automatically created by Lazarus. Do not edit! + This source is only used to compile and install the package. + } + +unit IdeInspector; + +interface + +uses + MainInspector, LazarusPackageIntf; + +implementation + +procedure Register; +begin + RegisterUnit('MainInspector', @MainInspector.Register); +end; + +initialization + RegisterPackage('IdeInspector', @Register); +end. diff --git a/components/IdeInspector/maininspector.lfm b/components/IdeInspector/maininspector.lfm new file mode 100644 index 0000000000..248feebede --- /dev/null +++ b/components/IdeInspector/maininspector.lfm @@ -0,0 +1,123 @@ +object IdeInspectForm: TIdeInspectForm + Left = 2033 + Height = 479 + Top = 182 + Width = 498 + Caption = 'IdeInspectForm' + ClientHeight = 479 + ClientWidth = 498 + Position = poDefault + LCLVersion = '0.9.29' + object ToolBar1: TToolBar + Left = 0 + Height = 26 + Top = 0 + Width = 498 + Caption = 'ToolBar1' + EdgeBorders = [ebBottom] + Images = ImageList1 + ParentShowHint = False + ShowCaptions = True + ShowHint = True + TabOrder = 0 + object btnComponent: TToolButton + Left = 32 + Top = 0 + AutoSize = True + DropdownMenu = popComponent + OnClick = btnComponentClick + Style = tbsDropDown + end + object btnSubComponent: TToolButton + Left = 67 + Top = 0 + AutoSize = True + DropdownMenu = popSubComponent + OnClick = btnSubComponentClick + Style = tbsDropDown + end + object ToolButton1: TToolButton + Left = 24 + Top = 0 + Width = 8 + Caption = 'ToolButton1' + Style = tbsSeparator + end + object btnRemoveSelected: TToolButton + Left = 1 + Top = 0 + ImageIndex = 0 + OnClick = btnRemoveSelectedClick + end + end + object TreeView1: TTreeView + Left = 0 + Height = 453 + Top = 26 + Width = 217 + Align = alLeft + DefaultItemHeight = 17 + HideSelection = False + ReadOnly = True + RightClickSelect = True + TabOrder = 1 + OnChange = TreeView1Change + OnClick = TreeView1Click + Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoReadOnly, tvoRightClickSelect, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw] + end + object Splitter1: TSplitter + Left = 217 + Height = 453 + Top = 26 + Width = 5 + end + object popComponent: TPopupMenu + OnPopup = popComponentPopup + left = 80 + top = 40 + end + object popSubComponent: TPopupMenu + OnPopup = popSubComponentPopup + left = 192 + top = 40 + end + object ImageList1: TImageList + left = 290 + top = 130 + Bitmap = { + 4C69010000001000000010000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006360 + F80AFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF007774FF1F7774 + FF2BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00625FF82B5D5B + F76F5956F53EFFFFFF00FFFFFF00FFFFFF00FFFFFF007774FF1F7A77FFFF7976 + FEFF726FFD2BFFFFFF00FFFFFF00FFFFFF00FFFFFF00615EF82B6461F8FF6A68 + F9FF5451F3A84F4DF229FFFFFF00FFFFFF007774FF1F7A77FFFF817EFFFF817E + FEFF7471FDFF6C69FB2BFFFFFF00FFFFFF00605DF72B625FF8FF6F6DFBFF7E7C + FFFF625FF8FF4A47F06F4542EE02FFFFFF007673FF087471FEFD7D7AFEFF8A87 + FFFF7C79FDFF6C69FBFF6361F92B5F5CF72B615EF8FF6E6CFAFF7D7AFFFF615F + F7FF4946F0FC4441EE05FFFFFF00FFFFFF00FFFFFF00716EFD086E6BFCFC7774 + FDFF8682FFFF7673FCFF6462F8FF605DF7FF6D6AFAFF7B79FFFF605DF7FF4845 + EFFC4341EE08FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF006967FB086663 + F9FC706DFBFF807EFFFF7E7BFFFF7C79FFFF7977FFFF5E5CF7FF4744EFFC4240 + EE08FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00615E + F8085D5AF6FD7D79FFFF5E5BFFFF5B58FFFF7674FFFF4643EFFD413FED08FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF005C59 + F62B5D5BF7FF7976FFFF5956FFFF5754FFFF7270FFFF4846F0FF3C39EB2BFFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF005B58F62B5C5A + F6FF6764FAFF7472FFFF7370FFFF706EFFFF6E6CFFFF5755F7FF3F3DEEFF3230 + E82BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF005A57F52B5B59F6FF6663 + FAFF7471FFFF5A58F6FF4341EEFC3E3CECFD504DF4FF6867FFFF504EF5FF3634 + EBFF2A27E52BFFFFFF00FFFFFF00FFFFFF005956F52B5B58F6FF6562FAFF7170 + FFFF5956F6FF4240EEFC3E3BEC083937EB083532E9FC4745F2FF6362FFFF4A48 + F4FF2F2DE9FF2220E32BFFFFFF00FFFFFF005451F3415856F5FF6361FAFF5855 + F6FF413FEDFC3D3AEC08FFFFFF00FFFFFF00302DE7082C2AE6FC413FF1FF4C4A + F6FF312FEAFF1F1DE241FFFFFF00FFFFFF00FFFFFF004A47F0414F4CF2FF403E + EDFD3C39EB08FFFFFF00FFFFFF00FFFFFF00FFFFFF002725E5082422E4FC312F + EAFF1F1DE241FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003F3DED413B38 + EB08FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00211FE3081E1C + E241FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00 + } + end +end diff --git a/components/IdeInspector/maininspector.pas b/components/IdeInspector/maininspector.pas new file mode 100644 index 0000000000..63ffe27cb3 --- /dev/null +++ b/components/IdeInspector/maininspector.pas @@ -0,0 +1,275 @@ +unit MainInspector; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, Buttons, + ComCtrls, Menus, MenuIntf, ObjectInspector, types; + +type + + { TIdeInspectForm } + + TIdeInspectForm = class(TForm) + ImageList1: TImageList; + popComponent: TPopupMenu; + popSubComponent: TPopupMenu; + Splitter1: TSplitter; + ToolBar1: TToolBar; + btnComponent: TToolButton; + btnSubComponent: TToolButton; + ToolButton1: TToolButton; + btnRemoveSelected: TToolButton; + TreeView1: TTreeView; + procedure btnSubComponentClick(Sender: TObject); + procedure MenuItem1Click(Sender: TObject); + procedure btnComponentClick(Sender: TObject); + procedure popComponentPopup(Sender: TObject); + procedure popSubComponentPopup(Sender: TObject); + procedure btnRemoveSelectedClick(Sender: TObject); + procedure TreeView1Change(Sender: TObject; Node: TTreeNode); + procedure TreeView1Click(Sender: TObject); + private + { private declarations } + protected + FPropertiesGrid: TCustomPropertiesGrid; + FSelected: TComponent; + procedure SetSelected(AComp: TComponent); + procedure UpdateTree; + procedure Notification(AComponent: TComponent; Operation: TOperation); override; + public + { public declarations } + constructor Create(TheOwner: TComponent); override; + destructor Destroy; override; + end; + +var + IdeInspectForm: TIdeInspectForm; + +resourcestring + ideinspInspectIDE = 'Inspect IDE'; + ideinspApplcicationComponents = 'Applcication.Components'; + ideinspScreenForms = 'Screen.Forms'; + ideinspQuickLinks = 'Quick links'; + ideinspChildren = 'Children'; + ideinspRemoveSelectedItemSFromTree = 'Remove selected item(s) from tree'; + +procedure Register; + +implementation + +{$R *.lfm} + +type + + { TExtMenuItem } + + TExtMenuItem = class(TMenuItem) + private + FTheObject: TPersistent; + public + property TheObject: TPersistent read FTheObject write FTheObject; + end; + +{ TIdeInspectForm } + +procedure TIdeInspectForm.MenuItem1Click(Sender: TObject); +begin + SetSelected(TComponent(TExtMenuItem(Sender).TheObject)); +end; + +procedure TIdeInspectForm.btnSubComponentClick(Sender: TObject); +begin + btnSubComponent.CheckMenuDropdown; +end; + +procedure TIdeInspectForm.btnComponentClick(Sender: TObject); +begin + btnComponent.CheckMenuDropdown; +end; + +procedure TIdeInspectForm.popComponentPopup(Sender: TObject); +var + m: TExtMenuItem; + i: Integer; +begin + popComponent.Items.Clear; + + m := TExtMenuItem.Create(Self); + m.Caption := ideinspApplcicationComponents + ' (' + IntToStr(Application.ComponentCount) + ')' ; + m.Enabled := False; + popComponent.Items.Add(m); + for i := 0 to Application.ComponentCount - 1 do begin + m := TExtMenuItem.Create(Self); + m.Caption := Application.Components[i].Name + + ' ['+Application.Components[i].ClassName+']'+ + ' ('+IntToStr(Application.Components[i].ComponentCount)+')'; + m.TheObject := Application.Components[i]; + m.OnClick := @MenuItem1Click; + popComponent.Items.Add(m); + end; + + m := TExtMenuItem.Create(Self); + m.Caption := ideinspScreenForms + ' (' + IntToStr(Screen.FormCount) + ')' ; + m.Enabled := False; + popComponent.Items.Add(m); + for i := 0 to Screen.FormCount - 1 do begin + m := TExtMenuItem.Create(Self); + m.Caption := Screen.Forms[i].Name + + ' ['+Screen.Forms[i].ClassName+']'+ + ' ('+IntToStr(Screen.Forms[i].ComponentCount)+')'; + m.TheObject := Screen.Forms[i]; + m.OnClick := @MenuItem1Click; + popComponent.Items.Add(m); + end; +end; + +procedure TIdeInspectForm.popSubComponentPopup(Sender: TObject); +var + i: Integer; + m: TExtMenuItem; +begin + popSubComponent.Items.Clear; + + for i := 0 to FSelected.ComponentCount - 1 do begin + m := TExtMenuItem.Create(Self); + m.Caption := FSelected.Components[i].Name + + ' ['+FSelected.Components[i].ClassName+']'+ + ' ('+IntToStr(FSelected.Components[i].ComponentCount)+')'; + m.TheObject := FSelected.Components[i]; + m.OnClick := @MenuItem1Click; + popSubComponent.Items.Add(m); + end; +end; + +procedure TIdeInspectForm.btnRemoveSelectedClick(Sender: TObject); +begin + if TreeView1.Selected = nil then + exit; + if TreeView1.Selected.Parent <> nil then + SetSelected(TComponent(TreeView1.Selected.Parent.Data)) + else + SetSelected(nil); + TreeView1.Selected.Delete; + UpdateTree; +end; + +procedure TIdeInspectForm.TreeView1Change(Sender: TObject; Node: TTreeNode); +begin + TreeView1Click(nil); +end; + +procedure TIdeInspectForm.TreeView1Click(Sender: TObject); +begin + if (TreeView1.Selected = nil) or (TreeView1.Selected.Data = nil) then + exit; + SetSelected(TComponent(TreeView1.Selected.Data)); +end; + +procedure TIdeInspectForm.SetSelected(AComp: TComponent); +begin + FSelected := AComp; + FPropertiesGrid.TIObject := FSelected; + btnSubComponent.Enabled := (FSelected <> nil) and (FSelected.ComponentCount > 0); + UpdateTree; +end; + +procedure TIdeInspectForm.UpdateTree; + function FindNode(AComp: TComponent): TTreeNode; + var + AParent: TTreeNode; + begin + Result := TreeView1.Items.FindNodeWithData(AComp); + if Result = nil then begin + if AComp.Owner <> nil then begin + AParent := FindNode(AComp.Owner); + Result := AParent.TreeNodes.AddChildObject + (AParent, + AComp.Name + ': ' + AComp.ClassName + + ' ('+IntToStr(AComp.ComponentCount)+')' + + ' ' + IntToHex(PtrUInt(AComp), 8), + AComp); + end else begin + Result := TreeView1.Items.AddObject + (nil, + AComp.Name + ': ' + AComp.ClassName + + ' ('+IntToStr(AComp.ComponentCount)+')' + + ' ' + IntToHex(PtrUInt(AComp), 8), + AComp); + end; + AComp.FreeNotification(Self); + end; + end; +var + ANode: TTreeNode; +begin + if FSelected = nil then exit; + + ANode := FindNode(FSelected); + ANode.Expanded := True; + ANode.Selected := True; +end; + +procedure TIdeInspectForm.Notification(AComponent: TComponent; Operation: TOperation); +var + ANode: TTreeNode; +begin + if (Operation = opRemove) and (TreeView1 <> nil) then begin + ANode := TreeView1.Items.FindNodeWithData(AComponent); + if ANode <> nil then begin + ANode.DeleteChildren; + if (AComponent = FSelected) or (TreeView1.Items.FindNodeWithData(FSelected) = nil) then begin + if ANode.Parent <> nil then + SetSelected(TComponent(ANode.Parent.Data)) + else + SetSelected(nil); + end; + ANode.Delete; + UpdateTree; + end; + end; + inherited Notification(AComponent, Operation); +end; + +constructor TIdeInspectForm.Create(TheOwner: TComponent); +begin + inherited Create(TheOwner); + FPropertiesGrid := TCustomPropertiesGrid.Create(Self); + with FPropertiesGrid do + begin + Name := 'FPropertiesGrid'; + Parent := self; + Align := alClient; + BorderSpacing.Around := 6; + end; + btnComponent.Caption := ideinspQuickLinks; + btnSubComponent.Caption := ideinspChildren; + btnRemoveSelected.Hint := ideinspRemoveSelectedItemSFromTree; + + SetSelected(Application); +end; + +destructor TIdeInspectForm.Destroy; +begin + FreeAndNil(TreeView1); + inherited Destroy; +end; + +procedure IDEMenuClicked(Sender: TObject); +begin + if not Assigned(IdeInspectForm) then begin + IdeInspectForm := TIdeInspectForm.Create(Application); + end; + IdeInspectForm.Show; +end; + +procedure Register; +begin + RegisterIDEMenuCommand(itmViewIDEInternalsWindows, 'mnuIdeInspector', ideinspInspectIDE, nil, + @IDEMenuClicked); +end; + +end. +