/ide/codebrowser.pas
Pascal | 3356 lines | 2875 code | 280 blank | 201 comment | 398 complexity | e2cb45deae453ab5eab4e6f5b1f1ff4f MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, MPL-2.0-no-copyleft-exception
- {
- ***************************************************************************
- * *
- * This source is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This code is distributed in the hope that it will be useful, but *
- * WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * General Public License for more details. *
- * *
- * A copy of the GNU General Public License is available on the World *
- * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
- * obtain it by writing to the Free Software Foundation, *
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- * *
- ***************************************************************************
- Author: Mattias Gaertner
- Abstract:
- Browser for packages, classes, methods, functions.
- Scope:
- Browse units of IDE, or a project or a package.
- Browse with required packages or without.
- Sort:
- Owner, unit, class, visibility, type (procedure, var, const, ...), identifier
- Notes:
- The codetools provides TCodeTree of every unit.
- ToDo:
- - pause
- - scan recently used packages
- - scan packages in global links
- }
- unit CodeBrowser;
- {$mode objfpc}{$H+}
- {off $DEFINE VerboseCodeBrowser}
- interface
- uses
- // RTL + FCL + LCL
- Classes, SysUtils, types, AVL_Tree,
- LCLProc, LResources, Forms, Controls, Graphics, Dialogs, Clipbrd, StdCtrls,
- ExtCtrls, ComCtrls, Buttons, Menus, HelpIntfs, LCLIntf,
- // CodeTools
- BasicCodeTools, DefineTemplates, CodeTree, CodeCache,
- CodeToolsStructs, CodeToolManager, PascalParserTool, LinkScanner, FileProcs,
- CodeIndex, StdCodeTools, SourceLog, CustomCodeTool,
- // LazUtils
- LazFileUtils, LazUtilities,
- // IDEIntf
- IDEWindowIntf, SrcEditorIntf, IDEMsgIntf, IDEDialogs, LazConfigStorage,
- IDEHelpIntf, PackageIntf, IDECommands, LazIDEIntf,
- IDEExternToolIntf,
- // IDE
- Project, DialogProcs, PackageSystem, PackageDefs, LazarusIDEStrConsts,
- IDEOptionDefs, etFPCMsgParser, BasePkgManager, EnvironmentOpts;
- type
- TCodeBrowserLevel = (
- cblPackages,
- cblUnits,
- cblIdentifiers
- );
-
- TCodeBrowserTextFilter = (
- cbtfBegins,
- cbtfContains
- );
-
- const
- CodeBrowserLevelNames: array[TCodeBrowserLevel] of string = (
- 'Packages',
- 'Units',
- 'Identifiers'
- );
-
- CodeBrowserTextFilterNames: array[TCodeBrowserTextFilter] of string = (
- 'Begins',
- 'Contains'
- );
- CodeBrowserIDEName = ' '+'Lazarus IDE';// Note: space is needed to avoid name clashing
- CodeBrowserProjectName = ' '+'Project';
- CodeBrowserHidden = ' ';
- CodeBrowserMaxTVIdentifiers = 5000; // the maximum amount of identifiers shown in the treeview
- type
- { TCodeBrowserViewOptions }
- TCodeBrowserViewOptions = class
- private
- FChangeStamp: integer;
- FModified: boolean;
- FScope: string;
- FLevels: TStrings;
- FShowEmptyNodes: boolean;
- FShowPrivate: boolean;
- FShowProtected: boolean;
- FStoreWithRequiredPackages: boolean;
- FWithRequiredPackages: boolean;
- FLevelFilterText: array[TCodeBrowserLevel] of string;
- FLevelFilterType: array[TCodeBrowserLevel] of TCodeBrowserTextFilter;
- function GetLevelFilterText(Level: TCodeBrowserLevel): string;
- function GetLevelFilterType(Level: TCodeBrowserLevel): TCodeBrowserTextFilter;
- procedure SetLevelFilterText(Level: TCodeBrowserLevel; const AValue: string);
- procedure SetLevelFilterType(Level: TCodeBrowserLevel;
- const AValue: TCodeBrowserTextFilter);
- procedure SetModified(const AValue: boolean);
- procedure SetScope(const AValue: string);
- procedure SetLevels(const AValue: TStrings);
- procedure SetShowEmptyNodes(const AValue: boolean);
- procedure SetShowPrivate(const AValue: boolean);
- procedure SetShowProtected(const AValue: boolean);
- procedure SetStoreWithRequiredPackages(const AValue: boolean);
- procedure SetWithRequiredPackages(const AValue: boolean);
- procedure IncreaseChangeStamp;
- public
- constructor Create;
- destructor Destroy; override;
- procedure Clear;
- procedure LoadFromConfig(ConfigStore: TConfigStorage; const Path: string);
- procedure SaveToConfig(ConfigStore: TConfigStorage; const Path: string);
- function HasLevel(Level: TCodeBrowserLevel): boolean;
- public
- property Scope: string read FScope write SetScope;
- property WithRequiredPackages: boolean read FWithRequiredPackages write SetWithRequiredPackages;
- property StoreWithRequiredPackages: boolean read FStoreWithRequiredPackages write SetStoreWithRequiredPackages;
- property Levels: TStrings read FLevels write SetLevels;
- property ShowPrivate: boolean read FShowPrivate write SetShowPrivate;
- property ShowProtected: boolean read FShowProtected write SetShowProtected;
- property ShowEmptyNodes: boolean read FShowEmptyNodes write SetShowEmptyNodes;
- property LevelFilterText[Level: TCodeBrowserLevel]: string read GetLevelFilterText write SetLevelFilterText;
- property LevelFilterType[Level: TCodeBrowserLevel]: TCodeBrowserTextFilter read GetLevelFilterType write SetLevelFilterType;
- property Modified: boolean read FModified write SetModified;
- property ChangeStamp: integer read FChangeStamp;
- end;
- TCodeBrowserWorkStage = (
- cbwsGetScopeOptions,
- cbwsGatherPackages,
- cbwsFreeUnusedPackages,
- cbwsAddNewPackages,
- cbwsGatherFiles,
- cbwsGatherOutdatedFiles,
- cbwsUpdateUnits,
- cbwsGetViewOptions,
- cbwsUpdateTreeView,
- cbwsFinished
- );
-
- TExpandableNodeType = (
- entPackage,
- entUnit,
- entClass
- );
-
- TCopyNodeType = (
- cntIdentifier,
- cntDescription
- );
- { TCodeBrowserView }
- TCodeBrowserView = class(TForm)
- AllClassesSeparatorMenuItem: TMenuItem;
- AllPackagesSeparatorMenuItem: TMenuItem;
- AllUnitsSeparatorMenuItem: TMenuItem;
- BrowseTreeView: TTreeView;
- UseIdentifierInCurUnitMenuItem: TMenuItem;
- UseUnitInCurUnitMenuItem: TMenuItem;
- RescanButton: TButton;
- IdleTimer1: TIdleTimer;
- UsePkgInProjectMenuItem: TMenuItem;
- UsePkgInCurUnitMenuItem: TMenuItem;
- UseSeparatorMenuItem: TMenuItem;
- ShowEmptyNodesCheckBox: TCheckBox;
- CollapseAllClassesMenuItem: TMenuItem;
- CollapseAllPackagesMenuItem: TMenuItem;
- CollapseAllUnitsMenuItem: TMenuItem;
- CopyDescriptionMenuItem: TMenuItem;
- CopyIdentifierMenuItem: TMenuItem;
- CopySeparatorMenuItem: TMenuItem;
- ExpandAllClassesMenuItem: TMenuItem;
- ExpandAllPackagesMenuItem: TMenuItem;
- ExpandAllUnitsMenuItem: TMenuItem;
- ExportMenuItem: TMenuItem;
- IdentifierFilterBeginsSpeedButton: TSpeedButton;
- IdentifierFilterContainsSpeedButton: TSpeedButton;
- IdentifierFilterEdit: TEdit;
- ImageList1: TImageList;
- LevelsGroupBox: TGroupBox;
- OpenMenuItem: TMenuItem;
- OptionsGroupBox: TGroupBox;
- PackageFilterBeginsSpeedButton: TSpeedButton;
- PackageFilterContainsSpeedButton: TSpeedButton;
- PackageFilterEdit: TEdit;
- PopupMenu1: TPopupMenu;
- ProgressBar1: TProgressBar;
- ScopeComboBox: TComboBox;
- ScopeGroupBox: TGroupBox;
- ScopeWithRequiredPackagesCheckBox: TCheckBox;
- ShowIdentifiersCheckBox: TCheckBox;
- ShowPackagesCheckBox: TCheckBox;
- ShowPrivateCheckBox: TCheckBox;
- ShowProtectedCheckBox: TCheckBox;
- ShowUnitsCheckBox: TCheckBox;
- StatusBar1: TStatusBar;
- UnitFilterBeginsSpeedButton: TSpeedButton;
- UnitFilterContainsSpeedButton: TSpeedButton;
- UnitFilterEdit: TEdit;
- procedure BrowseTreeViewMouseMove(Sender: TObject; {%H-}Shift: TShiftState; {%H-}X,
- {%H-}Y: Integer);
- procedure FormDeactivate(Sender: TObject);
- procedure UseIdentifierInCurUnitMenuItemClick(Sender: TObject);
- procedure UsePkgInCurUnitMenuItemClick(Sender: TObject);
- procedure UsePkgInProjectMenuItemClick(Sender: TObject);
- procedure UseUnitInCurUnitMenuItemClick(Sender: TObject);
- procedure BrowseTreeViewMouseDown(Sender: TOBject; {%H-}Button: TMouseButton;
- Shift: TShiftState; X, Y: Integer);
- procedure BrowseTreeViewShowHint(Sender: TObject; HintInfo: PHintInfo);
- procedure CollapseAllPackagesMenuItemClick(Sender: TObject);
- procedure CollapseAllUnitsMenuItemClick(Sender: TObject);
- procedure CollapseAllClassesMenuItemClick(Sender: TObject);
- procedure CopyDescriptionMenuItemClick(Sender: TObject);
- procedure CopyIdentifierMenuItemClick(Sender: TObject);
- procedure ExpandAllClassesMenuItemClick(Sender: TObject);
- procedure ExpandAllPackagesMenuItemClick(Sender: TObject);
- procedure ExpandAllUnitsMenuItemClick(Sender: TObject);
- procedure ExportMenuItemClick(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure IdleTimer1Timer(Sender: TObject);
- procedure PackageFilterEditChange(Sender: TObject);
- procedure PackageFilterEditEditingDone(Sender: TObject);
- procedure PopupMenu1Popup(Sender: TObject);
- procedure RescanButtonClick(Sender: TObject);
- procedure ScopeComboBoxChange(Sender: TObject);
- procedure ScopeWithRequiredPackagesCheckBoxChange(Sender: TObject);
- procedure OnIdle(Sender: TObject; var Done: Boolean);
- procedure OpenMenuItemClick(Sender: TObject);
- procedure ShowIdentifiersCheckBoxChange(Sender: TObject);
- procedure ShowPackagesCheckBoxChange(Sender: TObject);
- procedure ShowPrivateCheckBoxChange(Sender: TObject);
- procedure ShowUnitsCheckBoxChange(Sender: TObject);
- private
- FHintManager: THintWindowManager;
- FIDEDescription: string;
- FIdleConnected: boolean;
- FOptions: TCodeBrowserViewOptions;
- FOptionsChangeStamp: integer;
- FProjectDescription: string;
- FParserRoot: TCodeBrowserUnitList;
- FScannedBytes: PtrInt;
- FScannedIdentifiers: PtrInt;
- FScannedLines: PtrInt;
- FScannedPackages: integer;
- FScannedUnits: integer;
- FUpdateNeeded: boolean;
- FViewRoot: TCodeBrowserUnitList;
- FVisibleIdentifiers: PtrInt;
- FVisiblePackages: integer;
- FVisibleUnits: integer;
- FWorkingParserRoot: TCodeBrowserUnitList;
- fUpdateCount: integer;
- fStage: TCodeBrowserWorkStage;
- fOutdatedFiles: TAVLTree;// tree of TCodeBrowserUnit
- fLastStatusBarUpdate: TDateTime;
- ImgIDDefault: integer;
- ImgIDProgramCode: Integer;
- ImgIDUnitCode: Integer;
- ImgIDInterfaceSection: Integer;
- ImgIDImplementation: Integer;
- ImgIDInitialization: Integer;
- ImgIDFinalization: Integer;
- ImgIDTypeSection: Integer;
- ImgIDType: Integer;
- ImgIDVarSection: Integer;
- ImgIDVariable: Integer;
- ImgIDConstSection: Integer;
- ImgIDConst: Integer;
- ImgIDClass: Integer;
- ImgIDProc: Integer;
- ImgIDProperty: Integer;
- ImgIDPackage: Integer;
- ImgIDProject: Integer;
- procedure LoadOptions;
- procedure LoadLevelsGroupBox;
- procedure LoadFilterGroupbox;
- procedure FillScopeComboBox;
- procedure SetIdleConnected(AValue: boolean);
- procedure SetScannedBytes(const AValue: PtrInt);
- procedure SetScannedIdentifiers(const AValue: PtrInt);
- procedure SetScannedLines(const AValue: PtrInt);
- procedure SetScannedPackages(const AValue: integer);
- procedure SetScannedUnits(const AValue: integer);
- procedure SetUpdateNeeded(const AValue: boolean);
- procedure SetVisibleIdentifiers(const AValue: PtrInt);
- procedure SetVisiblePackages(const AValue: integer);
- procedure SetVisibleUnits(const AValue: integer);
- procedure Work(var Done: Boolean);
- procedure WorkGetScopeOptions;
- procedure WorkGatherPackages;
- procedure WorkFreeUnusedPackages;
- procedure WorkAddNewUnitLists;
- procedure WorkGatherFileLists;
- procedure WorkUpdateFileList(List: TCodeBrowserUnitList);
- procedure WorkGatherOutdatedFiles;
- procedure WorkUpdateUnits;
- procedure WorkUpdateUnit(AnUnit: TCodeBrowserUnit);
- procedure WorkGetViewOptions;
- procedure WorkUpdateTreeView;
- procedure FreeUnitList(List: TCodeBrowserUnitList);
- procedure UpdateStatusBar(Lazy: boolean);
- procedure RemoveUnit(AnUnit: TCodeBrowserUnit);
- function CountIdentifiers(Tool: TCodeTool): integer;
- procedure UpdateTreeView;
- procedure ClearTreeView;
- procedure InitTreeView;
- function ListOwnerToText(const ListOwner: string): string;
- procedure InitImageList;
- function GetNodeImage(CodeNode: TObject): integer;
- function GetTVNodeHint(TVNode: TTreeNode): string;
- function GetCodeHelp(TVNode: TTreeNode; out BaseURL, HTMLHint: string): boolean;
- procedure ExpandCollapseAllNodesInTreeView(NodeType: TExpandableNodeType;
- Expand: boolean);
- procedure CopyNode(TVNode: TTreeNode; NodeType: TCopyNodeType);
- function GetCodeTool(AnUnit: TCodeBrowserUnit): TStandardCodeTool;
- procedure GetNodeIdentifier(Tool: TStandardCodeTool;
- CTNode: TCodeTreeNode; out Identifier: string);
- procedure GetNodeDescription(Tool: TStandardCodeTool;
- CTNode: TCodeTreeNode; Identifier: string; out Description: string);
- function GetSelectedUnit: TCodeBrowserUnit;
- function GetSelectedPackage: TLazPackage;
- function GetCurUnitInSrcEditor(out FileOwner: TObject;
- out UnitCode: TCodeBuffer): boolean;
- function GetCurPackageInSrcEditor: TLazPackage;
- procedure OpenTVNode(TVNode: TTreeNode);
- procedure UseUnitInSrcEditor(InsertIdentifier: boolean);
- procedure CloseHintWindow;
- public
- procedure BeginUpdate;
- procedure EndUpdate;
- function ExportTree: TModalResult;
- function ExportTreeAsText(Filename: string): TModalResult;
- function GetScopeToCurUnitOwner(UseFCLAsDefault: boolean): string;
- function SetScopeToCurUnitOwner(UseFCLAsDefault,
- WithRequiredPackages: boolean): boolean;
- procedure SetFilterToSimpleIdentifier(Identifier: string);
- procedure InvalidateStage(AStage: TCodeBrowserWorkStage);
- public
- property ParserRoot: TCodeBrowserUnitList read FParserRoot;
- property WorkingParserRoot: TCodeBrowserUnitList read FWorkingParserRoot;
- property ViewRoot: TCodeBrowserUnitList read FViewRoot;
- property Options: TCodeBrowserViewOptions read FOptions;
- property IDEDescription: string read FIDEDescription;
- property ProjectDescription: string read FProjectDescription;
- property ScannedPackages: integer read FScannedPackages write SetScannedPackages;
- property ScannedUnits: integer read FScannedUnits write SetScannedUnits;
- property ScannedLines: PtrInt read FScannedLines write SetScannedLines;
- property ScannedBytes: PtrInt read FScannedBytes write SetScannedBytes;
- property ScannedIdentifiers: PtrInt read FScannedIdentifiers write SetScannedIdentifiers;
- property VisiblePackages: integer read FVisiblePackages write SetVisiblePackages;
- property VisibleUnits: integer read FVisibleUnits write SetVisibleUnits;
- property VisibleIdentifiers: PtrInt read FVisibleIdentifiers write SetVisibleIdentifiers;
- property UpdateNeeded: boolean read FUpdateNeeded write SetUpdateNeeded;
- property IdleConnected: boolean read FIdleConnected write SetIdleConnected;
- end;
- type
- { TQuickFixIdentifierNotFound_Search }
- TQuickFixIdentifierNotFound_Search = class(TMsgQuickFix)
- public
- function IsApplicable(Msg: TMessageLine; out Identifier: string): boolean;
- procedure CreateMenuItems(Fixes: TMsgQuickFixes); override;
- procedure QuickFix({%H-}Fixes: TMsgQuickFixes; Msg: TMessageLine); override;
- end;
- var
- CodeBrowserView: TCodeBrowserView = nil;
-
- function StringToCodeBrowserTextFilter(const s: string): TCodeBrowserTextFilter;
- procedure InitCodeBrowserQuickFixItems;
- procedure CreateCodeBrowser(DisableAutoSizing: boolean);
- procedure ShowCodeBrowser(const Identifier: string);
- implementation
- {$R *.lfm}
- const
- ProgressGetScopeStart=0;
- ProgressGetScopeSize=10;
- ProgressGatherPackagesStart=ProgressGetScopeStart+ProgressGetScopeSize;
- ProgressGatherPackagesSize=30;
- ProgressFreeUnusedPkgStart=ProgressGatherPackagesStart+ProgressGatherPackagesSize;
- ProgressFreeUnusedPkgSize=100;
- ProgressAddNewUnitListsStart=ProgressFreeUnusedPkgStart+ProgressFreeUnusedPkgSize;
- ProgressAddNewUnitListsSize=300;
- ProgressGatherFileListsStart=ProgressAddNewUnitListsStart+ProgressAddNewUnitListsSize;
- ProgressGatherFileListsSize=300;
- ProgressGatherOutdatedFilesStart=ProgressGatherFileListsStart+ProgressGatherFileListsSize;
- ProgressGatherOutdatedFilesSize=300;
- ProgressUpdateUnitsStart=ProgressGatherOutdatedFilesStart+ProgressGatherOutdatedFilesSize;
- ProgressUpdateUnitsSize=3000;
- ProgressGetViewOptionsStart=ProgressUpdateUnitsStart+ProgressUpdateUnitsSize;
- ProgressGetViewOptionsSize=10;
- ProgressUpdateTreeViewStart=ProgressGetViewOptionsStart+ProgressGetViewOptionsSize;
- ProgressUpdateTreeViewSize=1000;
- ProgressTotal=ProgressUpdateTreeViewStart+ProgressUpdateTreeViewSize;
- const
- ProcDescFlags = [phpWithStart,phpWithParameterNames,
- phpWithVarModifiers,phpWithResultType,phpWithoutSemicolon];
- ProcIdentifierFlags = [phpWithoutClassKeyword,phpWithParameterNames,
- phpWithoutSemicolon];
- PropDescFlags = [phpWithoutClassKeyword,phpWithParameterNames,
- phpWithVarModifiers,phpWithResultType];
- function StringToCodeBrowserTextFilter(const s: string): TCodeBrowserTextFilter;
- begin
- for Result:=Low(TCodeBrowserTextFilter) to High(TCodeBrowserTextFilter) do
- if SysUtils.CompareText(CodeBrowserTextFilterNames[Result],s)=0 then exit;
- Result:=cbtfBegins;
- end;
- procedure InitCodeBrowserQuickFixItems;
- begin
- RegisterIDEMsgQuickFix(TQuickFixIdentifierNotFound_Search.Create);
- end;
- procedure CreateCodeBrowser(DisableAutoSizing: boolean);
- begin
- if CodeBrowserView=nil then
- IDEWindowCreators.CreateForm(CodeBrowserView,TCodeBrowserView,
- DisableAutoSizing,LazarusIDE.OwningComponent)
- else if DisableAutoSizing then
- CodeBrowserView.DisableAutoSizing{$IFDEF DebugDisableAutoSizing}('CreateCodeBrowser'){$ENDIF};
- end;
- procedure ShowCodeBrowser(const Identifier: string);
- begin
- IDEWindowCreators.ShowForm(NonModalIDEWindowNames[nmiwCodeBrowser],true);
- CodeBrowserView.SetScopeToCurUnitOwner(true,true);
- CodeBrowserView.SetFilterToSimpleIdentifier(Identifier);
- end;
- { TCodeBrowserView }
- procedure TCodeBrowserView.FormCreate(Sender: TObject);
- begin
- FHintManager:=THintWindowManager.Create;
- FOptions:=TCodeBrowserViewOptions.Create;
-
- FIDEDescription:=lisLazarusIDE;
- FProjectDescription:=dlgProject;
- Name:=NonModalIDEWindowNames[nmiwCodeBrowser];
- Caption:=lisCodeBrowser;
- ScopeGroupBox.Caption:=dlgSearchScope;
- ScopeWithRequiredPackagesCheckBox.Caption:=lisWithRequiredPackages;
- RescanButton.Caption:=lisRescan;
- LevelsGroupBox.Caption:=lisLevels;
- ShowPackagesCheckBox.Caption:=lisShowPackages;
- ShowUnitsCheckBox.Caption:=lisShowUnits;
- ShowIdentifiersCheckBox.Caption:=lisShowIdentifiers;
- OptionsGroupBox.Caption:=lisFilter;
- ShowPrivateCheckBox.Caption:=lisPrivate;
- ShowProtectedCheckBox.Caption:=lisProtected;
- ShowEmptyNodesCheckBox.Caption:=lisShowEmptyUnitsPackages;
- ExpandAllPackagesMenuItem.Caption:=lisExpandAllPackages;
- CollapseAllPackagesMenuItem.Caption:=lisCollapseAllPackages;
- ExpandAllUnitsMenuItem.Caption:=lisExpandAllUnits;
- CollapseAllUnitsMenuItem.Caption:=lisCollapseAllUnits;
- ExpandAllClassesMenuItem.Caption:=lisExpandAllClasses;
- CollapseAllClassesMenuItem.Caption:=lisCollapseAllClasses;
- ExportMenuItem.Caption:=lisDlgExport;
- OpenMenuItem.Caption:=lisOpen;
- // UsePkgInProjectMenuItem.Caption: see PopupMenu1Popup
- // UsePkgInCurUnitMenuItem.Caption: see PopupMenu1Popup
- // UseUnitInCurUnitMenuItem.Caption: see PopupMenu1Popup
- PackageFilterBeginsSpeedButton.Caption:=lisBegins;
- PackageFilterBeginsSpeedButton.Hint:=lisPackageNameBeginsWith;
- PackageFilterContainsSpeedButton.Caption:=lisContains;
- PackageFilterContainsSpeedButton.Hint:=lisPackageNameContains;
- UnitFilterBeginsSpeedButton.Caption:=lisBegins;
- UnitFilterBeginsSpeedButton.Hint:=lisUnitNameBeginsWith;
- UnitFilterContainsSpeedButton.Caption:=lisContains;
- UnitFilterContainsSpeedButton.Hint:=lisUnitNameContains;
- IdentifierFilterBeginsSpeedButton.Caption:=lisBegins;
- IdentifierFilterBeginsSpeedButton.Hint:=lisIdentifierBeginsWith;
- IdentifierFilterContainsSpeedButton.Caption:=lisContains;
- IdentifierFilterContainsSpeedButton.Hint:=lisIdentifierContains;
-
- ProgressBar1.Max:=ProgressTotal;
- InitImageList;
- LoadOptions;
- FillScopeComboBox;
- ScopeComboBox.ItemIndex:=0;
- IdleConnected:=true;
- end;
- procedure TCodeBrowserView.FormDestroy(Sender: TObject);
- begin
- IdleConnected:=false;
- ClearTreeView;
- FreeAndNil(fOutdatedFiles);
- FreeAndNil(FViewRoot);
- FreeAndNil(FParserRoot);
- FreeAndNil(FWorkingParserRoot);
- FreeAndNil(FOptions);
- FreeAndNil(FHintManager);
- IdleConnected:=false;
- end;
- procedure TCodeBrowserView.IdleTimer1Timer(Sender: TObject);
- begin
- InvalidateStage(cbwsGetViewOptions);
- IdleTimer1.Enabled:=false;
- end;
- procedure TCodeBrowserView.PackageFilterEditChange(Sender: TObject);
- begin
- IdleTimer1.Enabled:=true;
- end;
- procedure TCodeBrowserView.PackageFilterEditEditingDone(Sender: TObject);
- begin
- InvalidateStage(cbwsGetViewOptions);
- end;
- procedure TCodeBrowserView.PopupMenu1Popup(Sender: TObject);
- var
- TVNode: TTreeNode;
- Node: TObject;
- Identifier: String;
- UnitList: TCodeBrowserUnitList;
- EnableUsePkgInProject: Boolean;
- APackage: TLazPackage;
- EnableUsePkgInCurUnit: Boolean;
- TargetPackage: TLazPackage;
- EnableUseUnitInCurUnit: Boolean;
- CurUnit: TCodeBrowserUnit;
- SrcEditUnitOwner: TObject;
- SrcEditUnitCode: TCodeBuffer;
- CurUnitName: String;
- SrcEditUnitName: String;
- CBNode: TCodeBrowserNode;
- EnableUseIdentifierInCurUnit: Boolean;
- SrcEdit: TSourceEditorInterface;
- begin
- ExpandAllPackagesMenuItem.Visible:=Options.HasLevel(cblPackages);
- CollapseAllPackagesMenuItem.Visible:=ExpandAllPackagesMenuItem.Visible;
- AllPackagesSeparatorMenuItem.Visible:=ExpandAllPackagesMenuItem.Visible;
-
- ExpandAllUnitsMenuItem.Visible:=Options.HasLevel(cblUnits);
- CollapseAllUnitsMenuItem.Visible:=ExpandAllUnitsMenuItem.Visible;
- AllUnitsSeparatorMenuItem.Visible:=ExpandAllUnitsMenuItem.Visible;
- ExpandAllClassesMenuItem.Visible:=Options.HasLevel(cblIdentifiers);
- CollapseAllClassesMenuItem.Visible:=ExpandAllClassesMenuItem.Visible;
- AllClassesSeparatorMenuItem.Visible:=ExpandAllClassesMenuItem.Visible;
- TVNode:=BrowseTreeView.Selected;
- Node:=nil;
- if TVNode<>nil then
- Node:=TObject(TVNode.Data);
- EnableUsePkgInProject:=false;
- EnableUsePkgInCurUnit:=false;
- EnableUseUnitInCurUnit:=false;
- EnableUseIdentifierInCurUnit:=false;
- if Node<>nil then begin
- Identifier:='';
- APackage:=nil;
- UnitList:=nil;
- CurUnit:=nil;
- TargetPackage:=nil;
- if Node is TCodeBrowserNode then begin
- Identifier:=TCodeBrowserNode(Node).Identifier;
- CBNode:=TCodeBrowserNode(Node);
- CurUnit:=CBNode.CBUnit;
- if CurUnit<>nil then
- UnitList:=CurUnit.UnitList;
- end else if Node is TCodeBrowserUnit then begin
- CurUnit:=TCodeBrowserUnit(Node);
- UnitList:=CurUnit.UnitList;
- end else if Node is TCodeBrowserUnitList then begin
- UnitList:=TCodeBrowserUnitList(Node);
- end;
- if UnitList<>nil then begin
- if UnitList.Owner=CodeBrowserProjectName then begin
- // project
- end else if UnitList.Owner=CodeBrowserIDEName then begin
- // IDE
- end else if UnitList.Owner=CodeBrowserHidden then begin
- // nothing
- end else begin
- // package
- APackage:=PackageGraph.FindPackageWithName(UnitList.Owner,nil);
- if APackage<>nil then begin
- // check if package can be added to project
- if Project1.FindDependencyByName(APackage.Name)=nil then begin
- EnableUsePkgInProject:=true;
- UsePkgInProjectMenuItem.Caption:=Format(lisUsePackageInProject, [
- APackage.Name]);
- end;
- // check if package can be added to package of src editor unit
- TargetPackage:=GetCurPackageInSrcEditor;
- if (TargetPackage<>nil)
- and (SysUtils.CompareText(TargetPackage.Name,APackage.Name)<>0)
- and (TargetPackage.FindDependencyByName(APackage.Name)=nil) then begin
- EnableUsePkgInCurUnit:=true;
- UsePkgInCurUnitMenuItem.Caption:=Format(
- lisUsePackageInPackage, [APackage.Name,
- TargetPackage.Name]);
- end;
- // check if unit can be added to project/package
- GetCurUnitInSrcEditor(SrcEditUnitOwner,SrcEditUnitCode);
- if (CurUnit<>nil) and (SrcEditUnitOwner<>nil) then begin
- CurUnitName:=ExtractFileNameOnly(CurUnit.Filename);
- SrcEditUnitName:=ExtractFileNameOnly(SrcEditUnitCode.Filename);
- if SysUtils.CompareText(CurUnitName,SrcEditUnitName)<>0 then begin
- EnableUseUnitInCurUnit:=true;
- UseUnitInCurUnitMenuItem.Caption:=
- Format(lisUseUnitInUnit, [CurUnitName, SrcEditUnitName]);
- if (Node is TCodeBrowserNode) and (Identifier<>'') then begin
- EnableUseIdentifierInCurUnit:=true;
- SrcEdit:=SourceEditorManagerIntf.ActiveEditor;
- UseIdentifierInCurUnitMenuItem.Caption:=
- Format(lisUseIdentifierInAt, [Identifier, ExtractFilename(
- SrcEdit.FileName), dbgs(SrcEdit.CursorScreenXY)]);
- end;
- end;
- end;
- end;
- end;
- end;
- OpenMenuItem.Visible:=true;
- CopyDescriptionMenuItem.Caption:=lisCopyDescription;
- CopyIdentifierMenuItem.Caption:=Format(lisCopyIdentifier, [Identifier]);
- CopyDescriptionMenuItem.Visible:=true;
- CopyIdentifierMenuItem.Visible:=Identifier<>'';
- CopySeparatorMenuItem.Visible:=true;
- UseUnitInCurUnitMenuItem.Enabled:=EnableUseUnitInCurUnit;
- UseUnitInCurUnitMenuItem.Visible:=true;
- if not EnableUseUnitInCurUnit then
- UseUnitInCurUnitMenuItem.Caption:=lisPkgMangUseUnit;
- UseIdentifierInCurUnitMenuItem.Enabled:=EnableUseIdentifierInCurUnit;
- UseIdentifierInCurUnitMenuItem.Visible:=true;
- if not EnableUseIdentifierInCurUnit then
- UseIdentifierInCurUnitMenuItem.Caption:=lisUseIdentifier;
- UsePkgInProjectMenuItem.Enabled:=EnableUsePkgInProject;
- UsePkgInProjectMenuItem.Visible:=true;
- if not EnableUsePkgInProject then
- UsePkgInProjectMenuItem.Caption:=lisUsePackageInProject2;
- UsePkgInCurUnitMenuItem.Enabled:=EnableUsePkgInCurUnit;
- UsePkgInCurUnitMenuItem.Visible:=true;
- if not EnableUsePkgInCurUnit then
- UsePkgInCurUnitMenuItem.Caption:=lisUsePackageInPackage2;
- end else begin
- OpenMenuItem.Visible:=false;
- CopyDescriptionMenuItem.Visible:=false;
- CopyIdentifierMenuItem.Visible:=false;
- CopySeparatorMenuItem.Visible:=false;
- UseUnitInCurUnitMenuItem.Visible:=false;
- UseIdentifierInCurUnitMenuItem.Visible:=false;
- UsePkgInProjectMenuItem.Visible:=false;
- UsePkgInCurUnitMenuItem.Visible:=false;
- UseSeparatorMenuItem.Visible:=false;
- end;
- end;
- procedure TCodeBrowserView.RescanButtonClick(Sender: TObject);
- begin
- UpdateNeeded:=true;
- InvalidateStage(cbwsGetScopeOptions);
- end;
- procedure TCodeBrowserView.ScopeComboBoxChange(Sender: TObject);
- begin
- InvalidateStage(cbwsGetScopeOptions);
- end;
- procedure TCodeBrowserView.ScopeWithRequiredPackagesCheckBoxChange(Sender: TObject);
- begin
- InvalidateStage(cbwsGetScopeOptions);
- end;
- procedure TCodeBrowserView.OnIdle(Sender: TObject; var Done: Boolean);
- begin
- if (Screen.GetCurrentModalForm<>nil) then exit;
- Work(Done);
- end;
- procedure TCodeBrowserView.OpenMenuItemClick(Sender: TObject);
- begin
- OpenTVNode(BrowseTreeView.Selected);
- end;
- procedure TCodeBrowserView.ShowIdentifiersCheckBoxChange(Sender: TObject);
- begin
- InvalidateStage(cbwsGetViewOptions);
- end;
- procedure TCodeBrowserView.ShowPackagesCheckBoxChange(Sender: TObject);
- begin
- //DebugLn(['TCodeBrowserView.ShowPackagesCheckBoxChange ']);
- InvalidateStage(cbwsGetViewOptions);
- end;
- procedure TCodeBrowserView.ShowPrivateCheckBoxChange(Sender: TObject);
- begin
- InvalidateStage(cbwsGetViewOptions);
- end;
- procedure TCodeBrowserView.ShowUnitsCheckBoxChange(Sender: TObject);
- begin
- InvalidateStage(cbwsGetViewOptions);
- end;
- procedure TCodeBrowserView.LoadOptions;
- begin
- BeginUpdate;
- ScopeWithRequiredPackagesCheckBox.Checked:=Options.WithRequiredPackages;
- ScopeComboBox.Text:=Options.Scope;
- LoadLevelsGroupBox;
- LoadFilterGroupbox;
- EndUpdate;
- end;
- procedure TCodeBrowserView.LoadLevelsGroupBox;
- begin
- ShowPackagesCheckBox.Checked:=Options.HasLevel(cblPackages);
- ShowUnitsCheckBox.Checked:=Options.HasLevel(cblUnits);
- ShowIdentifiersCheckBox.Checked:=Options.HasLevel(cblIdentifiers);
- end;
- procedure TCodeBrowserView.LoadFilterGroupbox;
- begin
- ShowPrivateCheckBox.Checked:=Options.ShowPrivate;
- ShowProtectedCheckBox.Checked:=Options.ShowProtected;
- ShowEmptyNodesCheckBox.Checked:=Options.ShowEmptyNodes;
- PackageFilterEdit.Text:=Options.LevelFilterText[cblPackages];
- case Options.LevelFilterType[cblPackages] of
- cbtfBegins: PackageFilterBeginsSpeedButton.Down:=true;
- cbtfContains: PackageFilterContainsSpeedButton.Down:=true;
- end;
- UnitFilterEdit.Text:=Options.LevelFilterText[cblUnits];
- case Options.LevelFilterType[cblUnits] of
- cbtfBegins: UnitFilterBeginsSpeedButton.Down:=true;
- cbtfContains: UnitFilterContainsSpeedButton.Down:=true;
- end;
- IdentifierFilterEdit.Text:=Options.LevelFilterText[cblIdentifiers];
- case Options.LevelFilterType[cblIdentifiers] of
- cbtfBegins: IdentifierFilterBeginsSpeedButton.Down:=true;
- cbtfContains: IdentifierFilterContainsSpeedButton.Down:=true;
- end;
- end;
- procedure TCodeBrowserView.FillScopeComboBox;
- var
- sl: TStringList;
- i: Integer;
- begin
- if ScopeComboBox.Items.Count=0 then begin
- sl:=TStringList.Create;
- try
- if PackageGraph<>nil then begin
- for i:=0 to PackageGraph.Count-1 do
- sl.Add(PackageGraph.Packages[i].Name);
- end;
- sl.Sort;
- sl.Insert(0,IDEDescription);
- sl.Insert(1,ProjectDescription);
- ScopeComboBox.Items.Assign(sl);
- finally
- sl.Free;
- end;
- end;
- end;
- procedure TCodeBrowserView.SetIdleConnected(AValue: boolean);
- begin
- if csDestroying in ComponentState then AValue:=false;
- if FIdleConnected=AValue then Exit;
- FIdleConnected:=AValue;
- if IdleConnected then
- Application.AddOnIdleHandler(@OnIdle)
- else
- Application.RemoveOnIdleHandler(@OnIdle);
- end;
- procedure TCodeBrowserView.InitImageList;
- begin
- ImgIDDefault := Imagelist1.AddResourceName(HInstance, 'ce_default');
- ImgIDProgramCode := Imagelist1.AddResourceName(HInstance, 'ce_program');
- ImgIDUnitCode := Imagelist1.AddResourceName(HInstance, 'ce_unit');
- ImgIDInterfaceSection := Imagelist1.AddResourceName(HInstance, 'ce_interface');
- ImgIDImplementation := Imagelist1.AddResourceName(HInstance, 'ce_implementation');
- ImgIDInitialization := Imagelist1.AddResourceName(HInstance, 'ce_initialization');
- ImgIDFinalization := Imagelist1.AddResourceName(HInstance, 'ce_finalization');
- ImgIDTypeSection := Imagelist1.AddResourceName(HInstance, 'ce_type');
- ImgIDType := Imagelist1.AddResourceName(HInstance, 'ce_type');
- ImgIDVarSection := Imagelist1.AddResourceName(HInstance, 'ce_variable');
- ImgIDVariable := Imagelist1.AddResourceName(HInstance, 'ce_variable');
- ImgIDConstSection := Imagelist1.AddResourceName(HInstance, 'ce_const');
- ImgIDConst := Imagelist1.AddResourceName(HInstance, 'ce_const');
- ImgIDClass := Imagelist1.AddResourceName(HInstance, 'ce_class');
- ImgIDProc := Imagelist1.AddResourceName(HInstance, 'ce_procedure');
- ImgIDProperty := Imagelist1.AddResourceName(HInstance, 'ce_property');
- ImgIDPackage := Imagelist1.AddResourceName(HInstance, 'item_package');
- ImgIDProject := Imagelist1.AddResourceName(HInstance, 'item_project');
- end;
- procedure TCodeBrowserView.SetScannedBytes(const AValue: PtrInt);
- begin
- if FScannedBytes=AValue then exit;
- FScannedBytes:=AValue;
- end;
- procedure TCodeBrowserView.SetScannedIdentifiers(const AValue: PtrInt);
- begin
- if FScannedIdentifiers=AValue then exit;
- FScannedIdentifiers:=AValue;
- end;
- procedure TCodeBrowserView.SetScannedLines(const AValue: PtrInt);
- begin
- if FScannedLines=AValue then exit;
- FScannedLines:=AValue;
- end;
- procedure TCodeBrowserView.SetScannedPackages(const AValue: integer);
- begin
- if FScannedPackages=AValue then exit;
- FScannedPackages:=AValue;
- end;
- procedure TCodeBrowserView.SetScannedUnits(const AValue: integer);
- begin
- if FScannedUnits=AValue then exit;
- FScannedUnits:=AValue;
- end;
- procedure TCodeBrowserView.SetUpdateNeeded(const AValue: boolean);
- procedure InvalidateFileList(StartList: TCodeBrowserUnitList);
- var
- APackage: TCodeBrowserUnitList;
- Node: TAVLTreeNode;
- begin
- if StartList=nil then exit;
- StartList.UnitsValid:=false;
- if (StartList.UnitLists=nil) then exit;
- Node:=StartList.UnitLists.FindLowest;
- while Node<>nil do begin
- APackage:=TCodeBrowserUnitList(Node.Data);
- InvalidateFileList(APackage);
- Node:=StartList.UnitLists.FindSuccessor(Node);
- end;
- end;
- begin
- if FUpdateNeeded=AValue then exit;
- FUpdateNeeded:=AValue;
- if FUpdateNeeded then begin
- InvalidateFileList(FParserRoot);
- InvalidateFileList(FWorkingParserRoot);
- InvalidateStage(cbwsGetScopeOptions);
- end;
- end;
- procedure TCodeBrowserView.SetVisibleIdentifiers(const AValue: PtrInt);
- begin
- if FVisibleIdentifiers=AValue then exit;
- FVisibleIdentifiers:=AValue;
- end;
- procedure TCodeBrowserView.SetVisiblePackages(const AValue: integer);
- begin
- if FVisiblePackages=AValue then exit;
- FVisiblePackages:=AValue;
- end;
- procedure TCodeBrowserView.SetVisibleUnits(const AValue: integer);
- begin
- if FVisibleUnits=AValue then exit;
- FVisibleUnits:=AValue;
- end;
- procedure TCodeBrowserView.UseUnitInSrcEditor(InsertIdentifier: boolean);
- var
- // temporary data, that can be freed on next idle
- SelectedUnit: TCodeBrowserUnit;
- TVNode: TTreeNode;
- Node: TObject;
- IdentifierNode: TCodeBrowserNode;
- // normal vars
- SelectedUnitName: String;
- SelectedCode: TCodeBuffer;
- List: TFPList;
- SelectedOwner: TObject;
- APackage: TLazPackage;
- TargetCode: TCodeBuffer;
- TargetOwner: TObject;
- SrcEdit: TSourceEditorInterface;
- Code: TCodeBuffer;
- CodeMarker: TSourceLogMarker;
- Identifier: String;
- SelectedUnitFilename: String;
- IdentStart: integer;
- IdentEnd: integer;
- InsertStartPos: TPoint;
- InsertEndPos: TPoint;
- begin
- TVNode:=BrowseTreeView.Selected;
- if TVNode=nil then exit;
- Node:=TObject(TVNode.Data);
- IdentifierNode:=nil;
- SelectedUnit:=nil;
- if Node is TCodeBrowserNode then begin
- IdentifierNode:=TCodeBrowserNode(Node);
- Identifier:=IdentifierNode.Identifier;
- SelectedUnit:=IdentifierNode.CBUnit;
- end else if Node is TCodeBrowserUnit then begin
- SelectedUnit:=TCodeBrowserUnit(Node);
- end else
- exit;
- if (SelectedUnit=nil) then exit;
- SelectedUnitFilename:=SelectedUnit.Filename;
- if InsertIdentifier then begin
- if (IdentifierNode=nil) or (Identifier='') then exit;
- end;
- if SelectedUnit.UnitList=nil then begin
- DebugLn(['TCodeBrowserView.UseUnitInSrcEditor not implemented: '
- +'SelectedUnit.UnitList=nil']);
- IDEMessageDialog('Implement me',
- 'TCodeBrowserView.UseUnitInSrcEditor not implemented: '
- +'SelectedUnit.UnitList=nil',
- mtInformation, [mbOk]);
- exit;
- end;
- SelectedOwner:=nil;
- if SelectedUnit.UnitList.Owner=CodeBrowserProjectName then begin
- // project
- SelectedOwner:=Project1;
- end else if SelectedUnit.UnitList.Owner=CodeBrowserIDEName then begin
- // IDE can not be added as dependency
- DebugLn(['TCodeBrowserView.UseUnitInSrcEditor IDE can not be '
- +'added as dependency']);
- exit;
- end else if SelectedUnit.UnitList.Owner=CodeBrowserHidden then begin
- // nothing
- DebugLn(['TCodeBrowserView.UseUnitInSrcEditor hidden unitlist']
- );
- exit;
- end else begin
- // package
- APackage:=PackageGraph.FindPackageWithName(SelectedUnit.UnitList.Owner,nil);
- if APackage=nil then begin
- DebugLn(['TCodeBrowserView.UseUnitInSrcEditor package not '
- +'found: ', SelectedUnit.UnitList.Owner]);
- exit;
- end;
- SelectedOwner:=APackage;
- end;
- // get target unit
- if not GetCurUnitInSrcEditor(TargetOwner, TargetCode) then exit;
- if (not (TargetOwner is TProject))
- and (not (TargetOwner is TLazPackage)) then begin
- DebugLn(['TCodeBrowserView.UseUnitInSrcEditor not implemented: '
- +'TargetOwner=', DbgSName(TargetOwner)]);
- IDEMessageDialog('Implement me',
- 'TCodeBrowserView.UseUnitInSrcEditor not implemented: '
- +'TargetOwner='+DbgSName(TargetOwner),
- mtInformation, [mbOk]);
- exit;
- end;
- if (SelectedOwner is TProject) and (TargetOwner<>SelectedOwner) then begin
- // unit of project can not be used by other packages/projects
- IDEMessageDialog(lisImpossible,
- lisAProjectUnitCanNotBeUsedByOtherPackagesProjects,
- mtError, [mbCancel]);
- exit;
- end;
- // safety first: clear the references, they will become invalid on next idle
- SelectedUnit:=nil;
- IdentifierNode:=nil;
- Node:=nil;
- TVNode:=nil;
- List:=TFPList.Create;
- CodeMarker:=nil;
- try
- SrcEdit:=SourceEditorManagerIntf.ActiveEditor;
- if SrcEdit=nil then exit;
- InsertStartPos:=SrcEdit.CursorTextXY;
- Code:=TCodeBuffer(SrcEdit.CodeToolsBuffer);
- CodeMarker:=Code.AddMarkerXY(InsertStartPos.Y,InsertStartPos.X,Self);
- List.Add(TargetOwner);
- if (SelectedOwner is TLazPackage) then begin
- // add package to TargetOwner
- APackage:=TLazPackage(SelectedOwner);
- if PkgBoss.AddDependencyToOwners(List, APackage)<>mrOk then begin
- DebugLn(['TCodeBrowserView.UseUnitInSrcEditor PkgBoss.'
- +'AddDependencyToOwners failed']);
- exit;
- end;
- end;
- // get nice unit name
- LazarusIDE.SaveSourceEditorChangesToCodeCache(nil);
- SelectedCode:=CodeToolBoss.LoadFile(SelectedUnitFilename, true, false);
- if SelectedCode=nil then begin
- debugln(['TCodeBrowserView.UseUnitInSrcEditor failed to load SelectedUnitFilename=',SelectedUnitFilename]);
- exit;
- end;
- SelectedUnitName:=CodeToolBoss.GetSourceName(SelectedCode, false);
- // add unit to uses section
- if not CodeToolBoss.AddUnitToMainUsesSection(TargetCode, SelectedUnitName,'') then
- begin
- DebugLn(['TCodeBrowserView.UseUnitInSrcEditor CodeToolBoss.'
- +'AddUnitToMainUsesSection failed: TargetCode=', TargetCode.Filename,
- ' SelectedUnitName=', SelectedUnitName]);
- LazarusIDE.DoJumpToCodeToolBossError;
- end;
- // insert identifier
- if InsertIdentifier then begin
- if CodeMarker.Deleted then begin
- DebugLn(['TCodeBrowserView.UseUnitInSrcEditor insert place was deleted']);
- exit;
- end;
- GetIdentStartEndAtPosition(Code.Source,CodeMarker.NewPosition,
- IdentStart,IdentEnd);
- Code.AbsoluteToLineCol(IdentStart,InsertStartPos.Y,InsertStartPos.X);
- InsertEndPos:=InsertStartPos;
- inc(InsertEndPos.X,IdentEnd-IdentStart);
- SrcEdit.ReplaceText(InsertStartPos,InsertEndPos,Identifier);
- end;
- finally
- List.Free;
- CodeMarker.Free;
- end;
- end;
- procedure TCodeBrowserView.Work(var Done: Boolean);
- // do some work
- // This is called during OnIdle, so progress in small steps
- var
- OldStage: TCodeBrowserWorkStage;
- begin
- OldStage:=fStage;
- case fStage of
- cbwsGetScopeOptions: WorkGetScopeOptions;
- cbwsGatherPackages: WorkGatherPackages;
- cbwsFreeUnusedPackages: WorkFreeUnusedPackages;
- cbwsAddNewPackages: WorkAddNewUnitLists;
- cbwsGatherFiles: WorkGatherFileLists;
- cbwsGatherOutdatedFiles: WorkGatherOutdatedFiles;
- cbwsUpdateUnits: WorkUpdateUnits;
- cbwsGetViewOptions: WorkGetViewOptions;
- cbwsUpdateTreeView: WorkUpdateTreeView;
- else
- FOptionsChangeStamp:=Options.ChangeStamp;
- UpdateNeeded:=false;
- Done:=true;
- ProgressBar1.Position:=ProgressTotal;
- ProgressBar1.Visible:=false;
- exit;
- end;
- if ord(OldStage)<ord(cbwsFinished) then begin
- Done:=false;
- ProgressBar1.Visible:=true;
- UpdateStatusBar(fStage<cbwsFinished);
- end;
- //if fStage=cbwsFinished then CodeToolBoss.WriteMemoryStats;
- end;
- procedure TCodeBrowserView.WorkGetScopeOptions;
- var
- CurChangStamp: LongInt;
- begin
- DebugLn(['TCodeBrowserView.WorkGetScopeOptions START']);
- IdleTimer1.Enabled:=false;
- ProgressBar1.Position:=ProgressGetScopeStart;
- CurChangStamp:=Options.ChangeStamp;
- Options.WithRequiredPackages:=ScopeWithRequiredPackagesCheckBox.Checked;
- Options.Scope:=ScopeComboBox.Text;
- // this stage finished -> next stage
- if UpdateNeeded or (Options.ChangeStamp<>CurChangStamp) then
- fStage:=cbwsGatherPackages
- else
- fStage:=cbwsGetViewOptions;
- ProgressBar1.Position:=ProgressGetScopeStart+ProgressGetScopeSize;
- end;
- procedure TCodeBrowserView.WorkGatherPackages;
- procedure AddPackage(APackage: TLazPackage);
- begin
- TCodeBrowserUnitList.Create(APackage.Name,FWorkingParserRoot);
- end;
-
- procedure AddPackages(FirstDependency: TPkgDependency);
- var
- List: TFPList;
- i: Integer;
- begin
- List:=nil;
- try
- PackageGraph.GetAllRequiredPackages(nil,FirstDependency,List);
- if (List=nil) then exit;
- for i:=0 to List.Count-1 do begin
- if TObject(List[i]) is TLazPackage then
- AddPackage(TLazPackage(List[i]));
- end;
- finally
- List.Free;
- end;
- end;
- var
- APackage: TLazPackage;
- RootOwner: string;
- i: Integer;
- begin
- // clean up
- if fOutdatedFiles<>nil then fOutdatedFiles.Clear;
- // find ParserRoot
- RootOwner:='';
- if Options.Scope=IDEDescription then begin
- RootOwner:=CodeBrowserIDEName;
- end else if Options.Scope=ProjectDescription then begin
- RootOwner:=CodeBrowserProjectName;
- end else begin
- APackage:=PackageGraph.FindPackageWithName(Options.Scope,nil);
- if APackage<>nil then
- RootOwner:=APackage.Name;
- end;
- DebugLn(['TCodeBrowserView.WorkGatherPackages RootOwner="',RootOwner,'"']);
- FreeAndNil(FWorkingParserRoot);
- FWorkingParserRoot:=TCodeBrowserUnitList.Create(RootOwner,nil);
-
- // find required packages
- if Options.WithRequiredPackages then begin
- if SysUtils.CompareText(FWorkingParserRoot.Owner,CodeBrowserIDEName)=0 then begin
- for i:=0 to PackageGraph.Count-1 do
- AddPackage(PackageGraph[i]);
- end else if SysUtils.CompareText(FWorkingParserRoot.Owner,CodeBrowserProjectName)=0
- then begin
- AddPackages(Project1.FirstRequiredDependency);
- end else if FWorkingParserRoot.Owner<>'' then begin
- APackage:=PackageGraph.FindPackageWithName(FWorkingParserRoot.Owner,nil);
- if APackage<>nil then
- AddPackages(APackage.FirstRequiredDependency);
- end;
- end;
-
- // update ParserRoot item (children will be updated on next Idle)
- if FParserRoot=nil then begin
- FParserRoot:=TCodeBrowserUnitList.Create(FWorkingParserRoot.Owner,nil);
- inc(FScannedPackages);
- end else begin
- FParserRoot.Owner:=FWorkingParserRoot.Owner;
- end;
-
- // this stage finished -> next stage
- fStage:=cbwsFreeUnusedPackages;
- ProgressBar1.Position:=ProgressGatherPackagesStart+ProgressGatherPackagesSize;
- end;
- procedure TCodeBrowserView.WorkFreeUnusedPackages;
- function FindUnusedUnitList: TCodeBrowserUnitList;
- var
- Node: TAVLTreeNode;
- UnusedPackage: TCodeBrowserUnitList;
- PackageName: String;
- begin
- // find an unused package (a package in ParserRoot but not in WorkingParserRoot)
- Result:=nil;
- if (FParserRoot=nil) or (FParserRoot.UnitLists=nil) then exit;
- Node:=FParserRoot.UnitLists.FindLowest;
- while Node<>nil do begin
- UnusedPackage:=TCodeBrowserUnitList(Node.Data);
- PackageName:=UnusedPackage.Owner;
- if (FWorkingParserRoot=nil)
- or (FWorkingParserRoot.UnitLists=nil)
- or (FWorkingParserRoot.UnitLists.FindKey(Pointer(PackageName),
- @CompareAnsiStringWithUnitListOwner)=nil)
- then begin
- Result:=UnusedPackage;
- exit;
- end;
- Node:=FParserRoot.UnitLists.FindSuccessor(Node);
- end;
- end;
-
- var
- UnusedPackage: TCodeBrowserUnitList;
- begin
- DebugLn(['TCodeBrowserView.WorkFreeUnusedPackages START']);
- // find an unused package
- UnusedPackage:=FindUnusedUnitList;
- if UnusedPackage=nil then begin
- // this stage finished -> next stage
- fStage:=cbwsAddNewPackages;
- ProgressBar1.Position:=ProgressFreeUnusedPkgStart+ProgressFreeUnusedPkgSize;
- exit;
- end;
- // free the unused package
- FreeUnitList(UnusedPackage);
- end;
- procedure TCodeBrowserView.WorkAddNewUnitLists;
- var
- Node: TAVLTreeNode;
- List: TCodeBrowserUnitList;
- begin
- ProgressBar1.Position:=ProgressAddNewUnitListsStart;
- if (FWorkingParserRoot<>nil) and (FWorkingParserRoot.UnitLists<>nil)
- and (FParserRoot<>nil) then begin
- Node:=FWorkingParserRoot.UnitLists.FindLowest;
- while Node<>nil do begin
- List:=TCodeBrowserUnitList(Node.Data);
- if FParserRoot.FindUnitList(List.Owner)=nil then begin
- // new unit list
- TCodeBrowserUnitList.Create(List.Owner,FParserRoot);
- inc(FScannedPackages);
- end;
- Node:=FWorkingParserRoot.UnitLists.FindSuccessor(Node);
- end;
- end;
-
- // this stage finished -> next stage
- fStage:=cbwsGatherFiles;
- ProgressBar1.Position:=ProgressAddNewUnitListsStart+ProgressAddNewUnitListsSize;
- end;
- procedure TCodeBrowserView.WorkGatherFileLists;
- function ListFilesAreValid(List: TCodeBrowserUnitList): boolean;
- begin
- Result:=List.UnitsValid;
- end;
- function FindListWithInvalidFileList(StartList: TCodeBrowserUnitList
- ): TCodeBrowserUnitList;
- var
- APackage: TCodeBrowserUnitList;
- Node: TAVLTreeNode;
- begin
- Result:=nil;
- if StartList=nil then exit;
- if not ListFilesAreValid(StartList) then begin
- Result:=StartList;
- exit;
- end;
- if (StartList.UnitLists=nil) then exit;
- Node:=StartList.UnitLists.FindLowest;
- while Node<>nil do begin
- APackage:=TCodeBrowserUnitList(Node.Data);
- Result:=FindListWithInvalidFileList(APackage);
- if Result<>nil then exit;
- Node:=StartList.UnitLists.FindSuccessor(Node);
- end;
- end;
- var
- List: TCodeBrowserUnitList;
- begin
- DebugLn(['TCodeBrowserView.WorkGatherFiles START']);
- // find a unit list which needs update
- List:=FindListWithInvalidFileList(FParserRoot);
- if List=nil then begin
- // this stage finished -> next stage
- fStage:=cbwsGatherOutdatedFiles;
- ProgressBar1.Position:=ProgressGatherFileListsStart+ProgressGatherFileListsSize;
- exit;
- end;
-
- WorkUpdateFileList(List);
- end;
- procedure TCodeBrowserView.WorkUpdateFileList(List: TCodeBrowserUnitList);
- var
- NewFileList: TAVLTree;
- procedure AddFile(const Filename: string; ClearIncludedByInfo: boolean);
- begin
- //DebugLn(['AddFile Filename="',Filename,'"']);
- if Filename='' then exit;
- if System.Pos('$',Filename)>0 then begin
- DebugLn(['WARNING: TCodeBrowserView.WorkUpdateFiles Macros in filename ',Filename]);
- exit;
- end;
- if NewFileList.FindKey(Pointer(Filename),@CompareAnsiStringWithUnitFilename)<>nil
- then exit;
- //DebugLn(['TCodeBrowserView.WorkUpdateFiles AddFile ',Filename]);
- NewFileList.Add(TCodeBrowserUnit.Create(Filename));
- if ClearIncludedByInfo then begin
- CodeToolBoss.SourceCache.ClearIncludedByEntry(Filename);
- end;
- end;
-
- procedure AddFilesOfProject(AProject: TProject);
- var
- AnUnitInfo: TUnitInfo;
- begin
- if AProject=nil then exit;
- AnUnitInfo:=AProject.FirstPartOfProject;
- //DebugLn(['AddFilesOfProject ',AnUnitInfo<>nil]);
- while AnUnitInfo<>nil do begin
- //DebugLn(['AddFilesOfProject ',AnUnitInfo.Filename]);
- if FilenameIsPascalUnit(AnUnitInfo.Filename)
- or (AnUnitInfo=aProject.MainUnitInfo) then
- AddFile(AnUnitInfo.Filename,false);
- AnUnitInfo:=AnUnitInfo.NextPartOfProject;
- end;
- end;
-
- procedure AddFilesOfPackageFCL;
- var
- LazDir: String;
- UnitSetID: string;
- UnitSetChanged: Boolean;
- UnitSet: TFPCUnitSetCache;
- Filename: String;
- ConfigCache: TFPCTargetConfigCache;
- Node: TAVLTreeNode;
- Item: PStringToStringTreeItem;
- begin
- // use unitset of the lazarus source directory
- LazDir:=AppendPathDelim(EnvironmentOptions.GetParsedLazarusDirectory);
- if (LazDir='') or (not FilenameIsAbsolute(LazDir)) then exit;
- UnitSetID:=CodeToolBoss.GetUnitSetIDForDirectory(LazDir);
- if UnitSetID='' then exit;
- UnitSetChanged:=false;
- UnitSet:=CodeToolBoss.FPCDefinesCache.FindUnitSetWithID(UnitSetID,
- UnitSetChanged,false);
- if UnitSet=nil then exit;
- ConfigCache:=UnitSet.GetConfigCache(false);
- if (ConfigCache=nil) or (ConfigCache.Units=nil) then exit;
- Node:=ConfigCache.Units.Tree.FindLowest;
- while Node<>nil do begin
- Item:=PStringToStringTreeItem(Node.Data);
- Filename:=Item^.Value;
- if (CompareFileExt(Filename,'ppu',false)=0) then begin
- // search source in fpc sources
- Filename:=UnitSet.GetUnitSrcFile(ExtractFileNameOnly(Filename));
- end;
- if FilenameIsPascalUnit(Filename) then
- AddFile(Filename,false);
- Node:=ConfigCache.Units.Tree.FindSuccessor(Node);
- end;
- end;
-
- procedure AddFilesOfPackage(APackage: TLazPackage);
- var
- i: Integer;
- PkgFile: TPkgFile;
- aFilename: String;
- begin
- if APackage=nil then exit;
- for i:=0 to APackage.FileCount-1 do begin
- PkgFile:=APackage.Files[i];
- if (PkgFile.FileType in PkgFileUnitTypes) then begin
- aFilename:=PkgFile.GetFullFilename;
- if not FilenameIsPascalUnit(aFilename) then begin
- debugln(['WARNING: AddFilesOfPackage: package ',APackage.Filename,' has a unit with a non unit extension: ',aFilename]);
- end;
- AddFile(aFilename,true);
- end;
- end;
- if APackage.Name='FCL' then begin
- AddFilesOfPackageFCL;
- end;
- end;
-
- procedure AddFilesOfDirectory(const Directory: string;
- ClearIncludedByInfo: boolean);
- // ! needs ending PathDelim !
- var
- FileInfo: TSearchRec;
- begin
- //DebugLn(['AddFilesOfDirectory Directory="',Directory,'"']);
- if (not FilenameIsAbsolute(Directory))
- or (not DirectoryExistsUTF8(Directory)) then begin
- DebugLn(['AddFilesOfDirectory WARNING: does not exist: "',Directory,'"']);
- exit;
- end;
- if FindFirstUTF8(Directory+FileMask,faAnyFile,FileInfo)=0 then begin
- repeat
- // check if special file
- if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='')
- then
- continue;
- if FilenameIsPascalUnit(FileInfo.Name) then
- AddFile(Directory+FileInfo.Name,ClearIncludedByInfo);
- until FindNextUTF8(FileInfo)<>0;
- end;
- FindCloseUTF8(FileInfo);
- end;
-
- procedure AddFilesOfSearchPath(const SrcPath, BaseDir: string;
- ClearIncludedByInfo: boolean);
- var
- Dir: String;
- p: Integer;
- begin
- //DebugLn(['AddFilesOfSearchPath SrcPath="',SrcPath,'" BaseDir="',BaseDir,'"']);
- p:=1;
- while (p<=length(SrcPath)) do begin
- Dir:=GetNextDelimitedItem(SrcPath,';',p);
- if Dir<>'' then begin
- if not FilenameIsAbsolute(Dir) then
- Dir:=BaseDir+PathDelim+Dir;
- Dir:=CleanAndExpandDirectory(Dir);
- AddFilesOfDirectory(Dir,ClearIncludedByInfo);
- end;
- end;
- end;
-
- procedure AddFilesOfIDE;
- var
- LazDefines: TDefineTemplate;
- LazSrcDir: TDefineTemplate;
- LazIDEDir: TDefineTemplate;
- LazIDESrcPath: TDefineTemplate;
- SrcPath: String;
- LazDir: String;
- begin
- LazDir:=AppendPathDelim(EnvironmentOptions.GetParsedLazarusDirectory);
- if not DirectoryExistsUTF8(LazDir) then begin
- DebugLn(['AddFilesOfIDE WARNING: lazarus directory not found: "',LazDir,'"']);
- exit;
- end;
- // get the SrcPath template of the lazarus/ide directory
- LazDefines:=CodeToolBoss.DefineTree
- .FindDefineTemplateByName(StdDefTemplLazarusSources,true);
- if LazDefines=nil then begin
- DebugLn(['AddFilesOfIDE WARNING: codetools define templates for lazarus not found']);
- exit;
- end;
- LazSrcDir:=LazDefines.FindChildByName(StdDefTemplLazarusSrcDir);
- if LazSrcDir=nil then begin
- DebugLn(['AddFilesOfIDE WARNING: codetools define templates for lazarus directory not found']);
- exit;
- end;
- LazIDEDir:=LazSrcDir.FindChildByName('ide');
- if LazIDEDir=nil then begin
- DebugLn(['AddFilesOfIDE WARNING: codetools define templates for lazarus ide directory not found']);
- exit;
- end;
- LazIDESrcPath:=LazIDEDir.FindChildByName('IDE path addition');
- if LazIDESrcPath=nil then begin
- DebugLn(['AddFilesOfIDE WARNING: codetools define templates for src path of lazarus ide directory not found']);
- exit;
- end;
- SrcPath:=StringReplace(LazIDESrcPath.Value,'$(#LazarusDir)',LazDir,
- [rfReplaceAll, rfIgnoreCase]);
- AddFilesOfSearchPath(SrcPath+';.',LazDir+'ide'+PathDelim,true);
- end;
- procedure DeleteUnusedFiles;
- var
- Node: TAVLTreeNode;
- CurUnit: TCodeBrowserUnit;
- NextNode: TAVLTreeNode;
- begin
- if List.Units=nil then exit;
- Node:=List.Units.FindLowest;
- while Node<>nil do begin
- NextNode:=List.Units.FindSuccessor(Node);
- CurUnit:=TCodeBrowserUnit(Node.Data);
- if NewFileList.FindKey(Pointer(CurUnit.Filename),
- @CompareAnsiStringWithUnitFilename)=nil
- then begin
- // this unit is not part of List anymore -> delete
- RemoveUnit(CurUnit);
- List.DeleteUnit(CurUnit);
- end;
- Node:=NextNode;
- end;
- end;
-
- procedure AddNewFiles;
- var
- Node: TAVLTreeNode;
- AnUnit: TCodeBrowserUnit;
- begin
- Node:=NewFileList.FindLowest;
- while Node<>nil do begin
- AnUnit:=TCodeBrowserUnit(Node.Data);
- //DebugLn(['AddNewFiles ',AnUnit.Filename,' exists=',List.FindUnit(AnUnit.Filename)<>nil]);
- if List.FindUnit(AnUnit.Filename)=nil then begin
- // this unit was not part of List -> add
- //DebugLn(['AddNewFiles "',List.Owner,'" "',AnUnit.Filename,'"']);
- List.AddUnit(AnUnit.Filename);
- end;
- Node:=NewFileList.FindSuccessor(Node);
- end;
- end;
- var
- APackage: TLazPackage;
- begin
- DebugLn(['TCodeBrowserView.WorkUpdateFiles ',List.Owner]);
- NewFileList:=TAVLTree.Create(@CompareUnitFilenames);
- try
- // get new list of files
- if List.Owner=CodeBrowserIDEName then begin
- AddFilesOfIDE;
- end else if List.Owner=CodeBrowserProjectName then begin
- AddFilesOfProject(Project1);
- end else begin
- APackage:=PackageGraph.FindPackageWithName(List.Owner,nil);
- AddFilesOfPackage(APackage);
- end;
-
- // update file list
- DeleteUnusedFiles;
- AddNewFiles;
-
- List.UnitsValid:=true;
- finally
- NewFileList.FreeAndClear;
- NewFileList.Free;
- end;
- end;
- procedure TCodeBrowserView.WorkGatherOutdatedFiles;
- // add all files to fOutdatedFiles
- procedure AddFile(AnUnit: TCodeBrowserUnit);
- begin
- if fOutdatedFiles=nil then
- fOutdatedFiles:=TAVLTree.Create(@CompareUnitFilenames);
- if fOutdatedFiles.Find(AnUnit)<>nil then exit;
- fOutdatedFiles.Add(AnUnit);
- end;
- procedure AddFiles(List: TCodeBrowserUnitList);
- var
- Node: TAVLTreeNode;
- begin
- if List.Units<>nil then begin
- Node:=List.Units.FindLowest;
- while Node<>nil do begin
- AddFile(TCodeBrowserUnit(Node.Data));
- Node:=List.Units.FindSuccessor(Node);
- end;
- end;
- if List.UnitLists<>nil then begin
- Node:=List.UnitLists.FindLowest;
- while Node<>nil do begin
- AddFiles(TCodeBrowserUnitList(Node.Data));
- Node:=List.UnitLists.FindSuccessor(Node);
- end;
- end;
- end;
- begin
- if fOutdatedFiles<>nil then
- fOutdatedFiles.Clear;
- AddFiles(ParserRoot);
-
- // this stage finished -> next stage
- fStage:=cbwsUpdateUnits;
- ProgressBar1.Position:=ProgressGatherOutdatedFilesStart+ProgressGatherOutdatedFilesSize;
- end;
- procedure TCodeBrowserView.WorkUpdateUnits;
- function FindOutdatedUnit: TCodeBrowserUnit;
- var
- Node: TAVLTreeNode;
- begin
- Result:=nil;
- if fOutdatedFiles=nil then exit;
- Node:=fOutdatedFiles.FindLowest;
- if Node=nil then exit;
- Result:=TCodeBrowserUnit(Node.Data);
- end;
- const
- SmallTimeStep = (1/86400)/5;
- var
- AnUnit: TCodeBrowserUnit;
- StartTime: TDateTime;
- begin
- //DebugLn(['TCodeBrowserView.WorkUpdateUnits START']);
- CodeToolBoss.ActivateWriteLock;
- try
- // parse units
- StartTime:=Now;
- repeat
- AnUnit:=FindOutdatedUnit;
- if AnUnit=nil then begin
- // this stage finished -> next stage
- fStage:=cbwsGetViewOptions;
- ProgressBar1.Position:=ProgressUpdateUnitsStart+ProgressUpdateUnitsSize;
- exit;
- end;
- WorkUpdateUnit(AnUnit);
- until Abs(Now-StartTime)>SmallTimeStep;
- finally
- CodeToolBoss.DeactivateWriteLock;
- end;
- end;
- procedure TCodeBrowserView.WorkUpdateUnit(AnUnit: TCodeBrowserUnit);
- procedure UpdateScannedCounters(Tool: TCodeTool);
- var
- LineCnt: Integer;
- ByteCnt: Integer;
- i: Integer;
- Link: TSourceLink;
- CodeBuf: TCodeBuffer;
- LastCode: TCodeBuffer;
- begin
- if (Tool=nil) or (Tool.Scanner=nil) then exit;
- LineCnt:=0;
- ByteCnt:=0;
- LastCode:=nil;
- for i:=0 to Tool.Scanner.LinkCount-1 do begin
- Link:=Tool.Scanner.Links[i];
- CodeBuf:=TCodeBuffer(Link.Code);
- if CodeBuf=nil then continue;
- if CodeBuf<>LastCode then begin
- inc(LineCnt,CodeBuf.LineCount);
- inc(ByteCnt,CodeBuf.SourceLength);
- LastCode:=CodeBuf;
- end;
- end;
- AnUnit.ScannedBytes:=ByteCnt;
- AnUnit.ScannedLines:=LineCnt;
- AnUnit.ScannedIdentifiers:=CountIdentifiers(Tool);
- AnUnit.CodeTool:=Tool;
- inc(FScannedBytes,AnUnit.ScannedBytes);
- inc(FScannedLines,AnUnit.ScannedLines);
- inc(FScannedIdentifiers,AnUnit.ScannedIdentifiers);
- //DebugLn(['UpdateScannedCounters ',ExtractFileName(AnUnit.Filename),' LineCnt=',LineCnt,' ByteCnt=',ByteCnt,' ',DbgSName(AnUnit.CodeTool)]);
- end;
- var
- MainCodeBuf: TCodeBuffer;
- Tool: TCodeTool;
- begin
- //DebugLn(['TCodeBrowserView.WorkUpdateUnit START ',AnUnit.Filename]);
- // mark as updated
- fOutdatedFiles.Remove(AnUnit);
- // reset scanning counters
- if AnUnit.Scanned then begin
- dec(FScannedBytes,AnUnit.ScannedBytes);
- dec(FScannedLines,AnUnit.ScannedLines);
- dec(FScannedIdentifiers,AnUnit.ScannedIdentifiers);
- AnUnit.ScannedBytes:=0;
- AnUnit.ScannedLines:=0;
- AnUnit.ScannedIdentifiers:=0;
- dec(FScannedUnits);
- end;
- AnUnit.Scanned:=true;
- inc(FScannedUnits);
- // load the file
- AnUnit.CodeBuffer:=CodeToolBoss.LoadFile(AnUnit.Filename,false,false);
- if AnUnit.CodeBuffer=nil then exit;
- // check if this is a unit
- MainCodeBuf:=CodeToolBoss.GetMainCode(AnUnit.CodeBuffer);
- if MainCodeBuf<>AnUnit.CodeBuffer then begin
- // this file was used as an include file
- DebugLn(['TCodeBrowserView.WorkUpdateUnit HINT: this is not a unit: ',AnUnit.Filename,
- ' (it was included by ',MainCodeBuf.Filename,')']);
- exit;
- end;
- // scan
- CodeToolBoss.Explore(AnUnit.CodeBuffer,Tool,false,true);
- UpdateScannedCounters(Tool);
- //DebugLn(['TCodeBrowserView.WorkUpdateUnit END ',AnUnit.Filename]);
- end;
- procedure TCodeBrowserView.WorkGetViewOptions;
- var
- NewLevels: TStringList;
- begin
- //DebugLn(['TCodeBrowserView.WorkGetViewOptions START']);
- Options.ShowPrivate:=ShowPrivateCheckBox.Checked;
- Options.ShowProtected:=ShowProtectedCheckBox.Checked;
- Options.ShowEmptyNodes:=ShowEmptyNodesCheckBox.Checked;
- // levels
- NewLevels:=TStringList.Create;
- if ShowPackagesCheckBox.Checked then
- NewLevels.Add(CodeBrowserLevelNames[cblPackages]);
- if ShowUnitsCheckBox.Checked then
- NewLevels.Add(CodeBrowserLevelNames[cblUnits]);
- if ShowIdentifiersCheckBox.Checked then
- NewLevels.Add(CodeBrowserLevelNames[cblIdentifiers]);
- Options.Levels:=NewLevels;
- NewLevels.Free;
- // level filter
- Options.LevelFilterText[cblPackages]:=PackageFilterEdit.Text;
- if PackageFilterBeginsSpeedButton.Down then
- Options.LevelFilterType[cblPackages]:=cbtfBegins;
- if PackageFilterContainsSpeedButton.Down then
- Options.LevelFilterType[cblPackages]:=cbtfContains;
- Options.LevelFilterText[cblUnits]:=UnitFilterEdit.Text;
- //DebugLn(['TCodeBrowserView.WorkGetOptions UnitFIlter=',Options.LevelFilterText[cblUnits],' Edit=',UnitFilterEdit.Text]);
- if UnitFilterBeginsSpeedButton.Down then
- Options.LevelFilterType[cblUnits]:=cbtfBegins;
- if UnitFilterContainsSpeedButton.Down then
- Options.LevelFilterType[cblUnits]:=cbtfContains;
- Options.LevelFilterText[cblIdentifiers]:=IdentifierFilterEdit.Text;
- if IdentifierFilterBeginsSpeedButton.Down then
- Options.LevelFilterType[cblIdentifiers]:=cbtfBegins;
- if IdentifierFilterContainsSpeedButton.Down then
- Options.LevelFilterType[cblIdentifiers]:=cbtfContains;
- DebugLn(['TCodeBrowserView.WorkGetViewOptions UpdateNeeded=',UpdateNeeded,' ChangeStamp=',Options.ChangeStamp<>FOptionsChangeStamp]);
- // this stage finished -> next stage
- if UpdateNeeded or (Options.ChangeStamp<>FOptionsChangeStamp) then
- fStage:=cbwsUpdateTreeView
- else
- fStage:=cbwsFinished;
- ProgressBar1.Position:=ProgressGetViewOptionsStart+ProgressGetViewOptionsSize;
- end;
- procedure TCodeBrowserView.WorkUpdateTreeView;
- begin
- ProgressBar1.Position:=ProgressUpdateTreeViewStart;
- UpdateTreeView;
- // this stage finished -> next stage
- fStage:=cbwsFinished;
- ProgressBar1.Position:=ProgressUpdateTreeViewStart+ProgressUpdateTreeViewSize;
- end;
- procedure TCodeBrowserView.FreeUnitList(List: TCodeBrowserUnitList);
- var
- Node: TAVLTreeNode;
- AnUnit: TCodeBrowserUnit;
- begin
- //DebugLn(['TCodeBrowserView.FreeUnitList ',List.Owner]);
- dec(FScannedPackages);
- if List.Units<>nil then begin
- Node:=List.Units.FindLowest;
- while Node<>nil do begin
- AnUnit:=TCodeBrowserUnit(Node.Data);
- RemoveUnit(AnUnit);
- Node:=List.Units.FindSuccessor(Node);
- end;
- end;
- List.Free;
- end;
- procedure TCodeBrowserView.UpdateStatusBar(Lazy: boolean);
- const
- SmallTimeStep = 1/86400;
- function BigIntToStr(i: integer): string;
- var
- p: Integer;
- ThousandSep: String;
- begin
- if i=0 then begin
- Result:='0';
- exit;
- end;
- Result:='';
- if i>=100000 then begin
- i:=i div 1000;
- Result:='k';
- if i>=100000 then begin
- i:=i div 1000;
- Result:='m';
- if i>=100000 then begin
- i:=i div 1000;
- Result:='g';
- if i>=100000 then begin
- i:=i div 1000;
- Result:='t';
- end;
- end;
- end;
- end;
- p:=0;
- ThousandSep:=AnsiToUTF8(DefaultFormatSettings.ThousandSeparator);
- while i>0 do begin
- if p=3 then begin
- Result:=ThousandSep+Result;
- p:=0;
- end;
- Result:=chr((i mod 10)+ord('0'))+Result;
- i:=i div 10;
- inc(p);
- end;
- end;
- var
- s: String;
- begin
- if Lazy and (Abs(Now-fLastStatusBarUpdate)<SmallTimeStep) then begin
- // the last update is not long ago
- // => skip update
- exit;
- end;
- fLastStatusBarUpdate:=Now;
- s:=Format(lisPackagesUnitsIdentifiersLinesBytes, [BigIntToStr(VisiblePackages)
- , BigIntToStr(ScannedPackages), BigIntToStr(VisibleUnits), BigIntToStr(
- ScannedUnits), BigIntToStr(VisibleIdentifiers), BigIntToStr(
- ScannedIdentifiers), BigIntToStr(ScannedLines), BigIntToStr(ScannedBytes)]);
- if fStage<>cbwsFinished then
- s:=Format(lisScanning2, [s]);
- StatusBar1.SimpleText:=s;
- end;
- function TCodeBrowserView.GetCodeTool(AnUnit: TCodeBrowserUnit): TStandardCodeTool;
- begin
- //DebugLn(['TCodeBrowserView.GetCodeTool ',AnUnit.CodeTool<>nil,' ',AnUnit.CodeBuffer<>nil]);
- Result:=AnUnit.CodeTool;
- if Result<>nil then exit;
- if AnUnit.CodeBuffer=nil then exit;
- Result:=CodeToolBoss.GetCodeToolForSource(AnUnit.CodeBuffer,true,false)
- as TCodeTool;
- AnUnit.CodeTool:=Result;
- //DebugLn(['TCodeBrowserView.GetCodeTool END ',AnUnit.Filename,' ',Result<>nil]);
- end;
- procedure TCodeBrowserView.GetNodeIdentifier(Tool: TStandardCodeTool;
- CTNode: TCodeTreeNode; out Identifier: string);
- function Shorten(const s: string): string;
- const
- MAX_LEN=100;
- begin
- Result:=DbgStr(s);
- if Length(Result)>MAX_LEN then
- Result:=LeftStr(Result, MAX_LEN)+'...';
- end;
- begin
- if CTNode.StartPos>=CTNode.EndPos then begin
- Identifier:='';
- exit;
- end;
- case CTNode.Desc of
- ctnProcedure:
- begin
- Identifier:=Tool.ExtractProcName(CTNode,ProcIdentifierFlags);
- end;
- ctnVarDefinition:
- begin
- Identifier:=Tool.ExtractDefinitionName(CTNode);
- end;
- ctnConstDefinition:
- begin
- Identifier:=Tool.ExtractDefinitionName(CTNode);
- end;
- ctnTypeDefinition,ctnGenericType:
- begin
- Identifier:=Tool.ExtractDefinitionName(CTNode);
- end;
- ctnProperty:
- begin
- Identifier:=Tool.ExtractPropName(CTNode,false);
- end;
- ctnEnumIdentifier:
- begin
- Identifier:=Tool.ExtractIdentifier(CTNode.StartPos);
- end;
- end;
- end;
- procedure TCodeBrowserView.GetNodeDescription(Tool: TStandardCodeTool;
- CTNode: TCodeTreeNode; Identifier: string; out Description: string);
- function Shorten(const s: string): string;
- const
- MAX_LEN=100;
- begin
- Result:=DbgStr(s);
- if Length(Result)>MAX_LEN then
- Result:=LeftStr(Result, MAX_LEN)+'...';
- end;
- const
- NodeFlags = [];
- var
- Inheritance: String;
- begin
- if CTNode.StartPos>=CTNode.EndPos then begin
- Description:='';
- exit;
- end;
- case CTNode.Desc of
- ctnProcedure:
- begin
- Description:=Tool.ExtractProcHead(CTNode,ProcDescFlags);
- end;
- ctnVarDefinition:
- begin
- Description:='var '+Identifier
- +' : '+Shorten(Tool.ExtractDefinitionNodeType(CTNode));
- end;
- ctnConstDefinition:
- begin
- Description:='const '+Shorten(Tool.ExtractNode(CTNode,NodeFlags));
- end;
- ctnTypeDefinition,ctnGenericType:
- begin
- Description:='type '+Identifier;
- if CTNode.FirstChild<>nil then begin
- case CTNode.FirstChild.Desc of
- ctnClass,ctnClassInterface,ctnObject,
- ctnObjCClass,ctnObjCCategory,ctnObjCProtocol,
- ctnCPPClass,
- ctnClassHelper,ctnRecordHelper,ctnTypeHelper:
- begin
- case CTNode.FirstChild.Desc of
- ctnClassInterface:
- Description:=Description+' = interface';
- ctnObject:
- Description:=Description+' = object';
- ctnObjCClass:
- Description:=Description+' = objcclass';
- ctnObjCCategory:
- Description:=Description+' = objccategory';
- ctnObjCProtocol:
- Description:=Description+' = objcprotocol';
- ctnCPPClass:
- Description:=Description+' = cppclass';
- ctnClassHelper:
- Description:=Description+' = class helper';
- ctnRecordHelper:
- Description:=Description+' = record helper';
- ctnTypeHelper:
- Description:=Description+' = type helper';
- else
- Description:=Description+' = class';
- end;
- Inheritance:=Tool.ExtractClassInheritance(CTNode.FirstChild,[]);
- if Inheritance<>'' then
- Description:=Description+'('+Inheritance+')';
- end;
- ctnRecordType:
- Description:=Description+' = record';
- end;
- end;
- end;
- ctnProperty:
- begin
- Description:='property '+Shorten(Tool.ExtractProperty(CTNode,PropDescFlags));
- end;
- ctnEnumIdentifier:
- begin
- Description:='enum '+Identifier;
- end;
- end;
- end;
- procedure TCodeBrowserView.UpdateTreeView;
- var
- ShowPackages: boolean;
- ShowUnits: boolean;
- ShowIdentifiers: boolean;
- ShowPrivate: boolean;
- ShowProtected: boolean;
- ShowEmptyNodes: boolean;
- NewPackageCount: integer;
- NewUnitCount: integer;
- NewIdentifierCount, ShownIdentifierCount: PtrInt;
- UsedMem: PtrUInt;
-
- LevelFilterText: array[TCodeBrowserLevel] of string;
- LevelFilterType: array[TCodeBrowserLevel] of TCodeBrowserTextFilter;
- function IncUsedMem(c: integer): boolean;
- begin
- Result:=(UsedMem div 16384)<>((UsedMem{%H-}+c) div 16384);
- {%H-}inc(UsedMem,c);
- end;
- function IdentifierFitsFilter(LvlType: TCodeBrowserLevel;
- const Identifier: string): boolean;
- begin
- //DebugLn(['IdentifierFitsFilter Identifier=',Identifier,' Filter=',LevelFilterText[LvlType]]);
- if (LevelFilterText[LvlType]='') then exit(true);
- if Identifier='' then exit(false);
- case LevelFilterType[LvlType] of
- cbtfBegins:
- Result:=ComparePrefixIdent(PChar(Pointer(LevelFilterText[LvlType])),
- PChar(Pointer(Identifier)));
- cbtfContains:
- begin
- Result:=IdentifierPos(PChar(Pointer(LevelFilterText[LvlType])),
- PChar(Pointer(Identifier)))>=0;
- //if Result then
- // debugln(['IdentifierFitsFilter Identifier="',Identifier,'" Filter="',LevelFilterText[LvlType],'"']);
- end
- else
- Result:=true;
- end;
- end;
- procedure AddUnitNodes(SrcUnit: TCodeBrowserUnit; var DestUnit: TObject);
- var
- CTTool: TStandardCodeTool;
-
- procedure AddChildNode(ParentBrowserNode: TCodeBrowserNode;
- CTNode: TCodeTreeNode);
- var
- NewChildNode: TCodeBrowserNode;
- ChildDescription, ChildIdentifier: string;
- NewCodePos: TCodePosition;
- begin
- //DebugLn(['AddChildNode ',ChildCTNode.DescAsString,' ',ChildDescription]);
- if ShownIdentifierCount>=CodeBrowserMaxTVIdentifiers then exit;
- if (CTNode.Parent.Desc=ctnClassPrivate) and (not ShowPrivate) then
- exit;
- if (CTNode.Parent.Desc=ctnClassProtected) and (not ShowProtected)
- then
- exit;
- GetNodeIdentifier(CTTool,CTNode,ChildIdentifier);
- if IdentifierFitsFilter(cblIdentifiers,ChildIdentifier) then begin
- inc(ShownIdentifierCount);
- GetNodeDescription(CTTool,CTNode,ChildIdentifier,ChildDescription);
- NewChildNode:=ParentBrowserNode.AddNode(ChildDescription,ChildIdentifier);
- if NewChildNode<>nil then begin
- NewChildNode.Desc:=CTNode.Desc;
- CTTool.CleanPosToCodePos(CTNode.StartPos,NewCodePos);
- NewChildNode.CodePos:=NewCodePos;
- {$IFDEF VerboseCodeBrowser}
- if (length(ChildDescription)>1000) then
- debugln(['AddChildNode WARNING: big description ',SrcUnit.Filename,' desc=',ChildDescription]);
- if IncUsedMem(NewChildNode.GetMemSize) then
- debugln(['AddChildNode used mem ',UsedMem]);
- {$ENDIF}
- end;
- end;
- end;
- procedure AddIdentifierNode(CTNode: TCodeTreeNode);
- var
- NewNode: TCodeBrowserNode;
- ChildCTNode: TCodeTreeNode;
- Description, Identifier: string;
- CurUnit: TCodeBrowserUnit;
- NewCodePos: TCodePosition;
- begin
- if not ShowIdentifiers then exit;
- if ShownIdentifierCount>CodeBrowserMaxTVIdentifiers then exit;
- if DestUnit=nil then
- DestUnit:=TCodeBrowserUnit.Create('');
- CurUnit:=TCodeBrowserUnit(DestUnit);
- //DebugLn(['AddIdentifierNode ',CTNode.DescAsString,' Description="',Description,'"']);
- GetNodeIdentifier(CTTool,CTNode,Identifier);
- NewNode:=CurUnit.AddNode('',Identifier);
- {$IFDEF VerboseCodeBrowser}
- if (length(Description)>100) then
- debugln(['AddIdentifierNode WARNING: big description ',CurUnit.Filename,' desc=',Description]);
- if IncUsedMem(NewNode.GetMemSize) then
- debugln(['AddIdentifierNode used mem ',UsedMem,' ',CurUnit.Filename,' ',CurUnit.ChildNodeCount]);
- {$ENDIF}
- NewNode.Desc:=CTNode.Desc;
- CTTool.CleanPosToCodePos(CTNode.StartPos,NewCodePos);
- NewNode.CodePos:=NewCodePos;
- //DebugLn(['AddIdentifierNode Code=',NewNode.FCodePos.Code<>nil,' P=',NewNode.FCodePos.P]);
-
- if (CTNode.Desc in [ctnTypeDefinition,ctnGenericType])
- and (CTNode.FirstChild<>nil)
- and (CTNode.FirstChild.Desc in AllClasses+[ctnRecordType,ctnEnumerationType])
- then begin
- // add child nodes
- ChildCTNode:=CTNode.FirstChild;
- while (ChildCTNode<>nil) and (ChildCTNode.StartPos<CTNode.EndPos) do
- begin
- if ChildCTNode.Desc in
- [ctnProcedure,ctnVarDefinition,ctnProperty,ctnEnumIdentifier]
- then begin
- AddChildNode(NewNode,ChildCTNode);
- end;
- if ChildCTNode.Desc=ctnProcedureHead then
- ChildCTNode:=ChildCTNode.NextSkipChilds
- else
- ChildCTNode:=ChildCTNode.Next;
- end;
- end;
-
- if (NewNode.ChildNodes=nil)
- and (not IdentifierFitsFilter(cblIdentifiers,Identifier)) then begin
- // identifier is not needed -> remove
- // ToDo: remove nodes later
- CurUnit.DeleteNode(NewNode);
- end else begin
- // keep node, set Description
- GetNodeDescription(CTTool,CTNode,Identifier,Description);
- NewNode.Description:=Description;
- inc(ShownIdentifierCount);
- end;
- end;
-
- var
- CTNode: TCodeTreeNode;
- begin
- if SrcUnit=nil then exit;
- //DebugLn(['AddUnitNodes SrcUnit.Filename="',SrcUnit.Filename,'"']);
- CTTool:=GetCodeTool(SrcUnit);
- if CTTool=nil then exit;
- if CTTool.Tree=nil then exit;
-
- CTNode:=CTTool.Tree.Root;
- while CTNode<>nil do begin
- //DebugLn(['AddUnitNodes ',CTNode.DescAsString]);
- case CTNode.Desc of
- ctnProcedure:
- if not CTTool.NodeIsMethodBody(CTNode) then
- AddIdentifierNode(CTNode);
- ctnVarDefinition,ctnConstDefinition,ctnTypeDefinition,ctnGenericType:
- if not CTTool.NodeIsForwardDeclaration(CTNode) then
- AddIdentifierNode(CTNode);
- end;
- // go to next node
- case CTNode.Desc of
- ctnProgram,ctnLibrary,ctnPackage,ctnUnit,ctnInterface,
- ctnTypeSection,ctnConstSection,ctnVarSection,ctnResStrSection:
- // go into child nodes
- CTNode:=CTNode.Next;
- ctnImplementation, ctnBeginBlock, ctnAsmBlock: break;
- else
- // skip children and go to next sibling or parent
- CTNode:=CTNode.NextSkipChilds;
- end;
- end;
- end;
-
- procedure AddUnits(SrcList: TCodeBrowserUnitList;
- var DestParentList: TCodeBrowserUnitList);
-
- procedure RaiseParentNotUnitList;
- begin
- raise Exception.Create('TCodeBrowserView.UpdateTreeView.AddUnits.RaiseParentNotUnitList');
- end;
-
- var
- Node: TAVLTreeNode;
- CurUnit: TCodeBrowserUnit;
- NewUnit: TCodeBrowserUnit;
- List: TCodeBrowserUnitList;
- OldDestParentList: TObject;
- begin
- if SrcList=nil then exit;
- //DebugLn(['AddUnits SrcList.Owner="',SrcList.Owner,'" HasUnits=',SrcList.Units<>nil]);
- if SrcList.Units=nil then exit;
- OldDestParentList:=DestParentList;
- NewUnit:=nil;
- Node:=SrcList.Units.FindLowest;
- while Node<>nil do begin
- CurUnit:=TCodeBrowserUnit(Node.Data);
- if (CurUnit.Filename='')
- or IdentifierFitsFilter(cblUnits,ExtractFileNameOnly(CurUnit.Filename))
- then begin
- if DestParentList=nil then begin
- DestParentList:=TCodeBrowserUnitList.Create(CodeBrowserHidden,nil);
- end else if not (DestParentList is TCodeBrowserUnitList) then
- RaiseParentNotUnitList;
- List:=TCodeBrowserUnitList(DestParentList);
- if ShowUnits then begin
- // create a unit node
- NewUnit:=List.AddUnit(CurUnit.Filename);
- NewUnit.CodeBuffer:=CurUnit.CodeBuffer;
- NewUnit.CodeTool:=CurUnit.CodeTool;
- end else if NewUnit=nil then begin
- // create a dummy unit node to add all identifiers
- NewUnit:=List.FindUnit('');
- if NewUnit=nil then
- NewUnit:=List.AddUnit('');
- end;
- //DebugLn(['AddUnits AddUnitNodes ',CurUnit.Filename]);
- AddUnitNodes(CurUnit,TObject(NewUnit));
- if (not ShowEmptyNodes) and (NewUnit.ChildNodeCount=0) then begin
- // remove empty unit
- List.DeleteUnit(NewUnit);
- NewUnit:=nil;
- if OldDestParentList=nil then begin
- FreeAndNil(DestParentList);
- end;
- end;
- if (NewUnit<>nil) and (NewUnit.UnitList=nil) and (List<>nil) then
- List.AddUnit(NewUnit);
- end;
- Node:=SrcList.Units.FindSuccessor(Node);
- end;
- end;
- procedure AddUnitLists(SrcList: TCodeBrowserUnitList;
- var DestParentList: TCodeBrowserUnitList);
- var
- Node: TAVLTreeNode;
- SubList: TCodeBrowserUnitList;
- NewList: TCodeBrowserUnitList;
- OldDestParentList: TCodeBrowserUnitList;
- NewListCreated: Boolean;
- CreateNode: Boolean;
- begin
- if SrcList=nil then exit;
- //DebugLn(['AddUnitLists SrcList.Owner="',SrcList.Owner,'"']);
- OldDestParentList:=DestParentList;
-
- // check filter
- CreateNode:=IdentifierFitsFilter(cblPackages,SrcList.Owner);
-
- // create node
- NewListCreated:=false;
- if CreateNode then begin
- if ShowPackages then begin
- if DestParentList=nil then begin
- DestParentList:=TCodeBrowserUnitList.Create(CodeBrowserHidden,nil);
- end;
- NewList:=TCodeBrowserUnitList.Create(SrcList.Owner,DestParentList);
- NewListCreated:=true;
- end else begin
- NewList:=DestParentList;
- end;
- end;
- // create nodes for unitlists
- if SrcList.UnitLists<>nil then begin
- Node:=SrcList.UnitLists.FindLowest;
- while Node<>nil do begin
- SubList:=TCodeBrowserUnitList(Node.Data);
- AddUnitLists(SubList,DestParentList);// DestParentList because: as sibling not as child!
- Node:=SrcList.UnitLists.FindSuccessor(Node);
- end;
- end;
- if CreateNode then begin
- // create nodes for units
- AddUnits(SrcList,NewList);
- // remove empty unit lists
- if (not ShowEmptyNodes) and NewListCreated and (NewList.IsEmpty) then begin
- //DebugLn(['AddUnitLists EMPTY ',NewList.Owner,' ',NewList.UnitListCount,' ',NewList.UnitCount]);
- if DestParentList=NewList then
- DestParentList:=nil;
- NewList.Free;
- NewList:=nil;
- if (OldDestParentList=nil) and (DestParentList<>nil)
- and DestParentList.IsEmpty then begin
- FreeAndNil(DestParentList);
- end;
- end;
- // update DestParentList
- if (DestParentList=nil) then
- DestParentList:=NewList;
- end;
- end;
- procedure AddTreeNodes(CodeNode: TObject; ParentViewNode: TTreeNode);
- var
- TVNode: TTreeNode;
- procedure RecursiveAdd(Tree: TAVLTree);
- var
- Node: TAVLTreeNode;
- begin
- if Tree<>nil then begin
- Node:=Tree.FindLowest;
- while Node<>nil do begin
- AddTreeNodes(TObject(Node.Data), TVNode);
- Node:=Tree.FindSuccessor(Node);
- end;
- end;
- end;
- {off $DEFINE DisableTreeViewNodes}
- procedure AddToTreeView(Name: String);
- begin
- {$IFNDEF DisableTreeViewNodes}
- TVNode:=BrowseTreeView.Items.AddChildObject(
- ParentViewNode, Name, CodeNode);
- TVNode.ImageIndex:=GetNodeImage(CodeNode);
- TVNode.SelectedIndex:=TVNode.ImageIndex;
- {$ENDIF}
- end;
- // create visual nodes (TTreeNode)
- var
- CurList: TCodeBrowserUnitList;
- CurListName: String;
- CurUnit: TCodeBrowserUnit;
- CurUnitName: String;
- CurTool: TStandardCodeTool;
- CurNode: TCodeBrowserNode;
- ExpandParent: Boolean;
- begin
- if CodeNode=nil then exit;
- ExpandParent:=true;
- //DebugLn(['AddTreeNodes ',DbgSName(CodeNode)]);
- TVNode:=ParentViewNode;
- if CodeNode is TCodeBrowserUnitList then begin
- CurList:=TCodeBrowserUnitList(CodeNode);
- //DebugLn(['AddTreeNodes ',CurList.Owner]);
- if CurList.Owner=CodeBrowserHidden then begin
- TVNode:=ParentViewNode;
- end else begin
- CurListName:=ListOwnerToText(CurList.Owner);
- inc(NewPackageCount);
- AddToTreeView(CurListName);
- end;
- RecursiveAdd(CurList.UnitLists);
- RecursiveAdd(CurList.Units);
- end
- else if CodeNode is TCodeBrowserUnit then begin
- CurUnit:=TCodeBrowserUnit(CodeNode);
- CurTool:=nil;
- if CurUnit.Filename<>'' then
- CurTool:=GetCodeTool(CurUnit);
- if CurTool<>nil then begin
- // add a tree node for this unit
- CurUnitName:=TCodeTool(CurTool).GetCachedSourceName;
- if CurUnitName='' then
- CurUnitName:=ExtractFileNameOnly(CurTool.MainFilename);
- inc(NewUnitCount);
- AddToTreeView(CurUnitName);
- end else begin
- // do not add a tree node for this unit
- TVNode:=ParentViewNode;
- end;
- // create tree nodes for code nodes
- RecursiveAdd(CurUnit.ChildNodes);
- end
- else if CodeNode is TCodeBrowserNode then begin
- CurNode:=TCodeBrowserNode(CodeNode);
- if CurNode.Description<>'' then begin
- inc(NewIdentifierCount);
- //if (NewIdentifierCount mod 100)=0 then
- // DebugLn(['AddTreeNodes ',NewIdentifierCount,' ',CurNode.Description]);
- AddToTreeView(CurNode.Description);
- // create tree nodes for child code nodes
- RecursiveAdd(CurNode.ChildNodes);
- // do not expand unit nodes
- if (ParentViewNode<>nil)
- and (TObject(ParentViewNode.Data) is TCodeBrowserUnit) then
- ExpandParent:=false;
- end;
- end;
- if ParentViewNode<>nil then
- ParentViewNode.Expanded:=ExpandParent;
- end;
- var
- lvl: TCodeBrowserLevel;
- i: Integer;
- begin
- UsedMem:=0;
- ShowPackages:=Options.HasLevel(cblPackages);
- ShowUnits:=Options.HasLevel(cblUnits);
- ShowIdentifiers:=Options.HasLevel(cblIdentifiers);
- ShowPrivate:=Options.ShowPrivate;
- ShowProtected:=Options.ShowProtected;
- ShowEmptyNodes:=Options.ShowEmptyNodes;
- NewPackageCount:=0;
- NewUnitCount:=0;
- NewIdentifierCount:=0;
- ShownIdentifierCount:=0;
- for lvl:=Low(TCodeBrowserLevel) to High(TCodeBrowserLevel) do begin
- LevelFilterText[lvl]:=Options.LevelFilterText[lvl];
- LevelFilterType[lvl]:=Options.LevelFilterType[lvl];
- debugln(['TCodeBrowserView.UpdateTreeView lvl=',ord(lvl),' type=',ord(LevelFilterType[lvl]),' filter="',LevelFilterText[lvl],'"']);
- end;
- //DebugLn(['TCodeBrowserView.UpdateTreeView ShowPackages=',ShowPackages,' ShowUnits=',ShowUnits,' ShowIdentifiers=',ShowIdentifiers]);
- BrowseTreeView.Cursor:=crHourGlass;
- BrowseTreeView.BeginUpdate;
- CodeToolBoss.ActivateWriteLock;
- try
- InitTreeView;
- // create internal nodes
- AddUnitLists(ParserRoot,fViewRoot);
- // create treeview nodes
- AddTreeNodes(ViewRoot,nil);
- // if there are only a few items expand the whole tree
- if BrowseTreeView.Items.Count<30 then
- for i:=0 to BrowseTreeView.Items.TopLvlCount-1 do
- BrowseTreeView.Items.TopLvlItems[i].Expand(true);
- finally
- CodeToolBoss.DeactivateWriteLock;
- //DebugLn(['TCodeBrowserView.UpdateTreeView EndUpdate']);
- BrowseTreeView.EndUpdate;
- //DebugLn(['TCodeBrowserView.UpdateTreeView AFER ENDUPDATE']);
- BrowseTreeView.Cursor:=crDefault;
- end;
- VisiblePackages:=NewPackageCount;
- VisibleUnits:=NewUnitCount;
- VisibleIdentifiers:=NewIdentifierCount;
- UpdateStatusBar(false);
- end;
- procedure TCodeBrowserView.RemoveUnit(AnUnit: TCodeBrowserUnit);
- begin
- if AnUnit.Scanned then begin
- dec(FScannedUnits);
- dec(FScannedLines,AnUnit.ScannedLines);
- dec(FScannedBytes,AnUnit.ScannedBytes);
- dec(FScannedIdentifiers,AnUnit.ScannedIdentifiers);
- AnUnit.Scanned:=false;
- if fOutdatedFiles<>nil then
- fOutdatedFiles.Remove(AnUnit);
- end;
- end;
- function TCodeBrowserView.CountIdentifiers(Tool: TCodeTool): integer;
- var
- Node: TCodeTreeNode;
- begin
- Result:=0;
- if (Tool=nil) or (Tool.Tree=nil) then exit;
- Node:=Tool.Tree.Root;
- while Node<>nil do begin
- if Node.Desc=ctnImplementation then break;
- if (Node.Desc in (AllIdentifierDefinitions+[ctnProcedure,ctnProperty]))
- and (not Tool.NodeIsForwardDeclaration(Node)) then
- inc(Result);
- if not (Node.Desc in [ctnProcedure,ctnBeginBlock,ctnAsmBlock]) then
- Node:=Node.Next
- else
- Node:=Node.NextSkipChilds;
- end;
- end;
- procedure TCodeBrowserView.ClearTreeView;
- begin
- BrowseTreeView.Items.Clear;
- FreeAndNil(FViewRoot);
- end;
- procedure TCodeBrowserView.InitTreeView;
- begin
- ClearTreeView;
- end;
- function TCodeBrowserView.ListOwnerToText(const ListOwner: string): string;
- begin
- if ListOwner=CodeBrowserIDEName then
- Result:=IDEDescription
- else if ListOwner=CodeBrowserProjectName then
- Result:=ProjectDescription
- else
- Result:=ListOwner;
- end;
- function TCodeBrowserView.GetNodeImage(CodeNode: TObject): integer;
- var
- List: TCodeBrowserUnitList;
- Node: TCodeBrowserNode;
- begin
- Result:=ImgIDDefault;
-
- if CodeNode is TCodeBrowserUnit then begin
- Result:=ImgIDUnitCode;
- end else if CodeNode is TCodeBrowserUnitList then begin
- List:=TCodeBrowserUnitList(CodeNode);
- if List.Owner=IDEDescription then
- Result:=ImgIDProject
- else if List.Owner=ProjectDescription then
- Result:=ImgIDProject
- else
- Result:=ImgIDPackage;
- end else if CodeNode is TCodeBrowserNode then begin
- Node:=TCodeBrowserNode(CodeNode);
- case Node.Desc of
- ctnProgram,ctnLibrary,ctnPackage:
- Result:=ImgIDProgramCode;
- ctnUnit:
- Result:=ImgIDUnitCode;
- ctnInterface:
- Result:=ImgIDInterfaceSection;
- ctnImplementation:
- Result:=ImgIDImplementation;
- ctnInitialization:
- Result:=ImgIDInitialization;
- ctnFinalization:
- Result:=ImgIDFinalization;
- ctnTypeSection:
- Result:=ImgIDTypeSection;
- ctnTypeDefinition,ctnGenericType:
- Result:=ImgIDType;
- ctnVarSection:
- Result:=ImgIDVarSection;
- ctnVarDefinition:
- Result:=ImgIDVariable;
- ctnConstSection,ctnResStrSection:
- Result:=ImgIDConstSection;
- ctnConstDefinition:
- Result:=ImgIDConst;
- ctnClass,ctnObject,ctnObjCClass,ctnObjCCategory,ctnObjCProtocol,ctnCPPClass:
- Result:=ImgIDClass;
- ctnProcedure:
- Result:=ImgIDProc;
- ctnProperty:
- Result:=ImgIDProperty;
- end;
- end;
- end;
- function TCodeBrowserView.GetTVNodeHint(TVNode: TTreeNode): string;
- var
- NodeData: TObject;
- CurUnit: TCodeBrowserUnit;
- Node: TCodeBrowserNode;
- Line, Column: integer;
- BaseURL, HTMLHint: String;
- begin
- Result:='';
- if (TVNode=nil) or (TVNode.Data=nil) then exit;
- NodeData:=TObject(TVNode.Data);
- //DebugLn(['TCodeBrowserView.GetTVNodeHint ',DbgSName(NodeData)]);
- if NodeData is TCodeBrowserUnitList then begin
- end else if NodeData is TCodeBrowserUnit then begin
- CurUnit:=TCodeBrowserUnit(NodeData);
- if CurUnit.Filename<>'' then
- Result:=TVNode.Text+LineEnding+CurUnit.Filename;
- end else if NodeData is TCodeBrowserNode then begin
- Node:=TCodeBrowserNode(NodeData);
- if Node.CodePos.Code<>nil then begin
- Result:=TVNode.Text+LineEnding+Node.CodePos.Code.Filename;
- Node.CodePos.Code.AbsoluteToLineCol(Node.CodePos.P,Line,Column);
- if Line>0 then
- Result:=Result+' ('+IntToStr(Line)+','+IntToStr(Column)+')';
- if GetCodeHelp(TVNode, BaseURL, HTMLHint) then
- Result := HTMLHint;
- end;
- end;
- end;
- function TCodeBrowserView.GetCodeHelp(TVNode: TTreeNode; out BaseURL,
- HTMLHint: string): boolean;
- var
- NodeData: TObject;
- Node: TCodeBrowserNode;
- Tool: TCodeTool;
- CleanPos: integer;
- CTNode: TCodeTreeNode;
- NewCodePos: TCodeXYPosition;
- begin
- Result:=false;
- BaseURL:='';
- HTMLHint:='';
- if (TVNode=nil) or (TVNode.Data=nil) then exit;
- NodeData:=TObject(TVNode.Data);
- if NodeData is TCodeBrowserNode then begin
- Node:=TCodeBrowserNode(NodeData);
- if Node.CodePos.Code=nil then exit;
- if not LazarusIDE.BeginCodeTools then // commit source editor changes to codetools
- exit;
- // parse unit
- CodeToolBoss.Explore(Node.CodePos.Code,Tool,false,false);
- if Tool=nil then exit;
- // find source position in parsed code
- if Tool.CodePosToCleanPos(Node.CodePos,CleanPos)<>0 then exit;
- // find node
- CTNode:=Tool.FindDeepestNodeAtPos(CleanPos,false);
- if (CTNode=nil) or (CTNode.Desc<>Node.Desc) then
- exit; // source has changed
- // find cleanpos of identifier
- case CTNode.Desc of
- ctnProcedure:
- begin
- if SysUtils.CompareText(Tool.ExtractProcName(CTNode,ProcIdentifierFlags),
- Node.Identifier)<>0
- then
- exit; // source has changed
- Tool.MoveCursorToProcName(CTNode,true);
- CleanPos:=Tool.CurPos.StartPos;
- end;
- ctnProperty:
- begin
- if SysUtils.CompareText(Tool.ExtractPropName(CTNode,false),Node.Identifier)<>0
- then
- exit; // source has changed
- Tool.MoveCursorToPropName(CTNode);
- CleanPos:=Tool.CurPos.StartPos;
- end;
- ctnGenericType:
- begin
- Tool.ExtractDefinitionName(CTNode);
- if CTNode.FirstChild<>nil then
- CleanPos:=CTNode.FirstChild.StartPos;
- if SysUtils.CompareText(Tool.ExtractIdentifier(CleanPos),Node.Identifier)<>0
- then
- exit; // source has changed
- end;
- ctnVarDefinition,ctnTypeDefinition,ctnConstDefinition,
- ctnEnumIdentifier:
- if SysUtils.CompareText(Tool.ExtractIdentifier(CleanPos),Node.Identifier)<>0
- then
- exit; // source has changed
- else
- exit;
- end;
- // get source position
- if not Tool.CleanPosToCaret(CleanPos,NewCodePos) then exit;
- // ask the help system about the identifier
- if LazarusHelp.GetHintForSourcePosition(NewCodePos.Code.Filename,
- Point(NewCodePos.X,NewCodePos.Y),BaseURL,HTMLHint)<>shrSuccess then exit;
- if HTMLHint <> '' then
- Result:=true;
- end;
- end;
- procedure TCodeBrowserView.ExpandCollapseAllNodesInTreeView(
- NodeType: TExpandableNodeType; Expand: boolean);
- var
- Node: TTreeNode;
- begin
- BrowseTreeView.BeginUpdate;
- Node:=BrowseTreeView.Items.GetFirstNode;
- while Node<>nil do begin
- if (Node.Data<>nil) then begin
- case NodeType of
- entPackage:
- if TObject(Node.Data) is TCodeBrowserUnitList then
- Node.Expanded:=Expand;
- entUnit:
- if TObject(Node.Data) is TCodeBrowserUnit then
- Node.Expanded:=Expand;
- entClass:
- if (TObject(Node.Data) is TCodeBrowserNode) then
- Node.Expanded:=Expand;
- end;
- end;
- Node:=Node.GetNext;
- end;
- BrowseTreeView.EndUpdate;
- end;
- procedure TCodeBrowserView.CopyNode(TVNode: TTreeNode; NodeType: TCopyNodeType);
- var
- Node: TCodeBrowserNode;
- s: string;
- begin
- if (TVNode=nil) or (TVNode.Data=nil) then exit;
- s:='';
- if TObject(TVNode.Data) is TCodeBrowserUnitList then begin
- s:=TVNode.Text;
- end;
- if TObject(TVNode.Data) is TCodeBrowserUnit then begin
- s:=TVNode.Text;
- end;
- if (TObject(TVNode.Data) is TCodeBrowserNode) then begin
- Node:=TCodeBrowserNode(TVNode.Data);
- if NodeType=cntIdentifier then
- s:=Node.Identifier
- else
- s:=Node.Description;
- end;
- Clipboard.AsText:=s;
- end;
- procedure TCodeBrowserView.InvalidateStage(AStage: TCodeBrowserWorkStage);
- begin
- if ord(fStage)<=ord(AStage) then exit;
- fStage:=AStage;
- IdleConnected:=true;
- end;
- function TCodeBrowserView.GetSelectedUnit: TCodeBrowserUnit;
- var
- TVNode: TTreeNode;
- Node: TObject;
- begin
- Result:=nil;
- TVNode:=BrowseTreeView.Selected;
- if TVNode=nil then exit;
- Node:=TObject(TVNode.Data);
- if Node=nil then exit;
- if not (Node is TCodeBrowserUnit) then exit;
- Result:=TCodeBrowserUnit(Node);
- end;
- function TCodeBrowserView.GetSelectedPackage: TLazPackage;
- var
- TVNode: TTreeNode;
- Node: TObject;
- UnitList: TCodeBrowserUnitList;
- begin
- Result:=nil;
- TVNode:=BrowseTreeView.Selected;
- if TVNode=nil then exit;
- Node:=TObject(TVNode.Data);
- if Node=nil then exit;
- if not (Node is TCodeBrowserUnitList) then exit;
- UnitList:=TCodeBrowserUnitList(Node);
- Result:=PackageGraph.FindPackageWithName(UnitList.Owner,nil);
- end;
- function TCodeBrowserView.GetCurUnitInSrcEditor(out FileOwner: TObject; out
- UnitCode: TCodeBuffer): boolean;
- var
- SrcEdit: TSourceEditorInterface;
- Code: TCodeBuffer;
- Owners: TFPList;
- begin
- FileOwner:=nil;
- UnitCode:=nil;
- Result:=false;
- SrcEdit:=SourceEditorManagerIntf.ActiveEditor;
- if SrcEdit=nil then exit;
- Code:=CodeToolBoss.GetMainCode(TCodeBuffer(SrcEdit.CodeToolsBuffer));
- if Code=nil then exit;
- Owners:=PkgBoss.GetOwnersOfUnit(Code.FileName);
- try
- if (Owners=nil) or (Owners.Count=0) then exit;
- FileOwner:=TObject(Owners[0]);
- UnitCode:=Code;
- Result:=true;
- finally
- Owners.Free;
- end;
- end;
- function TCodeBrowserView.GetCurPackageInSrcEditor: TLazPackage;
- var
- SrcEdit: TSourceEditorInterface;
- Owners: TFPList;
- i: Integer;
- begin
- Result:=nil;
- SrcEdit:=SourceEditorManagerIntf.ActiveEditor;
- if SrcEdit=nil then exit;
- Owners:=PkgBoss.GetOwnersOfUnit(SrcEdit.FileName);
- try
- if (Owners=nil) then exit;
- for i:=0 to Owners.Count-1 do begin
- if TObject(Owners[i]) is TLazPackage then begin
- Result:=TLazPackage(Owners[i]);
- exit;
- end;
- end;
- finally
- Owners.Free;
- end;
- end;
- procedure TCodeBrowserView.OpenTVNode(TVNode: TTreeNode);
- var
- NodeData: TObject;
- List: TCodeBrowserUnitList;
- APackage: TLazPackage;
- CurUnit: TCodeBrowserUnit;
- Node: TCodeBrowserNode;
- Line,Column: integer;
- begin
- if (TVNode=nil) or (TVNode.Data=nil) then exit;
- NodeData:=TObject(TVNode.Data);
- if NodeData is TCodeBrowserUnitList then begin
- List:=TCodeBrowserUnitList(NodeData);
- DebugLn(['TCodeBrowserView.OpenSelected "',List.Owner,'=',CodeBrowserProjectName,'"']);
- if List.Owner=CodeBrowserProjectName then begin
- // open project inspector
- DebugLn(['TCodeBrowserView.OpenSelected open project inspector']);
- ExecuteIDECommand(Self,ecProjectInspector);
- end else if List.Owner=CodeBrowserIDEName then begin
- // open the IDE -> already open
- end else if List.Owner=CodeBrowserHidden then begin
- // nothing
- end else begin
- // open package
- APackage:=PackageGraph.FindPackageWithName(List.Owner,nil);
- if APackage<>nil then begin
- PackageEditingInterface.DoOpenPackageWithName(List.Owner,[],false);
- end;
- end;
- end else if NodeData is TCodeBrowserUnit then begin
- CurUnit:=TCodeBrowserUnit(NodeData);
- if CurUnit.Filename<>'' then begin
- LazarusIDE.DoOpenEditorFile(CurUnit.Filename,-1,-1,[ofOnlyIfExists]);
- end;
- end else if NodeData is TCodeBrowserNode then begin
- Node:=TCodeBrowserNode(NodeData);
- if (Node.CodePos.Code<>nil)
- and (Node.CodePos.Code.Filename<>'') then begin
- Node.CodePos.Code.AbsoluteToLineCol(Node.CodePos.P,Line,Column);
- LazarusIDE.DoOpenFileAndJumpToPos(Node.CodePos.Code.Filename,
- Point(Column,Line),-1,-1,-1,[ofOnlyIfExists]);
- end;
- end;
- end;
- procedure TCodeBrowserView.BeginUpdate;
- begin
- inc(fUpdateCount);
- BrowseTreeView.BeginUpdate;
- end;
- procedure TCodeBrowserView.EndUpdate;
- begin
- dec(fUpdateCount);
- BrowseTreeView.EndUpdate;
- end;
- function TCodeBrowserView.ExportTree: TModalResult;
- var
- SaveDialog: TSaveDialog;
- begin
- SaveDialog:=TSaveDialog.Create(nil);
- try
- InitIDEFileDialog(SaveDialog);
- SaveDialog.Title:='Save tree as text (*.txt) ...';
- SaveDialog.FileName:='identifiers.txt';
- SaveDialog.DefaultExt:='txt';
- if not SaveDialog.Execute then exit(mrCancel);
- Result:=ExportTreeAsText(SaveDialog.FileName);
- finally
- StoreIDEFileDialog(SaveDialog);
- SaveDialog.Free;
- end;
- end;
- function TCodeBrowserView.ExportTreeAsText(Filename: string): TModalResult;
- procedure WriteNode(var List: TStrings; Node: TTreeNode; Prefix: String='');
- const
- CodeBrowserTypes: array[1..3] of TClass =
- (TCodeBrowserUnitList, TCodeBrowserUnit, TCodeBrowserNode);
- NodeIndent = ' ';
- var
- Child: TTreeNode;
- i: Integer;
- begin
- if Node=nil then exit;
- for i:=Low(CodeBrowserTypes) to High(CodeBrowserTypes) do begin
- if TObject(Node.Data) is CodeBrowserTypes[i] then begin
- List.Add(prefix+Node.Text);
- Prefix:=Prefix+NodeIndent;
- break;
- end;
- end;
- Child:=Node.GetFirstChild;
- while Child<>nil do begin
- WriteNode(List,Child,Prefix);
- Child:=Child.GetNextSibling;
- end;
- end;
- var
- List: TStrings;
- begin
- Filename:=TrimAndExpandFilename(Filename);
- if Filename='' then exit(mrCancel);
- Result:=CheckCreatingFile(Filename,true,true,true);
- if Result<>mrOk then exit;
- List:=TStringList.Create;
- try
- WriteNode(List,BrowseTreeView.Items.GetFirstNode);
- Result:=SaveStringToFile(Filename,List.Text,[],
- 'exporting identifiers as text');
- finally
- List.Free;
- end;
- end;
- function TCodeBrowserView.GetScopeToCurUnitOwner(UseFCLAsDefault: boolean): string;
- var
- SrcEdit: TSourceEditorInterface;
- Code: TCodeBuffer;
- MainCode: TCodeBuffer;
- Owners: TFPList;
- begin
- Result:='';
- if UseFCLAsDefault then
- Result:=PackageGraph.FCLPackage.Name;
- SrcEdit:=SourceEditorManagerIntf.ActiveEditor;
- if SrcEdit=nil then exit;
- Code:=TCodeBuffer(SrcEdit.CodeToolsBuffer);
- if Code=nil then exit;
- MainCode:=CodeToolBoss.GetMainCode(Code);
- if MainCode<>nil then
- Code:=MainCode;
- Owners:=PkgBoss.GetPossibleOwnersOfUnit(Code.FileName,[]);
- try
- if (Owners=nil) or (Owners.Count=0) then exit;
- if TObject(Owners[0])=Project1 then begin
- Result:=ProjectDescription;
- exit;
- end;
- if TObject(Owners[0]) is TLazPackage then begin
- Result:=TLazPackage(Owners[0]).Name;
- exit;
- end;
- finally
- Owners.Free;
- end;
- end;
- function TCodeBrowserView.SetScopeToCurUnitOwner(UseFCLAsDefault,
- WithRequiredPackages: boolean): boolean;
- var
- NewScope: String;
- begin
- Result:=false;
- NewScope:=GetScopeToCurUnitOwner(UseFCLAsDefault);
- if NewScope='' then exit;
- ScopeComboBox.Text:=NewScope;
- ScopeWithRequiredPackagesCheckBox.Checked:=WithRequiredPackages;
- InvalidateStage(cbwsGetScopeOptions);
- end;
- procedure TCodeBrowserView.SetFilterToSimpleIdentifier(Identifier: string);
- begin
- ShowPackagesCheckBox.Checked:=true;
- PackageFilterEdit.Text:='';
- PackageFilterContainsSpeedButton.Down:=true;
- ShowUnitsCheckBox.Checked:=true;
- UnitFilterEdit.Text:='';
- UnitFilterContainsSpeedButton.Down:=true;
- ShowIdentifiersCheckBox.Checked:=true;
- IdentifierFilterEdit.Text:=Identifier;
- IdentifierFilterBeginsSpeedButton.Down:=true;
- ShowEmptyNodesCheckBox.Checked:=false;
- InvalidateStage(cbwsGetViewOptions);
- end;
- procedure TCodeBrowserView.BrowseTreeViewShowHint(Sender: TObject; HintInfo: PHintInfo);
- var
- TVNode: TTreeNode;
- HintStr: String;
- begin
- //DebugLn(['TCodeBrowserView.BrowseTreeViewShowHint ',dbgs(HintInfo^.CursorPos)]);
- HintStr:='';
- TVNode:=BrowseTreeView.GetNodeAt(HintInfo^.CursorPos.X, HintInfo^.CursorPos.Y);
- if TVNode<>nil then
- HintStr:=GetTVNodeHint(TVNode);
- HintInfo^.HintStr:=''; // do not use the normal mechanism,
- // ... open a THintWindow with LazarusHelp instead
- if csDestroying in ComponentState then exit;
- FHintManager.ShowHint(HintInfo^.HintPos, HintStr);
- end;
- procedure TCodeBrowserView.CloseHintWindow;
- begin
- FHintManager.HideHint;
- end;
- procedure TCodeBrowserView.CollapseAllPackagesMenuItemClick(Sender: TObject);
- begin
- ExpandCollapseAllNodesInTreeView(entPackage,false);
- end;
- procedure TCodeBrowserView.CollapseAllUnitsMenuItemClick(Sender: TObject);
- begin
- ExpandCollapseAllNodesInTreeView(entUnit,false);
- end;
- procedure TCodeBrowserView.CollapseAllClassesMenuItemClick(Sender: TObject);
- begin
- ExpandCollapseAllNodesInTreeView(entClass,false);
- end;
- procedure TCodeBrowserView.CopyDescriptionMenuItemClick(Sender: TObject);
- begin
- CopyNode(BrowseTreeView.Selected,cntDescription);
- end;
- procedure TCodeBrowserView.CopyIdentifierMenuItemClick(Sender: TObject);
- begin
- CopyNode(BrowseTreeView.Selected,cntIdentifier);
- end;
- procedure TCodeBrowserView.ExpandAllClassesMenuItemClick(Sender: TObject);
- begin
- ExpandCollapseAllNodesInTreeView(entClass,true);
- end;
- procedure TCodeBrowserView.ExpandAllPackagesMenuItemClick(Sender: TObject);
- begin
- ExpandCollapseAllNodesInTreeView(entPackage,true);
- end;
- procedure TCodeBrowserView.ExpandAllUnitsMenuItemClick(Sender: TObject);
- begin
- ExpandCollapseAllNodesInTreeView(entUnit,true);
- end;
- procedure TCodeBrowserView.ExportMenuItemClick(Sender: TObject);
- begin
- ExportTree;
- end;
- procedure TCodeBrowserView.BrowseTreeViewMouseDown(Sender: TOBject;
- Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
- begin
- if ssDouble in Shift then
- OpenTVNode(BrowseTreeView.GetNodeAt(X,Y));
- end;
- procedure TCodeBrowserView.UsePkgInProjectMenuItemClick(Sender: TObject);
- var
- APackage: TLazPackage;
- begin
- APackage:=GetSelectedPackage;
- if APackage=nil then exit;
- PkgBoss.AddProjectDependency(Project1,APackage);
- end;
- procedure TCodeBrowserView.UseUnitInCurUnitMenuItemClick(Sender: TObject);
- begin
- UseUnitInSrcEditor(false);
- end;
- procedure TCodeBrowserView.UsePkgInCurUnitMenuItemClick(Sender: TObject);
- var
- APackage: TLazPackage;
- TargetPackage: TLazPackage;
- List: TFPList;
- begin
- APackage:=GetSelectedPackage;
- if APackage=nil then exit;
- TargetPackage:=GetCurPackageInSrcEditor;
- if TargetPackage=nil then exit;
- List:=TFPList.Create;
- try
- List.Add(TargetPackage);
- if PkgBoss.AddDependencyToOwners(List,APackage)=mrOk then begin
- PackageEditingInterface.DoOpenPackageWithName(TargetPackage.Name,[],false);
- end;
- finally
- List.Free;
- end;
- end;
- procedure TCodeBrowserView.UseIdentifierInCurUnitMenuItemClick(Sender: TObject);
- begin
- UseUnitInSrcEditor(true);
- end;
- procedure TCodeBrowserView.BrowseTreeViewMouseMove(Sender: TObject;
- Shift: TShiftState; X, Y: Integer);
- begin
- CloseHintWindow;
- end;
- procedure TCodeBrowserView.FormDeactivate(Sender: TObject);
- begin
- CloseHintWindow;
- end;
- { TCodeBrowserViewOptions }
- procedure TCodeBrowserViewOptions.SetModified(const AValue: boolean);
- begin
- if AValue then
- IncreaseChangeStamp;
- if FModified=AValue then exit;
- FModified:=AValue;
- end;
- function TCodeBrowserViewOptions.GetLevelFilterText(Level: TCodeBrowserLevel
- ): string;
- begin
- Result:=FLevelFilterText[Level];
- end;
- function TCodeBrowserViewOptions.GetLevelFilterType(Level: TCodeBrowserLevel
- ): TCodeBrowserTextFilter;
- begin
- Result:=FLevelFilterType[Level];
- end;
- procedure TCodeBrowserViewOptions.SetLevelFilterText(Level: TCodeBrowserLevel;
- const AValue: string);
- begin
- if FLevelFilterText[Level]=AValue then exit;
- FLevelFilterText[Level]:=AValue;
- Modified:=true;
- end;
- procedure TCodeBrowserViewOptions.SetLevelFilterType(Level: TCodeBrowserLevel;
- const AValue: TCodeBrowserTextFilter);
- begin
- if FLevelFilterType[Level]=AValue then exit;
- FLevelFilterType[Level]:=AValue;
- Modified:=true;
- end;
- procedure TCodeBrowserViewOptions.SetScope(const AValue: string);
- begin
- if FScope=AValue then exit;
- FScope:=AValue;
- Modified:=true;
- end;
- procedure TCodeBrowserViewOptions.SetLevels(const AValue: TStrings);
- begin
- if FLevels=AValue then exit;
- if FLevels.Text=AValue.Text then exit;
- FLevels.Assign(AValue);
- Modified:=true;
- end;
- procedure TCodeBrowserViewOptions.SetShowEmptyNodes(const AValue: boolean);
- begin
- if FShowEmptyNodes=AValue then exit;
- FShowEmptyNodes:=AValue;
- Modified:=true;
- end;
- procedure TCodeBrowserViewOptions.SetShowPrivate(const AValue: boolean);
- begin
- if FShowPrivate=AValue then exit;
- FShowPrivate:=AValue;
- Modified:=true;
- end;
- procedure TCodeBrowserViewOptions.SetShowProtected(const AValue: boolean);
- begin
- if FShowProtected=AValue then exit;
- FShowProtected:=AValue;
- Modified:=true;
- end;
- procedure TCodeBrowserViewOptions.SetStoreWithRequiredPackages(
- const AValue: boolean);
- begin
- if FStoreWithRequiredPackages=AValue then exit;
- FStoreWithRequiredPackages:=AValue;
- end;
- procedure TCodeBrowserViewOptions.SetWithRequiredPackages(const AValue: boolean);
- begin
- if FWithRequiredPackages=AValue then exit;
- FWithRequiredPackages:=AValue;
- Modified:=true;
- end;
- procedure TCodeBrowserViewOptions.IncreaseChangeStamp;
- begin
- CTIncreaseChangeStamp(FChangeStamp);
- end;
- constructor TCodeBrowserViewOptions.Create;
- begin
- FLevels:=TStringList.Create;
- FChangeStamp:=CTInvalidChangeStamp;
- Clear;
- end;
- destructor TCodeBrowserViewOptions.Destroy;
- begin
- FreeAndNil(FLevels);
- inherited Destroy;
- end;
- procedure TCodeBrowserViewOptions.Clear;
- var
- l: TCodeBrowserLevel;
- begin
- FLevels.Clear;
- FLevels.Text:=CodeBrowserLevelNames[cblPackages]+#13
- +CodeBrowserLevelNames[cblUnits]+#13
- +CodeBrowserLevelNames[cblIdentifiers];
- WithRequiredPackages:=false;
- ShowPrivate:=false;
- ShowProtected:=true;
- Scope:='Project';
- for l:=Low(TCodeBrowserLevel) to High(TCodeBrowserLevel) do begin
- FLevelFilterType[l]:=cbtfContains;
- FLevelFilterText[l]:='';
- end;
- IncreaseChangeStamp;
- Modified:=false;
- end;
- procedure TCodeBrowserViewOptions.LoadFromConfig(ConfigStore: TConfigStorage;
- const Path: string);
- var
- l: TCodeBrowserLevel;
- SubPath: String;
- begin
- Clear;
- WithRequiredPackages:=ConfigStore.GetValue(Path+'WithRequiredPackages/Value',false);
- Scope:=ConfigStore.GetValue(Path+'Scope/Value','Project');
- ShowPrivate:=ConfigStore.GetValue(Path+'ShowPrivate/Value',false);
- ShowProtected:=ConfigStore.GetValue(Path+'ShowProtected/Value',true);
- ShowEmptyNodes:=ConfigStore.GetValue(Path+'ShowEmptyNodes/Value',true);
- ConfigStore.GetValue(Path+'Levels/',FLevels);
- for l:=Low(TCodeBrowserLevel) to High(TCodeBrowserLevel) do begin
- SubPath:=Path+'LevelFilter/'+CodeBrowserLevelNames[l];
- FLevelFilterType[l]:=StringToCodeBrowserTextFilter(
- ConfigStore.GetValue(SubPath+'/Type',''));
- FLevelFilterText[l]:=ConfigStore.GetValue(SubPath+'/Text','');
- end;
- Modified:=false;
- end;
- procedure TCodeBrowserViewOptions.SaveToConfig(ConfigStore: TConfigStorage;
- const Path: string);
- var
- l: TCodeBrowserLevel;
- SubPath: String;
- b: Boolean;
- begin
- b:=WithRequiredPackages;
- if not StoreWithRequiredPackages then
- b:=false;
- ConfigStore.SetDeleteValue(Path+'WithRequiredPackages/Value',b,false);
- ConfigStore.SetDeleteValue(Path+'Scope/Value',Scope,'Project');
- ConfigStore.SetDeleteValue(Path+'ShowPrivate/Value',ShowPrivate,false);
- ConfigStore.SetDeleteValue(Path+'ShowProtected/Value',ShowProtected,true);
- ConfigStore.SetDeleteValue(Path+'ShowEmptyNodes/Value',ShowEmptyNodes,true);
- ConfigStore.SetValue(Path+'Levels/',FLevels);
- for l:=Low(TCodeBrowserLevel) to High(TCodeBrowserLevel) do begin
- SubPath:=Path+'LevelFilter/'+CodeBrowserLevelNames[l];
- ConfigStore.SetDeleteValue(SubPath+'/Type',
- CodeBrowserTextFilterNames[FLevelFilterType[l]],
- CodeBrowserTextFilterNames[cbtfBegins]);
- ConfigStore.SetDeleteValue(SubPath+'/Text',FLevelFilterText[l],'');
- end;
- Modified:=false;
- end;
- function TCodeBrowserViewOptions.HasLevel(Level: TCodeBrowserLevel): boolean;
- begin
- Result:=Levels.IndexOf(CodeBrowserLevelNames[Level])>=0;
- end;
- { TQuickFixIdentifierNotFound_Search }
- function TQuickFixIdentifierNotFound_Search.IsApplicable(Msg: TMessageLine; out
- Identifier: string): boolean;
- var
- Dummy: string;
- begin
- Result:=false;
- Identifier:='';
- if not Msg.HasSourcePosition then exit;
- Result:=TIDEFPCParser.MsgLineIsId(Msg,5000,Identifier,Dummy);
- end;
- procedure TQuickFixIdentifierNotFound_Search.CreateMenuItems(
- Fixes: TMsgQuickFixes);
- var
- Msg: TMessageLine;
- Identifier: string;
- i: Integer;
- begin
- for i:=0 to Fixes.LineCount-1 do begin
- Msg:=Fixes.Lines[i];
- if not IsApplicable(Msg,Identifier) then continue;
- Fixes.AddMenuItem(Self,Msg,lisQuickFixSearchIdentifier);
- exit;
- end;
- end;
- procedure TQuickFixIdentifierNotFound_Search.QuickFix(Fixes: TMsgQuickFixes;
- Msg: TMessageLine);
- var
- Identifier: String;
- KnownFilename: String;
- Caret: TPoint;
- Filename: String;
- begin
- if not IsApplicable(Msg,Identifier) then exit;
- if not LazarusIDE.BeginCodeTools then begin
- DebugLn(['TQuickFixIdentifierNotFound_Search.Execute failed because IDE busy']);
- exit;
- end;
- // get identifier
- if (Identifier='') or (not IsValidIdent(Identifier)) then begin
- DebugLn(['TQuickFixIdentifierNotFound_Search.Execute not an identifier "',dbgstr(Identifier),'"']);
- exit;
- end;
- Filename:=Msg.GetFullFilename;
- KnownFilename:= LazarusIDE.FindSourceFile(Filename, Project1.ProjectDirectory,
- [fsfSearchForProject, fsfUseIncludePaths, fsfMapTempToVirtualFiles]);
- Caret:=Point(Msg.Line,Msg.Column);
- if (KnownFilename <> '') and (KnownFilename <> Filename) then begin
- if LazarusIDE.DoOpenFileAndJumpToPos(KnownFilename,Caret,-1,-1,-1,OpnFlagsPlainFile)<>mrOk
- then
- if LazarusIDE.DoOpenFileAndJumpToPos(Filename,Caret,-1,-1,-1,OpnFlagsPlainFile)<>mrOk
- then exit;
- end
- else
- if LazarusIDE.DoOpenFileAndJumpToPos(Filename,Caret,-1,-1,-1,OpnFlagsPlainFile
- )<>mrOk
- then exit;
- // start code browser
- ShowCodeBrowser(Identifier);
- end;
- end.