4

I am working on a Sql editor, using TSynEdit in Delphi. I have my Object names (tables, stored procedures, domains and so on) in the Tablenames of the highlighter and Autocompletion, they show up in blue and underlined which is what i wanted but i wonder if i can make these linked to a event where i can actually open that object.

Is there a way to

a) Change the cursor to handPoint when mouse is over such keyword?

b) Execute a event, procedure, function when clicking on such keyword?

Thanks for any advice.

enter image description here

Franky Brandt
  • 193
  • 1
  • 11
  • Interesting q, because there doesn't seem to be an event triggered when a highlighter does its stuff, which would be the easiest way into this problem. I'm not a regular SynEdit user myself, but you might take a look at the answer to this q: https://stackoverflow.com/questions/6721178/delphi-simply-highlight-text-in-synedit – MartynA May 06 '18 at 06:36
  • @MartynA, such highlighting is done automatically for you in this case. It's enough to link the `TSynSQLSyn` highlighter with your `TSynEdit`, setup the `TableNameAttri` appearance and fill in the `TableNames` collection with your table names. But as you say, there is no way to setup cursor, or have an event triggered when you hover or click a table name token. – Victoria May 06 '18 at 17:30

1 Answers1

9

For getting mouse pointed token information you can write e.g. helper methods like this:

type
  TSynEditHelper = class helper for TSynEdit
  public
    function GetTokenInfo(const CursorPos: TPoint; out TokenType: Integer; out TokenText: UnicodeString): Boolean; overload;
    function GetTokenInfo(const LineCharPos: TBufferCoord; out TokenType: Integer; out TokenText: UnicodeString): Boolean; overload;
  end;

{ TSynEditHelper }

function TSynEditHelper.GetTokenInfo(const CursorPos: TPoint; out TokenType: Integer; out TokenText: UnicodeString): Boolean;
begin
  Result := GetTokenInfo(DisplayToBufferPos(PixelsToRowColumn(CursorPos.X, CursorPos.Y)), TokenType, TokenText);
end;

function TSynEditHelper.GetTokenInfo(const LineCharPos: TBufferCoord; out TokenType: Integer; out TokenText: UnicodeString): Boolean;
var
  I: Integer;
  A: TSynHighlighterAttributes;
begin
  Result := GetHighlighterAttriAtRowColEx(LineCharPos, TokenText, TokenType, I, A);
end;

And use them in the OnMouseCursor for setting the cursor and OnClick for keyword navigation:

procedure TForm1.SynEdit1Click(Sender: TObject);
var
  TokenType: Integer;
  TokenText: UnicodeString;
begin
  if TSynEdit(Sender).GetTokenInfo(TSynEdit(Sender).ScreenToClient(Mouse.CursorPos), TokenType, TokenText) and
    (TokenType = Ord(tkTableName)) then
  begin
    ShowMessage(Format('Table token clicked: %s', [TokenText]));
  end;
end;

procedure TForm1.SynEdit1MouseCursor(Sender: TObject; const ALineCharPos: TBufferCoord; var ACursor: TCursor);
var
  TokenType: Integer;
  TokenText: UnicodeString;
begin
  if TSynEdit(Sender).GetTokenInfo(ALineCharPos, TokenType, TokenText) and (TokenType = Ord(tkTableName)) then
    ACursor := crHandPoint;
end;

I couldn't find a native way for this feature.

Victoria
  • 7,822
  • 2
  • 21
  • 44
  • Thank you so much Victoria, this is exactly what i was looking for and works flawless! – Franky Brandt May 06 '18 at 17:05
  • 2
    Nice answer, bravo. Pity if there isn't a ntive way, though. +1 – MartynA May 06 '18 at 17:56
  • @MartynA, thank you! It is a pity. It would be enough if there was at least token type and text information in the `OnMouseCursor` and `OnClick` events (or maybe some kind of `OnKeywordClick` event would exist). – Victoria May 06 '18 at 18:05