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

View File

@ -46,12 +46,14 @@ object FPDocLinkEditorDlg: TFPDocLinkEditorDlg
AnchorSideTop.Control = LinkEdit
AnchorSideTop.Side = asrBottom
Left = 6
Height = 100
Top = 126
Height = 106
Top = 120
Width = 396
Align = alBottom
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Around = 6
BorderSpacing.Left = 6
BorderSpacing.Right = 6
BorderSpacing.Bottom = 6
OnPaint = CompletionBoxPaint
end
object ButtonPanel1: TButtonPanel
@ -73,7 +75,9 @@ object FPDocLinkEditorDlg: TFPDocLinkEditorDlg
Top = 93
Width = 396
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Around = 6
BorderSpacing.Left = 6
BorderSpacing.Top = 6
BorderSpacing.Right = 6
OnChange = LinkEditChange
OnKeyDown = LinkEditKeyDown
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'
+'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
+'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'
+'Right'#8'akBottom'#0#20'BorderSpacing.Around'#2#6#7'OnPaint'#7#18'Completio'
+'nBoxPaint'#0#0#12'TButtonPanel'#12'ButtonPanel1'#4'Left'#2#6#6'Height'#2','
+#3'Top'#3#232#0#5'Width'#3#140#1#8'TabOrder'#2#0#11'ShowButtons'#11#4'pbOK'#8
+'pbCancel'#0#0#0#5'TEdit'#8'LinkEdit'#22'AnchorSideLeft.Control'#7#5'Owner'
+#21'AnchorSideTop.Control'#7#9'LinkLabel'#18'AnchorSideTop.Side'#7#9'asrBott'
+'om'#23'AnchorSideRight.Control'#7#5'Owner'#20'AnchorSideRight.Side'#7#9'asr'
+'Bottom'#4'Left'#2#6#6'Height'#2#27#3'Top'#2']'#5'Width'#3#140#1#7'Anchors'
+#11#5'akTop'#6'akLeft'#7'akRight'#0#20'BorderSpacing.Around'#2#6#8'OnChange'
+#7#14'LinkEditChange'#9'OnKeyDown'#7#15'LinkEditKeyDown'#14'OnUTF8KeyPress'#7
+#20'LinkEditUTF8KeyPress'#14'ParentShowHint'#8#8'ShowHint'#9#8'TabOrder'#2#1
+#4'Text'#6#8'LinkEdit'#0#0#5'TEdit'#9'TitleEdit'#21'AnchorSideTop.Control'#7
+#10'TitleLabel'#18'AnchorSideTop.Side'#7#9'asrBottom'#23'AnchorSideRight.Con'
+'trol'#7#5'Owner'#20'AnchorSideRight.Side'#7#9'asrBottom'#4'Left'#2#6#6'Heig'
+'ht'#2#27#3'Top'#2#30#5'Width'#3#140#1#7'Anchors'#11#5'akTop'#6'akLeft'#7'ak'
+'Right'#0#17'BorderSpacing.Top'#2#6#19'BorderSpacing.Right'#2#6#8'TabOrder'#2
+#2#4'Text'#6#9'TitleEdit'#0#0#0
+'Right'#8'akBottom'#0#18'BorderSpacing.Left'#2#6#19'BorderSpacing.Right'#2#6
+#20'BorderSpacing.Bottom'#2#6#7'OnPaint'#7#18'CompletionBoxPaint'#0#0#12'TBu'
+'ttonPanel'#12'ButtonPanel1'#4'Left'#2#6#6'Height'#2','#3'Top'#3#232#0#5'Wid'
+'th'#3#140#1#8'TabOrder'#2#0#11'ShowButtons'#11#4'pbOK'#8'pbCancel'#0#0#0#5
+'TEdit'#8'LinkEdit'#22'AnchorSideLeft.Control'#7#5'Owner'#21'AnchorSideTop.C'
+'ontrol'#7#9'LinkLabel'#18'AnchorSideTop.Side'#7#9'asrBottom'#23'AnchorSideR'
+'ight.Control'#7#5'Owner'#20'AnchorSideRight.Side'#7#9'asrBottom'#4'Left'#2#6
+#6'Height'#2#27#3'Top'#2']'#5'Width'#3#140#1#7'Anchors'#11#5'akTop'#6'akLeft'
+#7'akRight'#0#18'BorderSpacing.Left'#2#6#17'BorderSpacing.Top'#2#6#19'Border'
+'Spacing.Right'#2#6#8'OnChange'#7#14'LinkEditChange'#9'OnKeyDown'#7#15'LinkE'
+'ditKeyDown'#14'OnUTF8KeyPress'#7#20'LinkEditUTF8KeyPress'#14'ParentShowHint'
+#8#8'ShowHint'#9#8'TabOrder'#2#1#4'Text'#6#8'LinkEdit'#0#0#5'TEdit'#9'TitleE'
+'dit'#21'AnchorSideTop.Control'#7#10'TitleLabel'#18'AnchorSideTop.Side'#7#9
+'asrBottom'#23'AnchorSideRight.Control'#7#5'Owner'#20'AnchorSideRight.Side'#7
+#9'asrBottom'#4'Left'#2#6#6'Height'#2#27#3'Top'#2#30#5'Width'#3#140#1#7'Anch'
+'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
Classes, SysUtils, LCLProc, LResources, Forms, Controls, Graphics, Dialogs,
ExtCtrls, StdCtrls, ButtonPanel, FileUtil, LCLType,
ExtCtrls, StdCtrls, ButtonPanel, FileUtil, LCLType, AvgLvlTree,
PackageIntf, ProjectIntf,
CodeHelp, LazarusIDEStrConsts, PackageSystem, PackageDefs, Laz_DOM;
@ -57,22 +57,27 @@ type
FSelected: integer;
FSelectedBGColor: TColor;
FSelectedTextColor: TColor;
FSorted: Boolean;
FTextColor: TColor;
FTop: integer;
FVisibleItems: integer;
FTree: TAvgLvlTree; // tree of TFPDocLinkCompletionItem
function GetCount: integer;
function GetItems(Index: integer): TFPDocLinkCompletionItem;
procedure SetSelected(const AValue: integer);
procedure SetSorted(const AValue: Boolean);
procedure SetTop(const AValue: integer);
public
constructor Create;
destructor Destroy; override;
procedure Clear;
procedure Sort;
procedure AddPackage(Pkg: TLazPackage);
procedure Add(Identifier, Description: string);
procedure AddIdentifier(Identifier: string);
procedure Draw(Canvas: TCanvas; Width, Height: integer);
property Count: integer read GetCount;
property Sorted: Boolean read FSorted write SetSorted;
property Items[Index: integer]: TFPDocLinkCompletionItem read GetItems;
property ItemHeight: integer read FItemHeight write FItemHeight;// pixel per item
property VisibleItems: integer read FVisibleItems write FVisibleItems;// visible lines
@ -134,6 +139,9 @@ type
function ShowFPDocLinkEditorDialog(SrcFilename: string;
StartFPDocFile: TLazFPDocFile; out Link, LinkTitle: string): TModalResult;
function CompareFPDocLinkCompletionItem(Data1, Data2: Pointer): integer;
function ComparePathWithFPDocLinkCompletionItem(AnsiString1, Data2: Pointer): integer;
implementation
function ShowFPDocLinkEditorDialog(SrcFilename: string;
@ -156,6 +164,24 @@ begin
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 }
procedure TFPDocLinkEditorDlg.FormCreate(Sender: TObject);
@ -388,7 +414,6 @@ procedure TFPDocLinkEditorDlg.AddIdentifiers(ModuleOwner: TObject;
var
DOMNode: TDOMNode;
ElementName: String;
p: Integer;
ModuleName: String;
begin
if FPDocFile=nil then exit;
@ -399,29 +424,24 @@ begin
if (SysUtils.CompareText(Prefix,copy(ElementName,1,length(Prefix)))=0)
then begin
// same prefix
// skip sub identifiers
p:=length(Prefix)+1;
while (p<=length(ElementName)) and (ElementName[p]<>'.') do inc(p);
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);
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;
DOMNode:=DOMNode.NextSibling;
@ -533,6 +553,13 @@ begin
FSelected:=AValue;
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);
begin
if FTop=AValue then exit;
@ -542,12 +569,14 @@ end;
constructor TFPDocLinkCompletionList.Create;
begin
FItems:=TFPList.Create;
FTree:=TAvgLvlTree.Create(@CompareFPDocLinkCompletionItem);
end;
destructor TFPDocLinkCompletionList.Destroy;
begin
Clear;
FreeAndNil(FItems);
FreeAndNil(FTree);
inherited Destroy;
end;
@ -555,25 +584,51 @@ procedure TFPDocLinkCompletionList.Clear;
var
i: Integer;
begin
FTree.Clear;
for i:=0 to FItems.Count-1 do TObject(FItems[i]).Free;
FItems.Clear;
FSelected:=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;
procedure TFPDocLinkCompletionList.AddPackage(Pkg: TLazPackage);
begin
FItems.Add(TFPDocLinkCompletionItem.Create('#'+Pkg.Name,'package '+Pkg.IDAsString));
Add('#'+Pkg.Name,'package '+Pkg.IDAsString);
end;
procedure TFPDocLinkCompletionList.Add(Identifier, Description: string);
var
Item: TFPDocLinkCompletionItem;
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;
procedure TFPDocLinkCompletionList.AddIdentifier(Identifier: string);
begin
FItems.Add(TFPDocLinkCompletionItem.Create(Identifier,'identifier'));
Add(Identifier,'identifier');
end;
procedure TFPDocLinkCompletionList.Draw(Canvas: TCanvas; Width, Height: integer);
@ -585,6 +640,7 @@ var
s: String;
begin
DebugLn(['TFPDocLinkCompletionList.Draw ',Width,' ',Height,' Count=',Count]);
Sorted:=true;
i:=Top;
y:=0;
dy:=ItemHeight;
@ -602,8 +658,6 @@ begin
Canvas.FillRect(0,y,Width,y+dy);
s:=Item.Text;
Canvas.TextOut(2,y+2,s);
s:=Item.Description;
Canvas.TextOut(152,y+2,s);
inc(y,dy);
inc(i);
end;