IDE: fpdoc link editor: sorting and removing doubles

git-svn-id: trunk@21057 -
This commit is contained in:
mattias 2009-08-01 13:27:50 +00:00
parent ca8e1d861d
commit 83c9549975
4 changed files with 122 additions and 56 deletions

View File

@ -1692,10 +1692,10 @@ function TCodeHelpManager.GetLinkedFPDocNode(StartFPDocFile: TLazFPDocFile;
function FindFPDocFilename(BaseDir, SearchPath, UnitName: string): string; function FindFPDocFilename(BaseDir, SearchPath, UnitName: string): string;
begin begin
if FilenameIsAbsolute(BaseDir) then Result:='';
Result:=SearchFileInPath(UnitName+'.xml',BaseDir,SearchPath,';',ctsfcDefault) if not IDEMacros.CreateAbsoluteSearchPath(SearchPath,BaseDir) then exit;
else //DebugLn(['FindFPDocFilename BaseDir=',BaseDir,' SearchPath=',SearchPath,' UnitName=',unitname]);
Result:=''; Result:=SearchFileInPath(UnitName+'.xml',BaseDir,SearchPath,';',ctsfcDefault);
end; end;
var var
@ -1714,6 +1714,7 @@ begin
CacheWasUsed:=false; CacheWasUsed:=false;
Result:=chprFailed; Result:=chprFailed;
//DebugLn(['TCodeHelpManager.GetLinkedFPDocNode Path="',Path,'"']);
if Path='' then exit; if Path='' then exit;
if StartDOMNode=nil then ; // for future use if StartDOMNode=nil then ; // for future use
@ -1723,6 +1724,7 @@ begin
// switch package // switch package
while (p<=length(Path)) and (Path[p]<>'.') do inc(p); while (p<=length(Path)) and (Path[p]<>'.') do inc(p);
PkgName:=copy(Path,2,p-2); PkgName:=copy(Path,2,p-2);
//DebugLn(['TCodeHelpManager.GetLinkedFPDocNode PkgName=',PkgName]);
if PkgName='' then exit; if PkgName='' then exit;
Pkg:=PackageGraph.FindAPackageWithName(PkgName,nil); Pkg:=PackageGraph.FindAPackageWithName(PkgName,nil);
if Pkg=nil then exit; if Pkg=nil then exit;
@ -1733,6 +1735,7 @@ begin
exit; exit;
end; end;
StartPos:=p+1; StartPos:=p+1;
p:=StartPos;
end else begin end else begin
// relative link (either in the same fpdoc file or of the same module) // relative link (either in the same fpdoc file or of the same module)
// use same package // use same package
@ -1750,11 +1753,12 @@ begin
// search in another unit // search in another unit
while (p<=length(Path)) and (Path[p]<>'.') do inc(p); while (p<=length(Path)) and (Path[p]<>'.') do inc(p);
UnitName:=copy(Path,StartPos,p-StartPos); UnitName:=copy(Path,StartPos,p-StartPos);
//DebugLn(['TCodeHelpManager.GetLinkedFPDocNode UnitName=',UnitName]);
if UnitName='' then exit; if UnitName='' then exit;
FPDocFilename:=''; FPDocFilename:='';
if ModuleOwner is TLazProject then begin if ModuleOwner is TLazProject then begin
AProject:=TLazProject(ModuleOwner); AProject:=TLazProject(ModuleOwner);
if AProject.LazDocPaths<>'' then begin if (AProject.LazDocPaths<>'') then begin
BaseDir:=ExtractFilePath(AProject.ProjectInfoFile); BaseDir:=ExtractFilePath(AProject.ProjectInfoFile);
FPDocFilename:=FindFPDocFilename(BaseDir,AProject.LazDocPaths,UnitName); FPDocFilename:=FindFPDocFilename(BaseDir,AProject.LazDocPaths,UnitName);
end; end;
@ -1765,6 +1769,7 @@ begin
FPDocFilename:=FindFPDocFilename(BaseDir,Pkg.LazDocPaths,UnitName); FPDocFilename:=FindFPDocFilename(BaseDir,Pkg.LazDocPaths,UnitName);
end; end;
end; end;
//DebugLn(['TCodeHelpManager.GetLinkedFPDocNode FPDocFilename=',FPDocFilename]);
if FPDocFilename='' then exit; if FPDocFilename='' then exit;
// load FPDocFile // load FPDocFile
@ -1776,10 +1781,12 @@ begin
exit; exit;
end; end;
StartPos:=p+1; StartPos:=p+1;
while (p<=length(Path)) and (Path[p]<>'.') do inc(p); p:=StartPos;
// find element // find element
while (p<=length(Path)) and (Path[p]<>'.') do inc(p);
ElementName:=copy(Path,p+1,length(Path)); ElementName:=copy(Path,p+1,length(Path));
//DebugLn(['TCodeHelpManager.GetLinkedFPDocNode ElementName=',ElementName]);
DOMNode:=FPDocFile.GetElementWithName(ElementName); DOMNode:=FPDocFile.GetElementWithName(ElementName);
if DOMNode<>nil then if DOMNode<>nil then
Result:=chprSuccess Result:=chprSuccess

View File

@ -46,12 +46,14 @@ object FPDocLinkEditorDlg: TFPDocLinkEditorDlg
AnchorSideTop.Control = LinkEdit AnchorSideTop.Control = LinkEdit
AnchorSideTop.Side = asrBottom AnchorSideTop.Side = asrBottom
Left = 6 Left = 6
Height = 100 Height = 106
Top = 126 Top = 120
Width = 396 Width = 396
Align = alBottom Align = alBottom
Anchors = [akTop, akLeft, akRight, akBottom] Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Around = 6 BorderSpacing.Left = 6
BorderSpacing.Right = 6
BorderSpacing.Bottom = 6
OnPaint = CompletionBoxPaint OnPaint = CompletionBoxPaint
end end
object ButtonPanel1: TButtonPanel object ButtonPanel1: TButtonPanel
@ -73,7 +75,9 @@ object FPDocLinkEditorDlg: TFPDocLinkEditorDlg
Top = 93 Top = 93
Width = 396 Width = 396
Anchors = [akTop, akLeft, akRight] Anchors = [akTop, akLeft, akRight]
BorderSpacing.Around = 6 BorderSpacing.Left = 6
BorderSpacing.Top = 6
BorderSpacing.Right = 6
OnChange = LinkEditChange OnChange = LinkEditChange
OnKeyDown = LinkEditKeyDown OnKeyDown = LinkEditKeyDown
OnUTF8KeyPress = LinkEditUTF8KeyPress OnUTF8KeyPress = LinkEditUTF8KeyPress

View File

@ -17,22 +17,23 @@ LazarusResources.Add('TFPDocLinkEditorDlg','FORMDATA',[
+'Width'#3#140#1#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#20'BorderSpaci' +'Width'#3#140#1#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#20'BorderSpaci'
+'ng.Around'#2#6#7'Caption'#6#10'TitleLabel'#11'ParentColor'#8#8'WordWrap'#9#0 +'ng.Around'#2#6#7'Caption'#6#10'TitleLabel'#11'ParentColor'#8#8'WordWrap'#9#0
+#0#9'TPaintBox'#13'CompletionBox'#21'AnchorSideTop.Control'#7#8'LinkEdit'#18 +#0#9'TPaintBox'#13'CompletionBox'#21'AnchorSideTop.Control'#7#8'LinkEdit'#18
+'AnchorSideTop.Side'#7#9'asrBottom'#4'Left'#2#6#6'Height'#2'd'#3'Top'#2'~'#5 +'AnchorSideTop.Side'#7#9'asrBottom'#4'Left'#2#6#6'Height'#2'j'#3'Top'#2'x'#5
+'Width'#3#140#1#5'Align'#7#8'alBottom'#7'Anchors'#11#5'akTop'#6'akLeft'#7'ak' +'Width'#3#140#1#5'Align'#7#8'alBottom'#7'Anchors'#11#5'akTop'#6'akLeft'#7'ak'
+'Right'#8'akBottom'#0#20'BorderSpacing.Around'#2#6#7'OnPaint'#7#18'Completio' +'Right'#8'akBottom'#0#18'BorderSpacing.Left'#2#6#19'BorderSpacing.Right'#2#6
+'nBoxPaint'#0#0#12'TButtonPanel'#12'ButtonPanel1'#4'Left'#2#6#6'Height'#2',' +#20'BorderSpacing.Bottom'#2#6#7'OnPaint'#7#18'CompletionBoxPaint'#0#0#12'TBu'
+#3'Top'#3#232#0#5'Width'#3#140#1#8'TabOrder'#2#0#11'ShowButtons'#11#4'pbOK'#8 +'ttonPanel'#12'ButtonPanel1'#4'Left'#2#6#6'Height'#2','#3'Top'#3#232#0#5'Wid'
+'pbCancel'#0#0#0#5'TEdit'#8'LinkEdit'#22'AnchorSideLeft.Control'#7#5'Owner' +'th'#3#140#1#8'TabOrder'#2#0#11'ShowButtons'#11#4'pbOK'#8'pbCancel'#0#0#0#5
+#21'AnchorSideTop.Control'#7#9'LinkLabel'#18'AnchorSideTop.Side'#7#9'asrBott' +'TEdit'#8'LinkEdit'#22'AnchorSideLeft.Control'#7#5'Owner'#21'AnchorSideTop.C'
+'om'#23'AnchorSideRight.Control'#7#5'Owner'#20'AnchorSideRight.Side'#7#9'asr' +'ontrol'#7#9'LinkLabel'#18'AnchorSideTop.Side'#7#9'asrBottom'#23'AnchorSideR'
+'Bottom'#4'Left'#2#6#6'Height'#2#27#3'Top'#2']'#5'Width'#3#140#1#7'Anchors' +'ight.Control'#7#5'Owner'#20'AnchorSideRight.Side'#7#9'asrBottom'#4'Left'#2#6
+#11#5'akTop'#6'akLeft'#7'akRight'#0#20'BorderSpacing.Around'#2#6#8'OnChange' +#6'Height'#2#27#3'Top'#2']'#5'Width'#3#140#1#7'Anchors'#11#5'akTop'#6'akLeft'
+#7#14'LinkEditChange'#9'OnKeyDown'#7#15'LinkEditKeyDown'#14'OnUTF8KeyPress'#7 +#7'akRight'#0#18'BorderSpacing.Left'#2#6#17'BorderSpacing.Top'#2#6#19'Border'
+#20'LinkEditUTF8KeyPress'#14'ParentShowHint'#8#8'ShowHint'#9#8'TabOrder'#2#1 +'Spacing.Right'#2#6#8'OnChange'#7#14'LinkEditChange'#9'OnKeyDown'#7#15'LinkE'
+#4'Text'#6#8'LinkEdit'#0#0#5'TEdit'#9'TitleEdit'#21'AnchorSideTop.Control'#7 +'ditKeyDown'#14'OnUTF8KeyPress'#7#20'LinkEditUTF8KeyPress'#14'ParentShowHint'
+#10'TitleLabel'#18'AnchorSideTop.Side'#7#9'asrBottom'#23'AnchorSideRight.Con' +#8#8'ShowHint'#9#8'TabOrder'#2#1#4'Text'#6#8'LinkEdit'#0#0#5'TEdit'#9'TitleE'
+'trol'#7#5'Owner'#20'AnchorSideRight.Side'#7#9'asrBottom'#4'Left'#2#6#6'Heig' +'dit'#21'AnchorSideTop.Control'#7#10'TitleLabel'#18'AnchorSideTop.Side'#7#9
+'ht'#2#27#3'Top'#2#30#5'Width'#3#140#1#7'Anchors'#11#5'akTop'#6'akLeft'#7'ak' +'asrBottom'#23'AnchorSideRight.Control'#7#5'Owner'#20'AnchorSideRight.Side'#7
+'Right'#0#17'BorderSpacing.Top'#2#6#19'BorderSpacing.Right'#2#6#8'TabOrder'#2 +#9'asrBottom'#4'Left'#2#6#6'Height'#2#27#3'Top'#2#30#5'Width'#3#140#1#7'Anch'
+#2#4'Text'#6#9'TitleEdit'#0#0#0 +'ors'#11#5'akTop'#6'akLeft'#7'akRight'#0#17'BorderSpacing.Top'#2#6#19'Border'
+'Spacing.Right'#2#6#8'TabOrder'#2#2#4'Text'#6#9'TitleEdit'#0#0#0
]); ]);

View File

@ -31,7 +31,7 @@ interface
uses uses
Classes, SysUtils, LCLProc, LResources, Forms, Controls, Graphics, Dialogs, Classes, SysUtils, LCLProc, LResources, Forms, Controls, Graphics, Dialogs,
ExtCtrls, StdCtrls, ButtonPanel, FileUtil, LCLType, ExtCtrls, StdCtrls, ButtonPanel, FileUtil, LCLType, AvgLvlTree,
PackageIntf, ProjectIntf, PackageIntf, ProjectIntf,
CodeHelp, LazarusIDEStrConsts, PackageSystem, PackageDefs, Laz_DOM; CodeHelp, LazarusIDEStrConsts, PackageSystem, PackageDefs, Laz_DOM;
@ -57,22 +57,27 @@ type
FSelected: integer; FSelected: integer;
FSelectedBGColor: TColor; FSelectedBGColor: TColor;
FSelectedTextColor: TColor; FSelectedTextColor: TColor;
FSorted: Boolean;
FTextColor: TColor; FTextColor: TColor;
FTop: integer; FTop: integer;
FVisibleItems: integer; FVisibleItems: integer;
FTree: TAvgLvlTree; // tree of TFPDocLinkCompletionItem
function GetCount: integer; function GetCount: integer;
function GetItems(Index: integer): TFPDocLinkCompletionItem; function GetItems(Index: integer): TFPDocLinkCompletionItem;
procedure SetSelected(const AValue: integer); procedure SetSelected(const AValue: integer);
procedure SetSorted(const AValue: Boolean);
procedure SetTop(const AValue: integer); procedure SetTop(const AValue: integer);
public public
constructor Create; constructor Create;
destructor Destroy; override; destructor Destroy; override;
procedure Clear; procedure Clear;
procedure Sort;
procedure AddPackage(Pkg: TLazPackage); procedure AddPackage(Pkg: TLazPackage);
procedure Add(Identifier, Description: string); procedure Add(Identifier, Description: string);
procedure AddIdentifier(Identifier: string); procedure AddIdentifier(Identifier: string);
procedure Draw(Canvas: TCanvas; Width, Height: integer); procedure Draw(Canvas: TCanvas; Width, Height: integer);
property Count: integer read GetCount; property Count: integer read GetCount;
property Sorted: Boolean read FSorted write SetSorted;
property Items[Index: integer]: TFPDocLinkCompletionItem read GetItems; property Items[Index: integer]: TFPDocLinkCompletionItem read GetItems;
property ItemHeight: integer read FItemHeight write FItemHeight;// pixel per item property ItemHeight: integer read FItemHeight write FItemHeight;// pixel per item
property VisibleItems: integer read FVisibleItems write FVisibleItems;// visible lines property VisibleItems: integer read FVisibleItems write FVisibleItems;// visible lines
@ -134,6 +139,9 @@ type
function ShowFPDocLinkEditorDialog(SrcFilename: string; function ShowFPDocLinkEditorDialog(SrcFilename: string;
StartFPDocFile: TLazFPDocFile; out Link, LinkTitle: string): TModalResult; StartFPDocFile: TLazFPDocFile; out Link, LinkTitle: string): TModalResult;
function CompareFPDocLinkCompletionItem(Data1, Data2: Pointer): integer;
function ComparePathWithFPDocLinkCompletionItem(AnsiString1, Data2: Pointer): integer;
implementation implementation
function ShowFPDocLinkEditorDialog(SrcFilename: string; function ShowFPDocLinkEditorDialog(SrcFilename: string;
@ -156,6 +164,24 @@ begin
end; end;
end; end;
function CompareFPDocLinkCompletionItem(Data1, Data2: Pointer): integer;
var
Item1: TFPDocLinkCompletionItem absolute Data1;
Item2: TFPDocLinkCompletionItem absolute Data2;
begin
Result:=SysUtils.CompareText(Item1.Text,Item2.Text);
end;
function ComparePathWithFPDocLinkCompletionItem(AnsiString1, Data2: Pointer
): integer;
var
s: String;
Item: TFPDocLinkCompletionItem absolute Data2;
begin
s:=AnsiString(AnsiString1);
Result:=SysUtils.CompareText(s,Item.Text);
end;
{ TFPDocLinkEditorDlg } { TFPDocLinkEditorDlg }
procedure TFPDocLinkEditorDlg.FormCreate(Sender: TObject); procedure TFPDocLinkEditorDlg.FormCreate(Sender: TObject);
@ -388,7 +414,6 @@ procedure TFPDocLinkEditorDlg.AddIdentifiers(ModuleOwner: TObject;
var var
DOMNode: TDOMNode; DOMNode: TDOMNode;
ElementName: String; ElementName: String;
p: Integer;
ModuleName: String; ModuleName: String;
begin begin
if FPDocFile=nil then exit; if FPDocFile=nil then exit;
@ -399,29 +424,24 @@ begin
if (SysUtils.CompareText(Prefix,copy(ElementName,1,length(Prefix)))=0) if (SysUtils.CompareText(Prefix,copy(ElementName,1,length(Prefix)))=0)
then begin then begin
// same prefix // same prefix
// skip sub identifiers if (FPDocFile<>nil) and (FPDocFile<>StartFPDocFile) then begin
p:=length(Prefix)+1; // different unit
while (p<=length(ElementName)) and (ElementName[p]<>'.') do inc(p); ElementName:=ExtractFileNameOnly(FPDocFile.Filename)+'.'+ElementName;
if p>length(ElementName) then begin
if (FPDocFile<>nil) and (FPDocFile<>StartFPDocFile) then begin
// different unit
ElementName:=ExtractFileNameOnly(FPDocFile.Filename)+'.'+ElementName;
end;
if (ModuleOwner<>nil) and (ModuleOwner<>StartModuleOwner) then begin
// different module
if ModuleOwner is TLazProject then begin
ModuleName:=lowercase(ExtractFileNameOnly(TLazProject(ModuleOwner).ProjectInfoFile));
end else if ModuleOwner is TLazPackage then begin
ModuleName:=TLazPackage(ModuleOwner).Name;
end;
if ModuleName<>'' then
ElementName:=ModuleName+'.'+ElementName
else
ElementName:='';
end;
if ElementName<>'' then
FItems.AddIdentifier(ElementName);
end; end;
if (ModuleOwner<>nil) and (ModuleOwner<>StartModuleOwner) then begin
// different module
if ModuleOwner is TLazProject then begin
ModuleName:=lowercase(ExtractFileNameOnly(TLazProject(ModuleOwner).ProjectInfoFile));
end else if ModuleOwner is TLazPackage then begin
ModuleName:=TLazPackage(ModuleOwner).Name;
end;
if ModuleName<>'' then
ElementName:='#'+ModuleName+'.'+ElementName
else
ElementName:='';
end;
if ElementName<>'' then
FItems.AddIdentifier(ElementName);
end; end;
end; end;
DOMNode:=DOMNode.NextSibling; DOMNode:=DOMNode.NextSibling;
@ -533,6 +553,13 @@ begin
FSelected:=AValue; FSelected:=AValue;
end; end;
procedure TFPDocLinkCompletionList.SetSorted(const AValue: Boolean);
begin
if FSorted=AValue then exit;
FSorted:=AValue;
if FSorted then Sort;
end;
procedure TFPDocLinkCompletionList.SetTop(const AValue: integer); procedure TFPDocLinkCompletionList.SetTop(const AValue: integer);
begin begin
if FTop=AValue then exit; if FTop=AValue then exit;
@ -542,12 +569,14 @@ end;
constructor TFPDocLinkCompletionList.Create; constructor TFPDocLinkCompletionList.Create;
begin begin
FItems:=TFPList.Create; FItems:=TFPList.Create;
FTree:=TAvgLvlTree.Create(@CompareFPDocLinkCompletionItem);
end; end;
destructor TFPDocLinkCompletionList.Destroy; destructor TFPDocLinkCompletionList.Destroy;
begin begin
Clear; Clear;
FreeAndNil(FItems); FreeAndNil(FItems);
FreeAndNil(FTree);
inherited Destroy; inherited Destroy;
end; end;
@ -555,25 +584,51 @@ procedure TFPDocLinkCompletionList.Clear;
var var
i: Integer; i: Integer;
begin begin
FTree.Clear;
for i:=0 to FItems.Count-1 do TObject(FItems[i]).Free; for i:=0 to FItems.Count-1 do TObject(FItems[i]).Free;
FItems.Clear; FItems.Clear;
FSelected:=0; FSelected:=0;
FTop:=0; FTop:=0;
FSorted:=true;
end;
procedure TFPDocLinkCompletionList.Sort;
var
Node: TAvgLvlTreeNode;
i: Integer;
begin
if FSorted then exit;
Node:=FTree.FindLowest;
i:=0;
while Node<>nil do begin
FItems[i]:=Node.Data;
inc(i);
Node:=FTree.FindSuccessor(Node);
end;
FSorted:=true;
end; end;
procedure TFPDocLinkCompletionList.AddPackage(Pkg: TLazPackage); procedure TFPDocLinkCompletionList.AddPackage(Pkg: TLazPackage);
begin begin
FItems.Add(TFPDocLinkCompletionItem.Create('#'+Pkg.Name,'package '+Pkg.IDAsString)); Add('#'+Pkg.Name,'package '+Pkg.IDAsString);
end; end;
procedure TFPDocLinkCompletionList.Add(Identifier, Description: string); procedure TFPDocLinkCompletionList.Add(Identifier, Description: string);
var
Item: TFPDocLinkCompletionItem;
begin begin
FItems.Add(TFPDocLinkCompletionItem.Create(Identifier,Description)); if FTree.FindKey(Pointer(Identifier),
@ComparePathWithFPDocLinkCompletionItem)<>nil
then exit;
Item:=TFPDocLinkCompletionItem.Create(Identifier,Description);
FItems.Add(Item);
FTree.Add(Item);
FSorted:=false;
end; end;
procedure TFPDocLinkCompletionList.AddIdentifier(Identifier: string); procedure TFPDocLinkCompletionList.AddIdentifier(Identifier: string);
begin begin
FItems.Add(TFPDocLinkCompletionItem.Create(Identifier,'identifier')); Add(Identifier,'identifier');
end; end;
procedure TFPDocLinkCompletionList.Draw(Canvas: TCanvas; Width, Height: integer); procedure TFPDocLinkCompletionList.Draw(Canvas: TCanvas; Width, Height: integer);
@ -585,6 +640,7 @@ var
s: String; s: String;
begin begin
DebugLn(['TFPDocLinkCompletionList.Draw ',Width,' ',Height,' Count=',Count]); DebugLn(['TFPDocLinkCompletionList.Draw ',Width,' ',Height,' Count=',Count]);
Sorted:=true;
i:=Top; i:=Top;
y:=0; y:=0;
dy:=ItemHeight; dy:=ItemHeight;
@ -602,8 +658,6 @@ begin
Canvas.FillRect(0,y,Width,y+dy); Canvas.FillRect(0,y,Width,y+dy);
s:=Item.Text; s:=Item.Text;
Canvas.TextOut(2,y+2,s); Canvas.TextOut(2,y+2,s);
s:=Item.Description;
Canvas.TextOut(152,y+2,s);
inc(y,dy); inc(y,dy);
inc(i); inc(i);
end; end;