diff --git a/components/codetools/codecompletiontool.pas b/components/codetools/codecompletiontool.pas index 3aac283a3b..1c35e35210 100644 --- a/components/codetools/codecompletiontool.pas +++ b/components/codetools/codecompletiontool.pas @@ -1449,15 +1449,15 @@ var ExprEnd: LongInt; ResultNodeExt: TCodeTreeNodeExtension; - function CheckExprIdentifier(const Identifier: string): boolean; + function CheckExprIdentifier(Identifier: PChar): boolean; var NodeExt: TCodeTreeNodeExtension; begin Result:=true; - if CompareIdentifiers('Result',PChar(Identifier))=0 then exit; - if CompareIdentifiers('FuncName',PChar(Identifier))=0 then exit; + if CompareIdentifiers('Result',Identifier)=0 then exit; + if CompareIdentifiers(PChar(FuncName),Identifier)=0 then exit; // check for const and type definitions - NodeExt:=FindCodeTreeNodeExt(Definitions,Identifier); + NodeExt:=FindCodeTreeNodeExt(Definitions,GetIdentifier(Identifier)); if (NodeExt<>nil) and (NodeExt.Node<>nil) then begin if NodeExt.Node.Desc in [ctnConstDefinition,ctnTypeDefinition] then exit; @@ -1471,7 +1471,7 @@ var begin if (ProcNode=nil) or (ProcNode.Desc<>ctnProcedure) then exit; - DebugLn(['CheckProcNode START ',ExtractProcHead(ProcNode,[])]); + //DebugLn(['CheckProcNode START ',ExtractProcHead(ProcNode,[])]); MoveCursorToNodeStart(ProcNode); // read 'function' ReadNextAtom; @@ -1518,7 +1518,7 @@ var end; if Node.Desc<>ctnBeginBlock then exit; - DebugLn(['CheckProcNode has begin block']); + //DebugLn(['CheckProcNode has begin block']); // check begin block is only a single assignment MoveCursorToNodeStart(Node); @@ -1538,14 +1538,15 @@ var if (CurPos.Flag in [cafSemicolon,cafEnd]) then break; // check if all identifiers can be used in a constant expression - if AtomIsIdentifier(false) and not CheckExprIdentifier(GetAtom) then + if AtomIsIdentifier(false) + and not CheckExprIdentifier(@Src[CurPos.StartPos]) then exit; ExprEnd:=CurPos.EndPos; ReadNextAtom; end; if ExprStart=ExprEnd then exit; - DebugLn(['CheckProcNode FOUND']); + //DebugLn(['CheckProcNode FOUND']); // save values ResultNodeExt:=NodeExtMemManager.NewNode; diff --git a/components/codetools/codetoolmanager.pas b/components/codetools/codetoolmanager.pas index 0fb797f9a2..fa4b43539f 100644 --- a/components/codetools/codetoolmanager.pas +++ b/components/codetools/codetoolmanager.pas @@ -51,6 +51,7 @@ uses type TCodeToolManager = class; TCodeTool = TEventsCodeTool; + TDirectivesTool = TCompilerDirectivesTree; TGetStringProc = procedure(const s: string) of object; TOnBeforeApplyChanges = procedure(Manager: TCodeToolManager; @@ -79,7 +80,9 @@ type FCheckFilesOnDisk: boolean; FCompleteProperties: boolean; FCurCodeTool: TCodeTool; // current codetool + FCurDirectivesTool: TDirectivesTool; FCursorBeyondEOL: boolean; + FDirectivesTools: TAVLTree; // tree of TDirectivesTool sorted for Code (TCodeBuffer) FErrorCode: TCodeBuffer; FErrorColumn: integer; FErrorLine: integer; @@ -98,7 +101,7 @@ type FResourceTool: TResourceCodeTool; FSetPropertyVariablename: string; FSourceExtensions: string; // default is '.pp;.pas;.lpr;.dpr;.dpk' - FSourceTools: TAVLTree; // tree of TCustomCodeTool sorted for pointer + FSourceTools: TAVLTree; // tree of TCustomCodeTool sorted TCustomCodeTool(Data).Scanner.MainCode FTabWidth: integer; FVisibleEditorLines: integer; FWriteExceptions: boolean; @@ -183,19 +186,28 @@ type // initializing single codetools function FindCodeToolForSource(Code: TCodeBuffer): TCustomCodeTool; - property CurCodeTool: TEventsCodeTool read FCurCodeTool; + property CurCodeTool: TCodeTool read FCurCodeTool; procedure ClearCurCodeTool; function InitCurCodeTool(Code: TCodeBuffer): boolean; function InitResourceTool: boolean; procedure ClearPositions; function GetCodeToolForSource(Code: TCodeBuffer; - GoToMainCode, ExceptionOnError: boolean): TCustomCodeTool; + GoToMainCode, ExceptionOnError: boolean): TCustomCodeTool; + + // initializing single compilerdirectivestrees + function FindDirectivesToolForSource(Code: TCodeBuffer + ): TDirectivesTool; + property CurDirectivesTool: TDirectivesTool read FCurDirectivesTool; + procedure ClearCurDirectivesTool; + function InitCurDirectivesTool(Code: TCodeBuffer): boolean; + function GetDirectivesToolForSource(Code: TCodeBuffer; + ExceptionOnError: boolean): TCompilerDirectivesTree; // exception handling procedure ClearError; function HandleException(AnException: Exception): boolean; procedure SetError(Code: TCodeBuffer; Line, Column: integer; - const TheMessage: string); + const TheMessage: string); property CatchExceptions: boolean read FCatchExceptions write FCatchExceptions; property WriteExceptions: boolean @@ -286,6 +298,8 @@ type WithStatements: boolean; OnlyInterface: boolean = false): boolean; function CheckSyntax(Code: TCodeBuffer; out NewCode: TCodeBuffer; out NewX, NewY, NewTopLine: integer; out ErrorMsg: string): boolean; + function ExploreDirectives(Code: TCodeBuffer; + out ADirectivesTool: TDirectivesTool): boolean; // compiler directives function GuessMisplacedIfdefEndif(Code: TCodeBuffer; X,Y: integer; @@ -640,6 +654,20 @@ begin Result:=0; end; +function CompareDirectivesTreeSources(Data1, Data2: Pointer): integer; +var + Src1, Src2: Pointer; +begin + Src1:=TCompilerDirectivesTree(Data1).Code; + Src2:=TCompilerDirectivesTree(Data2).Code; + if Src1Src2 then + Result:=+1 + else + Result:=0; +end; + function GetOwnerForCodeTreeNode(ANode: TCodeTreeNode): TObject; begin Result:=CodeToolBoss.GetOwnerForCodeTreeNode(ANode); @@ -706,6 +734,7 @@ begin FVisibleEditorLines:=20; FWriteExceptions:=true; FSourceTools:=TAVLTree.Create(@CompareCodeToolMainSources); + FDirectivesTools:=TAVLTree.Create(@CompareDirectivesTreeSources); IdentifierList:=TIdentifierList.Create; IdentifierHistory:=TIdentifierHistoryList.Create; IdentifierList.History:=IdentifierHistory; @@ -725,6 +754,8 @@ begin FreeAndNil(IdentifierList); FSourceTools.FreeAndClear; FreeAndNil(FSourceTools); + FDirectivesTools.FreeAndClear; + FreeAndNil(FDirectivesTools); FreeAndNil(FResourceTool); {$IFDEF CTDEBUG} DebugLn('[TCodeToolManager.Destroy] C'); @@ -1423,6 +1454,7 @@ end; function TCodeToolManager.HandleException(AnException: Exception): boolean; var ErrorSrcTool: TCustomCodeTool; DirtyPos: Integer; + ErrorDirTool: TCompilerDirectivesTree; begin fErrorMsg:=AnException.Message; fErrorTopLine:=0; @@ -1446,6 +1478,12 @@ begin fErrorCode:=ErrorSrcTool.ErrorPosition.Code; fErrorColumn:=ErrorSrcTool.ErrorPosition.X; fErrorLine:=ErrorSrcTool.ErrorPosition.Y; + end else if (AnException is ECDirectiveParserException) then begin + // Compiler directive parser error + ErrorDirTool:=ECDirectiveParserException(AnException).Sender; + fErrorCode:=ErrorDirTool.Code; + fErrorColumn:=-1; + fErrorLine:=-1; end else if (AnException is ESourceChangeCacheError) then begin // SourceChangeCache error fErrorCode:=nil; @@ -1514,6 +1552,22 @@ begin ErrorMsg:=ErrorMessage; end; +function TCodeToolManager.ExploreDirectives(Code: TCodeBuffer; out + ADirectivesTool: TDirectivesTool): boolean; +begin + Result:=false; + ADirectivesTool:=nil; + try + if InitCurDirectivesTool(Code) then begin + ADirectivesTool:=FCurDirectivesTool; + FCurDirectivesTool.Parse; + Result:=true; + end; + except + on e: Exception do Result:=HandleException(e); + end; +end; + function TCodeToolManager.JumpToMethod(Code: TCodeBuffer; X,Y: integer; var NewCode: TCodeBuffer; var NewX, NewY, NewTopLine: integer; var RevertableJump: boolean): boolean; @@ -4007,7 +4061,8 @@ end; function TCodeToolManager.FindCodeToolForSource(Code: TCodeBuffer ): TCustomCodeTool; -var ANode: TAVLTreeNode; +var + ANode: TAVLTreeNode; CurSrc, SearchedSrc: Pointer; begin ANode:=FSourceTools.Root; @@ -4062,6 +4117,14 @@ begin Result:=TCodeTool.Create; Result.Scanner:=Code.Scanner; FSourceTools.Add(Result); + TCodeTool(Result).OnGetCodeToolForBuffer:=@OnGetCodeToolForBuffer; + TCodeTool(Result).OnGetDirectoryCache:=@OnGetDirectoryCache; + TCodeTool(Result).OnFindUsedUnit:=@DoOnFindUsedUnit; + TCodeTool(Result).OnGetSrcPathForCompiledUnit:=@DoOnGetSrcPathForCompiledUnit; + TCodeTool(Result).OnGetMethodName:=@OnInternalGetMethodName; + Result.OnSetGlobalWriteLock:=@OnToolSetWriteLock; + Result.OnGetGlobalWriteLockInfo:=@OnToolGetWriteLockInfo; + TCodeTool(Result).OnParserProgress:=@OnParserProgress; end; with TCodeTool(Result) do begin AdjustTopLineDueToComment:=Self.AdjustTopLineDueToComment; @@ -4073,14 +4136,57 @@ begin Result.VisibleEditorLines:=FVisibleEditorLines; Result.JumpCentered:=FJumpCentered; Result.CursorBeyondEOL:=FCursorBeyondEOL; - TCodeTool(Result).OnGetCodeToolForBuffer:=@OnGetCodeToolForBuffer; - TCodeTool(Result).OnGetDirectoryCache:=@OnGetDirectoryCache; - TCodeTool(Result).OnFindUsedUnit:=@DoOnFindUsedUnit; - TCodeTool(Result).OnGetSrcPathForCompiledUnit:=@DoOnGetSrcPathForCompiledUnit; - TCodeTool(Result).OnGetMethodName:=@OnInternalGetMethodName; - Result.OnSetGlobalWriteLock:=@OnToolSetWriteLock; - Result.OnGetGlobalWriteLockInfo:=@OnToolGetWriteLockInfo; - TCodeTool(Result).OnParserProgress:=@OnParserProgress; +end; + +function TCodeToolManager.FindDirectivesToolForSource(Code: TCodeBuffer + ): TDirectivesTool; +var + ANode: TAVLTreeNode; + CurSrc, SearchedSrc: Pointer; +begin + ANode:=FDirectivesTools.Root; + SearchedSrc:=Pointer(Code); + while (ANode<>nil) do begin + CurSrc:=Pointer(TDirectivesTool(ANode.Data).Code); + if CurSrc>SearchedSrc then + ANode:=ANode.Left + else if CurSrcnil) do begin CurTool:=TCustomCodeTool(AToolNode.Data); - if CurTool.Tree.Root=RootCodeTreeNode then begin + if (CurTool.Tree<>nil) and (CurTool.Tree.Root=RootCodeTreeNode) then begin Result:=CurTool; exit; end; AToolNode:=FSourceTools.FindSuccessor(AToolNode); end; + + // search in directivestools + AToolNode:=FDirectivesTools.FindLowest; + while (AToolNode<>nil) do begin + CurDirTool:=TCompilerDirectivesTree(AToolNode.Data); + if (CurDirTool.Tree<>nil) and (CurDirTool.Tree.Root=RootCodeTreeNode) then + begin + Result:=CurDirTool; + exit; + end; + AToolNode:=FDirectivesTools.FindSuccessor(AToolNode); + end; end; function TCodeToolManager.DirectoryCachePoolGetString(const ADirectory: string; @@ -4248,6 +4369,10 @@ begin if Result<>0 then begin dec(Result,70000); exit; end; + Result:=FDirectivesTools.ConsistencyCheck; + if Result<>0 then begin + dec(Result,80000); exit; + end; finally if (Result<>0) and (FCatchExceptions=false) then raise Exception.CreateFmt(ctsTCodeToolManagerConsistencyCheck, [Result]); diff --git a/components/codetools/directivestree.pas b/components/codetools/directivestree.pas index 58d80c8b05..1476da4854 100644 --- a/components/codetools/directivestree.pas +++ b/components/codetools/directivestree.pas @@ -88,12 +88,20 @@ const H2Pas_Function_Prefix = 'H2PAS_FUNCTION_'; type - CDirectiveParserException = class(Exception) + TCompilerDirectivesTree = class; + + { ECDirectiveParserException } + + ECDirectiveParserException = class(Exception) + public + Sender: TCompilerDirectivesTree; + constructor Create(ASender: TCompilerDirectivesTree; const AMessage: string); end; { TCompilerDirectivesTree } TCompilerDirectivesTree = class + FChangeStep: integer; private FDefaultDirectiveFuncList: TKeyWordFunctionList; FDisableUnusedDefines: boolean; @@ -161,6 +169,7 @@ type destructor Destroy; override; procedure Clear; + procedure Parse; procedure Parse(aCode: TCodeBuffer; aNestedComments: boolean); function UpdateNeeded: boolean; procedure ReduceCompilerDirectives(Undefines, Defines: TStrings; @@ -192,6 +201,7 @@ type function AtomIsIdentifier: boolean; function GetAtom: string; procedure Replace(FromPos, ToPos: integer; const NewSrc: string); + procedure IncreaseChangeStep; procedure ResetMacros; procedure ClearMacros; procedure WriteDebugReport; @@ -204,6 +214,7 @@ type write FRemoveDisabledDirectives; property UndefH2PasFunctions: boolean read FUndefH2PasFunctions write FUndefH2PasFunctions; + property ChangeStep: integer read FChangeStep; end; TCompilerMacroStatus = ( @@ -602,6 +613,7 @@ end; procedure TCompilerDirectivesTree.InitParser; begin ParseChangeStep:=Code.ChangeStep; + IncreaseChangeStep; InitKeyWordList; Src:=Code.Source; SrcLen:=length(Src); @@ -642,7 +654,7 @@ procedure TCompilerDirectivesTree.EndIFNode(const ErrorMsg: string); procedure RaiseMissingStartNode; begin WriteDebugReport; - raise CDirectiveParserException.Create(ErrorMsg); + raise ECDirectiveParserException.Create(Self,ErrorMsg); end; begin @@ -1131,7 +1143,7 @@ var Change: PDefineChange; begin if StackPointer=0 then - raise CDirectiveParserException.Create('TCompilerDirectivesTree.DisableUnreachableBlocks.Pop without Push'); + raise ECDirectiveParserException.Create(Self,'TCompilerDirectivesTree.DisableUnreachableBlocks.Pop without Push'); // undo all changes while Stack[StackPointer]<>nil do begin Change:=Stack[StackPointer]; @@ -1320,7 +1332,7 @@ procedure TCompilerDirectivesTree.DisableIfNode(Node: TCodeTreeNode; procedure RaiseImpossible; begin - raise CDirectiveParserException.Create('TCompilerDirectivesTree.DisableIfNode'); + raise ECDirectiveParserException.Create(Self,'TCompilerDirectivesTree.DisableIfNode'); end; function GetExpr(ExprNode: TCodeTreeNode; out Negated: boolean): string; @@ -1627,13 +1639,18 @@ begin end; end; +procedure TCompilerDirectivesTree.Parse; +begin + Parse(Code,NestedComments) +end; + procedure TCompilerDirectivesTree.Parse(aCode: TCodeBuffer; aNestedComments: boolean); procedure RaiseDanglingIFDEF; begin WriteDebugReport; - raise CDirectiveParserException.Create('missing EndIf'); + raise ECDirectiveParserException.Create(Self,'missing EndIf'); end; var @@ -1679,7 +1696,7 @@ end; function TCompilerDirectivesTree.UpdateNeeded: boolean; begin Result:=true; - if (Code=nil) then exit; + if (Code=nil) or (Tree=nil) or (Tree.Root=nil) then exit; if Code.ChangeStep<>ParseChangeStep then exit; Result:=false; end; @@ -2441,6 +2458,7 @@ var DiffPos: Integer; begin DebugLn(['TCompilerDirectivesTree.Replace ',FromPos,'-',ToPos,' Old="',copy(Src,FromPos,ToPos-FromPos),'" New="',NewSrc,'"']); + IncreaseChangeStep; Code.Replace(FromPos,ToPos-FromPos,NewSrc); Src:=Code.Source; SrcLen:=length(Src); @@ -2456,6 +2474,14 @@ begin end; end; +procedure TCompilerDirectivesTree.IncreaseChangeStep; +begin + if FChangeStep<>$7fffffff then + inc(FChangeStep) + else + FChangeStep:=-$7fffffff; +end; + procedure TCompilerDirectivesTree.ResetMacros; begin if Macros<>nil then @@ -2502,5 +2528,14 @@ begin AdjustPositionAfterInsert(BeginEnd,false,FromPos,ToPos,DiffPos); end; +{ ECDirectiveParserException } + +constructor ECDirectiveParserException.Create(ASender: TCompilerDirectivesTree; + const AMessage: string); +begin + inherited Create(AMessage); + Sender:=ASender; +end; + end. diff --git a/components/h2pas/h2pasconvert.pas b/components/h2pas/h2pasconvert.pas index af71ca65e7..6ca0efba3c 100644 --- a/components/h2pas/h2pasconvert.pas +++ b/components/h2pas/h2pasconvert.pas @@ -3210,7 +3210,7 @@ end; class function TFixH2PasMissingIFDEFsInUnit.ClassDescription: string; begin - Result:='Adds missing h2pas IFDEFs for function bodies'; + Result:='Add missing h2pas IFDEFs for function bodies'; end; function TFixH2PasMissingIFDEFsInUnit.Execute(aText: TIDETextConverter diff --git a/ide/codeexplopts.lfm b/ide/codeexplopts.lfm index 04efe98774..df29f98c71 100644 --- a/ide/codeexplopts.lfm +++ b/ide/codeexplopts.lfm @@ -1,4 +1,10 @@ object CodeExplorerDlg: TCodeExplorerDlg + Left = 290 + Height = 300 + Top = 163 + Width = 400 + HorzScrollBar.Page = 399 + VertScrollBar.Page = 299 ActiveControl = UpdatePage BorderStyle = bsSizeToolWin Caption = 'CodeExplorerDlg' @@ -6,79 +12,82 @@ object CodeExplorerDlg: TCodeExplorerDlg ClientWidth = 400 OnCreate = CodeExplorerDlgCreate OnDestroy = CodeExplorerDlgDestroy - PixelsPerInch = 96 Position = poScreenCenter - HorzScrollBar.Page = 399 - VertScrollBar.Page = 299 - Left = 290 - Height = 300 - Top = 163 - Width = 400 object OkButton: TButton + AnchorSideRight.Control = CancelButton + Left = 200 + Height = 37 + Top = 256 + Width = 80 Anchors = [akRight, akBottom] AutoSize = True BorderSpacing.Around = 6 - + BorderSpacing.InnerBorder = 4 Caption = 'OkButton' OnClick = OkButtonClick TabOrder = 0 - AnchorSideRight.Control = CancelButton - Left = 229 - Height = 29 - Top = 264 - Width = 69 end object CancelButton: TButton + Left = 286 + Height = 37 + Top = 256 + Width = 106 Anchors = [akRight, akBottom] AutoSize = True BorderSpacing.Around = 6 - + BorderSpacing.InnerBorder = 4 Caption = 'CancelButton' ModalResult = 2 TabOrder = 1 - Left = 304 - Height = 29 - Top = 264 - Width = 88 end object MainNotebook: TNotebook + Height = 248 + Width = 400 Align = alTop Anchors = [akTop, akLeft, akRight, akBottom] PageIndex = 0 - Height = 256 - Width = 400 + TabOrder = 2 object UpdatePage: TPage Caption = 'UpdatePage' - ClientWidth = 392 - ClientHeight = 230 - Height = 230 - Width = 392 + ClientWidth = 396 + ClientHeight = 217 object RefreshRadioGroup: TRadioGroup + Left = 6 + Height = 141 + Top = 6 + Width = 384 Align = alTop + AutoFill = True BorderSpacing.Around = 6 Caption = 'RefreshRadioGroup' + ChildSizing.LeftRightSpacing = 6 + ChildSizing.TopBottomSpacing = 6 + ChildSizing.EnlargeHorizontal = crsHomogenousChildResize + ChildSizing.EnlargeVertical = crsHomogenousChildResize + ChildSizing.ShrinkHorizontal = crsScaleChilds + ChildSizing.ShrinkVertical = crsScaleChilds + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 1 + ClientHeight = 122 + ClientWidth = 380 Items.Strings = ( 'Manual' 'SwitchPage' 'Idle' ) TabOrder = 0 - Left = 6 - Height = 105 - Top = 6 - Width = 380 end object FollowCursorCheckBox: TCheckBox + Left = 6 + Height = 22 + Top = 165 + Width = 384 Align = alTop BorderSpacing.Top = 12 BorderSpacing.Around = 6 Caption = 'FollowCursorCheckBox' TabOrder = 1 Visible = False - Left = 6 - Height = 13 - Top = 129 - Width = 380 end end end diff --git a/ide/codeexplopts.lrs b/ide/codeexplopts.lrs index ddaa4094f1..e186566580 100644 --- a/ide/codeexplopts.lrs +++ b/ide/codeexplopts.lrs @@ -1,26 +1,35 @@ +{ This is an automatically generated lazarus resource file } + LazarusResources.Add('TCodeExplorerDlg','FORMDATA',[ - 'TPF0'#16'TCodeExplorerDlg'#15'CodeExplorerDlg'#13'ActiveControl'#7#10'Update' - +'Page'#11'BorderStyle'#7#13'bsSizeToolWin'#7'Caption'#6#15'CodeExplorerDlg' - +#12'ClientHeight'#3','#1#11'ClientWidth'#3#144#1#8'OnCreate'#7#21'CodeExplor' - +'erDlgCreate'#9'OnDestroy'#7#22'CodeExplorerDlgDestroy'#13'PixelsPerInch'#2 - +'`'#8'Position'#7#14'poScreenCenter'#18'HorzScrollBar.Page'#3#143#1#18'VertS' - +'crollBar.Page'#3'+'#1#4'Left'#3'"'#1#6'Height'#3','#1#3'Top'#3#163#0#5'Widt' - +'h'#3#144#1#0#7'TButton'#8'OkButton'#7'Anchors'#11#7'akRight'#8'akBottom'#0#8 - +'AutoSize'#9#20'BorderSpacing.Around'#2#6#7'Caption'#6#8'OkButton'#7'OnClick' - +#7#13'OkButtonClick'#8'TabOrder'#2#0#23'AnchorSideRight.Control'#7#12'Cancel' - +'Button'#4'Left'#3#229#0#6'Height'#2#29#3'Top'#3#8#1#5'Width'#2'E'#0#0#7'TBu' - +'tton'#12'CancelButton'#7'Anchors'#11#7'akRight'#8'akBottom'#0#8'AutoSize'#9 - +#20'BorderSpacing.Around'#2#6#7'Caption'#6#12'CancelButton'#11'ModalResult'#2 - +#2#8'TabOrder'#2#1#4'Left'#3'0'#1#6'Height'#2#29#3'Top'#3#8#1#5'Width'#2'X'#0 - +#0#9'TNotebook'#12'MainNotebook'#5'Align'#7#5'alTop'#7'Anchors'#11#5'akTop'#6 - +'akLeft'#7'akRight'#8'akBottom'#0#9'PageIndex'#2#0#6'Height'#3#0#1#5'Width'#3 - +#144#1#0#5'TPage'#10'UpdatePage'#7'Caption'#6#10'UpdatePage'#11'ClientWidth' - +#3#136#1#12'ClientHeight'#3#230#0#6'Height'#3#230#0#5'Width'#3#136#1#0#11'TR' - +'adioGroup'#17'RefreshRadioGroup'#5'Align'#7#5'alTop'#20'BorderSpacing.Aroun' - +'d'#2#6#7'Caption'#6#17'RefreshRadioGroup'#13'Items.Strings'#1#6#6'Manual'#6 - +#10'SwitchPage'#6#4'Idle'#0#8'TabOrder'#2#0#4'Left'#2#6#6'Height'#2'i'#3'Top' - +#2#6#5'Width'#3'|'#1#0#0#9'TCheckBox'#20'FollowCursorCheckBox'#5'Align'#7#5 - +'alTop'#17'BorderSpacing.Top'#2#12#20'BorderSpacing.Around'#2#6#7'Caption'#6 - +#20'FollowCursorCheckBox'#8'TabOrder'#2#1#7'Visible'#8#4'Left'#2#6#6'Height' - +#2#13#3'Top'#3#129#0#5'Width'#3'|'#1#0#0#0#0#0 + 'TPF0'#16'TCodeExplorerDlg'#15'CodeExplorerDlg'#4'Left'#3'"'#1#6'Height'#3',' + +#1#3'Top'#3#163#0#5'Width'#3#144#1#18'HorzScrollBar.Page'#3#143#1#18'VertScr' + +'ollBar.Page'#3'+'#1#13'ActiveControl'#7#10'UpdatePage'#11'BorderStyle'#7#13 + +'bsSizeToolWin'#7'Caption'#6#15'CodeExplorerDlg'#12'ClientHeight'#3','#1#11 + +'ClientWidth'#3#144#1#8'OnCreate'#7#21'CodeExplorerDlgCreate'#9'OnDestroy'#7 + +#22'CodeExplorerDlgDestroy'#8'Position'#7#14'poScreenCenter'#0#7'TButton'#8 + +'OkButton'#23'AnchorSideRight.Control'#7#12'CancelButton'#4'Left'#3#200#0#6 + +'Height'#2'%'#3'Top'#3#0#1#5'Width'#2'P'#7'Anchors'#11#7'akRight'#8'akBottom' + +#0#8'AutoSize'#9#20'BorderSpacing.Around'#2#6#25'BorderSpacing.InnerBorder'#2 + +#4#7'Caption'#6#8'OkButton'#7'OnClick'#7#13'OkButtonClick'#8'TabOrder'#2#0#0 + +#0#7'TButton'#12'CancelButton'#4'Left'#3#30#1#6'Height'#2'%'#3'Top'#3#0#1#5 + +'Width'#2'j'#7'Anchors'#11#7'akRight'#8'akBottom'#0#8'AutoSize'#9#20'BorderS' + +'pacing.Around'#2#6#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#12'Cancel' + +'Button'#11'ModalResult'#2#2#8'TabOrder'#2#1#0#0#9'TNotebook'#12'MainNoteboo' + +'k'#6'Height'#3#248#0#5'Width'#3#144#1#5'Align'#7#5'alTop'#7'Anchors'#11#5'a' + +'kTop'#6'akLeft'#7'akRight'#8'akBottom'#0#9'PageIndex'#2#0#8'TabOrder'#2#2#0 + +#5'TPage'#10'UpdatePage'#7'Caption'#6#10'UpdatePage'#11'ClientWidth'#3#140#1 + +#12'ClientHeight'#3#217#0#0#11'TRadioGroup'#17'RefreshRadioGroup'#4'Left'#2#6 + +#6'Height'#3#141#0#3'Top'#2#6#5'Width'#3#128#1#5'Align'#7#5'alTop'#8'AutoFil' + +'l'#9#20'BorderSpacing.Around'#2#6#7'Caption'#6#17'RefreshRadioGroup'#28'Chi' + +'ldSizing.LeftRightSpacing'#2#6#28'ChildSizing.TopBottomSpacing'#2#6#29'Chil' + +'dSizing.EnlargeHorizontal'#7#24'crsHomogenousChildResize'#27'ChildSizing.En' + +'largeVertical'#7#24'crsHomogenousChildResize'#28'ChildSizing.ShrinkHorizont' + +'al'#7#14'crsScaleChilds'#26'ChildSizing.ShrinkVertical'#7#14'crsScaleChilds' + +#18'ChildSizing.Layout'#7#29'cclLeftToRightThenTopToBottom'#27'ChildSizing.C' + +'ontrolsPerLine'#2#1#12'ClientHeight'#2'z'#11'ClientWidth'#3'|'#1#13'Items.S' + +'trings'#1#6#6'Manual'#6#10'SwitchPage'#6#4'Idle'#0#8'TabOrder'#2#0#0#0#9'TC' + +'heckBox'#20'FollowCursorCheckBox'#4'Left'#2#6#6'Height'#2#22#3'Top'#3#165#0 + +#5'Width'#3#128#1#5'Align'#7#5'alTop'#17'BorderSpacing.Top'#2#12#20'BorderSp' + +'acing.Around'#2#6#7'Caption'#6#20'FollowCursorCheckBox'#8'TabOrder'#2#1#7'V' + +'isible'#8#0#0#0#0#0 ]); diff --git a/ide/codeexplorer.lfm b/ide/codeexplorer.lfm index 4ee8c21b16..8d8acf7834 100644 --- a/ide/codeexplorer.lfm +++ b/ide/codeexplorer.lfm @@ -1,68 +1,126 @@ object CodeExplorerView: TCodeExplorerView Left = 378 - Height = 505 + Height = 517 Top = 175 - Width = 206 - HorzScrollBar.Page = 205 - VertScrollBar.Page = 504 + Width = 215 + HorzScrollBar.Page = 214 + VertScrollBar.Page = 516 ActiveControl = RefreshButton Caption = 'CodeExplorerView' + ClientHeight = 517 + ClientWidth = 215 KeyPreview = True OnClose = CodeExplorerViewCLOSE OnCreate = CodeExplorerViewCREATE OnDestroy = CodeExplorerViewDestroy OnResize = CodeExplorerViewRESIZE object RefreshButton: TButton - Height = 25 - Width = 96 + Height = 37 + Width = 80 + AutoSize = True BorderSpacing.InnerBorder = 4 Caption = 'Refresh' - OnClick = RefreshButtonCLICK + Constraints.MinWidth = 80 + OnClick = RefreshButtonClick TabOrder = 0 end object OptionsButton: TButton - Left = 110 - Height = 25 - Width = 96 + AnchorSideLeft.Control = RefreshButton + AnchorSideLeft.Side = asrBottom + Left = 83 + Height = 37 + Width = 80 + AutoSize = True + BorderSpacing.Left = 3 BorderSpacing.InnerBorder = 4 Caption = 'Options' + Constraints.MinWidth = 80 OnClick = OptionsButtonClick TabOrder = 1 end - object CodeTreeview: TTreeView - AnchorSideTop.Control = FilterEdit + object MainNotebook: TNotebook + AnchorSideTop.Control = OptionsButton AnchorSideTop.Side = asrBottom - Height = 456 - Top = 49 - Width = 206 + Height = 478 + Top = 39 + Width = 215 Align = alBottom Anchors = [akTop, akLeft, akRight, akBottom] - BorderSpacing.Top = 1 - DefaultItemHeight = 16 - HideSelection = False - Images = Imagelist1 - ParentCtl3D = False - PopupMenu = TreePopupmenu - RightClickSelect = True + BorderSpacing.Top = 2 + OnPageChanged = MainNotebookPageChanged + PageIndex = 0 TabOrder = 2 - OnDblClick = CodeTreeviewDBLCLICK - OnDeletion = CodeTreeviewDELETION - OnKeyUp = CodeTreeviewKeyUp - Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoRightClickSelect, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoNoDoubleClickExpand] - end - object FilterEdit: TEdit - AnchorSideLeft.Control = Owner - AnchorSideTop.Control = RefreshButton - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = Owner - AnchorSideRight.Side = asrBottom - Height = 23 - Top = 25 - Width = 206 - Anchors = [akTop, akLeft, akRight] - OnChange = FilterEditChange - TabOrder = 3 - Text = 'FilterEdit' + object CodePage: TPage + Caption = 'CodePage' + ClientWidth = 211 + ClientHeight = 447 + object CodeTreeview: TTreeView + AnchorSideTop.Control = CodeFilterEdit + AnchorSideTop.Side = asrBottom + Height = 423 + Top = 24 + Width = 211 + Align = alBottom + Anchors = [akTop, akLeft, akRight, akBottom] + BorderSpacing.Top = 1 + DefaultItemHeight = 19 + HideSelection = False + Images = Imagelist1 + ParentCtl3D = False + PopupMenu = TreePopupmenu + RightClickSelect = True + TabOrder = 0 + OnDblClick = CodeTreeviewDblClick + OnDeletion = CodeTreeviewDeletion + OnKeyUp = CodeTreeviewKeyUp + Options = [tvoAutoItemHeight, tvoKeepCollapsedNodes, tvoRightClickSelect, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoNoDoubleClickExpand] + end + object CodeFilterEdit: TEdit + AnchorSideLeft.Control = CodePage + AnchorSideTop.Control = CodePage + AnchorSideRight.Control = CodePage + AnchorSideRight.Side = asrBottom + Height = 23 + Width = 211 + Anchors = [akTop, akLeft, akRight] + OnChange = CodeFilterEditChange + TabOrder = 1 + Text = 'CodeFilterEdit' + end + end + object DirectivesPage: TPage + Caption = 'DirectivesPage' + ClientWidth = 211 + ClientHeight = 447 + object DirectivesFilterEdit: TEdit + AnchorSideLeft.Control = DirectivesPage + AnchorSideTop.Control = DirectivesPage + AnchorSideRight.Control = DirectivesPage + AnchorSideRight.Side = asrBottom + Height = 23 + Width = 211 + Anchors = [akTop, akLeft, akRight] + OnChange = DirectivesFilterEditChange + TabOrder = 0 + Text = 'DirectivesFilterEdit' + end + object DirectivesTreeView: TTreeView + AnchorSideTop.Control = DirectivesFilterEdit + AnchorSideTop.Side = asrBottom + Height = 423 + Top = 24 + Width = 211 + Align = alBottom + Anchors = [akTop, akLeft, akRight, akBottom] + BorderSpacing.Top = 1 + DefaultItemHeight = 19 + PopupMenu = TreePopupmenu + TabOrder = 1 + OnDblClick = DirectivesTreeViewDblClick + OnDeletion = DirectivesTreeViewDeletion + OnKeyUp = DirectivesTreeViewKeyUp + end + end end object Imagelist1: TImageList left = 64 @@ -71,5 +129,9 @@ object CodeExplorerView: TCodeExplorerView object TreePopupmenu: TPopupMenu left = 64 top = 72 + object MenuItem1: TMenuItem + Caption = 'New Item1' + Visible = False + end end end diff --git a/ide/codeexplorer.lrs b/ide/codeexplorer.lrs index e7cdf68322..eba4ec5dda 100644 --- a/ide/codeexplorer.lrs +++ b/ide/codeexplorer.lrs @@ -1,32 +1,55 @@ { Dit is een automatisch aangemaakt lazarus broncode bestand } LazarusResources.Add('TCodeExplorerView','FORMDATA',[ - 'TPF0'#17'TCodeExplorerView'#16'CodeExplorerView'#4'Left'#3'z'#1#6'Height'#3 - +#249#1#3'Top'#3#175#0#5'Width'#3#206#0#18'HorzScrollBar.Page'#3#205#0#18'Ver' - +'tScrollBar.Page'#3#248#1#13'ActiveControl'#7#13'RefreshButton'#7'Caption'#6 - +#16'CodeExplorerView'#10'KeyPreview'#9#7'OnClose'#7#21'CodeExplorerViewCLOSE' - +#8'OnCreate'#7#22'CodeExplorerViewCREATE'#9'OnDestroy'#7#23'CodeExplorerView' - +'Destroy'#8'OnResize'#7#22'CodeExplorerViewRESIZE'#0#7'TButton'#13'RefreshBu' - +'tton'#6'Height'#2#25#5'Width'#2'`'#25'BorderSpacing.InnerBorder'#2#4#7'Capt' - +'ion'#6#7'Refresh'#7'OnClick'#7#18'RefreshButtonCLICK'#8'TabOrder'#2#0#0#0#7 - +'TButton'#13'OptionsButton'#4'Left'#2'n'#6'Height'#2#25#5'Width'#2'`'#25'Bor' - +'derSpacing.InnerBorder'#2#4#7'Caption'#6#7'Options'#7'OnClick'#7#18'Options' - +'ButtonClick'#8'TabOrder'#2#1#0#0#9'TTreeView'#12'CodeTreeview'#21'AnchorSid' - +'eTop.Control'#7#10'FilterEdit'#18'AnchorSideTop.Side'#7#9'asrBottom'#6'Heig' - +'ht'#3#200#1#3'Top'#2'1'#5'Width'#3#206#0#5'Align'#7#8'alBottom'#7'Anchors' - +#11#5'akTop'#6'akLeft'#7'akRight'#8'akBottom'#0#17'BorderSpacing.Top'#2#1#17 - +'DefaultItemHeight'#2#16#13'HideSelection'#8#6'Images'#7#10'Imagelist1'#11'P' - +'arentCtl3D'#8#9'PopupMenu'#7#13'TreePopupmenu'#16'RightClickSelect'#9#8'Tab' - +'Order'#2#2#10'OnDblClick'#7#20'CodeTreeviewDBLCLICK'#10'OnDeletion'#7#20'Co' - +'deTreeviewDELETION'#7'OnKeyUp'#7#17'CodeTreeviewKeyUp'#7'Options'#11#17'tvo' - +'AutoItemHeight'#21'tvoKeepCollapsedNodes'#19'tvoRightClickSelect'#14'tvoSho' - +'wButtons'#12'tvoShowLines'#11'tvoShowRoot'#11'tvoToolTips'#22'tvoNoDoubleCl' - +'ickExpand'#0#0#0#5'TEdit'#10'FilterEdit'#22'AnchorSideLeft.Control'#7#5'Own' - +'er'#21'AnchorSideTop.Control'#7#13'RefreshButton'#18'AnchorSideTop.Side'#7#9 - +'asrBottom'#23'AnchorSideRight.Control'#7#5'Owner'#20'AnchorSideRight.Side'#7 - +#9'asrBottom'#6'Height'#2#23#3'Top'#2#25#5'Width'#3#206#0#7'Anchors'#11#5'ak' - +'Top'#6'akLeft'#7'akRight'#0#8'OnChange'#7#16'FilterEditChange'#8'TabOrder'#2 - +#3#4'Text'#6#10'FilterEdit'#0#0#10'TImageList'#10'Imagelist1'#4'left'#2'@'#3 - +'top'#2' '#0#0#10'TPopupMenu'#13'TreePopupmenu'#4'left'#2'@'#3'top'#2'H'#0#0 - +#0 + 'TPF0'#17'TCodeExplorerView'#16'CodeExplorerView'#4'Left'#3'z'#1#6'Height'#3#5 + +#2#3'Top'#3#175#0#5'Width'#3#215#0#18'HorzScrollBar.Page'#3#214#0#18'VertScr' + +'ollBar.Page'#3#4#2#13'ActiveControl'#7#13'RefreshButton'#7'Caption'#6#16'Co' + +'deExplorerView'#12'ClientHeight'#3#5#2#11'ClientWidth'#3#215#0#10'KeyPrevie' + +'w'#9#7'OnClose'#7#21'CodeExplorerViewCLOSE'#8'OnCreate'#7#22'CodeExplorerVi' + +'ewCREATE'#9'OnDestroy'#7#23'CodeExplorerViewDestroy'#8'OnResize'#7#22'CodeE' + +'xplorerViewRESIZE'#0#7'TButton'#13'RefreshButton'#6'Height'#2'%'#5'Width'#2 + +'P'#8'AutoSize'#9#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#7'Refresh' + +#20'Constraints.MinWidth'#2'P'#7'OnClick'#7#18'RefreshButtonClick'#8'TabOrde' + +'r'#2#0#0#0#7'TButton'#13'OptionsButton'#22'AnchorSideLeft.Control'#7#13'Ref' + +'reshButton'#19'AnchorSideLeft.Side'#7#9'asrBottom'#4'Left'#2'S'#6'Height'#2 + +'%'#5'Width'#2'P'#8'AutoSize'#9#18'BorderSpacing.Left'#2#3#25'BorderSpacing.' + +'InnerBorder'#2#4#7'Caption'#6#7'Options'#20'Constraints.MinWidth'#2'P'#7'On' + +'Click'#7#18'OptionsButtonClick'#8'TabOrder'#2#1#0#0#9'TNotebook'#12'MainNot' + +'ebook'#21'AnchorSideTop.Control'#7#13'OptionsButton'#18'AnchorSideTop.Side' + +#7#9'asrBottom'#6'Height'#3#222#1#3'Top'#2''''#5'Width'#3#215#0#5'Align'#7#8 + +'alBottom'#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#8'akBottom'#0#17'Bord' + +'erSpacing.Top'#2#2#13'OnPageChanged'#7#23'MainNotebookPageChanged'#9'PageIn' + +'dex'#2#0#8'TabOrder'#2#2#0#5'TPage'#8'CodePage'#7'Caption'#6#8'CodePage'#11 + +'ClientWidth'#3#211#0#12'ClientHeight'#3#191#1#0#9'TTreeView'#12'CodeTreevie' + +'w'#21'AnchorSideTop.Control'#7#14'CodeFilterEdit'#18'AnchorSideTop.Side'#7#9 + +'asrBottom'#6'Height'#3#167#1#3'Top'#2#24#5'Width'#3#211#0#5'Align'#7#8'alBo' + +'ttom'#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#8'akBottom'#0#17'BorderSp' + +'acing.Top'#2#1#17'DefaultItemHeight'#2#19#13'HideSelection'#8#6'Images'#7#10 + +'Imagelist1'#11'ParentCtl3D'#8#9'PopupMenu'#7#13'TreePopupmenu'#16'RightClic' + +'kSelect'#9#8'TabOrder'#2#0#10'OnDblClick'#7#20'CodeTreeviewDblClick'#10'OnD' + +'eletion'#7#20'CodeTreeviewDeletion'#7'OnKeyUp'#7#17'CodeTreeviewKeyUp'#7'Op' + +'tions'#11#17'tvoAutoItemHeight'#21'tvoKeepCollapsedNodes'#19'tvoRightClickS' + +'elect'#14'tvoShowButtons'#12'tvoShowLines'#11'tvoShowRoot'#11'tvoToolTips' + +#22'tvoNoDoubleClickExpand'#0#0#0#5'TEdit'#14'CodeFilterEdit'#22'AnchorSideL' + +'eft.Control'#7#8'CodePage'#21'AnchorSideTop.Control'#7#8'CodePage'#23'Ancho' + +'rSideRight.Control'#7#8'CodePage'#20'AnchorSideRight.Side'#7#9'asrBottom'#6 + +'Height'#2#23#5'Width'#3#211#0#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0 + +#8'OnChange'#7#20'CodeFilterEditChange'#8'TabOrder'#2#1#4'Text'#6#14'CodeFil' + +'terEdit'#0#0#0#5'TPage'#14'DirectivesPage'#7'Caption'#6#14'DirectivesPage' + +#11'ClientWidth'#3#211#0#12'ClientHeight'#3#191#1#0#5'TEdit'#20'DirectivesFi' + +'lterEdit'#22'AnchorSideLeft.Control'#7#14'DirectivesPage'#21'AnchorSideTop.' + +'Control'#7#14'DirectivesPage'#23'AnchorSideRight.Control'#7#14'DirectivesPa' + +'ge'#20'AnchorSideRight.Side'#7#9'asrBottom'#6'Height'#2#23#5'Width'#3#211#0 + +#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#8'OnChange'#7#26'DirectivesFi' + +'lterEditChange'#8'TabOrder'#2#0#4'Text'#6#20'DirectivesFilterEdit'#0#0#9'TT' + +'reeView'#18'DirectivesTreeView'#21'AnchorSideTop.Control'#7#20'DirectivesFi' + +'lterEdit'#18'AnchorSideTop.Side'#7#9'asrBottom'#6'Height'#3#167#1#3'Top'#2 + +#24#5'Width'#3#211#0#5'Align'#7#8'alBottom'#7'Anchors'#11#5'akTop'#6'akLeft' + +#7'akRight'#8'akBottom'#0#17'BorderSpacing.Top'#2#1#17'DefaultItemHeight'#2 + +#19#9'PopupMenu'#7#13'TreePopupmenu'#8'TabOrder'#2#1#10'OnDblClick'#7#26'Dir' + +'ectivesTreeViewDblClick'#10'OnDeletion'#7#26'DirectivesTreeViewDeletion'#7 + +'OnKeyUp'#7#23'DirectivesTreeViewKeyUp'#0#0#0#0#10'TImageList'#10'Imagelist1' + +#4'left'#2'@'#3'top'#2' '#0#0#10'TPopupMenu'#13'TreePopupmenu'#4'left'#2'@'#3 + +'top'#2'H'#0#9'TMenuItem'#9'MenuItem1'#7'Caption'#6#9'New Item1'#7'Visible'#8 + +#0#0#0#0 ]); diff --git a/ide/codeexplorer.pas b/ide/codeexplorer.pas index 6a93bbf061..ec9714422f 100644 --- a/ide/codeexplorer.pas +++ b/ide/codeexplorer.pas @@ -24,6 +24,11 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * *************************************************************************** + + Abstract: + Window showing the current source as tree structure. + Normally it shows the codetools nodes of the current unit in the + source editor. If an include file is open, the corresponding unit is shown. } unit CodeExplorer; @@ -36,37 +41,53 @@ uses Classes, SysUtils, LCLProc, LCLType, LResources, Forms, Controls, Graphics, Dialogs, Buttons, ComCtrls, Menus, // CodeTools - CodeToolManager, CodeAtom, CodeCache, CodeTree, PascalParserTool, - KeywordFuncLists, + CodeToolManager, CodeAtom, CodeCache, CodeTree, KeywordFuncLists, + DirectivesTree, PascalParserTool, // IDE Intf IDECommands, MenuIntf, // IDE LazarusIDEStrConsts, EnvironmentOpts, IDEOptionDefs, InputHistory, IDEProcs, - CodeExplOpts, StdCtrls; + CodeExplOpts, StdCtrls, ExtCtrls; type TCodeExplorerView = class; TOnGetCodeTree = - procedure(Sender: TObject; var ACodeTool: TCodeTool) of object; + procedure(Sender: TObject; var ACodeTool: TCodeTool) of object; + TOnGetDirectivesTree = + procedure(Sender: TObject; var ADirectivesTool: TDirectivesTool) of object; TOnJumpToCode = procedure(Sender: TObject; const Filename: string; - const Caret: TPoint; TopLine: integer) of object; + const Caret: TPoint; TopLine: integer) of object; TCodeExplorerViewFlag = ( - cevRefreshNeeded, - cevRefresing + cevCodeRefreshNeeded, + cevDirectivesRefreshNeeded, + cevRefreshing, + cevCheckOnIdle // check if a refresh is needed on next idle ); TCodeExplorerViewFlags = set of TCodeExplorerViewFlag; + + TCodeExplorerPage = ( + cepNone, + cepCode, + cepDirectives + ); { TCodeExplorerView } TCodeExplorerView = class(TForm) - FilterEdit: TEdit; - Imagelist1: TImageList; - TreePopupmenu: TPopupMenu; - RefreshButton: TButton; - OptionsButton: TButton; + CodeFilterEdit: TEdit; + CodePage: TPage; CodeTreeview: TTreeView; + DirectivesFilterEdit: TEdit; + DirectivesPage: TPage; + DirectivesTreeView: TTreeView; + Imagelist1: TImageList; + MainNotebook: TNotebook; + MenuItem1: TMenuItem; + OptionsButton: TButton; + RefreshButton: TButton; + TreePopupmenu: TPopupMenu; procedure CodeExplorerViewClose(Sender: TObject; var CloseAction: TCloseAction); procedure CodeExplorerViewCreate(Sender: TObject); @@ -76,59 +97,97 @@ type procedure CodeTreeviewDeletion(Sender: TObject; Node: TTreeNode); procedure CodeTreeviewKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); - procedure FilterEditChange(Sender: TObject); + procedure CodeFilterEditChange(Sender: TObject); + procedure DirectivesFilterEditChange(Sender: TObject); + procedure DirectivesTreeViewDblClick(Sender: TObject); + procedure DirectivesTreeViewDeletion(Sender: TObject; Node: TTreeNode); + procedure DirectivesTreeViewKeyUp(Sender: TObject; var Key: Word; + Shift: TShiftState); procedure JumpToMenuitemClick(Sender: TObject); + procedure MainNotebookPageChanged(Sender: TObject); procedure OptionsButtonClick(Sender: TObject); procedure RefreshButtonClick(Sender: TObject); procedure RefreshMenuitemClick(Sender: TObject); + procedure OnApplicationIdle(Sender: TObject; var Done: Boolean); private - FMainFilename: string; + FCodeFilename: string; + FDirectivesFilename: string; FFlags: TCodeExplorerViewFlags; + FLastCodeFilter: string; + FLastCodeChangeStep: integer; + FLastDirectivesFilter: string; + FLastDirectivesChangeStep: integer; FOnGetCodeTree: TOnGetCodeTree; + FOnGetDirectivesTree: TOnGetDirectivesTree; FOnJumpToCode: TOnJumpToCode; FUpdateCount: integer; + ImgIDClass: Integer; + ImgIDConst: Integer; + ImgIDConstSection: Integer; ImgIDDefault: integer; - ImgIDProgram: Integer; - ImgIDUnit: Integer; - ImgIDInterfaceSection: Integer; + ImgIDFinalization: Integer; ImgIDImplementation: Integer; ImgIDInitialization: Integer; - ImgIDFinalization: Integer; - ImgIDTypeSection: Integer; - ImgIDType: Integer; - ImgIDVarSection: Integer; - ImgIDVariable: Integer; - ImgIDConstSection: Integer; - ImgIDConst: Integer; - ImgIDClass: Integer; + ImgIDInterfaceSection: Integer; ImgIDProc: Integer; + ImgIDProgram: Integer; ImgIDProperty: Integer; - FLastFilter: string; - function GetFilter: string; - function GetNodeDescription(ACodeTool: TCodeTool; - CodeNode: TCodeTreeNode): string; - function GetNodeImage(CodeNode: TCodeTreeNode): integer; + ImgIDType: Integer; + ImgIDTypeSection: Integer; + ImgIDUnit: Integer; + ImgIDVariable: Integer; + ImgIDVarSection: Integer; + function GetCodeFilter: string; + function GetCurrentPage: TCodeExplorerPage; + function GetDirectivesFilter: string; + function GetCodeNodeDescription(ACodeTool: TCodeTool; + CodeNode: TCodeTreeNode): string; + function GetDirectiveNodeDescription(ADirectivesTool: TDirectivesTool; + Node: TCodeTreeNode): string; + function GetCodeNodeImage(CodeNode: TCodeTreeNode): integer; + function GetDirectiveNodeImage(CodeNode: TCodeTreeNode): integer; procedure CreateNodes(ACodeTool: TCodeTool; CodeNode: TCodeTreeNode; - ParentViewNode, InFrontViewNode: TTreeNode; CreateSiblings: boolean); - procedure SetFilter(const AValue: string); + ParentViewNode, InFrontViewNode: TTreeNode; + CreateSiblings: boolean); + procedure CreateNodes(ADirectivesTool: TDirectivesTool; + CodeNode: TCodeTreeNode; + ParentViewNode, InFrontViewNode: TTreeNode; + CreateSiblings: boolean); + procedure SetCodeFilter(const AValue: string); + procedure SetCurrentPage(const AValue: TCodeExplorerPage); + procedure SetDirectivesFilter(const AValue: string); protected procedure KeyUp(var Key: Word; Shift: TShiftState); override; + procedure ApplyCodeFilter; + procedure ApplyDirectivesFilter; public destructor Destroy; override; procedure BeginUpdate; procedure EndUpdate; - procedure Refresh; + procedure CheckOnIdle; + procedure Refresh(OnlyVisible: boolean); + procedure RefreshCode(OnlyVisible: boolean); + procedure RefreshDirectives(OnlyVisible: boolean); procedure JumpToSelection; procedure CurrentCodeBufferChanged; - procedure FilterChanged; + procedure CodeFilterChanged; + procedure DirectivesFilterChanged; function FilterNode(ANode: TTreeNode; const TheFilter: string): boolean; function FilterFits(const NodeText, TheFilter: string): boolean; virtual; + function GetCurrentTreeView: TCustomTreeView; public property OnGetCodeTree: TOnGetCodeTree read FOnGetCodeTree write FOnGetCodeTree; + property OnGetDirectivesTree: TOnGetDirectivesTree read FOnGetDirectivesTree + write FOnGetDirectivesTree; property OnJumpToCode: TOnJumpToCode read FOnJumpToCode write FOnJumpToCode; - property MainFilename: string read FMainFilename; - property Filter: string read GetFilter write SetFilter; + property CodeFilename: string read FCodeFilename; + property CodeFilter: string read GetCodeFilter write SetCodeFilter; + property DirectivesFilename: string read FDirectivesFilename; + property DirectivesFilter: string read GetDirectivesFilter + write SetDirectivesFilter; + property CurrentPage: TCodeExplorerPage read GetCurrentPage + write SetCurrentPage; end; const @@ -161,7 +220,7 @@ type procedure InitCodeExplorerOptions; begin if CodeExplorerOptions=nil then - CodeExplorerOptions:=TCodeExplorerOptions.Create; + CodeExplorerOptions:=TCodeExplorerOptions.Create; end; procedure LoadCodeExplorerOptions; @@ -223,8 +282,11 @@ begin RefreshButton.Caption:=dlgUnitDepRefresh; OptionsButton.Caption:=dlgFROpts; - FilterEdit.Text:=lisCEFilter; - + CodeFilterEdit.Text:=lisCEFilter; + CodePage.Caption:=dlgCodeGeneration; + DirectivesFilterEdit.Text:=lisCEFilter; + DirectivesPage.Caption:=lisDirectives; + AddResImg(Imagelist1,'ce_default',ImgIDDefault); AddResImg(Imagelist1,'ce_program',ImgIDProgram); AddResImg(Imagelist1,'ce_unit',ImgIDUnit); @@ -249,6 +311,8 @@ begin CEJumpToIDEMenuCommand.OnClick:=@JumpToMenuitemCLICK; CERefreshIDEMenuCommand.OnClick:=@RefreshMenuitemCLICK; + + Application.AddOnIdleHandler(@OnApplicationIdle); end; procedure TCodeExplorerView.CodeExplorerViewDestroy(Sender: TObject); @@ -258,18 +322,15 @@ end; procedure TCodeExplorerView.CodeExplorerViewRESIZE(Sender: TObject); begin - RefreshButton.Width:=ClientWidth div 2; - with OptionsButton do - SetBounds(RefreshButton.Width,Top, - Parent.ClientWidth-RefreshButton.Width,Height); + end; -procedure TCodeExplorerView.CodeTreeviewDBLCLICK(Sender: TObject); +procedure TCodeExplorerView.CodeTreeviewDblClick(Sender: TObject); begin JumpToSelection; end; -procedure TCodeExplorerView.CodeTreeviewDELETION(Sender: TObject; +procedure TCodeExplorerView.CodeTreeviewDeletion(Sender: TObject; Node: TTreeNode); begin if Node.Data<>nil then @@ -283,10 +344,35 @@ begin JumpToSelection; end; -procedure TCodeExplorerView.FilterEditChange(Sender: TObject); +procedure TCodeExplorerView.CodeFilterEditChange(Sender: TObject); begin if Sender=nil then ; - FilterChanged; + CodeFilterChanged; +end; + +procedure TCodeExplorerView.DirectivesFilterEditChange(Sender: TObject); +begin + if Sender=nil then ; + DirectivesFilterChanged; +end; + +procedure TCodeExplorerView.DirectivesTreeViewDblClick(Sender: TObject); +begin + JumpToSelection; +end; + +procedure TCodeExplorerView.DirectivesTreeViewDeletion(Sender: TObject; + Node: TTreeNode); +begin + if Node.Data<>nil then + TObject(Node.Data).Free; +end; + +procedure TCodeExplorerView.DirectivesTreeViewKeyUp(Sender: TObject; + var Key: Word; Shift: TShiftState); +begin + if (Key=VK_RETURN) and (Shift=[]) then + JumpToSelection; end; procedure TCodeExplorerView.CodeExplorerViewCLOSE(Sender: TObject; @@ -300,23 +386,35 @@ begin JumpToSelection; end; +procedure TCodeExplorerView.MainNotebookPageChanged(Sender: TObject); +begin + Refresh(true); +end; + procedure TCodeExplorerView.OptionsButtonClick(Sender: TObject); begin if ShowCodeExplorerOptions=mrOk then SaveCodeExplorerOptions; end; -procedure TCodeExplorerView.RefreshButtonCLICK(Sender: TObject); +procedure TCodeExplorerView.RefreshButtonClick(Sender: TObject); begin - Refresh; + Refresh(true); end; procedure TCodeExplorerView.RefreshMenuitemCLICK(Sender: TObject); begin - Refresh; + Refresh(true); end; -function TCodeExplorerView.GetNodeDescription(ACodeTool: TCodeTool; +procedure TCodeExplorerView.OnApplicationIdle(Sender: TObject; var Done: Boolean + ); +begin + if (cevCheckOnIdle in FFlags) or (CodeExplorerOptions.Refresh=cerOnIdle) then + Refresh(true); +end; + +function TCodeExplorerView.GetCodeNodeDescription(ACodeTool: TCodeTool; CodeNode: TCodeTreeNode): string; begin case CodeNode.Desc of @@ -347,50 +445,74 @@ begin end; end; -function TCodeExplorerView.GetFilter: string; +function TCodeExplorerView.GetDirectiveNodeDescription( + ADirectivesTool: TDirectivesTool; Node: TCodeTreeNode): string; begin - Result:=FilterEdit.Text; + Result:=ADirectivesTool.GetDirective(Node); +end; + +function TCodeExplorerView.GetCodeFilter: string; +begin + Result:=CodeFilterEdit.Text; if Result=lisCEFilter then Result:=''; end; -function TCodeExplorerView.GetNodeImage(CodeNode: TCodeTreeNode): integer; +function TCodeExplorerView.GetCurrentPage: TCodeExplorerPage; +begin + if MainNotebook.ActivePageComponent=CodePage then + Result:=cepCode + else if MainNotebook.ActivePageComponent=DirectivesPage then + Result:=cepDirectives + else + Result:=cepNone; +end; + +function TCodeExplorerView.GetDirectivesFilter: string; +begin + Result:=DirectivesFilterEdit.Text; + if Result=lisCEFilter then Result:=''; +end; + +function TCodeExplorerView.GetCodeNodeImage(CodeNode: TCodeTreeNode): integer; begin case CodeNode.Desc of - ctnProgram,ctnLibrary,ctnPackage: - Result:=ImgIDProgram; - ctnUnit: - Result:=ImgIDUnit; - ctnInterface: - Result:=ImgIDInterfaceSection; - ctnImplementation: - Result:=ImgIDImplementation; - ctnInitialization: - Result:=ImgIDInitialization; - ctnFinalization: - Result:=ImgIDFinalization; - ctnTypeSection: - Result:=ImgIDTypeSection; - ctnTypeDefinition: - Result:=ImgIDType; - ctnVarSection: - Result:=ImgIDVarSection; - ctnVarDefinition: - Result:=ImgIDVariable; - ctnConstSection,ctnResStrSection: - Result:=ImgIDConstSection; - ctnConstDefinition: - Result:=ImgIDConst; - ctnClass: - Result:=ImgIDClass; - ctnProcedure: - Result:=ImgIDProc; - ctnProperty: - Result:=ImgIDProperty; + ctnProgram,ctnLibrary,ctnPackage: Result:=ImgIDProgram; + ctnUnit: Result:=ImgIDInterfaceSection; + ctnImplementation: Result:=ImgIDImplementation; + ctnInitialization: Result:=ImgIDInitialization; + ctnFinalization: Result:=ImgIDFinalization; + ctnTypeSection: Result:=ImgIDTypeSection; + ctnTypeDefinition: Result:=ImgIDType; + ctnVarSection: Result:=ImgIDVarSection; + ctnVarDefinition: Result:=ImgIDVariable; + ctnConstSection,ctnResStrSection: Result:=ImgIDConstSection; + ctnConstDefinition: Result:=ImgIDConst; + ctnClass: Result:=ImgIDClass; + ctnProcedure: Result:=ImgIDProc; + ctnProperty: Result:=ImgIDProperty; else Result:=ImgIDDefault; end; end; +function TCodeExplorerView.GetDirectiveNodeImage(CodeNode: TCodeTreeNode + ): integer; +begin + case CodeNode.SubDesc of + cdnsInclude: Result:=ImgIDVarSection; + else + case CodeNode.Desc of + cdnIf: Result:=ImgIDTypeSection; + cdnElseIf: Result:=ImgIDTypeSection; + cdnElse: Result:=ImgIDTypeSection; + cdnEnd: Result:=ImgIDTypeSection; + cdnDefine: Result:=ImgIDConst; + else + Result:=ImgIDDefault; + end; + end; +end; + procedure TCodeExplorerView.CreateNodes(ACodeTool: TCodeTool; CodeNode: TCodeTreeNode; ParentViewNode, InFrontViewNode: TTreeNode; CreateSiblings: boolean); @@ -443,8 +565,8 @@ begin ViewNode:=ParentViewNode; if ShowNode then begin NodeData:=TViewNodeData.Create(CodeNode); - NodeText:=GetNodeDescription(ACodeTool,CodeNode); - NodeImageIndex:=GetNodeImage(CodeNode); + NodeText:=GetCodeNodeDescription(ACodeTool,CodeNode); + NodeImageIndex:=GetCodeNodeImage(CodeNode); if InFrontViewNode<>nil then ViewNode:=CodeTreeview.Items.InsertObjectBehind( InFrontViewNode,NodeText,NodeData) @@ -464,11 +586,70 @@ begin end; end; -procedure TCodeExplorerView.SetFilter(const AValue: string); +procedure TCodeExplorerView.CreateNodes(ADirectivesTool: TDirectivesTool; + CodeNode: TCodeTreeNode; ParentViewNode, InFrontViewNode: TTreeNode; + CreateSiblings: boolean); +var + NodeData: TViewNodeData; + NodeText: String; + ViewNode: TTreeNode; + NodeImageIndex: Integer; + ShowNode: Boolean; + ShowChilds: Boolean; begin - if Filter=AValue then exit; - FilterEdit.Text:=AValue; - FilterChanged; + while CodeNode<>nil do begin + ShowNode:=true; + ShowChilds:=true; + + // do not show root node + if CodeNode.Desc=cdnRoot then begin + ShowNode:=false; + end; + + ViewNode:=ParentViewNode; + if ShowNode then begin + NodeData:=TViewNodeData.Create(CodeNode); + NodeText:=GetDirectiveNodeDescription(ADirectivesTool,CodeNode); + NodeImageIndex:=GetDirectiveNodeImage(CodeNode); + if InFrontViewNode<>nil then + ViewNode:=DirectivesTreeView.Items.InsertObjectBehind( + InFrontViewNode,NodeText,NodeData) + else if ParentViewNode<>nil then + ViewNode:=DirectivesTreeView.Items.AddChildObject( + ParentViewNode,NodeText,NodeData) + else + ViewNode:=DirectivesTreeView.Items.AddObject(nil,NodeText,NodeData); + ViewNode.ImageIndex:=NodeImageIndex; + ViewNode.SelectedIndex:=NodeImageIndex; + InFrontViewNode:=ViewNode; + end; + if ShowChilds then + CreateNodes(ADirectivesTool,CodeNode.FirstChild,ViewNode,nil,true); + if not CreateSiblings then break; + CodeNode:=CodeNode.NextBrother; + end; +end; + +procedure TCodeExplorerView.SetCodeFilter(const AValue: string); +begin + if CodeFilter=AValue then exit; + CodeFilterEdit.Text:=AValue; + CodeFilterChanged; +end; + +procedure TCodeExplorerView.SetCurrentPage(const AValue: TCodeExplorerPage); +begin + case AValue of + cepCode: MainNotebook.ActivePageComponent:=CodePage; + cepDirectives: MainNotebook.ActivePageComponent:=DirectivesPage; + end; +end; + +procedure TCodeExplorerView.SetDirectivesFilter(const AValue: string); +begin + if DirectivesFilter=AValue then exit; + DirectivesFilterEdit.Text:=AValue; + DirectivesFilterChanged; end; procedure TCodeExplorerView.KeyUp(var Key: Word; Shift: TShiftState); @@ -477,6 +658,40 @@ begin ExecuteIDEShortCut(Self,Key,Shift,nil); end; +procedure TCodeExplorerView.ApplyCodeFilter; +var + ANode: TTreeNode; + TheFilter: String; +begin + TheFilter:=CodeFilterEdit.Text; + FLastCodeFilter:=TheFilter; + CodeTreeview.BeginUpdate; + CodeTreeview.Options:=CodeTreeview.Options+[tvoAllowMultiselect]; + ANode:=CodeTreeview.Items.GetFirstNode; + while ANode<>nil do begin + FilterNode(ANode,TheFilter); + ANode:=ANode.GetNextSibling; + end; + CodeTreeview.EndUpdate; +end; + +procedure TCodeExplorerView.ApplyDirectivesFilter; +var + ANode: TTreeNode; + TheFilter: String; +begin + TheFilter:=DirectivesFilterEdit.Text; + FLastDirectivesFilter:=TheFilter; + DirectivesTreeView.BeginUpdate; + DirectivesTreeView.Options:=DirectivesTreeView.Options+[tvoAllowMultiselect]; + ANode:=DirectivesTreeView.Items.GetFirstNode; + while ANode<>nil do begin + FilterNode(ANode,TheFilter); + ANode:=ANode.GetNextSibling; + end; + DirectivesTreeView.EndUpdate; +end; + destructor TCodeExplorerView.Destroy; begin inherited Destroy; @@ -490,55 +705,169 @@ begin end; procedure TCodeExplorerView.EndUpdate; +var + CurPage: TCodeExplorerPage; begin if FUpdateCount<=0 then RaiseException('TCodeExplorerView.EndUpdate'); dec(FUpdateCount); if FUpdateCount=0 then begin - if cevRefreshNeeded in FFlags then Refresh; + CurPage:=CurrentPage; + if (CurPage=cepCode) and (cevCodeRefreshNeeded in FFlags) then + RefreshCode(true); + if (CurPage=cepDirectives) and (cevDirectivesRefreshNeeded in FFlags) then + RefreshDirectives(true); end; end; -procedure TCodeExplorerView.Refresh; +procedure TCodeExplorerView.CheckOnIdle; +begin + Include(FFlags,cevCheckOnIdle); +end; + +procedure TCodeExplorerView.Refresh(OnlyVisible: boolean); +begin + Exclude(FFlags,cevCheckOnIdle); + RefreshCode(OnlyVisible); + RefreshDirectives(OnlyVisible); +end; + +procedure TCodeExplorerView.RefreshCode(OnlyVisible: boolean); var OldExpanded: TTreeNodeExpandedState; ACodeTool: TCodeTool; begin - if FUpdateCount>0 then begin - Include(FFlags,cevRefreshNeeded); + if (FUpdateCount>0) + or (OnlyVisible and ((CurrentPage<>cepCode) or (not IsVisible))) then begin + Include(FFlags,cevCodeRefreshNeeded); exit; end; - Exclude(FFlags,cevRefreshNeeded); + Exclude(FFlags,cevCodeRefreshNeeded); - Include(FFlags,cevRefresing); - - FilterEdit.Text:=lisCEFilter; + try + Include(FFlags,cevRefreshing); - // get the codetool with the updated codetree - ACodeTool:=nil; - if Assigned(OnGetCodeTree) then - OnGetCodeTree(Self,ACodeTool); + CodeFilterEdit.Text:=lisCEFilter; - // start updating the CodeTreeView - CodeTreeview.BeginUpdate; - OldExpanded:=TTreeNodeExpandedState.Create(CodeTreeView); + // get the codetool with the updated codetree + ACodeTool:=nil; + if Assigned(OnGetCodeTree) then + OnGetCodeTree(Self,ACodeTool); - if (ACodeTool=nil) or (ACodeTool.Tree=nil) or (ACodeTool.Tree.Root=nil) then - begin - CodeTreeview.Items.Clear; - FMainFilename:=''; - end else begin - FMainFilename:=ACodeTool.MainFilename; - CodeTreeview.Items.Clear; - CreateNodes(ACodeTool,ACodeTool.Tree.Root,nil,nil,true); + // check for changes in the codetools + if (ACodeTool=nil) then begin + if (FCodeFilename='') then begin + // still no tool + exit; + end; + end else begin + if (ACodeTool.MainFilename=FCodeFilename) + and (ACodeTool.Scanner<>nil) + and (ACodeTool.Scanner.ChangeStep=FLastCodeChangeStep) then begin + // still the same source + exit; + end; + end; + + // remember the codetools ChangeStep + if ACodeTool<>nil then begin + FCodeFilename:=ACodeTool.MainFilename; + if ACodeTool.Scanner<>nil then + FLastCodeChangeStep:=ACodeTool.Scanner.ChangeStep; + end else + FCodeFilename:=''; + + //DebugLn(['TCodeExplorerView.RefreshCode ',FCodeFilename]); + + // start updating the CodeTreeView + CodeTreeview.BeginUpdate; + OldExpanded:=TTreeNodeExpandedState.Create(CodeTreeView); + + if (ACodeTool=nil) or (ACodeTool.Tree=nil) or (ACodeTool.Tree.Root=nil) then + begin + CodeTreeview.Items.Clear; + end else begin + CodeTreeview.Items.Clear; + CreateNodes(ACodeTool,ACodeTool.Tree.Root,nil,nil,true); + end; + + // restore old expanded state + OldExpanded.Apply(CodeTreeView); + OldExpanded.Free; + CodeTreeview.EndUpdate; + + finally + Exclude(FFlags,cevRefreshing); end; +end; - // restore old expanded state - OldExpanded.Apply(CodeTreeView); - OldExpanded.Free; - CodeTreeview.EndUpdate; - - Exclude(FFlags,cevRefresing); +procedure TCodeExplorerView.RefreshDirectives(OnlyVisible: boolean); +var + ADirectivesTool: TDirectivesTool; + OldExpanded: TTreeNodeExpandedState; +begin + if (FUpdateCount>0) + or (OnlyVisible and ((CurrentPage<>cepDirectives) or (not IsVisible))) then + begin + Include(FFlags,cevDirectivesRefreshNeeded); + exit; + end; + Exclude(FFlags,cevDirectivesRefreshNeeded); + + try + Include(FFlags,cevRefreshing); + + DirectivesFilterEdit.Text:=lisCEFilter; + + // get the directivestool with the updated tree + ADirectivesTool:=nil; + if Assigned(OnGetDirectivesTree) then + OnGetDirectivesTree(Self,ADirectivesTool); + + // check for changes in the codetools + if (ADirectivesTool=nil) then begin + if (FDirectivesFilename='') then begin + // still no tool + exit; + end; + end else begin + if (ADirectivesTool.Code.Filename=FDirectivesFilename) + and (ADirectivesTool.ChangeStep=FLastDirectivesChangeStep) then begin + // still the same source + exit; + end; + end; + + // remember the codetools ChangeStep + if ADirectivesTool<>nil then begin + FDirectivesFilename:=ADirectivesTool.Code.Filename; + FLastDirectivesChangeStep:=ADirectivesTool.ChangeStep; + end else + FDirectivesFilename:=''; + + //DebugLn(['TCodeExplorerView.RefreshDirectives ',FDirectivesFilename]); + + // start updating the DirectivesTreeView + DirectivesTreeView.BeginUpdate; + OldExpanded:=TTreeNodeExpandedState.Create(DirectivesTreeView); + + if (ADirectivesTool=nil) or (ADirectivesTool.Tree=nil) + or (ADirectivesTool.Tree.Root=nil) then + begin + DirectivesTreeView.Items.Clear; + end else begin + DirectivesTreeView.Items.Clear; + CreateNodes(ADirectivesTool,ADirectivesTool.Tree.Root,nil,nil,true); + end; + + // restore old expanded state + OldExpanded.Apply(DirectivesTreeView); + OldExpanded.Free; + DirectivesTreeView.EndUpdate; + + finally + Exclude(FFlags,cevRefreshing); + end; end; procedure TCodeExplorerView.JumpToSelection; @@ -549,23 +878,42 @@ var NewTopLine: integer; CodeBuffer: TCodeBuffer; ACodeTool: TCodeTool; + CurTreeView: TCustomTreeView; begin - if tvoAllowMultiselect in CodeTreeview.Options then - CurItem:=CodeTreeView.GetFirstMultiSelected + CurTreeView:=GetCurrentTreeView; + if CurTreeView=nil then exit; + if tvoAllowMultiselect in CurTreeView.Options then + CurItem:=CurTreeView.GetFirstMultiSelected else - CurItem:=CodeTreeview.Selected; + CurItem:=CurTreeView.Selected; if CurItem=nil then exit; CurNode:=TViewNodeData(CurItem.Data); if CurNode.StartPos<1 then exit; - CodeBuffer:=CodeToolBoss.FindFile(MainFilename); - if CodeBuffer=nil then exit; - ACodeTool:=nil; - CodeToolBoss.Explore(CodeBuffer,ACodeTool,false); - if ACodeTool=nil then exit; - if not ACodeTool.CleanPosToCaretAndTopLine(CurNode.StartPos,Caret,NewTopLine) - then exit; - + case CurrentPage of + cepCode: + begin + CodeBuffer:=CodeToolBoss.FindFile(CodeFilename); + if CodeBuffer=nil then exit; + ACodeTool:=nil; + CodeToolBoss.Explore(CodeBuffer,ACodeTool,false); + if ACodeTool=nil then exit; + if not ACodeTool.CleanPosToCaretAndTopLine(CurNode.StartPos,Caret,NewTopLine) + then exit; + end; + cepDirectives: + begin + CodeBuffer:=CodeToolBoss.FindFile(DirectivesFilename); + if CodeBuffer=nil then exit; + CodeBuffer.AbsoluteToLineCol(CurNode.StartPos,Caret.Y,Caret.X); + if Caret.Y<1 then exit; + Caret.Code:=CodeBuffer; + NewTopLine:=Caret.Y-(CodeToolBoss.VisibleEditorLines div 2); + if NewTopLine<1 then NewTopLine:=1; + end; + else + exit; + end; if Assigned(OnJumpToCode) then OnJumpToCode(Self,Caret.Code.Filename,Point(Caret.X,Caret.Y),NewTopLine); end; @@ -573,33 +921,37 @@ end; procedure TCodeExplorerView.CurrentCodeBufferChanged; begin if CodeExplorerOptions.Refresh=cerSwitchEditorPage then - Refresh; + CheckOnIdle; end; -procedure TCodeExplorerView.FilterChanged; +procedure TCodeExplorerView.CodeFilterChanged; var TheFilter: String; - ANode: TTreeNode; begin - if FUpdateCount>0 then begin - Include(FFlags,cevRefreshNeeded); + TheFilter:=CodeFilterEdit.Text; + if FLastCodeFilter=TheFilter then exit; + if (FUpdateCount>0) or (CurrentPage<>cepCode) then begin + Include(FFlags,cevCodeRefreshNeeded); exit; end; - TheFilter:=FilterEdit.Text; - if FLastFilter=TheFilter then exit; - FLastFilter:=TheFilter; - CodeTreeview.BeginUpdate; - CodeTreeview.Options:=CodeTreeview.Options+[tvoAllowMultiselect]; - ANode:=CodeTreeview.Items.GetFirstNode; - while ANode<>nil do begin - FilterNode(ANode,TheFilter); - ANode:=ANode.GetNextSibling; - end; - CodeTreeview.EndUpdate; + ApplyCodeFilter; end; -function TCodeExplorerView.FilterNode(ANode: TTreeNode; const TheFilter: string - ): boolean; +procedure TCodeExplorerView.DirectivesFilterChanged; +var + TheFilter: String; +begin + TheFilter:=DirectivesFilterEdit.Text; + if FLastDirectivesFilter=TheFilter then exit; + if (FUpdateCount>0) or (CurrentPage<>cepDirectives) then begin + Include(FFlags,cevDirectivesRefreshNeeded); + exit; + end; + ApplyDirectivesFilter; +end; + +function TCodeExplorerView.FilterNode(ANode: TTreeNode; + const TheFilter: string): boolean; var ChildNode: TTreeNode; HasVisibleChilds: Boolean; @@ -648,6 +1000,15 @@ begin end; end; +function TCodeExplorerView.GetCurrentTreeView: TCustomTreeView; +begin + case CurrentPage of + cepCode: Result:=CodeTreeview; + cepDirectives: Result:=DirectivesTreeView; + else Result:=nil; + end; +end; + initialization {$I codeexplorer.lrs} CodeExplorerView:=nil; diff --git a/ide/lazarusidestrconsts.pas b/ide/lazarusidestrconsts.pas index e3d28dfb0a..14dd56d8df 100644 --- a/ide/lazarusidestrconsts.pas +++ b/ide/lazarusidestrconsts.pas @@ -3393,6 +3393,7 @@ resourcestring lisUIClearIncludedByReference = 'Clear include cache'; lisChangeParent = 'Change parent ...'; lisLazarusIDE = 'Lazarus IDE'; + lisDirectives = 'Directives'; implementation end. diff --git a/ide/main.pp b/ide/main.pp index 4710e9800f..2b18cb5927 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -449,6 +449,8 @@ type // code explorer events procedure OnCodeExplorerGetCodeTree(Sender: TObject; var ACodeTool: TCodeTool); + procedure OnCodeExplorerGetDirectivesTree(Sender: TObject; + var ADirectivesTool: TDirectivesTool); procedure OnCodeExplorerJumpToCode(Sender: TObject; const Filename: string; const Caret: TPoint; TopLine: integer); @@ -6844,12 +6846,13 @@ begin if CodeExplorerView=nil then begin CodeExplorerView:=TCodeExplorerView.Create(OwningComponent); CodeExplorerView.OnGetCodeTree:=@OnCodeExplorerGetCodeTree; + CodeExplorerView.OnGetDirectivesTree:=@OnCodeExplorerGetDirectivesTree; CodeExplorerView.OnJumpToCode:=@OnCodeExplorerJumpToCode; end; EnvironmentOptions.IDEWindowLayoutList.ItemByEnum(nmiwCodeExplorerName).Apply; CodeExplorerView.ShowOnTop; - CodeExplorerView.Refresh; + CodeExplorerView.Refresh(true); end; procedure TMainIDE.DoShowCodeBrowser; @@ -10330,6 +10333,17 @@ begin CodeToolBoss.Explore(ActiveUnitInfo.Source,ACodeTool,false); end; +procedure TMainIDE.OnCodeExplorerGetDirectivesTree(Sender: TObject; + var ADirectivesTool: TDirectivesTool); +var + ActiveUnitInfo: TUnitInfo; + ActiveSrcEdit: TSourceEditor; +begin + ADirectivesTool:=nil; + if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,[]) then exit; + CodeToolBoss.ExploreDirectives(ActiveUnitInfo.Source,ADirectivesTool); +end; + procedure TMainIDE.OnCodeExplorerJumpToCode(Sender: TObject; const Filename: string; const Caret: TPoint; TopLine: integer); begin