View Issue Details

IDProjectCategoryView StatusLast Update
0012785PatchesIDEpublic2008-12-13 02:54
ReporterAlexander S. KleninAssigned ToMartin Friebe 
PrioritynormalSeverityminorReproducibilityN/A
Status closedResolutionfixed 
Product Version0.9.27 (SVN)Product Build 
Target Version0.9.28Fixed in Version0.9.27 (SVN) 
Summary0012785: SynEdit: Mouse Link identifiers only
DescriptionSince ctrl+click works only on user-defined identifiers,
mouse link over keywords, numbers, etc should be disabled.

TagsNo tags attached.
Fixed in Revision17816
LazTarget
Widgetset
Attached Files
  • synedit_dont_link_keywords.patch (2,097 bytes)
    Index: synedit/synedit.pp
    ===================================================================
    --- synedit/synedit.pp	(revision 16933)
    +++ synedit/synedit.pp	(working copy)
    @@ -785,6 +785,7 @@
           var Attri: TSynHighlighterAttributes): boolean;                           //L505
     
         {$IFDEF SYN_LAZARUS}
    +    function IsLinkable(Y, X1, X2: Integer): Boolean;
         procedure GetWordBoundsAtRowCol(const XY: TPoint; var StartX, EndX: integer);
         function GetLineIndentProposal(Line: integer;
                                        IgnoreCurrentLineText: boolean): integer;
    @@ -3800,7 +3801,10 @@
           exit;
         GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),
                               fLastCtrlMouseLinkX1,fLastCtrlMouseLinkX2);
    -    if fLastCtrlMouseLinkX1=fLastCtrlMouseLinkX2 then
    +    if
    +      not IsLinkable(
    +        fLastMouseCaret.Y, fLastCtrlMouseLinkX1, fLastCtrlMouseLinkX2)
    +    then
           exit;
         fLastCtrlMouseLinkY:=fLastMouseCaret.Y;
         with fMarkupCtrlMouse do begin
    @@ -6887,7 +6891,7 @@
       end;
     
     var
    -  NewY, NewX1, NewX2: integer;
    +  NewY, NewX1, NewX2: Integer;
     begin
       fLastControlIsPressed:=(GetKeyShiftState=[SYNEDIT_LINK_MODIFIER]);
       if (eoShowCtrlMouseLinks in Options) and fLastControlIsPressed
    @@ -6895,7 +6899,7 @@
         // show link
         NewY:=fLastMouseCaret.Y;
         GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),NewX1,NewX2);
    -    if NewX1<>NewX2 then begin
    +    if IsLinkable(NewY, NewX1, NewX2) then begin
           // there is a word to underline as link
           if (NewY<>fLastCtrlMouseLinkY)
           or (NewX1<>fLastCtrlMouseLinkX1)
    @@ -6964,6 +6968,16 @@
     begin
       Result:=(length(c)=1) and (c[1] in IdentChars);
     end;
    +
    +function TCustomSynEdit.IsLinkable(Y, X1, X2: Integer): Boolean;
    +begin
    +  Result :=
    +    (X1 < X2) and (Y >= 1) and (Y <= Lines.Count) and
    +    not (Lines[Y - 1][X1] in ['0'..'9']) and
    +    not (Assigned(Highlighter) and
    +      Highlighter.IsKeyword(Copy(Lines[Y - 1], X1, X2 - X1)));
    +end;
    +
     {$ENDIF}
     
     procedure TCustomSynEdit.SetBookMark(BookMark: Integer; X: Integer; Y: Integer);
    
  • synedit_mouselink_indents_only.patch (2,114 bytes)
    Index: synedit/synedit.pp
    ===================================================================
    --- synedit/synedit.pp	(revision 17024)
    +++ synedit/synedit.pp	(working copy)
    @@ -785,6 +785,7 @@
           var Attri: TSynHighlighterAttributes): boolean;                           //L505
     
         {$IFDEF SYN_LAZARUS}
    +    function IsLinkable(Y, X1, X2: Integer): Boolean;
         procedure GetWordBoundsAtRowCol(const XY: TPoint; var StartX, EndX: integer);
         function GetLineIndentProposal(Line: integer;
                                        IgnoreCurrentLineText: boolean): integer;
    @@ -3800,7 +3801,10 @@
           exit;
         GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),
                               fLastCtrlMouseLinkX1,fLastCtrlMouseLinkX2);
    -    if fLastCtrlMouseLinkX1=fLastCtrlMouseLinkX2 then
    +    if
    +      not IsLinkable(
    +        fLastMouseCaret.Y, fLastCtrlMouseLinkX1, fLastCtrlMouseLinkX2)
    +    then
           exit;
         fLastCtrlMouseLinkY:=fLastMouseCaret.Y;
         with fMarkupCtrlMouse do begin
    @@ -6887,7 +6891,7 @@
       end;
     
     var
    -  NewY, NewX1, NewX2: integer;
    +  NewY, NewX1, NewX2: Integer;
     begin
       fLastControlIsPressed:=(GetKeyShiftState=[SYNEDIT_LINK_MODIFIER]);
       if (eoShowCtrlMouseLinks in Options) and fLastControlIsPressed
    @@ -6895,7 +6899,7 @@
         // show link
         NewY:=fLastMouseCaret.Y;
         GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),NewX1,NewX2);
    -    if NewX1<>NewX2 then begin
    +    if IsLinkable(NewY, NewX1, NewX2) then begin
           // there is a word to underline as link
           if (NewY<>fLastCtrlMouseLinkY)
           or (NewX1<>fLastCtrlMouseLinkX1)
    @@ -6964,6 +6968,16 @@
     begin
       Result:=(length(c)=1) and (c[1] in IdentChars);
     end;
    +
    +function TCustomSynEdit.IsLinkable(Y, X1, X2: Integer): Boolean;
    +var
    +  tok: String;
    +  attr: TSynHighlighterAttributes;
    +  tokType, start: Integer;
    +begin
    +  Result :=
    +    GetHighlighterAttriAtRowColEx(Point(X1, Y), tok, tokType, start, attr) and
    +    (tokType = 2 {Ord(SynHighlighterPar.tkIdentifier)});
    +end;
    +
     {$ENDIF}
     
     procedure TCustomSynEdit.SetBookMark(BookMark: Integer; X: Integer; Y: Integer);
    
  • synedit_mouselink_allowed_only.patch (9,364 bytes)
    Index: components/synedit/synedit.pp
    ===================================================================
    --- components/synedit/synedit.pp	(revision 17810)
    +++ components/synedit/synedit.pp	(working copy)
    @@ -306,6 +306,9 @@
       end;
       {$ENDIF}
     
    +  TSynMouseLinkEvent = procedure (
    +    Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean) of object;
    +
       { TCustomSynEdit }
     
       TCustomSynEdit = class(TSynEditBase)
    @@ -437,6 +440,7 @@
         {$IFDEF SYN_LAZARUS}
         FOnSpecialLineMarkup: TSpecialLineMarkupEvent;// needed, because bug fpc 11926
         FOnClickLink: TMouseEvent;
    +    FOnMouseLink: TSynMouseLinkEvent;
         {$ENDIF}
     
         {$IFDEF SYN_LAZARUS}
    @@ -753,6 +757,7 @@
           var Attri: TSynHighlighterAttributes): boolean;                           //L505
     
         {$IFDEF SYN_LAZARUS}
    +    function IsLinkable(Y, X1, X2: Integer): Boolean;
         procedure GetWordBoundsAtRowCol(const XY: TPoint; var StartX, EndX: integer);
         function GetLineIndentProposal(Line: integer;
                                        IgnoreCurrentLineText: boolean): integer;
    @@ -1039,6 +1044,7 @@
         property OnMouseUp;
         {$IFDEF SYN_LAZARUS}
         property OnClickLink : TMouseEvent read FOnClickLink write FOnClickLink;
    +    property OnMouseLink: TSynMouseLinkEvent read FOnMouseLink write FOnMouseLink;
         property OnMouseEnter;
         property OnMouseLeave;
         {$ENDIF}
    @@ -3270,7 +3276,10 @@
           exit;
         GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),
                               fLastCtrlMouseLinkX1,fLastCtrlMouseLinkX2);
    -    if fLastCtrlMouseLinkX1=fLastCtrlMouseLinkX2 then
    +    if
    +      not IsLinkable(
    +        fLastMouseCaret.Y, fLastCtrlMouseLinkX1, fLastCtrlMouseLinkX2)
    +    then
           exit;
         fLastCtrlMouseLinkY:=fLastMouseCaret.Y;
         with fMarkupCtrlMouse do begin
    @@ -5998,7 +6007,7 @@
       end;
     
     var
    -  NewY, NewX1, NewX2: integer;
    +  NewY, NewX1, NewX2: Integer;
     begin
       fLastControlIsPressed:=(GetKeyShiftState=[SYNEDIT_LINK_MODIFIER]);
       if (eoShowCtrlMouseLinks in Options) and fLastControlIsPressed
    @@ -6006,7 +6015,7 @@
         // show link
         NewY:=fLastMouseCaret.Y;
         GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),NewX1,NewX2);
    -    if NewX1<>NewX2 then begin
    +    if IsLinkable(NewY, NewX1, NewX2) then begin
           // there is a word to underline as link
           if (NewY<>fLastCtrlMouseLinkY)
           or (NewX1<>fLastCtrlMouseLinkX1)
    @@ -6075,6 +6084,14 @@
     begin
       Result:=(length(c)=1) and (c[1] in IdentChars);
     end;
    +
    +function TCustomSynEdit.IsLinkable(Y, X1, X2: Integer): Boolean;
    +begin
    +  Result := true;
    +  if Assigned(FOnMouseLink) then
    +    FOnMouseLink(Self, X1, Y, Result);
    +end;
    +
     {$ENDIF}
     
     procedure TCustomSynEdit.SetBookMark(BookMark: Integer; X: Integer; Y: Integer);
    Index: ide/main.pp
    ===================================================================
    --- ide/main.pp	(revision 17810)
    +++ ide/main.pp	(working copy)
    @@ -353,6 +353,8 @@
           APageIndex: integer; DeleteForwardHistory: boolean);
         procedure OnSrcNoteBookClickLink(Sender: TObject;
           Button: TMouseButton; Shift: TShiftstate; X, Y: Integer);
    +    procedure OnSrcNoteBookMouseLink(
    +      Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
         procedure OnSrcNotebookDeleteLastJumPoint(Sender: TObject);
         procedure OnSrcNotebookEditorVisibleChanged(Sender: TObject);
         procedure OnSrcNotebookEditorChanged(Sender: TObject);
    @@ -1776,6 +1778,7 @@
       SourceNotebook.OnAddJumpPoint := @OnSrcNoteBookAddJumpPoint;
       SourceNotebook.OnCloseClicked := @OnSrcNotebookFileClose;
       SourceNotebook.OnClickLink := @OnSrcNoteBookClickLink;
    +  SourceNotebook.OnMouseLink := @OnSrcNoteBookMouseLink;
       SourceNotebook.OnCurrentCodeBufferChanged:=@OnSrcNotebookCurCodeBufferChanged;
       SourceNotebook.OnDeleteLastJumpPoint := @OnSrcNotebookDeleteLastJumPoint;
       SourceNotebook.OnEditorVisibleChanged := @OnSrcNotebookEditorVisibleChanged;
    @@ -13675,6 +13678,19 @@
       {$ENDIF}
     end;
     
    +procedure TMainIDE.OnSrcNoteBookMouseLink(
    +  Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
    +var
    +  ActiveSrcEdit: TSourceEditor;
    +  ActiveUnitInfo: TUnitInfo;
    +  NewSource: TCodeBuffer;
    +  NewX, NewY, NewTopLine: integer;
    +begin
    +  if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,[]) then exit;
    +  AllowMouseLink := CodeToolBoss.FindDeclaration(
    +    ActiveUnitInfo.Source,X,Y,NewSource,NewX,NewY,NewTopLine);
    +end;
    +
     procedure TMainIDE.OnSrcNotebookMovingPage(Sender: TObject; OldPageIndex,
       NewPageIndex: integer);
     begin
    Index: ide/sourceeditor.lfm
    ===================================================================
    --- ide/sourceeditor.lfm	(revision 17810)
    +++ ide/sourceeditor.lfm	(working copy)
    @@ -3,13 +3,11 @@
       Height = 300
       Top = 374
       Width = 400
    -  HorzScrollBar.Page = 399
    -  VertScrollBar.Page = 299
       AllowDropFiles = True
       Caption = 'SourceNotebook'
       ClientHeight = 300
       ClientWidth = 400
    -  object StatusBar: TStatusBar
    +  object StatusBar: TStatusBar[0]
         Height = 20
         Top = 280
         Width = 400
    Index: ide/sourceeditor.pp
    ===================================================================
    --- ide/sourceeditor.pp	(revision 17810)
    +++ ide/sourceeditor.pp	(working copy)
    @@ -137,6 +137,7 @@
         FOnMouseMove: TMouseMoveEvent;
         FOnMouseDown: TMouseEvent;
         FOnClickLink: TMouseEvent;
    +    FOnMouseLink: TSynMouseLinkEvent;
         FOnMouseWheel : tMouseWheelEvent;
         FOnKeyDown: TKeyEvent;
     
    @@ -147,6 +148,8 @@
               Shift: TShiftState; X,Y: Integer);
         procedure EditorClickLink(Sender: TObject; Button: TMouseButton;
               Shift: TShiftState; X,Y: Integer);
    +    procedure EditorMouseLink(
    +      Sender: TObject; X,Y: Integer; var AllowMouseLink: Boolean);
         procedure EditorMouseWheel(Sender: TObject; Shift: TShiftState;
              WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
         procedure EditorKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    @@ -361,6 +364,7 @@
         property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove;
         property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;
         property OnClickLink: TMouseEvent read FOnClickLink write FOnClickLink;
    +    property OnMouseLink: TSynMouseLinkEvent read FOnMouseLink write FOnMouseLink;
         property OnMouseWheel: TMouseWheelEvent read FOnMouseWheel write FOnMouseWheel;
         property OnKeyDown: TKeyEvent read FOnKeyDown write FOnKeyDown;
         property Owner: TComponent read FAOwner;
    @@ -475,6 +479,7 @@
         FOnAddWatchAtCursor: TOnAddWatch;
         FOnCloseClicked: TOnCloseSrcEditor;
         FOnClickLink: TMouseEvent;
    +    FOnMouseLink: TSynMouseLinkEvent;
         FOnCurrentCodeBufferChanged: TNotifyEvent;
         FOnDeleteLastJumpPoint: TNotifyEvent;
         FOnEditorChanged: TNotifyEvent;
    @@ -571,6 +576,8 @@
                                   Shift: TShiftstate; X,Y: Integer);
         procedure EditorClickLink(Sender: TObject; Button: TMouseButton;
                                 Shift: TShiftstate; X,Y: Integer);
    +    procedure EditorMouseLink(
    +      Sender: TObject; X,Y: Integer; var AllowMouseLink: Boolean);
         procedure EditorKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
         procedure EditorMouseWheel(Sender: TObject; Shift: TShiftState;
              WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    @@ -750,6 +757,7 @@
         property OnCloseClicked: TOnCloseSrcEditor
                                          read FOnCloseClicked write FOnCloseClicked;
         property OnClickLink: TMouseEvent read FOnClickLink write FOnClickLink;
    +    property OnMouseLink: TSynMouseLinkEvent read FOnMouseLink write FOnMouseLink;
         property OnDeleteLastJumpPoint: TNotifyEvent
                            read FOnDeleteLastJumpPoint write FOnDeleteLastJumpPoint;
         property OnEditorVisibleChanged: TNotifyEvent
    @@ -2257,6 +2265,7 @@
           OnMouseWheel := @EditorMouseWheel;
           OnMouseDown := @EditorMouseDown;
           OnClickLink := @EditorClickLink;
    +      OnMouseLink := @EditorMouseLink;
           OnKeyDown := @EditorKeyDown;
         end;
         if FCodeTemplates<>nil then
    @@ -2669,10 +2678,18 @@
         OnMouseDown(Sender, Button, Shift, X,Y);
     end;
     
    +procedure TSourceEditor.EditorMouseLink(
    +  Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
    +begin
    +  //DebugLn(['TSourceEditor.EditorMouseLink ',X,',',Y]);
    +  if Assigned(OnMouseLink) then
    +    OnMouseLink(Sender, X, Y, AllowMouseLink);
    +end;
    +
     procedure TSourceEditor.EditorClickLink(Sender: TObject; Button: TMouseButton;
       Shift: TShiftState; X, Y: Integer);
     begin
    -  DebugLn(['TSourceEditor.EditorClickLink ',X,',',Y]);
    +  //DebugLn(['TSourceEditor.EditorClickLink ',X,',',Y]);
       if Assigned(OnClickLink) then
         OnClickLink(Sender, Button, Shift, X,Y);
     end;
    @@ -4409,6 +4426,7 @@
       Result.OnMouseDown := @EditorMouseDown;
       Result.OnMouseWheel := @EditorMouseWheel;
       Result.OnClickLink := @EditorClickLink;
    +  Result.OnMouseLink := @EditorMouseLink;
       Result.OnKeyDown :=@EditorKeyDown;
     
       Result.EditorComponent.EndUpdate;
    @@ -6232,6 +6250,13 @@
     
     end;
     
    +procedure TSourceNotebook.EditorMouseLink(
    +  Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
    +begin
    +  if Assigned(OnMouseLink) then
    +    OnMouseLink(Sender, X, Y, AllowMouseLink);
    +end;
    +
     Procedure TSourceNotebook.HintTimer(sender: TObject);
     var
       MousePos: TPoint;
    
  • synedit_mouselink_allowed_only2.patch (8,864 bytes)
    Index: components/synedit/synedit.pp
    ===================================================================
    --- components/synedit/synedit.pp	(revision 17814)
    +++ components/synedit/synedit.pp	(working copy)
    @@ -306,6 +306,9 @@
       end;
       {$ENDIF}
     
    +  TSynMouseLinkEvent = procedure (
    +    Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean) of object;
    +
       { TCustomSynEdit }
     
       TCustomSynEdit = class(TSynEditBase)
    @@ -437,6 +440,7 @@
         {$IFDEF SYN_LAZARUS}
         FOnSpecialLineMarkup: TSpecialLineMarkupEvent;// needed, because bug fpc 11926
         FOnClickLink: TMouseEvent;
    +    FOnMouseLink: TSynMouseLinkEvent;
         {$ENDIF}
     
         {$IFDEF SYN_LAZARUS}
    @@ -753,6 +757,7 @@
           var Attri: TSynHighlighterAttributes): boolean;                           //L505
     
         {$IFDEF SYN_LAZARUS}
    +    function IsLinkable(Y, X1, X2: Integer): Boolean;
         procedure GetWordBoundsAtRowCol(const XY: TPoint; var StartX, EndX: integer);
         function GetLineIndentProposal(Line: integer;
                                        IgnoreCurrentLineText: boolean): integer;
    @@ -1039,6 +1044,7 @@
         property OnMouseUp;
         {$IFDEF SYN_LAZARUS}
         property OnClickLink : TMouseEvent read FOnClickLink write FOnClickLink;
    +    property OnMouseLink: TSynMouseLinkEvent read FOnMouseLink write FOnMouseLink;
         property OnMouseEnter;
         property OnMouseLeave;
         {$ENDIF}
    @@ -3270,7 +3276,10 @@
           exit;
         GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),
                               fLastCtrlMouseLinkX1,fLastCtrlMouseLinkX2);
    -    if fLastCtrlMouseLinkX1=fLastCtrlMouseLinkX2 then
    +    if
    +      not IsLinkable(
    +        fLastMouseCaret.Y, fLastCtrlMouseLinkX1, fLastCtrlMouseLinkX2)
    +    then
           exit;
         fLastCtrlMouseLinkY:=fLastMouseCaret.Y;
         with fMarkupCtrlMouse do begin
    @@ -5998,7 +6007,7 @@
       end;
     
     var
    -  NewY, NewX1, NewX2: integer;
    +  NewY, NewX1, NewX2: Integer;
     begin
       fLastControlIsPressed:=(GetKeyShiftState=[SYNEDIT_LINK_MODIFIER]);
       if (eoShowCtrlMouseLinks in Options) and fLastControlIsPressed
    @@ -6006,7 +6015,7 @@
         // show link
         NewY:=fLastMouseCaret.Y;
         GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),NewX1,NewX2);
    -    if NewX1<>NewX2 then begin
    +    if IsLinkable(NewY, NewX1, NewX2) then begin
           // there is a word to underline as link
           if (NewY<>fLastCtrlMouseLinkY)
           or (NewX1<>fLastCtrlMouseLinkX1)
    @@ -6075,6 +6084,14 @@
     begin
       Result:=(length(c)=1) and (c[1] in IdentChars);
     end;
    +
    +function TCustomSynEdit.IsLinkable(Y, X1, X2: Integer): Boolean;
    +begin
    +  Result := X1 <> X2;
    +  if Result and Assigned(FOnMouseLink) then
    +    FOnMouseLink(Self, X1, Y, Result);
    +end;
    +
     {$ENDIF}
     
     procedure TCustomSynEdit.SetBookMark(BookMark: Integer; X: Integer; Y: Integer);
    Index: ide/main.pp
    ===================================================================
    --- ide/main.pp	(revision 17814)
    +++ ide/main.pp	(working copy)
    @@ -353,6 +353,8 @@
           APageIndex: integer; DeleteForwardHistory: boolean);
         procedure OnSrcNoteBookClickLink(Sender: TObject;
           Button: TMouseButton; Shift: TShiftstate; X, Y: Integer);
    +    procedure OnSrcNoteBookMouseLink(
    +      Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
         procedure OnSrcNotebookDeleteLastJumPoint(Sender: TObject);
         procedure OnSrcNotebookEditorVisibleChanged(Sender: TObject);
         procedure OnSrcNotebookEditorChanged(Sender: TObject);
    @@ -1776,6 +1778,7 @@
       SourceNotebook.OnAddJumpPoint := @OnSrcNoteBookAddJumpPoint;
       SourceNotebook.OnCloseClicked := @OnSrcNotebookFileClose;
       SourceNotebook.OnClickLink := @OnSrcNoteBookClickLink;
    +  SourceNotebook.OnMouseLink := @OnSrcNoteBookMouseLink;
       SourceNotebook.OnCurrentCodeBufferChanged:=@OnSrcNotebookCurCodeBufferChanged;
       SourceNotebook.OnDeleteLastJumpPoint := @OnSrcNotebookDeleteLastJumPoint;
       SourceNotebook.OnEditorVisibleChanged := @OnSrcNotebookEditorVisibleChanged;
    @@ -13675,6 +13678,19 @@
       {$ENDIF}
     end;
     
    +procedure TMainIDE.OnSrcNoteBookMouseLink(
    +  Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
    +var
    +  ActiveSrcEdit: TSourceEditor;
    +  ActiveUnitInfo: TUnitInfo;
    +  NewSource: TCodeBuffer;
    +  NewX, NewY, NewTopLine: integer;
    +begin
    +  if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,[]) then exit;
    +  AllowMouseLink := CodeToolBoss.FindDeclaration(
    +    ActiveUnitInfo.Source,X,Y,NewSource,NewX,NewY,NewTopLine);
    +end;
    +
     procedure TMainIDE.OnSrcNotebookMovingPage(Sender: TObject; OldPageIndex,
       NewPageIndex: integer);
     begin
    Index: ide/sourceeditor.pp
    ===================================================================
    --- ide/sourceeditor.pp	(revision 17814)
    +++ ide/sourceeditor.pp	(working copy)
    @@ -137,6 +137,7 @@
         FOnMouseMove: TMouseMoveEvent;
         FOnMouseDown: TMouseEvent;
         FOnClickLink: TMouseEvent;
    +    FOnMouseLink: TSynMouseLinkEvent;
         FOnMouseWheel : tMouseWheelEvent;
         FOnKeyDown: TKeyEvent;
     
    @@ -147,6 +148,8 @@
               Shift: TShiftState; X,Y: Integer);
         procedure EditorClickLink(Sender: TObject; Button: TMouseButton;
               Shift: TShiftState; X,Y: Integer);
    +    procedure EditorMouseLink(
    +      Sender: TObject; X,Y: Integer; var AllowMouseLink: Boolean);
         procedure EditorMouseWheel(Sender: TObject; Shift: TShiftState;
              WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
         procedure EditorKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    @@ -361,6 +364,7 @@
         property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove;
         property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;
         property OnClickLink: TMouseEvent read FOnClickLink write FOnClickLink;
    +    property OnMouseLink: TSynMouseLinkEvent read FOnMouseLink write FOnMouseLink;
         property OnMouseWheel: TMouseWheelEvent read FOnMouseWheel write FOnMouseWheel;
         property OnKeyDown: TKeyEvent read FOnKeyDown write FOnKeyDown;
         property Owner: TComponent read FAOwner;
    @@ -475,6 +479,7 @@
         FOnAddWatchAtCursor: TOnAddWatch;
         FOnCloseClicked: TOnCloseSrcEditor;
         FOnClickLink: TMouseEvent;
    +    FOnMouseLink: TSynMouseLinkEvent;
         FOnCurrentCodeBufferChanged: TNotifyEvent;
         FOnDeleteLastJumpPoint: TNotifyEvent;
         FOnEditorChanged: TNotifyEvent;
    @@ -571,6 +576,8 @@
                                   Shift: TShiftstate; X,Y: Integer);
         procedure EditorClickLink(Sender: TObject; Button: TMouseButton;
                                 Shift: TShiftstate; X,Y: Integer);
    +    procedure EditorMouseLink(
    +      Sender: TObject; X,Y: Integer; var AllowMouseLink: Boolean);
         procedure EditorKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
         procedure EditorMouseWheel(Sender: TObject; Shift: TShiftState;
              WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
    @@ -750,6 +757,7 @@
         property OnCloseClicked: TOnCloseSrcEditor
                                          read FOnCloseClicked write FOnCloseClicked;
         property OnClickLink: TMouseEvent read FOnClickLink write FOnClickLink;
    +    property OnMouseLink: TSynMouseLinkEvent read FOnMouseLink write FOnMouseLink;
         property OnDeleteLastJumpPoint: TNotifyEvent
                            read FOnDeleteLastJumpPoint write FOnDeleteLastJumpPoint;
         property OnEditorVisibleChanged: TNotifyEvent
    @@ -2257,6 +2265,7 @@
           OnMouseWheel := @EditorMouseWheel;
           OnMouseDown := @EditorMouseDown;
           OnClickLink := @EditorClickLink;
    +      OnMouseLink := @EditorMouseLink;
           OnKeyDown := @EditorKeyDown;
         end;
         if FCodeTemplates<>nil then
    @@ -2669,10 +2678,18 @@
         OnMouseDown(Sender, Button, Shift, X,Y);
     end;
     
    +procedure TSourceEditor.EditorMouseLink(
    +  Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
    +begin
    +  //DebugLn(['TSourceEditor.EditorMouseLink ',X,',',Y]);
    +  if Assigned(OnMouseLink) then
    +    OnMouseLink(Sender, X, Y, AllowMouseLink);
    +end;
    +
     procedure TSourceEditor.EditorClickLink(Sender: TObject; Button: TMouseButton;
       Shift: TShiftState; X, Y: Integer);
     begin
    -  DebugLn(['TSourceEditor.EditorClickLink ',X,',',Y]);
    +  //DebugLn(['TSourceEditor.EditorClickLink ',X,',',Y]);
       if Assigned(OnClickLink) then
         OnClickLink(Sender, Button, Shift, X,Y);
     end;
    @@ -4409,6 +4426,7 @@
       Result.OnMouseDown := @EditorMouseDown;
       Result.OnMouseWheel := @EditorMouseWheel;
       Result.OnClickLink := @EditorClickLink;
    +  Result.OnMouseLink := @EditorMouseLink;
       Result.OnKeyDown :=@EditorKeyDown;
     
       Result.EditorComponent.EndUpdate;
    @@ -6232,6 +6250,13 @@
     
     end;
     
    +procedure TSourceNotebook.EditorMouseLink(
    +  Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
    +begin
    +  if Assigned(OnMouseLink) then
    +    OnMouseLink(Sender, X, Y, AllowMouseLink);
    +end;
    +
     Procedure TSourceNotebook.HintTimer(sender: TObject);
     var
       MousePos: TPoint;
    

Relationships

related to 0012790 closedMartin Friebe Lazarus SynEdit: optimize calls to CodeTools in CtrlClick mode 

Activities

2008-12-11 15:24

 

synedit_dont_link_keywords.patch (2,097 bytes)
Index: synedit/synedit.pp
===================================================================
--- synedit/synedit.pp	(revision 16933)
+++ synedit/synedit.pp	(working copy)
@@ -785,6 +785,7 @@
       var Attri: TSynHighlighterAttributes): boolean;                           //L505
 
     {$IFDEF SYN_LAZARUS}
+    function IsLinkable(Y, X1, X2: Integer): Boolean;
     procedure GetWordBoundsAtRowCol(const XY: TPoint; var StartX, EndX: integer);
     function GetLineIndentProposal(Line: integer;
                                    IgnoreCurrentLineText: boolean): integer;
@@ -3800,7 +3801,10 @@
       exit;
     GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),
                           fLastCtrlMouseLinkX1,fLastCtrlMouseLinkX2);
-    if fLastCtrlMouseLinkX1=fLastCtrlMouseLinkX2 then
+    if
+      not IsLinkable(
+        fLastMouseCaret.Y, fLastCtrlMouseLinkX1, fLastCtrlMouseLinkX2)
+    then
       exit;
     fLastCtrlMouseLinkY:=fLastMouseCaret.Y;
     with fMarkupCtrlMouse do begin
@@ -6887,7 +6891,7 @@
   end;
 
 var
-  NewY, NewX1, NewX2: integer;
+  NewY, NewX1, NewX2: Integer;
 begin
   fLastControlIsPressed:=(GetKeyShiftState=[SYNEDIT_LINK_MODIFIER]);
   if (eoShowCtrlMouseLinks in Options) and fLastControlIsPressed
@@ -6895,7 +6899,7 @@
     // show link
     NewY:=fLastMouseCaret.Y;
     GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),NewX1,NewX2);
-    if NewX1<>NewX2 then begin
+    if IsLinkable(NewY, NewX1, NewX2) then begin
       // there is a word to underline as link
       if (NewY<>fLastCtrlMouseLinkY)
       or (NewX1<>fLastCtrlMouseLinkX1)
@@ -6964,6 +6968,16 @@
 begin
   Result:=(length(c)=1) and (c[1] in IdentChars);
 end;
+
+function TCustomSynEdit.IsLinkable(Y, X1, X2: Integer): Boolean;
+begin
+  Result :=
+    (X1 < X2) and (Y >= 1) and (Y <= Lines.Count) and
+    not (Lines[Y - 1][X1] in ['0'..'9']) and
+    not (Assigned(Highlighter) and
+      Highlighter.IsKeyword(Copy(Lines[Y - 1], X1, X2 - X1)));
+end;
+
 {$ENDIF}
 
 procedure TCustomSynEdit.SetBookMark(BookMark: Integer; X: Integer; Y: Integer);

2008-12-11 15:24

 

synedit_mouselink_indents_only.patch (2,114 bytes)
Index: synedit/synedit.pp
===================================================================
--- synedit/synedit.pp	(revision 17024)
+++ synedit/synedit.pp	(working copy)
@@ -785,6 +785,7 @@
       var Attri: TSynHighlighterAttributes): boolean;                           //L505
 
     {$IFDEF SYN_LAZARUS}
+    function IsLinkable(Y, X1, X2: Integer): Boolean;
     procedure GetWordBoundsAtRowCol(const XY: TPoint; var StartX, EndX: integer);
     function GetLineIndentProposal(Line: integer;
                                    IgnoreCurrentLineText: boolean): integer;
@@ -3800,7 +3801,10 @@
       exit;
     GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),
                           fLastCtrlMouseLinkX1,fLastCtrlMouseLinkX2);
-    if fLastCtrlMouseLinkX1=fLastCtrlMouseLinkX2 then
+    if
+      not IsLinkable(
+        fLastMouseCaret.Y, fLastCtrlMouseLinkX1, fLastCtrlMouseLinkX2)
+    then
       exit;
     fLastCtrlMouseLinkY:=fLastMouseCaret.Y;
     with fMarkupCtrlMouse do begin
@@ -6887,7 +6891,7 @@
   end;
 
 var
-  NewY, NewX1, NewX2: integer;
+  NewY, NewX1, NewX2: Integer;
 begin
   fLastControlIsPressed:=(GetKeyShiftState=[SYNEDIT_LINK_MODIFIER]);
   if (eoShowCtrlMouseLinks in Options) and fLastControlIsPressed
@@ -6895,7 +6899,7 @@
     // show link
     NewY:=fLastMouseCaret.Y;
     GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),NewX1,NewX2);
-    if NewX1<>NewX2 then begin
+    if IsLinkable(NewY, NewX1, NewX2) then begin
       // there is a word to underline as link
       if (NewY<>fLastCtrlMouseLinkY)
       or (NewX1<>fLastCtrlMouseLinkX1)
@@ -6964,6 +6968,16 @@
 begin
   Result:=(length(c)=1) and (c[1] in IdentChars);
 end;
+
+function TCustomSynEdit.IsLinkable(Y, X1, X2: Integer): Boolean;
+var
+  tok: String;
+  attr: TSynHighlighterAttributes;
+  tokType, start: Integer;
+begin
+  Result :=
+    GetHighlighterAttriAtRowColEx(Point(X1, Y), tok, tokType, start, attr) and
+    (tokType = 2 {Ord(SynHighlighterPar.tkIdentifier)});
+end;
+
 {$ENDIF}
 
 procedure TCustomSynEdit.SetBookMark(BookMark: Integer; X: Integer; Y: Integer);

Alexander S. Klenin

2008-12-11 15:28

developer   ~0023765

Only one of two attached should be applied.
For motivation, discussion and differences see
"SynEdit: TSynPasSyn and keywords" and "SynEdit: Mouse Link identifiers only"
threads at mailing list.

Alexander S. Klenin

2008-12-12 08:17

developer   ~0023794

After discussion with Martin I re-implemented this
by calling CodeTools. Now underlined links are exactly clickable ones.

2008-12-12 12:10

 

synedit_mouselink_allowed_only.patch (9,364 bytes)
Index: components/synedit/synedit.pp
===================================================================
--- components/synedit/synedit.pp	(revision 17810)
+++ components/synedit/synedit.pp	(working copy)
@@ -306,6 +306,9 @@
   end;
   {$ENDIF}
 
+  TSynMouseLinkEvent = procedure (
+    Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean) of object;
+
   { TCustomSynEdit }
 
   TCustomSynEdit = class(TSynEditBase)
@@ -437,6 +440,7 @@
     {$IFDEF SYN_LAZARUS}
     FOnSpecialLineMarkup: TSpecialLineMarkupEvent;// needed, because bug fpc 11926
     FOnClickLink: TMouseEvent;
+    FOnMouseLink: TSynMouseLinkEvent;
     {$ENDIF}
 
     {$IFDEF SYN_LAZARUS}
@@ -753,6 +757,7 @@
       var Attri: TSynHighlighterAttributes): boolean;                           //L505
 
     {$IFDEF SYN_LAZARUS}
+    function IsLinkable(Y, X1, X2: Integer): Boolean;
     procedure GetWordBoundsAtRowCol(const XY: TPoint; var StartX, EndX: integer);
     function GetLineIndentProposal(Line: integer;
                                    IgnoreCurrentLineText: boolean): integer;
@@ -1039,6 +1044,7 @@
     property OnMouseUp;
     {$IFDEF SYN_LAZARUS}
     property OnClickLink : TMouseEvent read FOnClickLink write FOnClickLink;
+    property OnMouseLink: TSynMouseLinkEvent read FOnMouseLink write FOnMouseLink;
     property OnMouseEnter;
     property OnMouseLeave;
     {$ENDIF}
@@ -3270,7 +3276,10 @@
       exit;
     GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),
                           fLastCtrlMouseLinkX1,fLastCtrlMouseLinkX2);
-    if fLastCtrlMouseLinkX1=fLastCtrlMouseLinkX2 then
+    if
+      not IsLinkable(
+        fLastMouseCaret.Y, fLastCtrlMouseLinkX1, fLastCtrlMouseLinkX2)
+    then
       exit;
     fLastCtrlMouseLinkY:=fLastMouseCaret.Y;
     with fMarkupCtrlMouse do begin
@@ -5998,7 +6007,7 @@
   end;
 
 var
-  NewY, NewX1, NewX2: integer;
+  NewY, NewX1, NewX2: Integer;
 begin
   fLastControlIsPressed:=(GetKeyShiftState=[SYNEDIT_LINK_MODIFIER]);
   if (eoShowCtrlMouseLinks in Options) and fLastControlIsPressed
@@ -6006,7 +6015,7 @@
     // show link
     NewY:=fLastMouseCaret.Y;
     GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),NewX1,NewX2);
-    if NewX1<>NewX2 then begin
+    if IsLinkable(NewY, NewX1, NewX2) then begin
       // there is a word to underline as link
       if (NewY<>fLastCtrlMouseLinkY)
       or (NewX1<>fLastCtrlMouseLinkX1)
@@ -6075,6 +6084,14 @@
 begin
   Result:=(length(c)=1) and (c[1] in IdentChars);
 end;
+
+function TCustomSynEdit.IsLinkable(Y, X1, X2: Integer): Boolean;
+begin
+  Result := true;
+  if Assigned(FOnMouseLink) then
+    FOnMouseLink(Self, X1, Y, Result);
+end;
+
 {$ENDIF}
 
 procedure TCustomSynEdit.SetBookMark(BookMark: Integer; X: Integer; Y: Integer);
Index: ide/main.pp
===================================================================
--- ide/main.pp	(revision 17810)
+++ ide/main.pp	(working copy)
@@ -353,6 +353,8 @@
       APageIndex: integer; DeleteForwardHistory: boolean);
     procedure OnSrcNoteBookClickLink(Sender: TObject;
       Button: TMouseButton; Shift: TShiftstate; X, Y: Integer);
+    procedure OnSrcNoteBookMouseLink(
+      Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
     procedure OnSrcNotebookDeleteLastJumPoint(Sender: TObject);
     procedure OnSrcNotebookEditorVisibleChanged(Sender: TObject);
     procedure OnSrcNotebookEditorChanged(Sender: TObject);
@@ -1776,6 +1778,7 @@
   SourceNotebook.OnAddJumpPoint := @OnSrcNoteBookAddJumpPoint;
   SourceNotebook.OnCloseClicked := @OnSrcNotebookFileClose;
   SourceNotebook.OnClickLink := @OnSrcNoteBookClickLink;
+  SourceNotebook.OnMouseLink := @OnSrcNoteBookMouseLink;
   SourceNotebook.OnCurrentCodeBufferChanged:=@OnSrcNotebookCurCodeBufferChanged;
   SourceNotebook.OnDeleteLastJumpPoint := @OnSrcNotebookDeleteLastJumPoint;
   SourceNotebook.OnEditorVisibleChanged := @OnSrcNotebookEditorVisibleChanged;
@@ -13675,6 +13678,19 @@
   {$ENDIF}
 end;
 
+procedure TMainIDE.OnSrcNoteBookMouseLink(
+  Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
+var
+  ActiveSrcEdit: TSourceEditor;
+  ActiveUnitInfo: TUnitInfo;
+  NewSource: TCodeBuffer;
+  NewX, NewY, NewTopLine: integer;
+begin
+  if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,[]) then exit;
+  AllowMouseLink := CodeToolBoss.FindDeclaration(
+    ActiveUnitInfo.Source,X,Y,NewSource,NewX,NewY,NewTopLine);
+end;
+
 procedure TMainIDE.OnSrcNotebookMovingPage(Sender: TObject; OldPageIndex,
   NewPageIndex: integer);
 begin
Index: ide/sourceeditor.lfm
===================================================================
--- ide/sourceeditor.lfm	(revision 17810)
+++ ide/sourceeditor.lfm	(working copy)
@@ -3,13 +3,11 @@
   Height = 300
   Top = 374
   Width = 400
-  HorzScrollBar.Page = 399
-  VertScrollBar.Page = 299
   AllowDropFiles = True
   Caption = 'SourceNotebook'
   ClientHeight = 300
   ClientWidth = 400
-  object StatusBar: TStatusBar
+  object StatusBar: TStatusBar[0]
     Height = 20
     Top = 280
     Width = 400
Index: ide/sourceeditor.pp
===================================================================
--- ide/sourceeditor.pp	(revision 17810)
+++ ide/sourceeditor.pp	(working copy)
@@ -137,6 +137,7 @@
     FOnMouseMove: TMouseMoveEvent;
     FOnMouseDown: TMouseEvent;
     FOnClickLink: TMouseEvent;
+    FOnMouseLink: TSynMouseLinkEvent;
     FOnMouseWheel : tMouseWheelEvent;
     FOnKeyDown: TKeyEvent;
 
@@ -147,6 +148,8 @@
           Shift: TShiftState; X,Y: Integer);
     procedure EditorClickLink(Sender: TObject; Button: TMouseButton;
           Shift: TShiftState; X,Y: Integer);
+    procedure EditorMouseLink(
+      Sender: TObject; X,Y: Integer; var AllowMouseLink: Boolean);
     procedure EditorMouseWheel(Sender: TObject; Shift: TShiftState;
          WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
     procedure EditorKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
@@ -361,6 +364,7 @@
     property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove;
     property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;
     property OnClickLink: TMouseEvent read FOnClickLink write FOnClickLink;
+    property OnMouseLink: TSynMouseLinkEvent read FOnMouseLink write FOnMouseLink;
     property OnMouseWheel: TMouseWheelEvent read FOnMouseWheel write FOnMouseWheel;
     property OnKeyDown: TKeyEvent read FOnKeyDown write FOnKeyDown;
     property Owner: TComponent read FAOwner;
@@ -475,6 +479,7 @@
     FOnAddWatchAtCursor: TOnAddWatch;
     FOnCloseClicked: TOnCloseSrcEditor;
     FOnClickLink: TMouseEvent;
+    FOnMouseLink: TSynMouseLinkEvent;
     FOnCurrentCodeBufferChanged: TNotifyEvent;
     FOnDeleteLastJumpPoint: TNotifyEvent;
     FOnEditorChanged: TNotifyEvent;
@@ -571,6 +576,8 @@
                               Shift: TShiftstate; X,Y: Integer);
     procedure EditorClickLink(Sender: TObject; Button: TMouseButton;
                             Shift: TShiftstate; X,Y: Integer);
+    procedure EditorMouseLink(
+      Sender: TObject; X,Y: Integer; var AllowMouseLink: Boolean);
     procedure EditorKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
     procedure EditorMouseWheel(Sender: TObject; Shift: TShiftState;
          WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
@@ -750,6 +757,7 @@
     property OnCloseClicked: TOnCloseSrcEditor
                                      read FOnCloseClicked write FOnCloseClicked;
     property OnClickLink: TMouseEvent read FOnClickLink write FOnClickLink;
+    property OnMouseLink: TSynMouseLinkEvent read FOnMouseLink write FOnMouseLink;
     property OnDeleteLastJumpPoint: TNotifyEvent
                        read FOnDeleteLastJumpPoint write FOnDeleteLastJumpPoint;
     property OnEditorVisibleChanged: TNotifyEvent
@@ -2257,6 +2265,7 @@
       OnMouseWheel := @EditorMouseWheel;
       OnMouseDown := @EditorMouseDown;
       OnClickLink := @EditorClickLink;
+      OnMouseLink := @EditorMouseLink;
       OnKeyDown := @EditorKeyDown;
     end;
     if FCodeTemplates<>nil then
@@ -2669,10 +2678,18 @@
     OnMouseDown(Sender, Button, Shift, X,Y);
 end;
 
+procedure TSourceEditor.EditorMouseLink(
+  Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
+begin
+  //DebugLn(['TSourceEditor.EditorMouseLink ',X,',',Y]);
+  if Assigned(OnMouseLink) then
+    OnMouseLink(Sender, X, Y, AllowMouseLink);
+end;
+
 procedure TSourceEditor.EditorClickLink(Sender: TObject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Integer);
 begin
-  DebugLn(['TSourceEditor.EditorClickLink ',X,',',Y]);
+  //DebugLn(['TSourceEditor.EditorClickLink ',X,',',Y]);
   if Assigned(OnClickLink) then
     OnClickLink(Sender, Button, Shift, X,Y);
 end;
@@ -4409,6 +4426,7 @@
   Result.OnMouseDown := @EditorMouseDown;
   Result.OnMouseWheel := @EditorMouseWheel;
   Result.OnClickLink := @EditorClickLink;
+  Result.OnMouseLink := @EditorMouseLink;
   Result.OnKeyDown :=@EditorKeyDown;
 
   Result.EditorComponent.EndUpdate;
@@ -6232,6 +6250,13 @@
 
 end;
 
+procedure TSourceNotebook.EditorMouseLink(
+  Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
+begin
+  if Assigned(OnMouseLink) then
+    OnMouseLink(Sender, X, Y, AllowMouseLink);
+end;
+
 Procedure TSourceNotebook.HintTimer(sender: TObject);
 var
   MousePos: TPoint;

2008-12-12 20:50

 

synedit_mouselink_allowed_only2.patch (8,864 bytes)
Index: components/synedit/synedit.pp
===================================================================
--- components/synedit/synedit.pp	(revision 17814)
+++ components/synedit/synedit.pp	(working copy)
@@ -306,6 +306,9 @@
   end;
   {$ENDIF}
 
+  TSynMouseLinkEvent = procedure (
+    Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean) of object;
+
   { TCustomSynEdit }
 
   TCustomSynEdit = class(TSynEditBase)
@@ -437,6 +440,7 @@
     {$IFDEF SYN_LAZARUS}
     FOnSpecialLineMarkup: TSpecialLineMarkupEvent;// needed, because bug fpc 11926
     FOnClickLink: TMouseEvent;
+    FOnMouseLink: TSynMouseLinkEvent;
     {$ENDIF}
 
     {$IFDEF SYN_LAZARUS}
@@ -753,6 +757,7 @@
       var Attri: TSynHighlighterAttributes): boolean;                           //L505
 
     {$IFDEF SYN_LAZARUS}
+    function IsLinkable(Y, X1, X2: Integer): Boolean;
     procedure GetWordBoundsAtRowCol(const XY: TPoint; var StartX, EndX: integer);
     function GetLineIndentProposal(Line: integer;
                                    IgnoreCurrentLineText: boolean): integer;
@@ -1039,6 +1044,7 @@
     property OnMouseUp;
     {$IFDEF SYN_LAZARUS}
     property OnClickLink : TMouseEvent read FOnClickLink write FOnClickLink;
+    property OnMouseLink: TSynMouseLinkEvent read FOnMouseLink write FOnMouseLink;
     property OnMouseEnter;
     property OnMouseLeave;
     {$ENDIF}
@@ -3270,7 +3276,10 @@
       exit;
     GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),
                           fLastCtrlMouseLinkX1,fLastCtrlMouseLinkX2);
-    if fLastCtrlMouseLinkX1=fLastCtrlMouseLinkX2 then
+    if
+      not IsLinkable(
+        fLastMouseCaret.Y, fLastCtrlMouseLinkX1, fLastCtrlMouseLinkX2)
+    then
       exit;
     fLastCtrlMouseLinkY:=fLastMouseCaret.Y;
     with fMarkupCtrlMouse do begin
@@ -5998,7 +6007,7 @@
   end;
 
 var
-  NewY, NewX1, NewX2: integer;
+  NewY, NewX1, NewX2: Integer;
 begin
   fLastControlIsPressed:=(GetKeyShiftState=[SYNEDIT_LINK_MODIFIER]);
   if (eoShowCtrlMouseLinks in Options) and fLastControlIsPressed
@@ -6006,7 +6015,7 @@
     // show link
     NewY:=fLastMouseCaret.Y;
     GetWordBoundsAtRowCol(PhysicalToLogicalPos(fLastMouseCaret),NewX1,NewX2);
-    if NewX1<>NewX2 then begin
+    if IsLinkable(NewY, NewX1, NewX2) then begin
       // there is a word to underline as link
       if (NewY<>fLastCtrlMouseLinkY)
       or (NewX1<>fLastCtrlMouseLinkX1)
@@ -6075,6 +6084,14 @@
 begin
   Result:=(length(c)=1) and (c[1] in IdentChars);
 end;
+
+function TCustomSynEdit.IsLinkable(Y, X1, X2: Integer): Boolean;
+begin
+  Result := X1 <> X2;
+  if Result and Assigned(FOnMouseLink) then
+    FOnMouseLink(Self, X1, Y, Result);
+end;
+
 {$ENDIF}
 
 procedure TCustomSynEdit.SetBookMark(BookMark: Integer; X: Integer; Y: Integer);
Index: ide/main.pp
===================================================================
--- ide/main.pp	(revision 17814)
+++ ide/main.pp	(working copy)
@@ -353,6 +353,8 @@
       APageIndex: integer; DeleteForwardHistory: boolean);
     procedure OnSrcNoteBookClickLink(Sender: TObject;
       Button: TMouseButton; Shift: TShiftstate; X, Y: Integer);
+    procedure OnSrcNoteBookMouseLink(
+      Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
     procedure OnSrcNotebookDeleteLastJumPoint(Sender: TObject);
     procedure OnSrcNotebookEditorVisibleChanged(Sender: TObject);
     procedure OnSrcNotebookEditorChanged(Sender: TObject);
@@ -1776,6 +1778,7 @@
   SourceNotebook.OnAddJumpPoint := @OnSrcNoteBookAddJumpPoint;
   SourceNotebook.OnCloseClicked := @OnSrcNotebookFileClose;
   SourceNotebook.OnClickLink := @OnSrcNoteBookClickLink;
+  SourceNotebook.OnMouseLink := @OnSrcNoteBookMouseLink;
   SourceNotebook.OnCurrentCodeBufferChanged:=@OnSrcNotebookCurCodeBufferChanged;
   SourceNotebook.OnDeleteLastJumpPoint := @OnSrcNotebookDeleteLastJumPoint;
   SourceNotebook.OnEditorVisibleChanged := @OnSrcNotebookEditorVisibleChanged;
@@ -13675,6 +13678,19 @@
   {$ENDIF}
 end;
 
+procedure TMainIDE.OnSrcNoteBookMouseLink(
+  Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
+var
+  ActiveSrcEdit: TSourceEditor;
+  ActiveUnitInfo: TUnitInfo;
+  NewSource: TCodeBuffer;
+  NewX, NewY, NewTopLine: integer;
+begin
+  if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,[]) then exit;
+  AllowMouseLink := CodeToolBoss.FindDeclaration(
+    ActiveUnitInfo.Source,X,Y,NewSource,NewX,NewY,NewTopLine);
+end;
+
 procedure TMainIDE.OnSrcNotebookMovingPage(Sender: TObject; OldPageIndex,
   NewPageIndex: integer);
 begin
Index: ide/sourceeditor.pp
===================================================================
--- ide/sourceeditor.pp	(revision 17814)
+++ ide/sourceeditor.pp	(working copy)
@@ -137,6 +137,7 @@
     FOnMouseMove: TMouseMoveEvent;
     FOnMouseDown: TMouseEvent;
     FOnClickLink: TMouseEvent;
+    FOnMouseLink: TSynMouseLinkEvent;
     FOnMouseWheel : tMouseWheelEvent;
     FOnKeyDown: TKeyEvent;
 
@@ -147,6 +148,8 @@
           Shift: TShiftState; X,Y: Integer);
     procedure EditorClickLink(Sender: TObject; Button: TMouseButton;
           Shift: TShiftState; X,Y: Integer);
+    procedure EditorMouseLink(
+      Sender: TObject; X,Y: Integer; var AllowMouseLink: Boolean);
     procedure EditorMouseWheel(Sender: TObject; Shift: TShiftState;
          WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
     procedure EditorKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
@@ -361,6 +364,7 @@
     property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove;
     property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;
     property OnClickLink: TMouseEvent read FOnClickLink write FOnClickLink;
+    property OnMouseLink: TSynMouseLinkEvent read FOnMouseLink write FOnMouseLink;
     property OnMouseWheel: TMouseWheelEvent read FOnMouseWheel write FOnMouseWheel;
     property OnKeyDown: TKeyEvent read FOnKeyDown write FOnKeyDown;
     property Owner: TComponent read FAOwner;
@@ -475,6 +479,7 @@
     FOnAddWatchAtCursor: TOnAddWatch;
     FOnCloseClicked: TOnCloseSrcEditor;
     FOnClickLink: TMouseEvent;
+    FOnMouseLink: TSynMouseLinkEvent;
     FOnCurrentCodeBufferChanged: TNotifyEvent;
     FOnDeleteLastJumpPoint: TNotifyEvent;
     FOnEditorChanged: TNotifyEvent;
@@ -571,6 +576,8 @@
                               Shift: TShiftstate; X,Y: Integer);
     procedure EditorClickLink(Sender: TObject; Button: TMouseButton;
                             Shift: TShiftstate; X,Y: Integer);
+    procedure EditorMouseLink(
+      Sender: TObject; X,Y: Integer; var AllowMouseLink: Boolean);
     procedure EditorKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
     procedure EditorMouseWheel(Sender: TObject; Shift: TShiftState;
          WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
@@ -750,6 +757,7 @@
     property OnCloseClicked: TOnCloseSrcEditor
                                      read FOnCloseClicked write FOnCloseClicked;
     property OnClickLink: TMouseEvent read FOnClickLink write FOnClickLink;
+    property OnMouseLink: TSynMouseLinkEvent read FOnMouseLink write FOnMouseLink;
     property OnDeleteLastJumpPoint: TNotifyEvent
                        read FOnDeleteLastJumpPoint write FOnDeleteLastJumpPoint;
     property OnEditorVisibleChanged: TNotifyEvent
@@ -2257,6 +2265,7 @@
       OnMouseWheel := @EditorMouseWheel;
       OnMouseDown := @EditorMouseDown;
       OnClickLink := @EditorClickLink;
+      OnMouseLink := @EditorMouseLink;
       OnKeyDown := @EditorKeyDown;
     end;
     if FCodeTemplates<>nil then
@@ -2669,10 +2678,18 @@
     OnMouseDown(Sender, Button, Shift, X,Y);
 end;
 
+procedure TSourceEditor.EditorMouseLink(
+  Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
+begin
+  //DebugLn(['TSourceEditor.EditorMouseLink ',X,',',Y]);
+  if Assigned(OnMouseLink) then
+    OnMouseLink(Sender, X, Y, AllowMouseLink);
+end;
+
 procedure TSourceEditor.EditorClickLink(Sender: TObject; Button: TMouseButton;
   Shift: TShiftState; X, Y: Integer);
 begin
-  DebugLn(['TSourceEditor.EditorClickLink ',X,',',Y]);
+  //DebugLn(['TSourceEditor.EditorClickLink ',X,',',Y]);
   if Assigned(OnClickLink) then
     OnClickLink(Sender, Button, Shift, X,Y);
 end;
@@ -4409,6 +4426,7 @@
   Result.OnMouseDown := @EditorMouseDown;
   Result.OnMouseWheel := @EditorMouseWheel;
   Result.OnClickLink := @EditorClickLink;
+  Result.OnMouseLink := @EditorMouseLink;
   Result.OnKeyDown :=@EditorKeyDown;
 
   Result.EditorComponent.EndUpdate;
@@ -6232,6 +6250,13 @@
 
 end;
 
+procedure TSourceNotebook.EditorMouseLink(
+  Sender: TObject; X, Y: Integer; var AllowMouseLink: Boolean);
+begin
+  if Assigned(OnMouseLink) then
+    OnMouseLink(Sender, X, Y, AllowMouseLink);
+end;
+
 Procedure TSourceNotebook.HintTimer(sender: TObject);
 var
   MousePos: TPoint;

Issue History

Date Modified Username Field Change
2008-12-11 15:24 Alexander S. Klenin New Issue
2008-12-11 15:24 Alexander S. Klenin File Added: synedit_dont_link_keywords.patch
2008-12-11 15:24 Alexander S. Klenin File Added: synedit_mouselink_indents_only.patch
2008-12-11 15:28 Alexander S. Klenin Note Added: 0023765
2008-12-11 16:28 Martin Friebe Status new => assigned
2008-12-11 16:28 Martin Friebe Assigned To => Martin Friebe
2008-12-12 08:17 Alexander S. Klenin Note Added: 0023794
2008-12-12 12:10 Alexander S. Klenin File Added: synedit_mouselink_allowed_only.patch
2008-12-12 20:50 Martin Friebe File Added: synedit_mouselink_allowed_only2.patch
2008-12-12 22:32 Martin Friebe Fixed in Revision => 17816
2008-12-12 22:32 Martin Friebe Status assigned => resolved
2008-12-12 22:32 Martin Friebe Fixed in Version => 0.9.27 (SVN)
2008-12-12 22:32 Martin Friebe Resolution open => fixed
2008-12-12 22:32 Martin Friebe Target Version => 0.9.28
2008-12-13 02:49 Alexander S. Klenin Status resolved => closed
2008-12-13 15:25 Martin Friebe Relationship added related to 0012790