~ubuntu-branches/ubuntu/saucy/lazarus/saucy

« back to all changes in this revision

Viewing changes to ide/codeexplorer.pas

  • Committer: Package Import Robot
  • Author(s): Paul Gevers, Abou Al Montacir, Bart Martens, Paul Gevers
  • Date: 2013-06-08 14:12:17 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20130608141217-7k0cy9id8ifcnutc
Tags: 1.0.8+dfsg-1
[ Abou Al Montacir ]
* New upstream major release and multiple maintenace release offering many
  fixes and new features marking a new milestone for the Lazarus development
  and its stability level.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_fixes_branch
* LCL changes:
  - LCL is now a normal package.
      + Platform independent parts of the LCL are now in the package LCLBase
      + LCL is automatically recompiled when switching the target platform,
        unless pre-compiled binaries for this target are already installed.
      + No impact on existing projects.
      + Linker options needed by LCL are no more added to projects that do
        not use the LCL package.
  - Minor changes in LCL basic classes behaviour
      + TCustomForm.Create raises an exception if a form resource is not
        found.
      + TNotebook and TPage: a new implementation of these classes was added.
      + TDBNavigator: It is now possible to have focusable buttons by setting
        Options = [navFocusableButtons] and TabStop = True, useful for
        accessibility and for devices with neither mouse nor touch screen.
      + Names of TControlBorderSpacing.GetSideSpace and GetSpace were swapped
        and are now consistent. GetSideSpace = Around + GetSpace.
      + TForm.WindowState=wsFullscreen was added
      + TCanvas.TextFitInfo was added to calculate how many characters will
        fit into a specified Width. Useful for word-wrapping calculations.
      + TControl.GetColorResolvingParent and
        TControl.GetRGBColorResolvingParent were added, simplifying the work
        to obtain the final color of the control while resolving clDefault
        and the ParentColor.
      + LCLIntf.GetTextExtentExPoint now has a good default implementation
        which works in any platform not providing a specific implementation.
        However, Widgetset specific implementation is better, when available.
      + TTabControl was reorganized. Now it has the correct class hierarchy
        and inherits from TCustomTabControl as it should.
  - New unit in the LCL:
      + lazdialogs.pas: adds non-native versions of various native dialogs,
        for example TLazOpenDialog, TLazSaveDialog, TLazSelectDirectoryDialog.
        It is used by widgetsets which either do not have a native dialog, or
        do not wish to use it because it is limited. These dialogs can also be
        used by user applications directly.
      + lazdeviceapis.pas: offers an interface to more hardware devices such
        as the accelerometer, GPS, etc. See LazDeviceAPIs
      + lazcanvas.pas: provides a TFPImageCanvas descendent implementing
        drawing in a LCL-compatible way, but 100% in Pascal.
      + lazregions.pas. LazRegions is a wholly Pascal implementation of
        regions for canvas clipping, event clipping, finding in which control
        of a region tree one an event should reach, for drawing polygons, etc.
      + customdrawncontrols.pas, customdrawndrawers.pas,
        customdrawn_common.pas, customdrawn_android.pas and
        customdrawn_winxp.pas: are the Lazarus Custom Drawn Controls -controls
        which imitate the standard LCL ones, but with the difference that they
        are non-native and support skinning.
  - New APIs added to the LCL to improve support of accessibility software
    such as screen readers.
* IDE changes:
  - Many improvments.
  - The detailed list of changes can be found here:
    http://wiki.lazarus.freepascal.org/New_IDE_features_since#v1.0_.282012-08-29.29
    http://wiki.lazarus.freepascal.org/Lazarus_1.0_release_notes#IDE_Changes
* Debugger / Editor changes:
  - Added pascal sources and breakpoints to the disassembler
  - Added threads dialog.
* Components changes:
  - TAChart: many fixes and new features
  - CodeTool: support Delphi style generics and new syntax extensions.
  - AggPas: removed to honor free licencing. (Closes: Bug#708695)
[Bart Martens]
* New debian/watch file fixing issues with upstream RC release.
[Abou Al Montacir]
* Avoid changing files in .pc hidden directory, these are used by quilt for
  internal purpose and could lead to surprises during build.
[Paul Gevers]
* Updated get-orig-source target and it compinion script orig-tar.sh so that they
  repack the source file, allowing bug 708695 to be fixed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
  Classes, SysUtils, types, LCLProc, LCLType, Forms, Controls, Graphics,
43
43
  Dialogs, Buttons, ComCtrls, Menus, AvgLvlTree, StdCtrls, ExtCtrls,
44
44
  // CodeTools
45
 
  BasicCodeTools, CustomCodeTool, CodeToolManager, CodeAtom, CodeCache,
46
 
  CodeTree, KeywordFuncLists, FindDeclarationTool, DirectivesTree,
 
45
  FileProcs, BasicCodeTools, CustomCodeTool, CodeToolManager, CodeAtom,
 
46
  CodeCache, CodeTree, KeywordFuncLists, FindDeclarationTool, DirectivesTree,
47
47
  PascalParserTool,
48
48
  // IDE Intf
49
49
  LazIDEIntf, IDECommands, MenuIntf, SrcEditorIntf,
128
128
    MainNotebook: TPageControl;
129
129
    MenuItem1: TMenuItem;
130
130
    CodeTreeviewButtonPanel: TPanel;
131
 
    OptionsSpeedButton: TSpeedButton;
132
 
    RefreshSpeedButton: TSpeedButton;
133
 
    ModeSpeedButton: TSpeedButton;
 
131
    CodeOptionsSpeedButton: TSpeedButton;
 
132
    CodeRefreshSpeedButton: TSpeedButton;
 
133
    CodeModeSpeedButton: TSpeedButton;
 
134
    DirOptionsSpeedButton: TSpeedButton;
 
135
    DirRefreshSpeedButton: TSpeedButton;
134
136
    TreePopupmenu: TPopupMenu;
135
137
    procedure CodeExplorerViewCreate(Sender: TObject);
136
138
    procedure CodeExplorerViewDestroy(Sender: TObject);
 
139
    procedure CodeFilterEditExit(Sender: TObject);
137
140
    procedure CodeTreeviewDblClick(Sender: TObject);
138
141
    procedure CodeTreeviewDeletion(Sender: TObject; Node: TTreeNode);
139
142
    procedure CodeTreeviewKeyUp(Sender: TObject; var Key: Word;
145
148
    procedure DirectivesTreeViewKeyUp(Sender: TObject; var Key: Word;
146
149
      Shift: TShiftState);
147
150
    procedure IdleTimer1Timer(Sender: TObject);
148
 
    procedure JumpToMenuitemClick(Sender: TObject);
 
151
    procedure JumpToMenuItemClick(Sender: TObject);
 
152
    procedure JumpToImplementationMenuItemClick(Sender: TObject);
 
153
    procedure ShowSrcEditPosMenuItemClick(Sender: TObject);
149
154
    procedure MainNotebookPageChanged(Sender: TObject);
150
 
    procedure ModeSpeedButtonClick(Sender: TObject);
151
 
    procedure OptionsSpeedButtonClick(Sender: TObject);
152
 
    procedure RefreshMenuitemClick(Sender: TObject);
153
 
    procedure RefreshSpeedButtonClick(Sender: TObject);
 
155
    procedure CodeModeSpeedButtonClick(Sender: TObject);
 
156
    procedure CodeOptionsSpeedButtonClick(Sender: TObject);
 
157
    procedure RefreshMenuItemClick(Sender: TObject);
 
158
    procedure CodeRefreshSpeedButtonClick(Sender: TObject);
154
159
    procedure RenameMenuItemClick(Sender: TObject);
155
160
    procedure TreePopupmenuPopup(Sender: TObject);
156
161
    procedure OnUserInput(Sender: TObject; Msg: Cardinal);
157
162
  private
 
163
    fCategoryNodes: array[TCodeExplorerCategory] of TTreeNode;
158
164
    FCodeFilename: string;
159
 
    fCategoryNodes: array[TCodeExplorerCategory] of TTreeNode;
160
 
    fObserverNode: TTreeNode;
161
 
    fObserverCatNodes: array[TCEObserverCategory] of TTreeNode;
162
 
    fObserverCatOverflow: array[TCEObserverCategory] of boolean;
163
165
    FDirectivesFilename: string;
164
166
    FFlags: TCodeExplorerViewFlags;
 
167
    FLastCodeChangeStep: integer;
165
168
    FLastCodeFilter: string;
166
 
    FLastCodeChangeStep: integer;
167
169
    fLastCodeOptionsChangeStep: integer;
 
170
    FLastCodeValid: boolean;
 
171
    FLastCodeXY: TPoint;
 
172
    FLastCode: TCodeBuffer;
 
173
    FLastDirectivesChangeStep: integer;
168
174
    FLastDirectivesFilter: string;
169
 
    FLastDirectivesChangeStep: integer;
 
175
    FLastMode: TCodeExplorerMode;
170
176
    FMode: TCodeExplorerMode;
171
 
    FLastMode: TCodeExplorerMode;
172
 
    FLastCodeValid: boolean;
173
 
    FLastCodeXY: TPoint;
 
177
    fObserverCatNodes: array[TCEObserverCategory] of TTreeNode;
 
178
    fObserverCatOverflow: array[TCEObserverCategory] of boolean;
 
179
    fObserverNode: TTreeNode;
 
180
    fSurroundingNode: TTreeNode;
174
181
    FOnGetDirectivesTree: TOnGetDirectivesTree;
175
182
    FOnJumpToCode: TOnJumpToCode;
176
183
    FOnShowOptions: TNotifyEvent;
 
184
    fSortCodeTool: TCodeTool;
177
185
    FUpdateCount: integer;
178
 
    fSortCodeTool: TCodeTool;
179
186
    ImgIDClass: Integer;
180
187
    ImgIDConst: Integer;
181
188
    ImgIDSection: Integer;
206
213
    procedure CreateIdentifierNodes(ACodeTool: TCodeTool; CodeNode: TCodeTreeNode;
207
214
                          ParentViewNode, InFrontViewNode: TTreeNode;
208
215
                          CreateSiblings: boolean);
 
216
    function GetCTNodePath(ACodeTool: TCodeTool; CodeNode: TCodeTreeNode): string;
 
217
    procedure CreateNodePath(ACodeTool: TCodeTool; aNodeData: TObject);
 
218
    procedure AddImplementationNode(ACodeTool: TCodeTool; CodeNode: TCodeTreeNode);
209
219
    procedure CreateDirectiveNodes(ADirectivesTool: TDirectivesTool;
210
220
                          CodeNode: TCodeTreeNode;
211
221
                          ParentViewNode, InFrontViewNode: TTreeNode;
216
226
                            CodeNode: TCodeTreeNode; StartPos, EndPos: integer;
217
227
                            ObserverState: TCodeObserverStatementState);
218
228
    procedure FindObserverTodos(Tool: TCodeTool);
 
229
    procedure CreateSurrounding(Tool: TCodeTool);
 
230
    procedure DeleteTVNode(TVNode: TTreeNode);
219
231
    procedure SetCodeFilter(const AValue: string);
220
232
    procedure SetCurrentPage(const AValue: TCodeExplorerPage);
221
233
    procedure SetDirectivesFilter(const AValue: string);
224
236
  protected
225
237
    fLastCodeTool: TCodeTool;
226
238
    fCodeSortedForStartPos: TAvgLvlTree;// tree of TTreeNode sorted for TViewNodeData(Node.Data).StartPos, secondary EndPos
 
239
    fNodesWithPath: TAvgLvlTree; // tree of TViewNodeData sorted for Path and Params
227
240
    procedure ApplyCodeFilter;
228
241
    procedure ApplyDirectivesFilter;
229
242
    function CompareCodeNodes(Node1, Node2: TTreeNode): integer;
 
243
    function FilterNode(ANode: TTreeNode; const TheFilter: string): boolean;
230
244
  public
231
 
    destructor Destroy; override;
232
245
    procedure BeginUpdate;
233
246
    procedure EndUpdate;
234
247
    procedure CheckOnIdle;
237
250
    procedure RefreshCode(OnlyVisible: boolean);
238
251
    procedure RefreshDirectives(OnlyVisible: boolean);
239
252
    procedure ClearCTNodes(ATreeView: TTreeView);// remove temporary references
240
 
    function JumpToSelection: boolean; // jump in source editor
 
253
    function JumpToSelection(ToImplementation: boolean = false): boolean; // jump in source editor
241
254
    function SelectSourceEditorNode: boolean;
242
255
    function SelectCodePosition(CodeBuf: TCodeBuffer; X, Y: integer): boolean; // select deepest node
243
256
    function FindCodeTVNodeAtCleanPos(CleanPos: integer): TTreeNode;
245
258
    procedure CurrentCodeBufferChanged;
246
259
    procedure CodeFilterChanged;
247
260
    procedure DirectivesFilterChanged;
248
 
    function FilterNode(ANode: TTreeNode; const TheFilter: string): boolean;
249
261
    function FilterFits(const NodeText, TheFilter: string): boolean; virtual;
250
262
    function GetCurrentTreeView: TCustomTreeView;
251
263
  public
270
282
var
271
283
  CodeExplorerView: TCodeExplorerView = nil;
272
284
  CEJumpToIDEMenuCommand: TIDEMenuCommand;
 
285
  CEJumpToImplementationIDEMenuCommand: TIDEMenuCommand;
 
286
  CEShowSrcEditPosIDEMenuCommand: TIDEMenuCommand;
273
287
  CERefreshIDEMenuCommand: TIDEMenuCommand;
274
288
  CERenameIDEMenuCommand: TIDEMenuCommand;
275
289
 
284
298
{$R *.lfm}
285
299
 
286
300
type
 
301
 
 
302
  { TViewNodeData }
 
303
 
287
304
  TViewNodeData = class
288
305
  public
289
 
    CTNode: TCodeTreeNode; // only valid during update, other times it is nil
 
306
    CTNode: TCodeTreeNode; // only valid during update, at other times it is nil
290
307
    Desc: TCodeTreeNodeDesc;
291
308
    SubDesc: TCodeTreeNodeSubDesc;
292
309
    StartPos, EndPos: integer;
293
 
    constructor Create(CodeNode: TCodeTreeNode);
 
310
    Path: string;
 
311
    Params: string;
 
312
    ImplementationNode: TViewNodeData;
 
313
    SortChildren: boolean; // sort for TVNode text (optional) and StartPos, EndPos
 
314
    constructor Create(CodeNode: TCodeTreeNode; SortTheChildren: boolean = true);
 
315
    destructor Destroy; override;
 
316
    procedure CreateParams(ACodeTool: TCodeTool);
294
317
  end;
295
318
 
296
319
function CompareViewNodeDataStartPos(Node1, Node2: TTreeNode): integer;
325
348
    Result:=0;
326
349
end;
327
350
 
 
351
function CompareViewNodePathsAndParams(NodeData1, NodeData2: Pointer): integer;
 
352
var
 
353
  Node1: TViewNodeData absolute NodeData1;
 
354
  Node2: TViewNodeData absolute NodeData2;
 
355
begin
 
356
  Result:=SysUtils.CompareText(Node1.Path,Node2.Path);
 
357
  if Result<>0 then exit;
 
358
  Result:=SysUtils.CompareText(Node1.Params,Node2.Params);
 
359
end;
 
360
 
 
361
function CompareViewNodePaths(NodeData1, NodeData2: Pointer): integer;
 
362
var
 
363
  Node1: TViewNodeData absolute NodeData1;
 
364
  Node2: TViewNodeData absolute NodeData2;
 
365
begin
 
366
  Result:=SysUtils.CompareText(Node1.Path,Node2.Path);
 
367
end;
 
368
 
328
369
procedure RegisterStandardCodeExplorerMenuItems;
329
370
var
330
371
  Path: String;
331
372
begin
332
373
  CodeExplorerMenuRoot:=RegisterIDEMenuRoot(CodeExplorerMenuRootName);
333
374
  Path:=CodeExplorerMenuRoot.Name;
334
 
  CEJumpToIDEMenuCommand:=RegisterIDEMenuCommand(Path, 'Jump to', lisMenuJumpTo
335
 
    );
336
 
  CERefreshIDEMenuCommand:=RegisterIDEMenuCommand(Path, 'Refresh',
337
 
    dlgUnitDepRefresh);
338
 
  CERenameIDEMenuCommand:=RegisterIDEMenuCommand(Path, 'Rename', lisFRIRename);
 
375
  CEJumpToIDEMenuCommand:=RegisterIDEMenuCommand(Path, 'Jump to', lisMenuJumpTo);
 
376
  CEJumpToImplementationIDEMenuCommand:=RegisterIDEMenuCommand(Path,
 
377
    'Jump to implementation', lisMenuJumpToImplementation);
 
378
  CEShowSrcEditPosIDEMenuCommand:=RegisterIDEMenuCommand(Path, 'Show position of source editor',
 
379
    lisShowPositionOfSourceEditor);
 
380
  CERefreshIDEMenuCommand:=RegisterIDEMenuCommand(Path, 'Refresh', dlgUnitDepRefresh);
 
381
  CERenameIDEMenuCommand:=RegisterIDEMenuCommand(Path, 'Rename', lisRename);
339
382
end;
340
383
 
341
384
function GetToDoComment(const Src: string; CommentStartPos,
380
423
 
381
424
{ TViewNodeData }
382
425
 
383
 
constructor TViewNodeData.Create(CodeNode: TCodeTreeNode);
 
426
constructor TViewNodeData.Create(CodeNode: TCodeTreeNode;
 
427
  SortTheChildren: boolean);
384
428
begin
385
429
  CTNode:=CodeNode;
386
430
  Desc:=CodeNode.Desc;
387
431
  SubDesc:=CodeNode.SubDesc;
388
432
  StartPos:=CodeNode.StartPos;
389
433
  EndPos:=CodeNode.EndPos;
 
434
  SortChildren:=SortTheChildren;
 
435
end;
 
436
 
 
437
destructor TViewNodeData.Destroy;
 
438
begin
 
439
  FreeAndNil(ImplementationNode);
 
440
  inherited Destroy;
 
441
end;
 
442
 
 
443
procedure TViewNodeData.CreateParams(ACodeTool: TCodeTool);
 
444
begin
 
445
  if Params<>'' then exit;
 
446
  if CTNode.Desc=ctnProcedure then
 
447
    Params:=ACodeTool.ExtractProcHead(CTNode,
 
448
      [phpWithoutClassKeyword,phpWithoutClassName,phpWithoutName,phpWithoutSemicolon]);
 
449
  if Params='' then
 
450
    Params:=' ';
390
451
end;
391
452
 
392
453
{ TCodeExplorerView }
401
462
 
402
463
  MainNotebook.ActivePage:=CodePage;
403
464
 
404
 
  RefreshSpeedButton.Hint:=dlgUnitDepRefresh;
405
 
  OptionsSpeedButton.Hint:=dlgFROpts;
 
465
  CodePage.Caption:=lisCode;
 
466
  CodeRefreshSpeedButton.Hint:=dlgUnitDepRefresh;
 
467
  CodeOptionsSpeedButton.Hint:=dlgFROpts;
406
468
  CodeFilterEdit.Text:=lisCEFilter;
407
 
  CodePage.Caption:=lisCode;
 
469
  DirectivesPage.Caption:=lisDirectives;
408
470
  DirectivesFilterEdit.Text:=lisCEFilter;
409
 
  DirectivesPage.Caption:=lisDirectives;
410
 
  
 
471
  DirRefreshSpeedButton.Hint:=dlgUnitDepRefresh;
 
472
  DirOptionsSpeedButton.Hint:=dlgFROpts;
411
473
 
412
 
  RefreshSpeedButton.LoadGlyphFromLazarusResource('laz_refresh');
413
 
  OptionsSpeedButton.LoadGlyphFromLazarusResource('menu_environment_options');
 
474
  CodeRefreshSpeedButton.LoadGlyphFromLazarusResource('laz_refresh');
 
475
  CodeOptionsSpeedButton.LoadGlyphFromLazarusResource('menu_environment_options');
 
476
  DirRefreshSpeedButton.LoadGlyphFromLazarusResource('laz_refresh');
 
477
  DirOptionsSpeedButton.LoadGlyphFromLazarusResource('menu_environment_options');
414
478
 
415
479
  ImgIDDefault := Imagelist1.AddLazarusResource('ce_default');
416
480
  ImgIDProgram := Imagelist1.AddLazarusResource('ce_program');
436
500
  CodeExplorerMenuRoot.MenuItem:=TreePopupMenu.Items;
437
501
  //CodeExplorerMenuRoot.Items.WriteDebugReport(' ');
438
502
 
439
 
  CEJumpToIDEMenuCommand.OnClick:=@JumpToMenuitemCLICK;
440
 
  CERefreshIDEMenuCommand.OnClick:=@RefreshMenuitemCLICK;
 
503
  CEJumpToIDEMenuCommand.OnClick:=@JumpToMenuItemClick;
 
504
  CEJumpToImplementationIDEMenuCommand.OnClick:=@JumpToImplementationMenuItemClick;
 
505
  CEShowSrcEditPosIDEMenuCommand.OnClick:=@ShowSrcEditPosMenuItemClick;
 
506
  CERefreshIDEMenuCommand.OnClick:=@RefreshMenuItemClick;
441
507
  CERenameIDEMenuCommand.OnClick:=@RenameMenuItemClick;
442
508
 
 
509
  fNodesWithPath:=TAvgLvlTree.Create(@CompareViewNodePathsAndParams);
 
510
 
443
511
  Application.AddOnUserInputHandler(@OnUserInput);
444
512
end;
445
513
 
446
514
procedure TCodeExplorerView.CodeExplorerViewDestroy(Sender: TObject);
447
515
begin
448
516
  //debugln('TCodeExplorerView.CodeExplorerViewDestroy');
 
517
  fLastCodeTool:=nil;
 
518
  FreeAndNil(fNodesWithPath);
 
519
  FreeAndNil(fCodeSortedForStartPos);
 
520
  if CodeExplorerView=Self then
 
521
    CodeExplorerView:=nil;
 
522
end;
 
523
 
 
524
procedure TCodeExplorerView.CodeFilterEditExit(Sender: TObject);
 
525
begin
 
526
  if CodeFilterEdit.Text='' then
 
527
    CodeFilterEdit.Text:=lisCEFilter;
449
528
end;
450
529
 
451
530
procedure TCodeExplorerView.CodeTreeviewDblClick(Sender: TObject);
505
584
  and (fsModal in Screen.ActiveCustomForm.FormState) then
506
585
    exit;
507
586
  if not IsVisible then exit;
508
 
  if Active then exit;
 
587
  Exclude(FFlags,cevCheckOnIdle);
 
588
  case CurrentPage of
 
589
  cepNone: ;
 
590
  cepCode: if (CurrentPage<>cepCode) or CodeTreeview.Focused then exit;
 
591
  cepDirectives: if (CurrentPage<>cepDirectives) or DirectivesTreeView.Focused then exit;
 
592
  end;
509
593
  Refresh(true);
510
594
end;
511
595
 
512
 
procedure TCodeExplorerView.JumpToMenuitemCLICK(Sender: TObject);
513
 
begin
514
 
  JumpToSelection;
 
596
procedure TCodeExplorerView.JumpToMenuItemClick(Sender: TObject);
 
597
begin
 
598
  JumpToSelection(false);
 
599
end;
 
600
 
 
601
procedure TCodeExplorerView.JumpToImplementationMenuItemClick(Sender: TObject);
 
602
begin
 
603
  JumpToSelection(true);
 
604
end;
 
605
 
 
606
procedure TCodeExplorerView.ShowSrcEditPosMenuItemClick(Sender: TObject);
 
607
begin
 
608
  SelectSourceEditorNode;
515
609
end;
516
610
 
517
611
procedure TCodeExplorerView.MainNotebookPageChanged(Sender: TObject);
519
613
  Refresh(true);
520
614
end;
521
615
 
522
 
procedure TCodeExplorerView.ModeSpeedButtonClick(Sender: TObject);
 
616
procedure TCodeExplorerView.CodeModeSpeedButtonClick(Sender: TObject);
523
617
begin
524
618
  // Let's Invert Mode of Exibition
525
619
  if Mode = cemCategory then
528
622
    SetMode(cemCategory);
529
623
end;
530
624
 
531
 
procedure TCodeExplorerView.OptionsSpeedButtonClick(Sender: TObject);
 
625
procedure TCodeExplorerView.CodeOptionsSpeedButtonClick(Sender: TObject);
532
626
begin
533
627
  if Assigned(FOnShowOptions) then
534
628
  begin
537
631
  end;
538
632
end;
539
633
 
540
 
procedure TCodeExplorerView.RefreshMenuitemCLICK(Sender: TObject);
 
634
procedure TCodeExplorerView.RefreshMenuItemClick(Sender: TObject);
541
635
begin
 
636
  FLastCodeChangeStep:=CTInvalidChangeStamp;
542
637
  Refresh(true);
543
638
end;
544
639
 
545
 
procedure TCodeExplorerView.RefreshSpeedButtonClick(Sender: TObject);
 
640
procedure TCodeExplorerView.CodeRefreshSpeedButtonClick(Sender: TObject);
546
641
begin
547
 
  Refresh(true);
 
642
  RefreshMenuItemClick(Sender);
548
643
end;
549
644
 
550
645
procedure TCodeExplorerView.RenameMenuItemClick(Sender: TObject);
563
658
  CurItem: TTreeNode;
564
659
  CanRename: boolean;
565
660
  CurNode: TViewNodeData;
 
661
  HasImplementation: Boolean;
566
662
begin
567
663
  CanRename:=false;
 
664
  HasImplementation:=false;
568
665
  CurTreeView:=GetCurrentTreeView;
569
666
  if CurTreeView<>nil then begin
570
667
    if tvoAllowMultiselect in CurTreeView.Options then
583
680
          ;
584
681
        end;
585
682
      end;
 
683
      if (CurNode.ImplementationNode<>nil)
 
684
      and (CurNode.ImplementationNode.StartPos>0) then
 
685
        HasImplementation:=true;
586
686
    end;
587
687
  end;
588
688
  CERenameIDEMenuCommand.Visible:=CanRename;
589
 
  DebugLn(['TCodeExplorerView.TreePopupmenuPopup ',CERenameIDEMenuCommand.Visible]);
 
689
  CEJumpToImplementationIDEMenuCommand.Visible:=HasImplementation;
 
690
  //DebugLn(['TCodeExplorerView.TreePopupmenuPopup ',CERenameIDEMenuCommand.Visible]);
590
691
end;
591
692
 
592
693
procedure TCodeExplorerView.OnUserInput(Sender: TObject; Msg: Cardinal);
599
700
  CodeNode: TCodeTreeNode): string;
600
701
begin
601
702
  Result:='?';
 
703
 
602
704
  try
603
705
    case CodeNode.Desc of
604
706
 
605
707
    ctnUnit, ctnProgram, ctnLibrary, ctnPackage:
606
708
      Result:=CodeNode.DescAsString+' '+ACodeTool.ExtractSourceName;
607
709
 
 
710
    ctnTypeSection:
 
711
      Result:='Type';
 
712
 
 
713
    ctnVarSection:
 
714
      Result:='Var';
 
715
 
 
716
    ctnConstSection:
 
717
      Result:='Const';
 
718
 
 
719
    ctnLabelSection:
 
720
      Result:='Label';
 
721
 
 
722
    ctnResStrSection:
 
723
      Result:='Resourcestring';
 
724
 
608
725
    ctnTypeDefinition,ctnVarDefinition,ctnConstDefinition,ctnUseUnit:
609
726
      Result:=ACodeTool.ExtractIdentifier(CodeNode.StartPos);
610
727
 
612
729
      Result:=ACodeTool.ExtractDefinitionName(CodeNode);
613
730
 
614
731
    ctnClass,ctnObject,ctnObjCClass,ctnObjCCategory,ctnObjCProtocol,
615
 
    ctnInterface,ctnCPPClass:
 
732
    ctnClassInterface,ctnCPPClass:
616
733
      Result:='('+ACodeTool.ExtractClassInheritance(CodeNode,[])+')';
617
734
 
618
 
    ctnEnumIdentifier:
 
735
    ctnEnumIdentifier, ctnLabelType:
619
736
      Result:=ACodeTool.ExtractIdentifier(CodeNode.StartPos);
620
737
 
621
738
    ctnProcedure:
625
742
                     phpWithParameterNames,phpWithDefaultValues,phpWithResultType,
626
743
                     phpWithOfObject,phpWithCallingSpecs,phpWithProcModifiers]);
627
744
 
 
745
    ctnProcedureHead:
 
746
      Result:='Procedure Header';
 
747
 
628
748
    ctnProperty:
629
749
      Result:=ACodeTool.ExtractPropName(CodeNode,false); // property keyword is not needed because there are icons
630
750
 
 
751
    ctnInterface:
 
752
      Result:='Interface';
 
753
 
 
754
    ctnBeginBlock:
 
755
      Result:='Begin block';
 
756
 
 
757
    ctnAsmBlock:
 
758
      Result:='Asm block';
 
759
 
631
760
    else
632
761
      Result:=CodeNode.DescAsString;
633
762
    end;
702
831
  end;
703
832
end;
704
833
 
705
 
function TCodeExplorerView.GetDirectiveNodeImage(CodeNode: TCodeTreeNode
706
 
  ): integer;
 
834
function TCodeExplorerView.GetDirectiveNodeImage(CodeNode: TCodeTreeNode): integer;
707
835
begin
708
836
  case CodeNode.SubDesc of
709
837
  cdnsInclude:  Result:=ImgIDSection;
731
859
  ShowNode: Boolean;
732
860
  ShowChilds: Boolean;
733
861
  Category: TCodeExplorerCategory;
 
862
  CurParentViewNode: TTreeNode;
734
863
begin
735
864
  while CodeNode<>nil do begin
736
865
    ShowNode:=true;
737
866
    ShowChilds:=true;
 
867
    CurParentViewNode:=ParentViewNode;
738
868
 
739
869
    // don't show statements
740
870
    if (CodeNode.Desc in AllPascalStatements+[ctnParameterList]) then begin
759
889
      ShowNode:=false;
760
890
    end;
761
891
 
762
 
    // don't show modifier nodes
763
 
    if CodeNode.Desc in [ctnIdentifier,ctnRangedArrayType,
 
892
    // don't show subs
 
893
    if CodeNode.Desc in [ctnConstant,ctnIdentifier,ctnRangedArrayType,
764
894
      ctnOpenArrayType,ctnOfConstType,ctnRangeType,ctnTypeType,ctnFileType,
765
 
      ctnVariantType,ctnEnumerationType,ctnSetType,ctnProcedureType]
766
 
    then
767
 
      ShowNode:=false;
768
 
      
769
 
    // don't show End.
770
 
    if CodeNode.Desc=ctnEndPoint then
 
895
      ctnVariantType,ctnSetType,ctnProcedureType]
 
896
    then begin
 
897
      ShowNode:=false;
 
898
      ShowChilds:=false;
 
899
    end;
 
900
 
 
901
    // show enums, but not the brackets
 
902
    if CodeNode.Desc=ctnEnumerationType then
 
903
      ShowNode:=false;
 
904
 
 
905
    // don't show special nodes
 
906
    if CodeNode.Desc in [ctnEndPoint] then
771
907
      ShowNode:=false;
772
908
      
773
909
    // don't show class visibility section nodes
774
 
    if (CodeNode.Desc in AllClassSections) then begin
 
910
    if (CodeNode.Desc in AllClassSections) then
775
911
      ShowNode:=false;
776
 
    end;
777
912
 
778
913
    if Mode=cemCategory then begin
779
914
      // don't show method bodies
783
918
        ShowChilds:=false;
784
919
      end;
785
920
 
 
921
      // don't show single hint modifiers
 
922
      if (CodeNode.Desc = ctnHintModifier) and (CurParentViewNode = nil) then
 
923
      begin
 
924
        ShowNode:=false;
 
925
        ShowChilds:=false;
 
926
      end;
 
927
 
786
928
      // category mode: put nodes in categories
787
929
      Category:=cecNone;
788
930
      if ShowNode
789
931
      and ((CodeNode.Parent=nil)
790
 
      or (CodeNode.Parent.Desc in AllCodeSections)
791
 
      or (CodeNode.Parent.Parent=nil)
792
 
      or (CodeNode.Parent.Parent.Desc in AllCodeSections)) then
 
932
        or (CodeNode.Parent.Desc in AllCodeSections)
 
933
        or (CodeNode.Parent.Parent=nil)
 
934
        or (CodeNode.Parent.Parent.Desc in AllCodeSections)) then
793
935
      begin
794
936
        // top level definition
795
937
        case CodeNode.Desc of
796
 
        ctnUsesSection:     Category:=cecUses;
 
938
        ctnUseUnit:         Category:=cecUses;
797
939
        ctnTypeDefinition,ctnGenericType:  Category:=cecTypes;
798
940
        ctnVarDefinition:   Category:=cecVariables;
799
 
        ctnConstDefinition: Category:=cecConstants;
 
941
        ctnConstDefinition,ctnEnumIdentifier: Category:=cecConstants;
800
942
        ctnProcedure:       Category:=cecProcedures;
801
943
        ctnProperty:        Category:=cecProperties;
802
944
        end;
809
951
              NodeText:=CodeExplorerLocalizedString(Category);
810
952
              NodeImageIndex:=GetCodeNodeImage(ACodeTool,CodeNode.Parent);
811
953
              fCategoryNodes[Category]:=CodeTreeview.Items.AddChildObject(nil,
812
 
                                                               NodeText,NodeData);
 
954
                                                             NodeText,NodeData);
813
955
              fCategoryNodes[Category].ImageIndex:=NodeImageIndex;
814
956
              fCategoryNodes[Category].SelectedIndex:=NodeImageIndex;
815
957
            end;
816
 
            ParentViewNode:=fCategoryNodes[Category];
 
958
            if (CurParentViewNode=nil) then
 
959
              CurParentViewNode:=fCategoryNodes[Category];
817
960
            InFrontViewNode:=nil;
818
961
          end;
819
962
        end else begin
820
963
          ShowNode:=false;
821
964
        end;
822
 
      end else if (CodeNode.Parent<>nil)
823
 
      and (CodeNode.Parent.Desc in (AllClassSections+AllClassInterfaces+[ctnRecordType]))
824
 
      then begin
825
 
        // show class, interface and record nodes
826
 
        ShowNode:=true;
827
965
      end else begin
828
 
        ShowNode:=false;
 
966
        // not a top level node
829
967
      end;
830
 
      //DebugLn(['TCodeExplorerView.CreateNodes ',CodeNode.DescAsString,' ShowNode=',ShowNode,' ShowChilds=',ShowChilds]);
 
968
      //DebugLn(['TCodeExplorerView.CreateIdentifierNodes ',CodeNode.DescAsString,' ShowNode=',ShowNode,' ShowChilds=',ShowChilds]);
831
969
    end;
832
970
    
833
971
    if ShowNode then begin
 
972
      // add a node to the TTreeView
834
973
      NodeData:=TViewNodeData.Create(CodeNode);
 
974
      CreateNodePath(ACodeTool,NodeData);
835
975
      NodeText:=GetCodeNodeDescription(ACodeTool,CodeNode);
836
976
      NodeImageIndex:=GetCodeNodeImage(ACodeTool,CodeNode);
 
977
      //if NodeText='TCodeExplorerView' then
 
978
      //  debugln(['TCodeExplorerView.CreateIdentifierNodes CodeNode=',CodeNode.DescAsString,' NodeText="',NodeText,'" Category=',dbgs(Category),' InFrontViewNode=',InFrontViewNode<>nil,' CurParentViewNode=',CurParentViewNode<>nil]);
837
979
      if InFrontViewNode<>nil then
838
980
        ViewNode:=CodeTreeview.Items.InsertObjectBehind(
839
981
                                              InFrontViewNode,NodeText,NodeData)
840
 
      else if ParentViewNode<>nil then
 
982
      else if CurParentViewNode<>nil then
841
983
        ViewNode:=CodeTreeview.Items.AddChildObject(
842
 
                                               ParentViewNode,NodeText,NodeData)
 
984
                                               CurParentViewNode,NodeText,NodeData)
843
985
      else
844
986
        ViewNode:=CodeTreeview.Items.AddObject(nil,NodeText,NodeData);
845
987
      ViewNode.ImageIndex:=NodeImageIndex;
846
988
      ViewNode.SelectedIndex:=NodeImageIndex;
847
989
      InFrontViewNode:=ViewNode;
848
990
    end else begin
849
 
      ViewNode:=ParentViewNode;
 
991
      // do not add a node to the TTreeView
 
992
      ViewNode:=CurParentViewNode;
 
993
      AddImplementationNode(ACodeTool,CodeNode);
850
994
    end;
851
995
    if ShowChilds then
852
996
      CreateIdentifierNodes(ACodeTool,CodeNode.FirstChild,ViewNode,nil,true);
877
1021
 
878
1022
    ViewNode:=ParentViewNode;
879
1023
    if ShowNode then begin
880
 
      NodeData:=TViewNodeData.Create(CodeNode);
 
1024
      NodeData:=TViewNodeData.Create(CodeNode,false);
881
1025
      NodeText:=GetDirectiveNodeDescription(ADirectivesTool,CodeNode);
882
1026
      NodeImageIndex:=GetDirectiveNodeImage(CodeNode);
883
1027
      if InFrontViewNode<>nil then
1105
1249
          end;
1106
1250
        end;
1107
1251
 
1108
 
      ctnClassConst..ctnClassPublished:
 
1252
      ctnClassClassVar..ctnClassPublished:
1109
1253
        begin
1110
1254
          if (cefcUnsortedClassVisibility in ObserverCats)
1111
1255
          and (CodeNode.PriorBrother<>nil)
1188
1332
    fObserverCatNodes[f].Data:=Data;
1189
1333
    fObserverCatNodes[f].ImageIndex:=ImgIDHint;
1190
1334
    fObserverCatNodes[f].SelectedIndex:=ImgIDHint;
1191
 
    fObserverNode.Expanded:=true;
1192
1335
  end;
1193
1336
  Result:=fObserverCatNodes[f];
1194
1337
end;
1200
1343
  Data: TViewNodeData;
1201
1344
  ObsTVNode: TTreeNode;
1202
1345
  NodeText: String;
1203
 
  NodeImageIndCex: LongInt;
 
1346
  NodeImageIndex: LongInt;
1204
1347
  TVNode: TTreeNode;
1205
1348
  ProcNode: TCodeTreeNode;
1206
1349
  OldPos: LongInt;
1265
1408
              phpWithoutClassName])]);
1266
1409
            Tool.MoveCursorToCleanPos(OldPos);
1267
1410
          end;
1268
 
          NodeImageIndCex:=ImgIDConst;
 
1411
          NodeImageIndex:=ImgIDConst;
1269
1412
          TVNode:=CodeTreeview.Items.AddChild(ObsTVNode,NodeText);
1270
1413
          TVNode.Data:=Data;
1271
1414
          TVNode.Text:=NodeText;
1272
 
          TVNode.ImageIndex:=NodeImageIndCex;
1273
 
          TVNode.SelectedIndex:=NodeImageIndCex;
 
1415
          TVNode.ImageIndex:=NodeImageIndex;
 
1416
          TVNode.SelectedIndex:=NodeImageIndex;
1274
1417
        end;
1275
1418
      end;
1276
1419
    end;
1344
1487
                phpWithoutClassName])]);
1345
1488
              Tool.MoveCursorToCleanPos(OldPos);
1346
1489
            end;
1347
 
            NodeImageIndCex:=ImgIDConst;
 
1490
            NodeImageIndex:=ImgIDConst;
1348
1491
            TVNode:=CodeTreeview.Items.AddChild(ObsTVNode,NodeText);
1349
1492
            TVNode.Data:=Data;
1350
1493
            TVNode.Text:=NodeText;
1351
 
            TVNode.ImageIndex:=NodeImageIndCex;
1352
 
            TVNode.SelectedIndex:=NodeImageIndCex;
 
1494
            TVNode.ImageIndex:=NodeImageIndex;
 
1495
            TVNode.SelectedIndex:=NodeImageIndex;
1353
1496
          end;
1354
1497
        end;
1355
1498
      end;
1494
1637
        fObserverCatOverflow[cefcToDos]:=true;
1495
1638
        break;
1496
1639
      end else begin
1497
 
        Data:=TViewNodeData.Create(Tool.Tree.Root);
 
1640
        Data:=TViewNodeData.Create(Tool.Tree.Root,false);
1498
1641
        Data.Desc:=ctnConstant;
1499
1642
        Data.SubDesc:=ctnsNone;
1500
1643
        Data.StartPos:=p;
1514
1657
  until p>SrcLen;
1515
1658
end;
1516
1659
 
 
1660
procedure TCodeExplorerView.CreateSurrounding(Tool: TCodeTool);
 
1661
 
 
1662
  function CTNodeIsEnclosing(CTNode: TCodeTreeNode; p: integer): boolean;
 
1663
  var
 
1664
    NextCTNode: TCodeTreeNode;
 
1665
  begin
 
1666
    Result:=false;
 
1667
    if (p<CTNode.StartPos) or (p>CTNode.EndPos) then exit;
 
1668
    if (p=CTNode.EndPos) then begin
 
1669
      NextCTNode:=CTNode.NextSkipChilds;
 
1670
      if (NextCTNode<>nil) and (NextCTNode.StartPos<=p) then exit;
 
1671
    end;
 
1672
    Result:=true;
 
1673
  end;
 
1674
 
 
1675
  procedure CreateSubNodes(ParentTVNode: TTreeNode; CTNode: TCodeTreeNode;
 
1676
    p: integer);
 
1677
  var
 
1678
    ChildCTNode: TCodeTreeNode;
 
1679
    ChildData: TViewNodeData;
 
1680
    ChildTVNode: TTreeNode;
 
1681
    AddChilds: Boolean;
 
1682
    Add: Boolean;
 
1683
    CurParentTVNode: TTreeNode;
 
1684
  begin
 
1685
    ChildCTNode:=CTNode.FirstChild;
 
1686
    while ChildCTNode<>nil do
 
1687
    begin
 
1688
      AddChilds:=false;
 
1689
      Add:=false;
 
1690
      if CTNodeIsEnclosing(ChildCTNode,p) then begin
 
1691
        AddChilds:=true;
 
1692
        Add:=true;
 
1693
        if ChildCTNode.Desc in AllClasses then
 
1694
          Add:=false;
 
1695
      end else if (CTNode.Desc=ctnProcedure)
 
1696
      and (ChildCTNode.Desc<>ctnProcedureHead) then begin
 
1697
        Add:=true
 
1698
      end;
 
1699
 
 
1700
      CurParentTVNode:=ParentTVNode;
 
1701
      if Add then
 
1702
      begin
 
1703
        ChildData:=TViewNodeData.Create(ChildCTNode,false);
 
1704
        ChildTVNode:=CodeTreeview.Items.AddChildObject(
 
1705
                     ParentTVNode,GetCodeNodeDescription(Tool,ChildCTNode),ChildData);
 
1706
        ChildTVNode.ImageIndex:=GetCodeNodeImage(Tool,ChildCTNode);
 
1707
        ChildTVNode.SelectedIndex:=ChildTVNode.ImageIndex;
 
1708
        CurParentTVNode:=ChildTVNode;
 
1709
      end else
 
1710
        ChildTVNode:=nil;
 
1711
      if AddChilds then
 
1712
      begin
 
1713
        CreateSubNodes(CurParentTVNode,ChildCTNode,p);
 
1714
        if ChildTVNode<>nil then
 
1715
          ChildTVNode.Expanded:=true;
 
1716
      end;
 
1717
      ChildCTNode:=ChildCTNode.NextBrother;
 
1718
    end;
 
1719
  end;
 
1720
 
 
1721
var
 
1722
  CodeNode: TCodeTreeNode;
 
1723
  Data: TViewNodeData;
 
1724
  TVNode: TTreeNode;
 
1725
  CurPos: TCodeXYPosition;
 
1726
  p: integer;
 
1727
begin
 
1728
  if fSurroundingNode = nil then
 
1729
  begin
 
1730
    fSurroundingNode:=CodeTreeview.Items.Add(nil, lisCESurrounding);
 
1731
    Data:=TViewNodeData.Create(Tool.Tree.Root,false);
 
1732
    Data.Desc:=ctnNone;
 
1733
    Data.StartPos:=Tool.SrcLen;
 
1734
    fSurroundingNode.Data:=Data;
 
1735
    fSurroundingNode.ImageIndex:=ImgIDSection;
 
1736
    fSurroundingNode.SelectedIndex:=ImgIDSection;
 
1737
  end;
 
1738
 
 
1739
  CurPos.Code:=FLastCode;
 
1740
  CurPos.X:=FLastCodeXY.X;
 
1741
  CurPos.Y:=FLastCodeXY.Y;
 
1742
  fLastCodeTool.CaretToCleanPos(CurPos,p);
 
1743
 
 
1744
  // add all top lvl sections
 
1745
  CodeNode:=Tool.Tree.Root;
 
1746
  while CodeNode<>nil do begin
 
1747
    Data:=TViewNodeData.Create(CodeNode,false);
 
1748
    TVNode:=CodeTreeview.Items.AddChildObject(
 
1749
                       fSurroundingNode,GetCodeNodeDescription(Tool,CodeNode),Data);
 
1750
    TVNode.ImageIndex:=GetCodeNodeImage(Tool,CodeNode);
 
1751
    TVNode.SelectedIndex:=TVNode.ImageIndex;
 
1752
    if CTNodeIsEnclosing(CodeNode,p) then
 
1753
      CreateSubNodes(TVNode,CodeNode,p);
 
1754
    TVNode.Expanded:=true;
 
1755
 
 
1756
    CodeNode:=CodeNode.NextBrother;
 
1757
  end;
 
1758
  fSurroundingNode.Expanded:=true;
 
1759
end;
 
1760
 
 
1761
procedure TCodeExplorerView.DeleteTVNode(TVNode: TTreeNode);
 
1762
var
 
1763
  c: TCodeExplorerCategory;
 
1764
  oc: TCEObserverCategory;
 
1765
begin
 
1766
  if TVNode=nil then exit;
 
1767
  if TVNode.Data<>nil then begin
 
1768
    if (TObject(TVNode.Data) is TViewNodeData) and (fCodeSortedForStartPos<>nil)
 
1769
    then
 
1770
      fCodeSortedForStartPos.Remove(TVNode);
 
1771
    TObject(TVNode.Data).Free;
 
1772
    TVNode.Data:=nil;
 
1773
  end;
 
1774
  if TVNode.Parent=nil then begin
 
1775
    if TVNode=fObserverNode then
 
1776
      fObserverNode:=nil
 
1777
    else if TVNode=fSurroundingNode then
 
1778
      fSurroundingNode:=nil
 
1779
    else begin
 
1780
      for c:=low(fCategoryNodes) to high(fCategoryNodes) do
 
1781
        if fCategoryNodes[c]=TVNode then
 
1782
          fCategoryNodes[c]:=nil;
 
1783
    end;
 
1784
  end else if TVNode=fObserverNode then begin
 
1785
    for oc:=low(fObserverCatNodes) to high(fObserverCatNodes) do
 
1786
      if fObserverCatNodes[oc]=TVNode then
 
1787
        fObserverCatNodes[oc]:=nil;
 
1788
  end;
 
1789
  TVNode.Delete;
 
1790
end;
 
1791
 
1517
1792
procedure TCodeExplorerView.SetCodeFilter(const AValue: string);
1518
1793
begin
1519
1794
  if CodeFilter=AValue then exit;
1547
1822
begin
1548
1823
  if FMode=cemCategory
1549
1824
  then begin
1550
 
    ModeSpeedButton.LoadGlyphFromLazarusResource('show_category');
1551
 
    ModeSpeedButton.Hint:=lisCEModeShowSourceNodes;
 
1825
    CodeModeSpeedButton.LoadGlyphFromLazarusResource('show_category');
 
1826
    CodeModeSpeedButton.Hint:=lisCEModeShowSourceNodes;
1552
1827
  end
1553
1828
  else begin
1554
 
    ModeSpeedButton.LoadGlyphFromLazarusResource('show_source');
1555
 
    ModeSpeedButton.Hint:=lisCEModeShowCategories;
 
1829
    CodeModeSpeedButton.LoadGlyphFromLazarusResource('show_source');
 
1830
    CodeModeSpeedButton.Hint:=lisCEModeShowCategories;
1556
1831
  end;
1557
1832
  Refresh(true);
1558
1833
end;
1568
1843
  ANode: TTreeNode;
1569
1844
  TheFilter: String;
1570
1845
begin
1571
 
  TheFilter:=CodeFilterEdit.Text;
 
1846
  TheFilter:=GetCodeFilter;
 
1847
  //DebugLn(['TCodeExplorerView.ApplyCodeFilter ====================="',TheFilter,'"']);
1572
1848
  FLastCodeFilter:=TheFilter;
1573
1849
  CodeTreeview.BeginUpdate;
1574
 
  CodeTreeview.Options:=CodeTreeview.Options+[tvoAllowMultiselect];
1575
 
  //DebugLn(['TCodeExplorerView.ApplyCodeFilter =====================']);
1576
1850
  ANode:=CodeTreeview.Items.GetFirstNode;
1577
1851
  while ANode<>nil do begin
1578
1852
    FilterNode(ANode,TheFilter);
1598
1872
  DirectivesTreeView.EndUpdate;
1599
1873
end;
1600
1874
 
1601
 
destructor TCodeExplorerView.Destroy;
1602
 
begin
1603
 
  inherited Destroy;
1604
 
  fLastCodeTool:=nil;
1605
 
  FreeAndNil(fCodeSortedForStartPos);
1606
 
  if CodeExplorerView=Self then
1607
 
    CodeExplorerView:=nil;
1608
 
end;
1609
 
 
1610
1875
procedure TCodeExplorerView.BeginUpdate;
1611
1876
begin
1612
1877
  inc(FUpdateCount);
1647
1912
  var
1648
1913
    TVNode: TTreeNode;
1649
1914
    Data: TViewNodeData;
 
1915
    ShowInterfaceImplementation: Boolean;
1650
1916
  begin
 
1917
    ShowInterfaceImplementation:=(Mode <> cemCategory)
 
1918
      or (not (cecSurrounding in CodeExplorerOptions.Categories));
 
1919
    if not ShowInterfaceImplementation then exit;
1651
1920
    TVNode:=CodeTreeview.Items.GetFirstNode;
1652
1921
    while TVNode<>nil do begin
1653
1922
      Data:=TViewNodeData(TVNode.Data);
1685
1954
    TVNode:=CodeTreeview.Items.GetFirstNode;
1686
1955
    while TVNode<>nil do begin
1687
1956
      NextTVNode:=TVNode.GetNext;
1688
 
      DeleteNode:=false;
1689
 
      DeleteNextNode:=false;
1690
 
      if (NextTVNode<>nil)
1691
 
      and (CompareTextIgnoringSpace(TVNode.Text,NextTVNode.Text,false)=0) then
 
1957
      if NextTVNode=nil then break;
 
1958
      if (TVNode.Parent<>nil) and (NextTVNode.Parent=TVNode.Parent) then
1692
1959
      begin
1693
 
        Data:=TViewNodeData(TVNode.Data);
1694
 
        NextData:=TViewNodeData(NextTVNode.Data);
1695
 
        if IsForward(Data) then
1696
 
          DeleteNode:=true;
1697
 
        if IsForward(NextData) then
1698
 
          DeleteNextNode:=true;
1699
 
      end;
1700
 
      if DeleteNextNode then begin
1701
 
        TViewNodeData(NextTVNode.Data).Free;
1702
 
        NextTVNode.Data:=nil;
1703
 
        NextTVNode.Delete;
1704
 
        NextTVNode:=TVNode;
1705
 
      end else if DeleteNode then begin
1706
 
        TViewNodeData(TVNode.Data).Free;
1707
 
        TVNode.Data:=nil;
1708
 
        TVNode.Delete;
 
1960
        DeleteNode:=false;
 
1961
        DeleteNextNode:=false;
 
1962
        if (CompareTextIgnoringSpace(TVNode.Text,NextTVNode.Text,false)=0) then
 
1963
        begin
 
1964
          Data:=TViewNodeData(TVNode.Data);
 
1965
          NextData:=TViewNodeData(NextTVNode.Data);
 
1966
          if IsForward(Data) then
 
1967
            DeleteNode:=true;
 
1968
          if IsForward(NextData) then
 
1969
            DeleteNextNode:=true;
 
1970
        end;
 
1971
        if DeleteNextNode then begin
 
1972
          DeleteTVNode(NextTVNode);
 
1973
          NextTVNode:=TVNode;
 
1974
        end else if DeleteNode then begin
 
1975
          NextTVNode:=TVNode.GetNextSkipChildren;
 
1976
          DeleteTVNode(TVNode);
 
1977
        end;
1709
1978
      end;
1710
1979
      TVNode:=NextTVNode;
1711
1980
    end;
1722
1991
  NewXY: TPoint;
1723
1992
  OnlyXYChanged: Boolean;
1724
1993
  CurFollowNode: Boolean;
 
1994
  TVNode: TTreeNode;
 
1995
  TheFilter: String;
1725
1996
begin
1726
1997
  if (FUpdateCount>0)
1727
1998
  or (OnlyVisible and ((CurrentPage<>cepCode) or (not IsVisible))) then begin
1748
2019
    if ACodeTool=nil then exit;
1749
2020
 
1750
2021
    fLastCodeTool:=ACodeTool;
 
2022
    FLastCode:=Code;
1751
2023
 
1752
2024
    // check for changes in the codetool
 
2025
    TheFilter:=GetCodeFilter;
1753
2026
    OnlyXYChanged:=false;
1754
2027
    if (ACodeTool=nil) then begin
1755
2028
      if (FCodeFilename='') then begin
1758
2031
      end;
1759
2032
      //debugln(['TCodeExplorerView.RefreshCode no tool']);
1760
2033
    end else begin
1761
 
      if not FLastCodeValid then begin
 
2034
      if CompareText(FLastCodeFilter,TheFilter)<>0 then begin
 
2035
        // debugln(['TCodeExplorerView.RefreshCode filter changed']);
 
2036
      end else if not FLastCodeValid then begin
1762
2037
        //debugln(['TCodeExplorerView.RefreshCode last code not valid'])
1763
2038
      end else if ACodeTool.MainFilename<>FCodeFilename then begin
1764
2039
        //debugln(['TCodeExplorerView.RefreshCode File changed ',ACodeTool.MainFilename,' ',FCodeFilename])
1793
2068
      FLastMode:=Mode;
1794
2069
      fLastCodeOptionsChangeStep:=CodeExplorerOptions.ChangeStep;
1795
2070
      FLastCodeXY:=SrcEdit.CursorTextXY;
 
2071
      FLastCodeFilter:=TheFilter;
1796
2072
      // remember the codetools ChangeStep
1797
2073
      if ACodeTool<>nil then begin
1798
2074
        FCodeFilename:=ACodeTool.MainFilename;
1803
2079
 
1804
2080
      if fCodeSortedForStartPos<>nil then
1805
2081
        fCodeSortedForStartPos.Clear;
 
2082
      fNodesWithPath.Clear;
1806
2083
 
1807
2084
      //DebugLn(['TCodeExplorerView.RefreshCode ',FCodeFilename]);
1808
2085
 
1818
2095
      fObserverNode:=nil;
1819
2096
      for f:=low(TCEObserverCategory) to high(TCEObserverCategory) do
1820
2097
        fObserverCatNodes[f]:=nil;
 
2098
      fSurroundingNode:=nil;
1821
2099
 
1822
 
      if (ACodeTool=nil) or (ACodeTool.Tree=nil) or (ACodeTool.Tree.Root=nil) then
1823
 
      begin
1824
 
        CodeTreeview.Items.Clear;
1825
 
      end else begin
1826
 
        CodeTreeview.Items.Clear;
 
2100
      CodeTreeview.Items.Clear;
 
2101
      if (ACodeTool<>nil) and (ACodeTool.Tree<>nil) and (ACodeTool.Tree.Root<>nil)
 
2102
      then begin
1827
2103
        CreateIdentifierNodes(ACodeTool,ACodeTool.Tree.Root,nil,nil,true);
1828
 
        if (Mode = cemCategory) and
1829
 
           (cecCodeObserver in CodeExplorerOptions.Categories) then
1830
 
          CreateObservations(ACodeTool);
 
2104
        if (Mode = cemCategory) then
 
2105
        begin
 
2106
          if (cecCodeObserver in CodeExplorerOptions.Categories) then
 
2107
            CreateObservations(ACodeTool);
 
2108
          if (cecSurrounding in CodeExplorerOptions.Categories) then
 
2109
            CreateSurrounding(ACodeTool);
 
2110
        end;
1831
2111
      end;
1832
2112
 
 
2113
      // sort nodes
1833
2114
      fSortCodeTool:=ACodeTool;
1834
 
      CodeTreeview.CustomSort(@CompareCodeNodes);
 
2115
      TVNode:=CodeTreeview.Items.GetFirstNode;
 
2116
      while TVNode<>nil do begin
 
2117
        if (TVNode.GetFirstChild<>nil)
 
2118
        and (TObject(TVNode.Data) is TViewNodeData)
 
2119
        and TViewNodeData(TVNode.Data).SortChildren then begin
 
2120
          TVNode.CustomSort(@CompareCodeNodes);
 
2121
        end;
 
2122
        TVNode:=TVNode.GetNext;
 
2123
      end;
1835
2124
 
1836
2125
      DeleteDuplicates(ACodeTool);
1837
2126
 
1840
2129
        AutoExpandNodes;
1841
2130
 
1842
2131
      BuildCodeSortedForStartPos;
 
2132
      // clear references to the TCodeTreeNode to avoid dangling pointers
1843
2133
      ClearCTNodes(CodeTreeview);
1844
2134
 
1845
2135
      ApplyCodeFilter;
1846
2136
 
1847
2137
      if OldExpanded<>nil then
1848
 
        OldExpanded.Apply(CodeTreeView);
 
2138
        OldExpanded.Apply(CodeTreeView,false);
1849
2139
 
1850
2140
      if CurFollowNode then
1851
2141
        SelectCodePosition(Code,FLastCodeXY.X,FLastCodeXY.Y);
1852
2142
 
1853
2143
      CodeTreeview.EndUpdate;
1854
2144
    end;
 
2145
    Caption := lisMenuViewCodeExplorer + ' - ' + ExtractFileName(FCodeFilename);
 
2146
    if HostDockSite <> nil then
 
2147
      HostDockSite.UpdateDockCaption();
1855
2148
  finally
1856
2149
    Exclude(FFlags,cevRefreshing);
1857
2150
    OldExpanded.Free;
1942
2235
  end;
1943
2236
end;
1944
2237
 
1945
 
function TCodeExplorerView.JumpToSelection: boolean;
 
2238
function TCodeExplorerView.JumpToSelection(ToImplementation: boolean): boolean;
1946
2239
var
1947
2240
  CurItem: TTreeNode;
1948
2241
  CurNode: TViewNodeData;
1964
2257
    CurItem:=CurTreeView.Selected;
1965
2258
  if CurItem=nil then exit;
1966
2259
  CurNode:=TViewNodeData(CurItem.Data);
 
2260
  if ToImplementation then begin
 
2261
    CurNode:=CurNode.ImplementationNode;
 
2262
    if CurNode=nil then exit;
 
2263
  end;
1967
2264
  if CurNode.StartPos<1 then exit;
1968
2265
  CodeBuffer:=nil;
1969
2266
  case CurrentPage of
2037
2334
  if CurrentPage=cepCode then begin
2038
2335
    if FLastCodeValid and (fLastCodeTool<>nil) then begin
2039
2336
      CodePos:=CodeXYPosition(X,Y,CodeBuf);
 
2337
      CodeBuf.LineColToPosition(Y,X,CleanPos);
 
2338
      //debugln(['TCodeExplorerView.SelectCodePosition Code ',ExtractFileName(CodeBuf.Filename),' y=',y,' x=',x,' CleanPos=',CleanPos,' ',dbgstr(copy(CodeBuf.Source,CleanPos-20,20)),'|',dbgstr(copy(CodeBuf.Source,CleanPos,20))]);
2040
2339
      if fLastCodeTool.CaretToCleanPos(CodePos,CleanPos)<>0 then exit;
 
2340
      //debugln(['TCodeExplorerView.SelectCodePosition CleanSrc ',ExtractFileName(CodeBuf.Filename),' y=',y,' x=',x,' Tool=',ExtractFileName(fLastCodeTool.MainFilename),' ',dbgstr(copy(fLastCodeTool.Src,CleanPos-20,20)),'|',dbgstr(copy(fLastCodeTool.Src,CleanPos,20))]);
2041
2341
      TVNode:=FindCodeTVNodeAtCleanPos(CleanPos);
2042
2342
      if TVNode=nil then exit;
 
2343
      //debugln(['TCodeExplorerView.SelectCodePosition ',TVNode.Text]);
2043
2344
      CodeTreeview.BeginUpdate;
2044
2345
      CodeTreeview.Options:=CodeTreeview.Options-[tvoAllowMultiselect];
2045
2346
      if not TVNode.IsVisible then begin
2051
2352
        CodeTreeview.Selected:=TVNode;
2052
2353
        //debugln(['TCodeExplorerView.SelectCodePosition ',TVNode.Text]);
2053
2354
      end;
 
2355
      //debugln(['TCodeExplorerView.SelectCodePosition TVNode=',TVNode.Text,' Selected=',CodeTreeview.Selected=TVNode]);
2054
2356
      CodeTreeview.EndUpdate;
2055
2357
      Result:=true;
2056
2358
    end;
2057
2359
  end;
2058
2360
end;
2059
2361
 
2060
 
function TCodeExplorerView.FindCodeTVNodeAtCleanPos(CleanPos: integer
2061
 
  ): TTreeNode;
 
2362
function TCodeExplorerView.FindCodeTVNodeAtCleanPos(CleanPos: integer): TTreeNode;
2062
2363
// find TTreeNode in CodeTreeView containing the codetools clean position
2063
2364
// if there are several nodes, the one with the shortest range (EndPos-StartPos)
2064
2365
// is returned.
2065
2366
var
 
2367
  Best: TTreeNode;
 
2368
  BestStartPos, BestEndPos: integer;
 
2369
 
 
2370
  procedure Check(TVNode: TTreeNode; NodeData: TViewNodeData);
 
2371
  begin
 
2372
    if NodeData=nil then exit;
 
2373
    if (NodeData.StartPos>CleanPos) or (NodeData.EndPos<CleanPos) then exit;
 
2374
    //debugln(['FindCodeTVNodeAtCleanPos.Check TVNode="',TVNode.Text,'" NodeData="',dbgstr(copy(fLastCodeTool.Src,NodeData.StartPos,40)),'"']);
 
2375
    if (Best<>nil) then begin
 
2376
      if (BestEndPos=CleanPos) and (NodeData.EndPos>CleanPos) then begin
 
2377
        // for example  a,|b  then b is better
 
2378
      end else if BestEndPos-BestStartPos > NodeData.EndPos-NodeData.StartPos then begin
 
2379
        // smaller range is better
 
2380
      end else
 
2381
        exit;
 
2382
    end;
 
2383
    Best:=TVNode;
 
2384
    BestStartPos:=NodeData.StartPos;
 
2385
    BestEndPos:=NodeData.EndPos;
 
2386
  end;
 
2387
 
 
2388
var
2066
2389
  AVLNode: TAvgLvlTreeNode;
2067
2390
  Node: TTreeNode;
2068
2391
  NodeData: TViewNodeData;
2070
2393
  Result:=nil;
2071
2394
  if (fLastCodeTool=nil) or (not FLastCodeValid) or (CodeTreeview=nil)
2072
2395
  or (fCodeSortedForStartPos=nil) then exit;
 
2396
 
2073
2397
  // find nearest node in tree
2074
 
 
 
2398
  Best:=nil;
 
2399
  BestStartPos:=0;
 
2400
  BestEndPos:=0;
2075
2401
  AVLNode:=fCodeSortedForStartPos.FindLowest;
2076
2402
  while AVLNode<>nil do begin
2077
2403
    Node:=TTreeNode(AVLNode.Data);
2078
2404
    NodeData:=TViewNodeData(Node.Data);
2079
2405
    //debugln(['TCodeExplorerView.FindCodeTVNodeAtCleanPos Node ',NodeData.StartPos,'-',NodeData.EndPos,' ',Node.Text,' ',CleanPos]);
2080
 
    if NodeData.StartPos>CleanPos then exit;
2081
 
    if NodeData.EndPos>=CleanPos then begin
2082
 
      if (Result=nil)
2083
 
      or (NodeData.EndPos-NodeData.StartPos
2084
 
         < TViewNodeData(Result.Data).EndPos-TViewNodeData(Result.Data).StartPos)
2085
 
      then
2086
 
        Result:=Node;
2087
 
    end;
 
2406
    Check(Node,NodeData);
 
2407
    Check(Node,NodeData.ImplementationNode);
2088
2408
    AVLNode:=fCodeSortedForStartPos.FindSuccessor(AVLNode);
2089
2409
  end;
 
2410
  Result:=Best;
2090
2411
end;
2091
2412
 
2092
2413
procedure TCodeExplorerView.BuildCodeSortedForStartPos;
2095
2416
  NodeData: TViewNodeData;
2096
2417
begin
2097
2418
  if fCodeSortedForStartPos<>nil then
2098
 
   fCodeSortedForStartPos.Clear;
 
2419
    fCodeSortedForStartPos.Clear;
2099
2420
  if (CodeTreeview=nil) then exit;
2100
2421
  TVNode:=CodeTreeview.Items.GetFirstNode;
2101
2422
  while TVNode<>nil do begin
 
2423
    if TVNode.Parent=nil then begin
 
2424
      if (TVNode=fObserverNode) or (TVNode=fSurroundingNode) then break;
 
2425
    end;
2102
2426
    NodeData:=TViewNodeData(TVNode.Data);
2103
2427
    if (NodeData<>nil) and (NodeData.StartPos>0)
2104
2428
    and (NodeData.EndPos>=NodeData.StartPos) then begin
2121
2445
var
2122
2446
  TheFilter: String;
2123
2447
begin
2124
 
  TheFilter:=CodeFilterEdit.Text;
 
2448
  TheFilter:=GetCodeFilter;
2125
2449
  if FLastCodeFilter=TheFilter then exit;
2126
2450
  if (FUpdateCount>0) or (CurrentPage<>cepCode) then begin
2127
2451
    Include(FFlags,cevCodeRefreshNeeded);
2128
2452
    exit;
2129
2453
  end;
2130
 
  ApplyCodeFilter;
 
2454
  if (FLastCodeFilter='')
 
2455
  or (System.Pos(lowercase(FLastCodeFilter),lowercase(TheFilter))>0)
 
2456
  then begin
 
2457
    // longer filter => just delete nodes
 
2458
    ApplyCodeFilter;
 
2459
  end else begin
 
2460
    CheckOnIdle;
 
2461
  end;
2131
2462
end;
2132
2463
 
2133
2464
procedure TCodeExplorerView.DirectivesFilterChanged;
2147
2478
  const TheFilter: string): boolean;
2148
2479
var
2149
2480
  ChildNode: TTreeNode;
2150
 
  HasVisibleChilds: Boolean;
 
2481
  NextNode: TTreeNode;
2151
2482
begin
2152
2483
  if ANode=nil then exit(false);
2153
2484
  ChildNode:=ANode.GetFirstChild;
2154
 
  HasVisibleChilds:=false;
2155
2485
  while ChildNode<>nil do begin
2156
 
    if FilterNode(ChildNode,TheFilter) then
2157
 
      HasVisibleChilds:=true;
2158
 
    ChildNode:=ChildNode.GetNextSibling;
 
2486
    NextNode:=ChildNode.GetNextSibling;
 
2487
    FilterNode(ChildNode,TheFilter);
 
2488
    ChildNode:=NextNode;
2159
2489
  end;
2160
 
  ANode.Expanded:=HasVisibleChilds;
2161
 
  ANode.MultiSelected:=FilterFits(ANode.Text,TheFilter);
2162
 
  Result:=ANode.Expanded or ANode.MultiSelected;
 
2490
  Result:=(ANode.Parent<>nil) and (ANode.GetFirstChild=nil)
 
2491
          and (not FilterFits(ANode.Text,TheFilter));
 
2492
  //debugln(['TCodeExplorerView.FilterNode "',ANode.Text,'" Parent=',ANode.Parent<>nil,' Child=',ANode.GetFirstChild<>nil,' Filter=',FilterFits(ANode.Text,TheFilter),' Result=',Result]);
 
2493
  if Result then
 
2494
    DeleteTVNode(ANode);
2163
2495
end;
2164
2496
 
2165
 
function TCodeExplorerView.FilterFits(const NodeText, TheFilter: string
2166
 
  ): boolean;
 
2497
function TCodeExplorerView.FilterFits(const NodeText, TheFilter: string): boolean;
2167
2498
var
2168
2499
  Src: PChar;
2169
2500
  PFilter: PChar;
2172
2503
begin
2173
2504
  if TheFilter='' then begin
2174
2505
    Result:=true;
 
2506
  end else if NodeText='' then begin
 
2507
    Result:=false;
2175
2508
  end else begin
2176
2509
    Src:=PChar(NodeText);
2177
2510
    PFilter:=PChar(TheFilter);
2203
2536
  end;
2204
2537
end;
2205
2538
 
 
2539
function TCodeExplorerView.GetCTNodePath(ACodeTool: TCodeTool;
 
2540
  CodeNode: TCodeTreeNode): string;
 
2541
var
 
2542
  CurName: String;
 
2543
begin
 
2544
  Result:='';
 
2545
  while CodeNode<>nil do begin
 
2546
    CurName:='';
 
2547
    case CodeNode.Desc of
 
2548
 
 
2549
    ctnTypeDefinition,ctnVarDefinition,ctnConstDefinition,ctnUseUnit:
 
2550
      CurName:=ACodeTool.ExtractIdentifier(CodeNode.StartPos);
 
2551
 
 
2552
    ctnGenericType:
 
2553
      CurName:=ACodeTool.ExtractDefinitionName(CodeNode);
 
2554
 
 
2555
    ctnEnumIdentifier:
 
2556
      CurName:=ACodeTool.ExtractIdentifier(CodeNode.StartPos);
 
2557
 
 
2558
    ctnProcedure:
 
2559
      CurName:=ACodeTool.ExtractProcName(CodeNode,[]);
 
2560
 
 
2561
    ctnProperty:
 
2562
      CurName:=ACodeTool.ExtractPropName(CodeNode,false); // property keyword is not needed because there are icons
 
2563
 
 
2564
    end;
 
2565
    if CurName<>'' then begin
 
2566
      if Result<>'' then Result:='.'+Result;
 
2567
      Result:=CurName+Result;
 
2568
    end;
 
2569
    CodeNode:=CodeNode.Parent;
 
2570
  end;
 
2571
end;
 
2572
 
 
2573
procedure TCodeExplorerView.CreateNodePath(ACodeTool: TCodeTool;
 
2574
  aNodeData: TObject);
 
2575
var
 
2576
  NodeData: TViewNodeData absolute aNodeData;
 
2577
  AVLNode: TAvgLvlTreeNode;
 
2578
begin
 
2579
  if NodeData.CTNode.Desc=ctnProcedure then
 
2580
    NodeData.Path:=GetCTNodePath(ACodeTool,NodeData.CTNode);
 
2581
  if NodeData.Path='' then exit;
 
2582
  AVLNode:=fNodesWithPath.FindKey(NodeData,@CompareViewNodePaths);
 
2583
  if AVLNode=nil then begin
 
2584
    // unique path
 
2585
    fNodesWithPath.Add(NodeData);
 
2586
    exit;
 
2587
  end;
 
2588
  // there is already a node with this path
 
2589
  // => add params to distinguish overloads
 
2590
  NodeData.CreateParams(ACodeTool);
 
2591
  TViewNodeData(AVLNode.Data).CreateParams(ACodeTool);
 
2592
  fNodesWithPath.Add(NodeData);
 
2593
end;
 
2594
 
 
2595
procedure TCodeExplorerView.AddImplementationNode(ACodeTool: TCodeTool;
 
2596
  CodeNode: TCodeTreeNode);
 
2597
var
 
2598
  NodeData: TViewNodeData;
 
2599
  AVLNode: TAvgLvlTreeNode;
 
2600
  DeclData: TViewNodeData;
 
2601
begin
 
2602
  if (CodeNode.Desc=ctnProcedure)
 
2603
  and ((ctnsForwardDeclaration and CodeNode.SubDesc)=0) then begin
 
2604
    NodeData:=TViewNodeData.Create(CodeNode);
 
2605
    try
 
2606
      NodeData.Path:=GetCTNodePath(ACodeTool,NodeData.CTNode);
 
2607
      if NodeData.Path='' then exit;
 
2608
      //debugln(['TCodeExplorerView.AddImplementationNode Proc=',NodeData.Path]);
 
2609
      AVLNode:=fNodesWithPath.FindKey(NodeData,@CompareViewNodePaths);
 
2610
      if (AVLNode=nil) or (TViewNodeData(AVLNode.Data).ImplementationNode<>nil)
 
2611
      then begin
 
2612
        // there is no declaration, or there is already an implementation
 
2613
        // => ignore
 
2614
        exit;
 
2615
      end;
 
2616
      DeclData:=TViewNodeData(AVLNode.Data);
 
2617
      if (DeclData.Params<>'') then begin
 
2618
        // there are several nodes with this Path
 
2619
        NodeData.CreateParams(ACodeTool);
 
2620
        AVLNode:=fNodesWithPath.Find(NodeData);
 
2621
        if (AVLNode=nil) or (TViewNodeData(AVLNode.Data).ImplementationNode<>nil)
 
2622
        then begin
 
2623
          // there is no declaration, or there is already an implementation
 
2624
          // => ignore
 
2625
          exit;
 
2626
        end;
 
2627
        DeclData:=TViewNodeData(AVLNode.Data);
 
2628
      end;
 
2629
      // implementation found
 
2630
      //debugln(['TCodeExplorerView.AddImplementationNode implementation found: ',NodeData.Path,'(',NodeData.Params,')']);
 
2631
      NodeData.Desc:=CodeNode.Desc;
 
2632
      NodeData.SubDesc:=CodeNode.SubDesc;
 
2633
      NodeData.StartPos:=CodeNode.StartPos;
 
2634
      NodeData.EndPos:=CodeNode.EndPos;
 
2635
      DeclData.ImplementationNode:=NodeData;
 
2636
      NodeData:=nil;
 
2637
    finally
 
2638
      NodeData.Free;
 
2639
    end;
 
2640
  end;
 
2641
end;
 
2642
 
2206
2643
function TCodeExplorerView.CompareCodeNodes(Node1, Node2: TTreeNode): integer;
2207
2644
const
2208
2645
  SortDesc = AllIdentifierDefinitions+[ctnProcedure,ctnProperty];
2213
2650
    ctnTypeSection,
2214
2651
    ctnTypeDefinition,ctnGenericType:
2215
2652
      Result:=1;
2216
 
    ctnVarSection,ctnConstSection,ctnResStrSection,ctnLabelSection,
2217
 
    ctnVarDefinition,ctnConstDefinition,ctnProperty:
 
2653
    ctnConstSection,ctnConstDefinition:
2218
2654
      Result:=2;
 
2655
    ctnVarSection,ctnClassClassVar,ctnResStrSection,ctnLabelSection,
 
2656
    ctnVarDefinition:
 
2657
      Result:=3;
2219
2658
    ctnInterface,ctnImplementation,ctnProgram,ctnPackage,ctnLibrary,
2220
2659
    ctnProcedure:
2221
 
      Result:=3;
 
2660
      Result:=4;
 
2661
    ctnProperty:
 
2662
      Result:=5;
2222
2663
    ctnUsesSection:
2223
 
      Result:=4;
 
2664
      Result:=6;
2224
2665
 
2225
2666
    // class sections
2226
 
    ctnClassConst,
2227
 
    ctnClassType,
2228
 
    ctnClassVar,
2229
 
    ctnClassClassVar,
 
2667
    ctnClassGUID,
2230
2668
    ctnClassPrivate,
2231
2669
    ctnClassProtected,
2232
2670
    ctnClassPublic,
2233
 
    ctnClassPublished   : Result:=Desc-ctnClassConst;
 
2671
    ctnClassPublished   : Result:=Desc-ctnClassGUID;
2234
2672
    
2235
2673
    else Result:=10000;
2236
2674
    end;
2279
2717
    Result:=Stack[StackPtr-1].StatementStartPos;
2280
2718
end;
2281
2719
 
2282
 
procedure TCodeObserverStatementState.SetStatementStartPos(const AValue: integer
2283
 
  );
 
2720
procedure TCodeObserverStatementState.SetStatementStartPos(const AValue: integer);
2284
2721
begin
2285
2722
  if StackPtr=0 then
2286
2723
    TopLvlStatementStartPos:=AValue