IDE+object inspector: shwoing code help hints for properties

git-svn-id: trunk@17478 -
This commit is contained in:
mattias 2008-11-20 16:27:27 +00:00
parent 7c665e0d4c
commit 04b8a93513
6 changed files with 234 additions and 190 deletions

View File

@ -74,6 +74,7 @@ function FindDeclarationOfOIProperty(AnInspector: TObjectInspectorDlg;
Row: TOIPropertyGridRow; out Code: TCodeBuffer; out Caret: TPoint;
out NewTopLine: integer): Boolean;
implementation
function CreateDefaultOIFavouriteProperties: TOIFavouriteProperties;

View File

@ -163,6 +163,9 @@ type
var ErrMsg: string): TShowHelpResult; override;
procedure ShowHelpForMessage(Line: integer); override;
procedure ShowHelpForObjectInspector(Sender: TObject); override;
function CreateHint(aHintWindow: THintWindow; ScreenPos: TPoint;
const BaseURL: string; var TheHint: string;
out HintWinRect: TRect): boolean; override;
function GetHintForSourcePosition(const ExpandedFilename: string;
const CodePos: TPoint;
out BaseURL, HTMLHint: string): TShowHelpResult;
@ -1245,6 +1248,50 @@ begin
end;
end;
function TIDEHelpManager.CreateHint(aHintWindow: THintWindow; ScreenPos: TPoint;
const BaseURL: string; var TheHint: string; out HintWinRect: TRect): boolean;
var
IsHTML: Boolean;
Provider: TAbstractIDEHTMLProvider;
HTMLControl: TControl;
ms: TMemoryStream;
NewWidth, NewHeight: integer;
begin
IsHTML:=SysUtils.CompareText(copy(TheHint,1,6),'<HTML>')=0;
if aHintWindow.ControlCount>0 then begin
aHintWindow.Controls[0].Free;
end;
if IsHTML then begin
Provider:=nil;
HTMLControl:=CreateIDEHTMLControl(aHintWindow,Provider);
Provider.BaseURL:=BaseURL;
HTMLControl.Parent:=aHintWindow;
HTMLControl.Align:=alClient;
ms:=TMemoryStream.Create;
try
if TheHint<>'' then
ms.Write(TheHint[1],length(TheHint));
ms.Position:=0;
Provider.ControlIntf.SetHTMLContent(ms);
finally
ms.Free;
end;
Provider.ControlIntf.GetPreferredControlSize(NewWidth,NewHeight);
if NewWidth<=0 then
NewWidth:=500;
if NewHeight<=0 then
NewHeight:=200;
HintWinRect := Rect(0,0,NewWidth,NewHeight);
TheHint:='';
end else begin
HintWinRect := aHintWindow.CalcHintRect(Screen.Width, TheHint, nil);
end;
OffsetRect(HintWinRect, ScreenPos.X, ScreenPos.Y+30);
Result:=true;
end;
function TIDEHelpManager.GetHintForSourcePosition(const ExpandedFilename: string;
const CodePos: TPoint; out BaseURL, HTMLHint: string): TShowHelpResult;
var

View File

@ -75,7 +75,7 @@ uses
// lcl
LCLProc, LCLMemManager, LCLType, LCLIntf, LConvEncoding, LMessages,
LResources, StdCtrls, Forms, Buttons, Menus, FileUtil, Controls, GraphType,
Graphics, ExtCtrls, Dialogs, InterfaceBase, LDockCtrl,
HelpIntfs, Graphics, ExtCtrls, Dialogs, InterfaceBase, LDockCtrl,
// codetools
LinkScanner, BasicCodeTools, AVL_Tree, Laz_XMLCfg,
CodeToolsStructs, CodeToolManager, CodeCache, DefineTemplates,
@ -83,8 +83,8 @@ uses
SynEditKeyCmds,
// IDE interface
AllIDEIntf, BaseIDEIntf, ObjectInspector, PropEdits, MacroIntf, IDECommands,
SrcEditorIntf, NewItemIntf, IDEExternToolIntf, IDEMsgIntf, PackageIntf,
ProjectIntf, MenuIntf, LazIDEIntf, IDEDialogs,
SrcEditorIntf, NewItemIntf, IDEExternToolIntf, IDEMsgIntf,
PackageIntf, ProjectIntf, MenuIntf, LazIDEIntf, IDEDialogs,
// protocol
IDEProtocol,
// compile
@ -390,8 +390,11 @@ type
procedure OIOnAddToFavourites(Sender: TObject);
procedure OIOnRemoveFromFavourites(Sender: TObject);
procedure OIOnFindDeclarationOfProperty(Sender: TObject);
procedure OIOnUpdateRestricted(Sender: TObject);
procedure OIOnSelectionChange(Sender: TObject);
function OIOnPropertyHint(Sender: TObject; PointedRow: TOIPropertyGridRow;
ScreenPos: TPoint; aHintWindow: THintWindow;
out HintWinRect: TRect; out AHint: string): boolean;
procedure OIOnUpdateRestricted(Sender: TObject);
function OnPropHookGetMethodName(const Method: TMethod;
PropOwner: TObject): String;
procedure OnPropHookGetMethods(TypeData: PTypeData; Proc:TGetStringProc);
@ -1380,6 +1383,34 @@ begin
end;
end;
procedure TMainIDE.OIOnSelectionChange(Sender: TObject);
begin
// handled by property hook
end;
function TMainIDE.OIOnPropertyHint(Sender: TObject;
PointedRow: TOIPropertyGridRow; ScreenPos: TPoint; aHintWindow: THintWindow;
out HintWinRect: TRect; out AHint: string): boolean;
var
Code: TCodeBuffer;
Caret: TPoint;
NewTopLine: integer;
BaseURL: string;
begin
Result:=false;
AHint:='';
HintWinRect:=Rect(0,0,0,0);
if not BeginCodeTools then exit;
if FindDeclarationOfOIProperty(ObjectInspector1,PointedRow,Code,Caret,NewTopLine)
then begin
if TIDEHelpManager(HelpBoss).GetHintForSourcePosition(Code.Filename,
Caret,BaseURL,aHint)=shrSuccess
then begin
Result:=HelpBoss.CreateHint(aHintWindow,ScreenPos,BaseURL,aHint,HintWinRect);
end;
end;
end;
procedure TMainIDE.OIOnUpdateRestricted(Sender: TObject);
begin
if Sender = nil then Sender := ObjectInspector1;
@ -1389,49 +1420,6 @@ begin
end;
end;
procedure TMainIDE.OIOnSelectionChange(Sender: TObject);
var
OI: TObjectInspectorDlg absolute Sender;
Row: TOIPropertyGridRow;
Code: TCodeBuffer;
Caret: TPoint;
NewTopLine: integer;
BaseURL, HTMLHint: String;
CacheWasUsed: Boolean;
Stream: TStringStream;
begin
if (Sender is TObjectInspectorDlg) then
begin
if OI.ShowInfoBox then
begin
Row := OI.GetActivePropertyRow;
Stream := nil;
if (Row <> nil) and FindDeclarationOfOIProperty(OI, Row, Code, Caret, NewTopLine) then
begin
if CodeHelpBoss.GetHTMLHint(Code, Caret.X, Caret.Y, True, BaseURL, HTMLHint, CacheWasUsed) = chprSuccess then
begin
FOIHelpProvider.BaseURL := BaseURL;
Stream := TStringStream.Create(HTMLHint);
try
FOIHelpProvider.ControlIntf.SetHTMLContent(Stream);
finally
Stream.Free;
end;
end;
end;
if Stream = nil then
begin
Stream := TStringStream.Create('');
try
FOIHelpProvider.ControlIntf.SetHTMLContent(Stream);
finally
Stream.Free;
end;
end;
end;
end;
end;
function TMainIDE.OnPropHookGetMethodName(const Method: TMethod;
PropOwner: TObject): String;
var
@ -1694,6 +1682,7 @@ begin
ObjectInspector1.OnShowOptions:=@OIOnShowOptions;
ObjectInspector1.OnViewRestricted:=@OIOnViewRestricted;
ObjectInspector1.OnSelectionChange:=@OIOnSelectionChange;
ObjectInspector1.OnPropertyHint:=@OIOnPropertyHint;
ObjectInspector1.OnDestroy:=@OIOnDestroy;
HelpControl := CreateIDEHTMLControl(ObjectInspector1, FOIHelpProvider);
HelpControl.Parent := ObjectInspector1.InfoPanel;

View File

@ -5089,51 +5089,16 @@ procedure TSourceNotebook.ActivateHint(const ScreenPos: TPoint;
const BaseURL, TheHint: string);
var
HintWinRect: TRect;
IsHTML: Boolean;
Provider: TAbstractIDEHTMLProvider;
HTMLControl: TControl;
ms: TMemoryStream;
NewWidth, NewHeight: integer;
AHint: String;
begin
if csDestroying in ComponentState then exit;
if FHintWindow<>nil then
FHintWindow.Visible:=false;
if FHintWindow=nil then
FHintWindow:=THintWindow.Create(Self);
IsHTML:=SysUtils.CompareText(copy(TheHint,1,6),'<HTML>')=0;
//DebugLn(['TSourceNotebook.ActivateHint IsHTML=',IsHTML,' TheHint=',TheHint]);
if FHintWindow.ControlCount>0 then begin
//DebugLn(['TSourceNotebook.ActivateHint ',dbgsName(FHintWindow.Controls[0])]);
FHintWindow.Controls[0].Free;
end;
if IsHTML then begin
Provider:=nil;
HTMLControl:=CreateIDEHTMLControl(FHintWindow,Provider);
Provider.BaseURL:=BaseURL;
HTMLControl.Parent:=FHintWindow;
HTMLControl.Align:=alClient;
ms:=TMemoryStream.Create;
try
if TheHint<>'' then
ms.Write(TheHint[1],length(TheHint));
ms.Position:=0;
Provider.ControlIntf.SetHTMLContent(ms);
finally
ms.Free;
end;
Provider.ControlIntf.GetPreferredControlSize(NewWidth,NewHeight);
if NewWidth<=0 then
NewWidth:=500;
if NewHeight<=0 then
NewHeight:=200;
HintWinRect := Rect(0,0,NewWidth,NewHeight);
OffsetRect(HintWinRect, ScreenPos.X, ScreenPos.Y+30);
FHintWindow.ActivateHint(HintWinRect,'');
end else begin
HintWinRect := FHintWindow.CalcHintRect(Screen.Width, TheHint, nil);
OffsetRect(HintWinRect, ScreenPos.X, ScreenPos.Y+30);
FHintWindow.ActivateHint(HintWinRect,TheHint);
end;
AHint:=TheHint;
if LazarusHelp.CreateHint(FHintWindow,ScreenPos,BaseURL,AHint,HintWinRect) then
FHintWindow.ActivateHint(HintWinRect,aHint);
end;
procedure TSourceNotebook.HideHint;

View File

@ -23,7 +23,8 @@ unit IDEHelpIntf;
interface
uses
Classes, SysUtils, LCLProc, Controls, HelpIntfs, LazHelpIntf, TextTools;
Classes, SysUtils, LCLProc, Forms, Controls, HelpIntfs, LazHelpIntf,
TextTools;
type
{ THelpDBIRegExprMessage
@ -61,6 +62,9 @@ type
var ErrMsg: string): TShowHelpResult; virtual; abstract;
procedure ShowHelpForMessage(Line: integer); virtual; abstract;
procedure ShowHelpForObjectInspector(Sender: TObject); virtual; abstract;
function CreateHint(aHintWindow: THintWindow; ScreenPos: TPoint;
const BaseURL: string; var TheHint: string;
out HintWinRect: TRect): boolean; virtual; abstract;
function ConvertSourcePosToPascalHelpContext(const CaretPos: TPoint;
const Filename: string): TPascalHelpContextList; virtual; abstract;

View File

@ -35,8 +35,13 @@ unit ObjectInspector;
interface
uses
InterfaceBase, Forms, SysUtils, Buttons, Types, Classes, Graphics, GraphType,
StdCtrls, LCLType, LCLIntf, LCLProc, Controls, ComCtrls, ExtCtrls, TypInfo,
// IMPORTANT: the object inspector is a tool and can be used in other programs
// too. Don't put Lazarus IDE specific things here.
// FCL
SysUtils, Types, Classes, TypInfo,
// LCL
InterfaceBase, Forms, Buttons, Graphics, GraphType,
StdCtrls, LCLType, LCLIntf, LCLProc, Controls, ComCtrls, ExtCtrls,
LMessages, LResources, LazConfigStorage, Menus, Dialogs, Themes,
ObjInspStrConsts,
PropEdits, GraphPropEdits, ListViewPropEdit, ImageListEditor,
@ -323,6 +328,11 @@ type
oiqeShowValue
);
TOIPropertyHint = function(Sender: TObject; PointedRow: TOIPropertyGridRow;
ScreenPos: TPoint; aHintWindow: THintWindow;
out HintWinRect: TRect; out AHint: string
): boolean of object;
TOICustomPropertyGrid = class(TCustomControl)
private
FBackgroundColor: TColor;
@ -332,6 +342,7 @@ type
FHighlightColor: TColor;
FLayout: TOILayout;
FOnOIKeyDown: TKeyEvent;
FOnPropertyHint: TOIPropertyHint;
FOnSelectionChange: TNotifyEvent;
FReferencesColor: TColor;
FRowSpacing: integer;
@ -537,6 +548,7 @@ type
property OnModified: TNotifyEvent read FOnModified write FOnModified;
property OnOIKeyDown: TKeyEvent read FOnOIKeyDown write FOnOIKeyDown;
property OnSelectionChange: TNotifyEvent read FOnSelectionChange write FOnSelectionChange;
property OnPropertyHint: TOIPropertyHint read FOnPropertyHint write FOnPropertyHint;
property PrefferedSplitterX: integer read FPreferredSplitterX
write FPreferredSplitterX default 100;
property PropertyEditorHook: TPropertyEditorHook read FPropertyEditorHook
@ -690,6 +702,7 @@ type
FAutoShow: Boolean;
FFavourites: TOIFavouriteProperties;
FInfoBoxHeight: integer;
FOnPropertyHint: TOIPropertyHint;
FOnSelectionChange: TNotifyEvent;
FRestricted: TOIRestrictedProperties;
FOnAddToFavourites: TNotifyEvent;
@ -737,6 +750,9 @@ type
procedure HookLookupRootChange;
procedure OnGridModified(Sender: TObject);
procedure OnGridSelectionChange(Sender: TObject);
function OnGridPropertyHint(Sender: TObject; PointedRow: TOIPropertyGridRow;
ScreenPos: TPoint; aHintWindow: THintWindow;
out HintWinRect: TRect; out AHint: string): boolean;
procedure SetAvailComboBoxText;
procedure HookGetSelection(const ASelection: TPersistentSelectionList);
procedure HookSetSelection(const ASelection: TPersistentSelectionList);
@ -772,6 +788,7 @@ type
read FPropertyEditorHook write SetPropertyEditorHook;
property OnModified: TNotifyEvent read FOnModified write FOnModified;
property OnSelectionChange: TNotifyEvent read FOnSelectionChange write FOnSelectionChange;
property OnPropertyHint: TOIPropertyHint read FOnPropertyHint write FOnPropertyHint;
property OnShowOptions: TNotifyEvent read FOnShowOptions
write SetOnShowOptions;
property OnRemainingKeyUp: TKeyEvent read FOnRemainingKeyUp
@ -1950,7 +1967,7 @@ var
begin
Result:=pehNone;
if (RowIndex<0) or (RowIndex>=RowCount) then exit;
if SplitterX>=X then begin
if SplitterX<=X then begin
if (FCurrentButton<>nil)
and (FCurrentButton.Left<=X) then
Result:=pehEditButton
@ -2981,10 +2998,18 @@ begin
Begin
if Assigned(PointedRow.Editor) then begin
HintType := GetHintTypeAt(Index,Position.X);
if (HintType = pehName) and Assigned(OnPropertyHint) then begin
if OnPropertyHint(Self,PointedRow,Position,FHintWindow,Rect,AHint) then
begin
FHintWindow.ActivateHint(Rect,AHint);
end;
exit;
end;
AHint := PointedRow.Editor.GetHint(HintType,Position.X,Position.Y);
end;
end;
end;
if AHint = '' then Exit;
Rect := FHintWindow.CalcHintRect(0,AHint,nil); //no maxwidth
Position := Mouse.CursorPos;
@ -4321,6 +4346,15 @@ begin
if Assigned(FOnSelectionChange) then OnSelectionChange(Self);
end;
function TObjectInspectorDlg.OnGridPropertyHint(Sender: TObject;
PointedRow: TOIPropertyGridRow; ScreenPos: TPoint; aHintWindow: THintWindow;
out HintWinRect: TRect; out AHint: string): boolean;
begin
Result:=false;
if Assigned(FOnPropertyHint) then
Result:=FOnPropertyHint(Sender,PointedRow,ScreenPos,aHintWindow,HintWinRect,AHint);
end;
procedure TObjectInspectorDlg.SetAvailComboBoxText;
begin
case FSelection.Count of
@ -4623,6 +4657,7 @@ begin
PopupMenu:=MainPopupMenu;
OnModified:=@OnGridModified;
OnSelectionChange:=@OnGridSelectionChange;
OnPropertyHint:=@OnGridPropertyHint;
OnOIKeyDown:=@OnGridKeyDown;
OnKeyUp:=@OnGridKeyUp;
OnDblClick:=@OnGridDblClick;
@ -4640,6 +4675,7 @@ begin
PopupMenu:=MainPopupMenu;
OnModified:=@OnGridModified;
OnSelectionChange:=@OnGridSelectionChange;
OnPropertyHint:=@OnGridPropertyHint;
OnOIKeyDown:=@OnGridKeyDown;
OnKeyUp:=@OnGridKeyUp;
OnDblClick:=@OnGridDblClick;
@ -4661,6 +4697,7 @@ begin
PopupMenu:=MainPopupMenu;
OnModified:=@OnGridModified;
OnSelectionChange:=@OnGridSelectionChange;
OnPropertyHint:=@OnGridPropertyHint;
OnOIKeyDown:=@OnGridKeyDown;
OnKeyUp:=@OnGridKeyUp;
OnDblClick:=@OnGridDblClick;
@ -4682,6 +4719,7 @@ begin
PopupMenu:=MainPopupMenu;
OnModified:=@OnGridModified;
OnSelectionChange:=@OnGridSelectionChange;
OnPropertyHint:=@OnGridPropertyHint;
OnOIKeyDown:=@OnGridKeyDown;
OnKeyUp:=@OnGridKeyUp;
OnDblClick:=@OnGridDblClick;