mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-07-27 00:36:35 +02:00
247 lines
7.7 KiB
ObjectPascal
247 lines
7.7 KiB
ObjectPascal
unit ChmLangRef;
|
||
|
||
{$mode objfpc}{$H+}
|
||
|
||
interface
|
||
|
||
uses
|
||
Classes, SysUtils, chmreader, chmsitemap,
|
||
Dialogs, LazHelpIntf, HelpIntfs,
|
||
FileUtil, LazFileUtils, LazStringUtils, LazUTF8,
|
||
IDEHelpIntf, MacroIntf;
|
||
|
||
const
|
||
sFPCLangRef = 'FPC Language Reference';
|
||
|
||
type
|
||
|
||
{ TLangRefHelpDatabase }
|
||
|
||
TLangRefHelpDatabase = class(THelpDatabase)
|
||
private
|
||
FCHMSearchPath: string;
|
||
FKeywordNodes: TList;
|
||
FKeyWordsList: TStringListUTF8Fast;
|
||
FRTLIndex: TStringList;
|
||
procedure ClearKeywordNodes;
|
||
procedure LoadChmIndex(const Path, ChmFileName: string;
|
||
IndexStrings: TStrings; const Filter: string = '');
|
||
public
|
||
constructor Create(TheOwner: TComponent); override;
|
||
destructor Destroy; override;
|
||
procedure LoadKeywordList(const Path: string);
|
||
function GetNodesForKeyword(const HelpKeyword: string;
|
||
var ListOfNodes: THelpNodeQueryList; var ErrMsg: string
|
||
): TShowHelpResult; override;
|
||
function ShowHelp(Query: THelpQuery; {%H-}BaseNode, NewNode: THelpNode;
|
||
{%H-}QueryItem: THelpQueryItem;
|
||
var ErrMsg: string): TShowHelpResult; override;
|
||
property CHMSearchPath: string read FCHMSearchPath write FCHMSearchPath;
|
||
end;
|
||
|
||
procedure RegisterLangRefHelpDatabase;
|
||
|
||
var
|
||
LangRefHelpDatabase: TLangRefHelpDatabase = nil;
|
||
|
||
implementation
|
||
|
||
procedure RegisterLangRefHelpDatabase;
|
||
begin
|
||
if not Assigned(LangRefHelpDatabase) then
|
||
LangRefHelpDatabase := TLangRefHelpDatabase(HelpDatabases.CreateHelpDatabase(sFPCLangRef, TLangRefHelpDatabase, true));
|
||
end;
|
||
|
||
{ TLangRefHelpDatabase }
|
||
|
||
procedure TLangRefHelpDatabase.ClearKeywordNodes;
|
||
var
|
||
i: Integer;
|
||
begin
|
||
for i := 0 to FKeywordNodes.Count - 1 do
|
||
TObject(FKeywordNodes[i]).Free;
|
||
FKeywordNodes.Clear;
|
||
end;
|
||
|
||
constructor TLangRefHelpDatabase.Create(TheOwner: TComponent);
|
||
begin
|
||
inherited Create(TheOwner);
|
||
FKeywordNodes := TList.Create;
|
||
FKeyWordsList := TStringListUTF8Fast.Create;
|
||
FKeyWordsList.CaseSensitive := False;
|
||
FRTLIndex := TStringList.Create;
|
||
FRTLIndex.CaseSensitive := False;
|
||
end;
|
||
|
||
destructor TLangRefHelpDatabase.Destroy;
|
||
begin
|
||
ClearKeywordNodes;
|
||
FKeywordNodes.Free;
|
||
FKeyWordsList.Free;
|
||
FRTLIndex.Free;
|
||
inherited Destroy;
|
||
end;
|
||
|
||
procedure TLangRefHelpDatabase.LoadKeywordList(const Path: string);
|
||
begin
|
||
FRTLIndex.Clear; // Path has been changed
|
||
LoadChmIndex(Path, 'ref.chm', FKeyWordsList);
|
||
end;
|
||
|
||
procedure TLangRefHelpDatabase.LoadChmIndex(const Path, ChmFileName: string;
|
||
IndexStrings: TStrings; const Filter: string = '');
|
||
var
|
||
chm: TChmFileList;
|
||
fchm: TChmReader;
|
||
SM: TChmSiteMap;
|
||
X, Y: Integer;
|
||
s: string;
|
||
Filename: String;
|
||
SMItem: TChmSiteMapItem;
|
||
begin
|
||
fCHMSearchPath := Path;
|
||
if fCHMSearchPath = '' then
|
||
begin
|
||
fCHMSearchPath := '$(LazarusDir)/docs/chm;$(LazarusDir)/docs/html';
|
||
IDEMacros.SubstituteMacros(fCHMSearchPath);
|
||
fCHMSearchPath := MinimizeSearchPath(GetForcedPathDelims(fCHMSearchPath));
|
||
end;
|
||
Filename:=SearchFileInPath(ChmFileName,'',fCHMSearchPath,';',[]);
|
||
|
||
IndexStrings.Clear;
|
||
if (Filename<>'') then
|
||
begin
|
||
chm := TChmFileList.Create(Utf8ToSys(Filename));
|
||
try
|
||
if chm.Count = 0 then Exit;
|
||
fchm := chm.Chm[0];
|
||
SM := fChm.GetIndexSitemap;
|
||
if SM <> nil then
|
||
begin
|
||
for X := 0 to SM.Items.Count - 1 do
|
||
begin
|
||
SMItem:=SM.Items.Item[X];
|
||
{$IF FPC_Fullversion>30100}
|
||
s := SMItem.Name;
|
||
{$ELSE}
|
||
s := SMItem.Text;
|
||
{$ENDIF}
|
||
if SMItem.Children.Count = 0 then
|
||
begin
|
||
if (SMItem.Local<>'')
|
||
and ((Filter = '') or (Pos(Filter, SMItem.Local) > 0)) then
|
||
IndexStrings.Add(s + '=' + SMItem.Local)
|
||
end else begin
|
||
with SMItem.Children do
|
||
for Y := 0 to Count - 1 do
|
||
begin
|
||
if (Item[Y].Local<>'')
|
||
|