mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 19:09:23 +02:00
* initial hhp loading in chmproject.
* chmproject now supports #Windows (the CHM feature, not the OS), but doesn't pass it to writer yet. * Some keys in chmproject moved from files/ to settings/ were they belong. hopefully with backwards compat loading capability. Low errorchecking etc, and only initially tested. Not for 2.4.2 git-svn-id: trunk@15444 -
This commit is contained in:
parent
ead5707179
commit
b2ad17dd2a
@ -25,7 +25,7 @@ unit chmfilewriter;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, chmwriter;
|
Classes, SysUtils, chmwriter, inifiles, contnrs;
|
||||||
|
|
||||||
type
|
type
|
||||||
TChmProject = class;
|
TChmProject = class;
|
||||||
@ -49,13 +49,18 @@ type
|
|||||||
FOutputFileName: String;
|
FOutputFileName: String;
|
||||||
FTableOfContentsFileName: String;
|
FTableOfContentsFileName: String;
|
||||||
FTitle: String;
|
FTitle: String;
|
||||||
|
FWindows : TObjectList;
|
||||||
|
FMergeFiles : TStringlist;
|
||||||
|
fDefaultWindow : string;
|
||||||
protected
|
protected
|
||||||
function GetData(const DataName: String; out PathInChm: String; out FileName: String; var Stream: TStream): Boolean;
|
function GetData(const DataName: String; out PathInChm: String; out FileName: String; var Stream: TStream): Boolean;
|
||||||
procedure LastFileAdded(Sender: TObject);
|
procedure LastFileAdded(Sender: TObject);
|
||||||
|
procedure readIniOptions(keyvaluepairs:tstringlist);
|
||||||
public
|
public
|
||||||
constructor Create; virtual;
|
constructor Create; virtual;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure LoadFromFile(AFileName: String); virtual;
|
procedure LoadFromFile(AFileName: String); virtual;
|
||||||
|
procedure LoadFromhhp (AFileName:String;LeaveInclude:Boolean); virtual;
|
||||||
procedure SaveToFile(AFileName: String); virtual;
|
procedure SaveToFile(AFileName: String); virtual;
|
||||||
procedure WriteChm(AOutStream: TStream); virtual;
|
procedure WriteChm(AOutStream: TStream); virtual;
|
||||||
function ProjectDir: String;
|
function ProjectDir: String;
|
||||||
@ -74,8 +79,10 @@ type
|
|||||||
property MakeSearchable: Boolean read FMakeSearchable write FMakeSearchable;
|
property MakeSearchable: Boolean read FMakeSearchable write FMakeSearchable;
|
||||||
property DefaultPage: String read FDefaultPage write FDefaultPage;
|
property DefaultPage: String read FDefaultPage write FDefaultPage;
|
||||||
property DefaultFont: String read FDefaultFont write FDefaultFont;
|
property DefaultFont: String read FDefaultFont write FDefaultFont;
|
||||||
|
property Windows :TObjectList read FWindows write FWindows;
|
||||||
|
property MergeFiles :TStringlist read FMergeFiles write FMergefiles;
|
||||||
property OnProgress: TChmProgressCB read FOnProgress write FOnProgress;
|
property OnProgress: TChmProgressCB read FOnProgress write FOnProgress;
|
||||||
|
property DefaultWindow : String read FDefaultWindow write FDefaultWindow;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TChmContextNode = Class
|
TChmContextNode = Class
|
||||||
@ -86,7 +93,7 @@ type
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses XmlCfg, chmsitemap;
|
uses XmlCfg, chmsitemap, CHMTypes;
|
||||||
|
|
||||||
{ TChmProject }
|
{ TChmProject }
|
||||||
|
|
||||||
@ -153,6 +160,8 @@ end;
|
|||||||
constructor TChmProject.Create;
|
constructor TChmProject.Create;
|
||||||
begin
|
begin
|
||||||
FFiles := TStringList.Create;
|
FFiles := TStringList.Create;
|
||||||
|
FWindows:=TObjectList.Create(True);
|
||||||
|
FMergeFiles:=TStringlist.Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TChmProject.Destroy;
|
destructor TChmProject.Destroy;
|
||||||
@ -160,16 +169,111 @@ var i : integer;
|
|||||||
begin
|
begin
|
||||||
for i:=0 to ffiles.count -1 do
|
for i:=0 to ffiles.count -1 do
|
||||||
ffiles.objects[i].free;
|
ffiles.objects[i].free;
|
||||||
|
FMergeFiles.Free;
|
||||||
FFiles.Free;
|
FFiles.Free;
|
||||||
|
FWindows.Free;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Type
|
||||||
|
TSectionEnum = (secOptions,secWindows,secFiles,secMergeFiles,secAlias,secMap,secInfoTypes,secTextPopups,secUnknown);
|
||||||
|
TOptionEnum = (OPTAUTO_INDEX,OPTAUTO_TOC,OPTBINARY_INDEX,OPTBINARY_TOC,OPTCITATION,
|
||||||
|
OPTCOMPRESS,OPTCOPYRIGHT,OPTCOMPATIBILITY,OPTCOMPILED_FILE,OPTCONTENTS_FILE,
|
||||||
|
OPTCREATE_CHI_FILE,OPTDBCS,OPTDEFAULT_FONT,OPTDEFAULT_WINDOW,OPTDEFAULT_TOPIC,
|
||||||
|
OPTDISPLAY_COMPILE_NOTES,OPTDISPLAY_COMPILE_PROGRESS,OPTENHANCED_DECOMPILATION,OPTERROR_LOG_FILE,OPTFLAT,
|
||||||
|
OPTFULL_TEXT_SEARCH_STOP_LIST,OPTFULL_TEXT_SEARCH,OPTIGNORE,OPTINDEX_FILE,OPTLANGUAGE,OPTPREFIX,
|
||||||
|
OPTSAMPLE_STAGING_PATH,OPTSAMPLE_LIST_FILE,OPTTMPDIR,OPTTITLE,OPTCUSTOM_TAB,OPTUNKNOWN);
|
||||||
|
|
||||||
|
Const
|
||||||
|
SectionNames : Array[TSectionEnum] of String =
|
||||||
|
('OPTIONS','WINDOWS','FILES','MERGE FILES','ALIAS','MAP','INFOTYPES','TEXT POPUPS','UNKNOWN');
|
||||||
|
|
||||||
|
OptionKeys : array [TOptionEnum] of String =
|
||||||
|
('AUTO INDEX','AUTO TOC','BINARY INDEX','BINARY TOC','CITATION',
|
||||||
|
'COMPRESS','COPYRIGHT','COMPATIBILITY','COMPILED FILE','CONTENTS FILE',
|
||||||
|
'CREATE CHI FILE','DBCS','DEFAULT FONT','DEFAULT WINDOW','DEFAULT TOPIC',
|
||||||
|
'DISPLAY COMPILE NOTES','DISPLAY COMPILE PROGRESS','ENHANCED DECOMPILATION','ERROR LOG FILE','FLAT',
|
||||||
|
'FULL-TEXT SEARCH STOP LIST','FULL TEXT SEARCH','IGNORE','INDEX FILE','LANGUAGE','PREFIX',
|
||||||
|
'SAMPLE STAGING PATH','SAMPLE LIST FILE','TMPDIR','TITLE','CUSTOM TAB','UNKNOWN');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function FindSectionName (const name:string):TSectionEnum;
|
||||||
|
|
||||||
|
begin
|
||||||
|
result:=low(TSectionEnum);
|
||||||
|
while (result<secUnknown) and (name<>SectionNames[Result]) do
|
||||||
|
inc(result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function FindOptionName(Const name:string):TOptionEnum;
|
||||||
|
|
||||||
|
begin
|
||||||
|
result:=low(TOptionEnum);
|
||||||
|
while (result<optUnknown) and (name<>OptionKeys[Result]) do
|
||||||
|
inc(result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChmProject.readIniOptions(keyvaluepairs:tstringlist);
|
||||||
|
var i : integer;
|
||||||
|
Opt : TOptionEnum;
|
||||||
|
OptVal,
|
||||||
|
OptValUpper : string;
|
||||||
|
begin
|
||||||
|
for i:=0 to keyvaluepairs.count-1 do
|
||||||
|
begin
|
||||||
|
Opt:=findoptionname(uppercase(keyvaluepairs.names[i]));
|
||||||
|
optval :=keyvaluepairs.valuefromindex[i];
|
||||||
|
optvalupper:=uppercase(OptVal);
|
||||||
|
case Opt Of
|
||||||
|
OPTAUTO_INDEX : ;
|
||||||
|
OPTAUTO_TOC : ;
|
||||||
|
OPTBINARY_INDEX : MakeBinaryIndex:=optvalupper='YES';
|
||||||
|
OPTBINARY_TOC : MakeBinaryToc :=optvalupper='YES';
|
||||||
|
OPTCITATION : ;
|
||||||
|
OPTCOMPRESS : ; // Doesn't seem to have effect in workshop
|
||||||
|
OPTCOPYRIGHT : ;
|
||||||
|
OPTCOMPATIBILITY : ;
|
||||||
|
OPTCOMPILED_FILE : OutputFilename:=optval;
|
||||||
|
OPTCONTENTS_FILE : TableOfContentsFileName:=optval;
|
||||||
|
OPTCREATE_CHI_FILE : ;
|
||||||
|
OPTDBCS : ; // What this field makes unicode is not known?
|
||||||
|
OPTDEFAULT_FONT : defaultfont:=optval;
|
||||||
|
OPTDEFAULT_WINDOW : defaultwindow:=optval;
|
||||||
|
OPTDEFAULT_TOPIC : defaultpage:=optval;
|
||||||
|
OPTDISPLAY_COMPILE_NOTES : ;
|
||||||
|
OPTDISPLAY_COMPILE_PROGRESS : ;
|
||||||
|
OPTENHANCED_DECOMPILATION : ;
|
||||||
|
OPTERROR_LOG_FILE : ;
|
||||||
|
OPTFLAT : ;
|
||||||
|
OPTFULL_TEXT_SEARCH_STOP_LIST: ;
|
||||||
|
OPTIGNORE : ;
|
||||||
|
OPTINDEX_FILE : Indexfilename:=optval;
|
||||||
|
OPTLANGUAGE : ;
|
||||||
|
OPTPREFIX : ; // doesn't seem to have effect
|
||||||
|
OPTSAMPLE_STAGING_PATH : ;
|
||||||
|
OPTSAMPLE_LIST_FILE : ;
|
||||||
|
OPTTMPDIR : ;
|
||||||
|
OPTTITLE : Title:=optval;
|
||||||
|
OPTCUSTOM_TAB : ;
|
||||||
|
OPTUNKNOWN : ; // can be used for errors on unknown keys
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TChmProject.LoadFromFile(AFileName: String);
|
procedure TChmProject.LoadFromFile(AFileName: String);
|
||||||
var
|
var
|
||||||
Cfg: TXMLConfig;
|
Cfg: TXMLConfig;
|
||||||
|
MergeFileCount,
|
||||||
|
WinCount,
|
||||||
FileCount: Integer;
|
FileCount: Integer;
|
||||||
I : Integer;
|
I : Integer;
|
||||||
nd : TChmContextNode;
|
nd : TChmContextNode;
|
||||||
|
win: TCHMWindow;
|
||||||
|
s : String;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Cfg := TXMLConfig.Create(nil);
|
Cfg := TXMLConfig.Create(nil);
|
||||||
Cfg.Filename := AFileName;
|
Cfg.Filename := AFileName;
|
||||||
@ -185,20 +289,257 @@ begin
|
|||||||
nd.contextname:=Cfg.GetValue('Files/FileName'+IntToStr(I)+'/ContextName','');
|
nd.contextname:=Cfg.GetValue('Files/FileName'+IntToStr(I)+'/ContextName','');
|
||||||
Files.AddObject(nd.urlname,nd);
|
Files.AddObject(nd.urlname,nd);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
WinCount:= Cfg.GetValue('Windows/Count/Value', 0);
|
||||||
|
for i:=0 To WinCount-1 do
|
||||||
|
begin
|
||||||
|
win:=TCHMWindow.Create;
|
||||||
|
win.loadfromxml(cfg,'Windows/item'+inttostr(i)+'/');
|
||||||
|
fwindows.add(win);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Mergefilecount:=Cfg.getValue('MergeFiles/Count/Value', 0);
|
||||||
|
for i:=0 To MergeFileCount-1 do
|
||||||
|
Mergefiles.add(Cfg.getValue('MergeFiles/FileName'+IntToStr(I)+'/value',''));
|
||||||
|
|
||||||
|
// load some values that changed key backwards compatible.
|
||||||
|
|
||||||
IndexFileName := Cfg.GetValue('Files/IndexFile/Value','');
|
IndexFileName := Cfg.GetValue('Files/IndexFile/Value','');
|
||||||
|
if IndexFileName='' Then
|
||||||
|
IndexFileName := Cfg.GetValue('Settings/IndexFile/Value','');
|
||||||
|
|
||||||
TableOfContentsFileName := Cfg.GetValue('Files/TOCFile/Value','');
|
TableOfContentsFileName := Cfg.GetValue('Files/TOCFile/Value','');
|
||||||
|
If TableOfContentsFileName='' then
|
||||||
|
TableOfContentsFileName := Cfg.GetValue('Settings/TOCFile/Value','');
|
||||||
|
|
||||||
// For chm file merging, bintoc must be false and binindex true. Change defaults in time?
|
// For chm file merging, bintoc must be false and binindex true. Change defaults in time?
|
||||||
MakeBinaryTOC := Cfg.GetValue('Files/MakeBinaryTOC/Value', True);
|
// OTOH, merging will be mostly done for fpdoc files, and that doesn't care about defaults.
|
||||||
MakeBinaryIndex:= Cfg.GetValue('Files/MakeBinaryIndex/Value', False);
|
|
||||||
|
S:=Cfg.GetValue('Files/MakeBinaryTOC/Value', '');
|
||||||
|
if s='' Then
|
||||||
|
MakeBinaryTOC := Cfg.GetValue('Settings/MakeBinaryTOC/Value', True)
|
||||||
|
else
|
||||||
|
MakeBinaryTOC := Cfg.GetValue('Files/MakeBinaryTOC/Value', True);
|
||||||
|
|
||||||
|
S:=Cfg.GetValue('Files/MakeBinaryIndex/Value', '');
|
||||||
|
if s='' Then
|
||||||
|
MakeBinaryIndex := Cfg.GetValue('Settings/MakeBinaryIndex/Value', False)
|
||||||
|
else
|
||||||
|
MakeBinaryIndex := Cfg.GetValue('Files/MakeBinaryIndex/Value', False);
|
||||||
|
|
||||||
AutoFollowLinks := Cfg.GetValue('Settings/AutoFollowLinks/Value', False);
|
AutoFollowLinks := Cfg.GetValue('Settings/AutoFollowLinks/Value', False);
|
||||||
MakeSearchable := Cfg.GetValue('Settings/MakeSearchable/Value', False);
|
MakeSearchable := Cfg.GetValue('Settings/MakeSearchable/Value', False);
|
||||||
DefaultPage := Cfg.GetValue('Settings/DefaultPage/Value', '');
|
DefaultPage := Cfg.GetValue('Settings/DefaultPage/Value', '');
|
||||||
Title := Cfg.GetValue('Settings/Title/Value', '');
|
Title := Cfg.GetValue('Settings/Title/Value', '');
|
||||||
OutputFileName := Cfg.GetValue('Settings/OutputFileName/Value', '');
|
OutputFileName := Cfg.GetValue('Settings/OutputFileName/Value', '');
|
||||||
DefaultFont := Cfg.GetValue('Settings/DefaultFont/Value', '');
|
DefaultFont := Cfg.GetValue('Settings/DefaultFont/Value', '');
|
||||||
|
DefaultWindow:= Cfg.GetValue('Settings/DefaultWindow/Value', '');
|
||||||
Cfg.Free;
|
Cfg.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function cleanupstring(const s:string):string;
|
||||||
|
var
|
||||||
|
i:integer;
|
||||||
|
begin
|
||||||
|
i:=pos(';',s);
|
||||||
|
if i>0 then
|
||||||
|
result:=trim(copy(s,1,i-1))
|
||||||
|
else
|
||||||
|
result:=trim(s);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TChmProject.LoadFromhhp (AFileName:String;LeaveInclude:Boolean);
|
||||||
|
// leaveinclude=true leaves includefiles includefiles.
|
||||||
|
|
||||||
|
procedure addalias(const key,value :string);
|
||||||
|
|
||||||
|
var i,j : integer;
|
||||||
|
node: TCHMContextNode;
|
||||||
|
keyupper : string;
|
||||||
|
begin
|
||||||
|
{$ifdef hhp_debug}
|
||||||
|
writeln('alias entry:',key,'=',value);
|
||||||
|
{$endif}
|
||||||
|
keyupper:=uppercase(value);
|
||||||
|
i:=0; j:=files.count;
|
||||||
|
while (i<j) and (uppercase(TCHMContextnode(files.objects[i]).UrlName)<>keyupper) do
|
||||||
|
inc(i);
|
||||||
|
if i=j then
|
||||||
|
begin
|
||||||
|
{$ifdef hhp_debug}
|
||||||
|
writeln('alias new node:',key);
|
||||||
|
{$endif}
|
||||||
|
node:=TCHMContextNode.create;
|
||||||
|
node.URLName:=value;
|
||||||
|
node.contextname:=key;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
node:=TCHMContextNode(Files.objects[i]);
|
||||||
|
node.ContextName:=key;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure processalias(strs:TStringlist);
|
||||||
|
var i,j : integer;
|
||||||
|
s : string;
|
||||||
|
strls2:tstringlist;
|
||||||
|
|
||||||
|
begin
|
||||||
|
for i:=0 to strs.count-1 do
|
||||||
|
begin
|
||||||
|
s:=cleanupstring(strs[i]);
|
||||||
|
if uppercase(copy(s,1,8))='#INCLUDE' then
|
||||||
|
begin
|
||||||
|
delete(s,1,8);
|
||||||
|
s:=trim(s);
|
||||||
|
if fileexists(s) then
|
||||||
|
begin
|
||||||
|
strls2:=TstringList.create;
|
||||||
|
strls2.loadfromfile(s);
|
||||||
|
processalias(strls2);
|
||||||
|
strls2.free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
s:=cleanupstring(s);
|
||||||
|
j:=pos('=',s);
|
||||||
|
if j>0 then
|
||||||
|
addalias(trim(copy(s,1,j-1)),copy(s,j+1,length(s)-j));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure addmap(const key,value :string);
|
||||||
|
|
||||||
|
var i,j : integer;
|
||||||
|
node: TCHMContextNode;
|
||||||
|
keyupper : string;
|
||||||
|
begin
|
||||||
|
{$ifdef hhp_debug}
|
||||||
|
writeln('map entry:',key,'=',value);
|
||||||
|
{$endif}
|
||||||
|
keyupper:=uppercase(key);
|
||||||
|
i:=0; j:=files.count;
|
||||||
|
while (i<j) and (uppercase(TCHMContextnode(files.objects[i]).contextname)<>keyupper) do
|
||||||
|
inc(i);
|
||||||
|
if i=j then
|
||||||
|
raise Exception.create('context "'+key+'" not found!')
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
node:=TCHMContextNode(Files.objects[i]);
|
||||||
|
node.Contextnumber:=strtointdef(value,0);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure processmap(strs:TStringlist);
|
||||||
|
var i,j : integer;
|
||||||
|
s : string;
|
||||||
|
strls2:tstringlist;
|
||||||
|
|
||||||
|
begin
|
||||||
|
for i:=0 to strs.count-1 do
|
||||||
|
begin
|
||||||
|
s:=cleanupstring(strs[i]);
|
||||||
|
{$ifdef hhp_debug}
|
||||||
|
writeln('map item:',s);
|
||||||
|
{$endif}
|
||||||
|
if uppercase(copy(s,1,8))='#INCLUDE' then
|
||||||
|
begin
|
||||||
|
delete(s,1,8);
|
||||||
|
s:=trim(s);
|
||||||
|
if fileexists(s) then
|
||||||
|
begin
|
||||||
|
strls2:=TstringList.create;
|
||||||
|
strls2.loadfromfile(s);
|
||||||
|
processmap(strls2);
|
||||||
|
strls2.free;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
s:=cleanupstring(s);
|
||||||
|
if uppercase(copy(s,1,7))='#DEFINE' Then
|
||||||
|
begin
|
||||||
|
delete(s,1,7);
|
||||||
|
s:=trim(s);
|
||||||
|
j:=pos(' ',s);
|
||||||
|
if j>0 then
|
||||||
|
addmap(trim(copy(s,1,j-1)),copy(s,j+1,length(s)-j));
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{$ifdef hhp_debug}
|
||||||
|
writeln('map leftover:',s);
|
||||||
|
{$endif}
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
Fini : TMemIniFile; // TMemInifile is more compatible with Delphi. Delphi's API based TIniFile fails on .hhp files.
|
||||||
|
secs,strs : TStringList;
|
||||||
|
i,j : Integer;
|
||||||
|
section : TSectionEnum;
|
||||||
|
nd : TChmContextNode;
|
||||||
|
|
||||||
|
begin
|
||||||
|
Fini:=TMeminiFile.Create(AFileName);
|
||||||
|
secs := TStringList.create;
|
||||||
|
strs := TStringList.create;
|
||||||
|
fini.readsections(secs);
|
||||||
|
|
||||||
|
// Do the files section first so that we can emit errors if
|
||||||
|
// other sections reference unknown files.
|
||||||
|
|
||||||
|
fini.readsectionvalues(SectionNames[secFiles] ,strs);
|
||||||
|
if strs.count>0 then
|
||||||
|
for j:=0 to strs.count-1 do
|
||||||
|
begin
|
||||||
|
nd:=TChmContextNode.Create;
|
||||||
|
nd.urlname:=strs[j];
|
||||||
|
nd.contextnumber:=0;
|
||||||
|
nd.contextname:='';
|
||||||
|
Files.AddObject(nd.urlname,nd);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// aliases also add file nodes.
|
||||||
|
|
||||||
|
fini.readsectionvalues(SectionNames[secAlias] ,strs); // resolve all aliases.
|
||||||
|
if strs.count>0 then
|
||||||
|
processalias(strs);
|
||||||
|
|
||||||
|
// map files only add to existing file nodes.
|
||||||
|
fini.readsectionvalues(SectionNames[secmap] ,strs);
|
||||||
|
if strs.count>0 then
|
||||||
|
processmap(strs);
|
||||||
|
|
||||||
|
|
||||||
|
for i:=0 to secs.count-1 do
|
||||||
|
begin
|
||||||
|
section:=FindSectionName(Uppercase(Secs[i]));
|
||||||
|
if section<>secunknown then
|
||||||
|
fini.readsectionvalues(secs[i] ,strs);
|
||||||
|
case section of
|
||||||
|
secOptions : readinioptions(strs);
|
||||||
|
secWindows : for j:=0 to strs.count-1 do
|
||||||
|
FWindows.add(TCHMWindow.Create(strs[j]));
|
||||||
|
secFiles : ; // already done
|
||||||
|
secMergeFiles: FMergeFiles.Assign(Strs); // just a filelist
|
||||||
|
secAlias : ; // already done
|
||||||
|
secMap : ; // already done
|
||||||
|
secInfoTypes : ; // unused for now.
|
||||||
|
secTextPopups: ; // rarely used.
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
secs.free;
|
||||||
|
strs.free;
|
||||||
|
fini.free;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TChmProject.AddFileWithContext(contextid:integer;filename:ansistring;contextname:ansistring='');
|
procedure TChmProject.AddFileWithContext(contextid:integer;filename:ansistring;contextname:ansistring='');
|
||||||
var x : integer;
|
var x : integer;
|
||||||
nd : TChmContextNode;
|
nd : TChmContextNode;
|
||||||
@ -247,16 +588,35 @@ begin
|
|||||||
Cfg.SetValue('Files/FileName'+IntToStr(I)+'/ContextName', nd.contextname);
|
Cfg.SetValue('Files/FileName'+IntToStr(I)+'/ContextName', nd.contextname);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
Cfg.SetValue('Files/IndexFile/Value', IndexFileName);
|
|
||||||
Cfg.SetValue('Files/TOCFile/Value', TableOfContentsFileName);
|
Cfg.SetValue('Windows/Count/Value', FWindows.count);
|
||||||
Cfg.SetValue('Files/MakeBinaryTOC/Value',MakeBinaryTOC);
|
for i:=0 To FWindows.Count-1 do
|
||||||
Cfg.SetValue('Files/MakeBinaryIndex/Value',MakeBinaryIndex);
|
TCHMWindow(FWindows[i]).savetoxml(cfg,'Windows/item'+inttostr(i)+'/');
|
||||||
|
|
||||||
|
Cfg.SetValue('MergeFiles/Count/Value', FMergeFiles.count);
|
||||||
|
for i:=0 To FMergeFiles.Count-1 do
|
||||||
|
Cfg.SetValue('MergeFiles/FileName'+IntToStr(I)+'/value',FMergeFiles[i]);
|
||||||
|
|
||||||
|
// delete legacy keys.
|
||||||
|
Cfg.SetValue('Files/IndexFile/Value','');
|
||||||
|
Cfg.SetValue('Files/TOCFile/Value', '');
|
||||||
|
Cfg.SetValue('Files/MakeBinaryTOC/Value','');
|
||||||
|
Cfg.SetValue('Files/MakeBinaryIndex/Value','');
|
||||||
|
Cfg.SetValue('Settings/IndexFile/Value', IndexFileName);
|
||||||
|
Cfg.SetValue('Settings/TOCFile/Value', TableOfContentsFileName);
|
||||||
|
Cfg.SetValue('Settings/MakeBinaryTOC/Value',MakeBinaryTOC);
|
||||||
|
Cfg.SetValue('Settings/MakeBinaryIndex/Value',MakeBinaryIndex);
|
||||||
|
|
||||||
Cfg.SetValue('Settings/AutoFollowLinks/Value', AutoFollowLinks);
|
Cfg.SetValue('Settings/AutoFollowLinks/Value', AutoFollowLinks);
|
||||||
Cfg.SetValue('Settings/MakeSearchable/Value', MakeSearchable);
|
Cfg.SetValue('Settings/MakeSearchable/Value', MakeSearchable);
|
||||||
Cfg.SetValue('Settings/DefaultPage/Value', DefaultPage);
|
Cfg.SetValue('Settings/DefaultPage/Value', DefaultPage);
|
||||||
Cfg.SetValue('Settings/Title/Value', Title);
|
Cfg.SetValue('Settings/Title/Value', Title);
|
||||||
Cfg.SetValue('Settings/OutputFileName/Value', OutputFileName);
|
Cfg.SetValue('Settings/OutputFileName/Value', OutputFileName);
|
||||||
Cfg.SetValue('Settings/DefaultFont/Value', DefaultFont);
|
Cfg.SetValue('Settings/DefaultFont/Value', DefaultFont);
|
||||||
|
|
||||||
|
Cfg.SetValue('Settings/DefaultWindow/Value', DefaultWindow);
|
||||||
|
|
||||||
|
|
||||||
Cfg.Flush;
|
Cfg.Flush;
|
||||||
Cfg.Free;
|
Cfg.Free;
|
||||||
end;
|
end;
|
||||||
|
@ -25,7 +25,7 @@ unit chmtypes;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils;
|
Classes, SysUtils,xmlcfg;
|
||||||
|
|
||||||
type
|
type
|
||||||
TSectionName = (snMSCompressed, snUnCompressed);
|
TSectionName = (snMSCompressed, snUnCompressed);
|
||||||
@ -91,6 +91,38 @@ type
|
|||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TCHMWindow = Class
|
||||||
|
window_type,
|
||||||
|
Title_bar_text,
|
||||||
|
Toc_file,
|
||||||
|
index_file,
|
||||||
|
Default_File,
|
||||||
|
Home_button_file,
|
||||||
|
Jumpbutton_1_File,
|
||||||
|
Jumpbutton_1_Text,
|
||||||
|
Jumpbutton_2_File,
|
||||||
|
Jumpbutton_2_Text : string;
|
||||||
|
nav_style : integer; // overlay with bitfields (next 2 also)
|
||||||
|
navpanewidth : integer;
|
||||||
|
buttons : integer;
|
||||||
|
left,
|
||||||
|
top,
|
||||||
|
right,
|
||||||
|
bottom : integer;
|
||||||
|
styleflags ,
|
||||||
|
xtdstyleflags,
|
||||||
|
window_show_state,
|
||||||
|
navpane_initially_closed,
|
||||||
|
navpane_default,
|
||||||
|
navpane_location,
|
||||||
|
wm_notify_id : integer;
|
||||||
|
Constructor create(s:string='');
|
||||||
|
procedure load_from_ini(txt:string);
|
||||||
|
procedure savetoxml(cfg:TXMLConfig;key:string);
|
||||||
|
procedure loadfromxml(cfg:TXMLConfig;key:string);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
TTOCIdxHeader = record
|
TTOCIdxHeader = record
|
||||||
BlockSize: DWord; // 4096
|
BlockSize: DWord; // 4096
|
||||||
EntriesOffset: DWord;
|
EntriesOffset: DWord;
|
||||||
@ -392,5 +424,144 @@ begin
|
|||||||
//WriteLn(ChunkLevelCount);
|
//WriteLn(ChunkLevelCount);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
function getnext(const s:string;var i: integer;len:integer):string;
|
||||||
|
var
|
||||||
|
ind : integer;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if i>len then exit('');
|
||||||
|
ind:=i;
|
||||||
|
if s[ind]='"' then
|
||||||
|
begin
|
||||||
|
inc(ind);
|
||||||
|
while (ind<=len) and (s[ind]<>'"') do inc(ind);
|
||||||
|
result:=copy(s,i+1,ind-i-1);
|
||||||
|
inc(ind); // skip "
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
while (ind<=len) and (s[ind]<>',') do inc(ind);
|
||||||
|
result:=copy(s,i,ind-i);
|
||||||
|
end;
|
||||||
|
i:=ind+1; // skip ,
|
||||||
|
end;
|
||||||
|
|
||||||
|
function getnextint(const txt:string;var ind: integer;len:integer):integer;
|
||||||
|
|
||||||
|
var s : string;
|
||||||
|
begin
|
||||||
|
s:=getnext(txt,ind,len);
|
||||||
|
result:=strtointdef(s,0); // I think this does C style hex, if not fixup here.
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCHMWindow.load_from_ini(txt:string);
|
||||||
|
var ind,len,
|
||||||
|
j,k : integer;
|
||||||
|
arr : array[0..3] of integer;
|
||||||
|
s2 : string;
|
||||||
|
begin
|
||||||
|
j:=pos('=',txt);
|
||||||
|
if j>0 then
|
||||||
|
txt[j]:=',';
|
||||||
|
ind:=1; len:=length(txt);
|
||||||
|
window_type :=getnext(txt,ind,len);
|
||||||
|
Title_bar_text :=getnext(txt,ind,len);
|
||||||
|
index_file :=getnext(txt,ind,len);
|
||||||
|
Toc_file :=getnext(txt,ind,len);
|
||||||
|
Default_File :=getnext(txt,ind,len);
|
||||||
|
Home_button_file :=getnext(txt,ind,len);
|
||||||
|
Jumpbutton_1_File :=getnext(txt,ind,len);
|
||||||
|
Jumpbutton_1_Text :=getnext(txt,ind,len);
|
||||||
|
Jumpbutton_2_File :=getnext(txt,ind,len);
|
||||||
|
Jumpbutton_2_Text :=getnext(txt,ind,len);
|
||||||
|
|
||||||
|
nav_style :=getnextint(txt,ind,len);
|
||||||
|
navpanewidth :=getnextint(txt,ind,len);
|
||||||
|
buttons :=getnextint(txt,ind,len);
|
||||||
|
k:=0;
|
||||||
|
repeat
|
||||||
|
s2:=getnext(txt,ind,len);
|
||||||
|
if (length(s2)>0) and (s2[1]='[') then delete(s2,1,1);
|
||||||
|
j:=pos(']',s2);
|
||||||
|
if j>0 then delete(s2,j,1);
|
||||||
|
arr[k]:=strtointdef(s2,0);
|
||||||
|
inc(k);
|
||||||
|
until (j<>0) or (ind>len);
|
||||||
|
left :=arr[0];
|
||||||
|
top :=arr[1];
|
||||||
|
right :=arr[2];
|
||||||
|
bottom:=arr[3];
|
||||||
|
styleflags :=getnextint(txt,ind,len);
|
||||||
|
xtdstyleflags :=getnextint(txt,ind,len);
|
||||||
|
window_show_state :=getnextint(txt,ind,len);
|
||||||
|
navpane_initially_closed :=getnextint(txt,ind,len);
|
||||||
|
navpane_default :=getnextint(txt,ind,len);
|
||||||
|
navpane_location :=getnextint(txt,ind,len);
|
||||||
|
wm_notify_id :=getnextint(txt,ind,len);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCHMWindow.savetoxml(cfg:TXMLConfig;key:string);
|
||||||
|
begin
|
||||||
|
cfg.setvalue(key+'window_type',window_type);
|
||||||
|
cfg.setvalue(key+'title_bar_text',title_bar_text);
|
||||||
|
cfg.setvalue(key+'toc_file', Toc_file );
|
||||||
|
cfg.setvalue(key+'index_file', index_file );
|
||||||
|
cfg.setvalue(key+'default_file', Default_File );
|
||||||
|
cfg.setvalue(key+'home_button_file', Home_button_file);
|
||||||
|
cfg.setvalue(key+'jumpbutton_1_file', Jumpbutton_1_File );
|
||||||
|
cfg.setvalue(key+'jumpbutton_1_text', Jumpbutton_1_Text );
|
||||||
|
cfg.setvalue(key+'jumpbutton_2_file', Jumpbutton_2_File );
|
||||||
|
cfg.setvalue(key+'jumpbutton_2_text', Jumpbutton_2_Text );
|
||||||
|
cfg.setvalue(key+'nav_style', nav_style );
|
||||||
|
cfg.setvalue(key+'navpanewidth', navpanewidth );
|
||||||
|
cfg.setvalue(key+'buttons', buttons );
|
||||||
|
cfg.setvalue(key+'left', left);
|
||||||
|
cfg.setvalue(key+'top', top );
|
||||||
|
cfg.setvalue(key+'right', right );
|
||||||
|
cfg.setvalue(key+'bottom', bottom );
|
||||||
|
cfg.setvalue(key+'styleflags', styleflags);
|
||||||
|
cfg.setvalue(key+'xtdstyleflags', xtdstyleflags );
|
||||||
|
cfg.setvalue(key+'window_show_state', window_show_state );
|
||||||
|
cfg.setvalue(key+'navpane_initially_closed',navpane_initially_closed );
|
||||||
|
cfg.setvalue(key+'navpane_default',navpane_default);
|
||||||
|
cfg.setvalue(key+'navpane_location',navpane_location );
|
||||||
|
cfg.setvalue(key+'wm_notify_id',wm_notify_id );
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCHMWindow.loadfromxml(cfg:TXMLConfig;key:string);
|
||||||
|
|
||||||
|
begin
|
||||||
|
window_type :=cfg.getvalue(key+'window_type','');
|
||||||
|
Title_bar_text :=cfg.getvalue(key+'title_bar_text','');
|
||||||
|
Toc_file :=cfg.getvalue(key+'toc_file','');
|
||||||
|
Index_file :=cfg.getvalue(key+'index_file','');
|
||||||
|
Default_File :=cfg.getvalue(key+'default_file','');
|
||||||
|
Home_button_file :=cfg.getvalue(key+'home_button_file','');
|
||||||
|
Jumpbutton_1_File :=cfg.getvalue(key+'jumpbutton_1_file','');
|
||||||
|
Jumpbutton_1_Text :=cfg.getvalue(key+'jumpbutton_1_text','');
|
||||||
|
Jumpbutton_2_File :=cfg.getvalue(key+'jumpbutton_2_file','');
|
||||||
|
Jumpbutton_2_Text :=cfg.getvalue(key+'jumpbutton_2_text','');
|
||||||
|
nav_style :=cfg.getvalue(key+'nav_style',0);
|
||||||
|
navpanewidth :=cfg.getvalue(key+'navpanewidth',0);
|
||||||
|
buttons :=cfg.getvalue(key+'buttons',0);
|
||||||
|
left :=cfg.getvalue(key+'left',0);
|
||||||
|
top :=cfg.getvalue(key+'top',0);
|
||||||
|
right :=cfg.getvalue(key+'right',0);
|
||||||
|
bottom :=cfg.getvalue(key+'bottom',0);
|
||||||
|
styleflags :=cfg.getvalue(key+'styleflags',0);
|
||||||
|
xtdstyleflags :=cfg.getvalue(key+'xtdstyleflags',0);
|
||||||
|
window_show_state :=cfg.getvalue(key+'window_show_state',0);
|
||||||
|
navpane_initially_closed :=cfg.getvalue(key+'navpane_initially_closed',0);
|
||||||
|
navpane_default :=cfg.getvalue(key+'navpane_default',0);
|
||||||
|
navpane_location :=cfg.getvalue(key+'navpane_location',0);
|
||||||
|
wm_notify_id :=cfg.getvalue(key+'wm_notify_id',0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Constructor TCHMWindow.create(s:string='');
|
||||||
|
|
||||||
|
begin
|
||||||
|
if s<>'' then
|
||||||
|
load_from_ini(s);
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user