News:

;) This forum is the property of Proton software developers

Main Menu

Looking for Help in Delphi and TVirtualStringTrees

Started by JohnB, Jul 21, 2024, 04:47 PM

Previous topic - Next topic

JohnB

I know a number of users on this forum are Delphi coders and some might be familiar with the TVirtualStringTree library.  I am trying extend the code explorer in Positron Studio to encompass the whole project i.e. the Main Bas file and all include files in the same way the ProtonIDE does it.

This is my basic structure:

type
  PItemRecord = ^TItemRecord;
  TItemRecord = record
    RecType: TItemCategory;
    Caption: String;            // Caption visible in explorer
    ImageIndex: Integer;        // Image visible in explorer
    Key: Integer;               // L0 Key to Child records or L1 Line Number or Index to Includes
    ChildCount: Integer;        // ChildCount (L0), ChildCount
  end;

  tFileTree = record
    Level: Integer;            // Level defines nesting depth. e.g. Main.Bas|
                                                                            |Main.Inc|
                                                                                     |Inc.Inc etc
                                         
    FileName: String;          // the file name of the current file
    L0CodeData: Array of TItemRecord;  // Top level Items e.g. Variables, Constants ,declares etc
    L1CodeData: Array of TItemRecord;  // Second level items e.g. SFRs, Identifiers, etc
    Includes: Array of tFileTree;      // Array of Records of Files included in main file record.
  end;

The difficulty I am having is working out how to map these to the VirtualStringTree.  The code below is the code I use currently to map onto the explorer tree.

procedure TfmCodeExplorerVT.vtCodeExplrInitNode(Sender: TBaseVirtualTree;
  ParentNode, Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
Var Level: Cardinal;
    i,j: Cardinal;
    L0Data: PItemRecord;
    L1Data: PItemRecord;
begin
  with Sender do begin
    Level := GetNodeLevel(Node);
    case Level of
    0:  begin
          i :=  Node.Index;
          L0Data := GetNodeData(Node);
          if Assigned(L0Data) then with L0Data^ do begin
            Caption := L0CodeData[i].Caption;
            RecType := L0CodeData[i].RecType;
            ImageIndex := L0CodeData[i].ImageIndex;
            if L0CodeData[i].ChildCount > 0 then begin
              Include(InitialStates, ivsHasChildren);
              Key := L0CodeData[i].Key;
              for j := 0 to L0CodeData[i].ChildCount -1 do
                AddChild(Node);
            end;
          end;
        end;
    1:  begin
          L0Data := Node.Parent.GetData;
          L1Data := GetNodeData(Node);
          if Assigned(L0Data) and Assigned(L1Data) then begin
            i := L0Data^.Key + Node.Index;
            with L1Data^ do begin
              Caption := L1CodeData[i].Caption;
              RecType := L1CodeData[i].RecType;
              ImageIndex := L1CodeData[i].ImageIndex;
              Key := L1CodeData[i].Key;
            end;
          end;
        end;
    end;
    invalidatetobottom(Node);
  end;
end;

As each source file only actually uses 2 grid levels it should be possible to map the nested files onto the VirtualStringGrid where L0 and L1 Arrays are determined when the Grid Level is an Odd and Even number.

My brain is hurting at the moment and would welcome chatting it over with someone with the right knowledge.

JohnB

John Drew

Sorry John, beyond me. I hope you receive some help as your IDE is excellent.
John D

top204

Sorry I cannot help John. I have never used a tree component in Delphi, and indirect and structures (Records) in Pascal are still quite new to me, and I have not used them a lot in Delphi.

You are a much better programmer than me in Delphi John.


JohnB

I think I am getting towards the bottom of the problem, its been particularly difficult debugging reentrant code which uses arrays of records which in themselves contain arrays of records. Its so easy to get lost.

If I can get this going it will make the application feel snappier and more responsive.
JohnB

top204

I just noticed the end of your original post. The ProtonIDE only shows the data in the file that is in focus (in the editor window), and does not show all the data from include files in the explorer as well?

JohnB

@top204
In the Proton IDE if you open a file which has a number of include statments the ProtonIDE explorer will present those nodes as expandable.  Expand any include node and you will see a list of child nodes (Variables, procs etc) in that file. Click on any child node in that include node the IDE will open that page at the line of the item in the Explorer.  This can go on to any depth and this is what I am trying to replicate.  I am not trying to merge the include file into the current open file.
JohnB

ricardourio

Hi John,

    Is it a native component ? I didn't find it in Delphi 12.1

Ricardo Urio

JohnB

@ricardourio VirtualStringTree is a Delphi open source control which can support huge data sets is extremely fast and has a very small memory footprint. Instead of holding all the tree's data within the control as in TTreeView it holds simply the tree framework with no knowledge of the data.  It relies on the application to provide the data and is entirely event driven.  Its a more difficult VCL to get to grips with but it is sooo much faster than anything else.
JohnB

JohnB

@top204
I've redesigned my database again after thinking about how the original Code explorer worked. As Studio is more Project based when you move between pages within the project I will still rebuild the Code Explorer from the main file so you will always see the whole project in the explorer even when you are focussed on an include file.
JohnB

top204

QuoteIn the Proton IDE if you open a file which has a number of include statments the ProtonIDE explorer will present those nodes as expandable.

Well I'll be blowed!! I never knew that, and after all of these years using it John. :-) But, what you don't have or know about, you can't miss. :-)

Thanks for pointing it out John.

An optional Project based IDE is much, much better.



JohnB

If a file is open which is not in the open project it will be treated as a main file in its own right and any includes within will appear as child nodes etc.
JohnB