Browse Source

--- Merging r13536 into '.':
U ide/wchmhwrap.pas
U ide/whelp.pas
U ide/whtmlhlp.pas
--- Merging r13599 into '.':
G ide/wchmhwrap.pas
--- Merging r13638 into '.':
G ide/wchmhwrap.pas
G ide/whtmlhlp.pas
--- Merging r13660 into '.':
G ide/wchmhwrap.pas
G ide/whtmlhlp.pas

git-svn-id: branches/fixes_2_4@13780 -

marco 16 years ago
parent
commit
e41e06b68c
3 changed files with 182 additions and 57 deletions
  1. 112 39
      ide/wchmhwrap.pas
  2. 1 1
      ide/whelp.pas
  3. 69 17
      ide/whtmlhlp.pas

+ 112 - 39
ide/wchmhwrap.pas

@@ -15,32 +15,41 @@
  **********************************************************************}
 unit wchmhwrap;
 
-interface 
+interface
 {$Mode Delphi}
 
 Uses  wutils,whelp,whtml,SysUtils,ChmReader,ChmSiteMap,Classes;
 
 Type
-//      TopicLinks: PTopicLinkCollection;IndexEntries : PUnsortedIndexEntryCollection;  
+//      TopicLinks: PTopicLinkCollection;IndexEntries : PUnsortedIndexEntryCollection;
 
      TChmWrapper = Class
                      private
-                       ffs   : Classes.TFileStream;
-                       fchmr : TChmReader;
-                       findex: TChmSiteMap;
-                       ftopic: TChmSiteMap;
-                       floaded  : boolean;
-                     public    
-                      constructor Create(name:String);
+                       ffs   	   : Classes.TFileStream;
+                       fchmr 	   : TChmReader;
+                       findex	   : TChmSiteMap;
+                       ftopic	   : TChmSiteMap;
+                       floaded     : boolean;
+                       fileid	   : integer;
+                       fshortname  : string;
+                       flongname   : string;
+                       fTopicLinks : PTopicLinkCollection;
+                     public
+                      constructor Create(name:String;aid:integer;TopicLinks:PTopicLinkCollection);
                       function	  LoadIndex(id:integer;TopicLinks: PTopicLinkCollection;IndexEntries : PUnsortedIndexEntryCollection;helpfacility:PHelpFacility):boolean;
                       function    GetTopic(name:string):PMemoryTextFile;
                       destructor  Destroy;override;
                     end;
 
 function combinepaths(relpath,basepath:String):String;
+function CHMResolve( href: ansistring; var AFileId,ALinkId : longint):boolean;
 
+function stringreplace(const s:ansistring;const oldstr:ansistring; const newstr:ansistring):ansistring;
 implementation
 
+var CHMIndex : TStringList; // list to register open CHMs.
+
+
 function combinepaths(relpath,basepath:String):String;
 
 begin
@@ -56,35 +65,44 @@ begin
        basepath:=extractfiledir(basepath);
        delete(relpath,1,3);
      end;
-       
-   {$ifdef combinedebug}
+
+  {$ifdef combinedebug}
     debugmessageS({$i %file%},'combine out "'+relpath+'" and "'+basepath+'"',{$i %line%},'1',0,0);
   {$endif}
-  
+  if (length(basepath)>0) and (length(relpath)>0) then
+    begin
+      if (relpath[1]<>'/') and (basepath[length(basepath)]<>'/') then
+        basepath:=basepath+'/';
+       {$ifdef combinedebug}
+        debugmessageS({$i %file%},'combine out2 "'+relpath+'" and "'+basepath+'"',{$i %line%},'1',0,0);
+       {$endif}
+    end;
+
   result:=basepath+relpath;
 end;
 
-
-Constructor TChmWrapper.Create(name:string);
+Constructor TChmWrapper.Create(name:string;aid:integer;TopicLinks:PTopicLinkCollection);
 
 begin
-  ffs:=Classes.TFileStream.create(name,fmOpenRead);
+  ffs:=Classes.TFileStream.create(name,fmOpenRead or fmsharedenynone);
   fchmr:=TChmReader.Create(ffs,True); // owns ffs
   findex:=nil;
+  FTopicLinks:=TopicLinks;
   if not fchmr.isvalidfile then
     begin
       freeandnil(fchmr);
       freeandnil(ffs);
-      exit;  
-    end;      
+      exit;
+    end;
+  fileid:=aid;
+  flongname:=name;
+  fshortname:=lowercase(extractfilename(name)); // We assume ms-its: urls are case insensitive wrt filename.
+  chmindex.addobject(fshortname,self);
   {$ifdef wdebug}
-    debugmessageS({$i %file%},'TCHMWrapper: before sitemap creation ',{$i %line%},'1',0,0);
+    debugmessageS({$i %file%},'TCHMWrapper.Create: before sitemap creation '+fshortname+' id='+inttostr(aid),{$i %line%},'1',0,0);
   {$endif}
   findex:=TChmSiteMap.create(stindex);
   ftopic:=TChmSiteMap.create(sttoc);
-  {$ifdef wdebug}
-    debugmessageS({$i %file%},'TCHMWrapper: after sitemap creation ',{$i %line%},'1',0,0);
-  {$endif}
   floaded:=false;
 end;
 
@@ -97,7 +115,7 @@ begin
 //  if (length(alias)>0) and (alias[1]<>'/') then Alias:='/'+alias;
   FormatAlias:=Alias;
 end;
-              
+
 var
     m : Classes.TMemoryStream;
     i,j : integer;
@@ -105,18 +123,18 @@ var
     tli: integer;
 begin
  result:=false;
- if not assigned (fchmr) then exit;
  if floaded then exit;
+ if not assigned (fchmr) then exit;
  {$ifdef wdebug}
-     debugmessageS({$i %file%},'TCHMWrapper: indexfilename:'+fchmr.indexfile,{$i %line%},'1',0,0); 
+     debugmessageS({$i %file%},'TCHMWrapper: indexfilename:'+fchmr.indexfile,{$i %line%},'1',0,0);
  {$endif}
-  
+
   m:=fchmr.getobject(fchmr.indexfile);
   try
    if assigned(m) then
      begin
       {$ifdef wdebug}
-       debugmessageS({$i %file%},'TCHMWrapper: stream size loaded :'+inttostr(m.size),{$i %line%},'1',0,0); 
+       debugmessageS({$i %file%},'TCHMWrapper: stream size loaded :'+inttostr(m.size),{$i %line%},'1',0,0);
       {$endif}
       findex.loadfromStream(m);
     end;
@@ -124,21 +142,21 @@ begin
     freeandnil(m);
     end;
    {$ifdef wdebug}
-     debugmessageS({$i %file%},'TCHMWrapper: loadindex after final ',{$i %line%},'1',0,0); 
+     debugmessageS({$i %file%},'TCHMWrapper: loadindex after final ',{$i %line%},'1',0,0);
   {$endif}
-  
-  tli:=TopicLinks^.AddItem(fchmr.defaultpage); 
+
+  tli:=TopicLinks^.AddItem(fchmr.defaultpage);
   TLI:=EncodeHTMLCtx(ID,TLI+1);
   IndexEntries^.Insert(NewIndexEntry(  FormatAlias('Table of contents'),ID,TLI));
   for i:=0 to findex.items.count-1 do
     begin
       item:=findex.items.item[i];
-      tli:=TopicLinks^.AddItem('/'+item.local); 
+      tli:=TopicLinks^.AddItem('/'+item.local);
       TLI:=EncodeHTMLCtx(ID,TLI+1);
       IndexEntries^.Insert(NewIndexEntry(  FormatAlias(item.text),ID,TLI));
     end;
    {$ifdef wdebug}
-     debugmessageS({$i %file%},'TCHMWrapper: endloadindex ',{$i %line%},'1',0,0); 
+     debugmessageS({$i %file%},'TCHMWrapper: endloadindex ',{$i %line%},'1',0,0);
   {$endif}
   floaded:=true;
   result:=true;
@@ -161,7 +179,7 @@ begin
       if (s[i]=' ') and not inquote then lastpoint:=i;
       if (s[i]='"') then inquote:=not inquote;
       inc(i);
-    end;  
+    end;
   scanvalue:=lastpoint;
 end;
 
@@ -191,19 +209,19 @@ var
 begin
   result:=nil;
   if not assigned(fchmr) or (name='') then exit;
-  
+
   If (name[1]<>'/') and (copy(name,1,7)<>'ms-its:') Then
     name:='/'+name;
   linedata:=Classes.TStringList.create;
   try
     {$ifdef wdebug}
-     debugmessageS({$i %file%},'TCHMWrapper: Getting file '+name,{$i %line%},'1',0,0); 
+     debugmessageS({$i %file%},'TCHMWrapper: Getting file '+name,{$i %line%},'1',0,0);
     {$endif}
 //    if uppercase(name)='TABLE OF CONTENTS' Then
   //    m:=fchmr.getobject(fchmr.tocfile)
 //    else
       m:=fchmr.getobject(name);
-    
+
     if not assigned(m) then exit;
     linedata.loadfromstream(m);
     result:=new(PMemoryTextFile,Init);
@@ -220,15 +238,70 @@ begin
   end;
 end;
 
-
 destructor TChmWrapper.Destroy;
 
+var i : integer;
 begin
+  i:=chmindex.indexof(fshortname);
+  if i<>-1 then
+    begin
+      chmindex.delete(i);
+      {$ifdef wdebug}
+       debugmessageS({$i %file%},'TCHMWrapper: deregistering '+fshortname,{$i %line%},'1',0,0);
+      {$endif}
+    end;
   freeandnil(ftopic);
   freeandnil(findex);
   freeandnil(fchmr);
+  {$ifdef wdebug}
+    debugmessageS({$i %file%},'TCHMWrapper: destroying ',{$i %line%},'1',0,0);
+  {$endif}
+
 end;
-// m:=r.getobject(r.indexfile);
-//  siteindex.loadfromStream(m);
 
-end.
+function CHMResolve( href: ansistring; var AFileId,ALinkId : longint):boolean;
+
+var filename, restlink : ansistring;
+    I :integer;
+    chmw: TCHMWrapper;
+begin
+  result:=false;
+  if copy(href,1,7)='ms-its:' then
+    begin
+      {$ifdef wdebug}
+              debugmessageS({$i %file%},'TCHMWrapper: resolving '+href,{$i %line%},'1',0,0);
+      {$endif}
+
+       delete(href,1,7);
+       i:=pos('::',href);
+       if i<>0 then
+         begin
+           filename:=lowercase(copy(href,1,i-1));
+           restlink:=lowercase(copy(href,i+2,length(href)-(I+2)+1));
+           i:=chmindex.indexof(filename);
+           if i<>-1 then
+             begin
+               {$ifdef wdebug}
+                 debugmessageS({$i %file%},'TCHMWrapper: resolving '+filename+' '+inttostr(i),{$i %line%},'1',0,0);
+                 debugmessageS({$i %file%},'TCHMWrapper: resolving '+restlink+' ',{$i %line%},'1',0,0);
+               {$endif}
+               chmw:=TCHMWrapper(chmindex.objects[i]);
+               Afileid:=chmw.fileid;
+               alinkid:=chmw.fTopicLinks.additem(restlink);
+               result:=true;
+            end;    
+         end;
+    end
+end;
+
+function stringreplace(const s:ansistring;const oldstr:ansistring; const newstr:ansistring):ansistring;
+
+begin
+  result:=sysutils.stringreplace(s,oldstr,newstr,[rfreplaceall]);
+end;
+initialization
+  ChmIndex:=TStringlist.create;
+  ChmIndex.sorted:=true;
+finalization
+  ChmIndex.Free;
+end.

+ 1 - 1
ide/whelp.pas

@@ -156,7 +156,7 @@ type
 const TopicCacheSize    : sw_integer = 10;
       HelpStreamBufSize : sw_integer = 4096;
       HelpFacility      : PHelpFacility = nil;
-      MaxHelpTopicSize  : sw_word = 3*65520;
+      MaxHelpTopicSize  : sw_word = 1024*1024;
 
 function  NewTopic(FileID: byte; HelpCtx: THelpCtx; Pos: longint; Param: string;
           ExtData: pointer; ExtDataSize: longint): PTopic;

+ 69 - 17
ide/whtmlhlp.pas

@@ -111,6 +111,7 @@ type
       procedure DocTableItem(Entered: boolean); virtual;
       procedure DocHorizontalRuler; virtual;
       function CanonicalizeURL(const Base,Relative:String):string; virtual;
+      procedure Resolve( href: ansistring; var AFileId,ALinkId : sw_integer); virtual;
     public
       function  GetSectionColor(Section: THTMLSection; var Color: byte): boolean; virtual;
     private
@@ -133,6 +134,7 @@ type
       CurHeadLevel: integer;
       PAlign: TParagraphAlign;
       LinkIndexes: array[0..MaxTopicLinks] of sw_integer;
+      FileIDLinkIndexes: array[0..MaxTopicLinks] of sw_integer;
       LinkPtr: sw_integer;
       LastTextChar: char;
 {      Anchor: TAnchor;}
@@ -148,8 +150,9 @@ type
     PCHMTopicRenderer = ^TCHMTopicRenderer;
     TCHMTopicRenderer = object(THTMLTopicRenderer)
       function CanonicalizeURL(const Base,Relative:String):string; virtual;
+      procedure Resolve( href: ansistring; var AFileId,ALinkId : sw_integer); virtual;
       end;
-      
+
     PCustomHTMLHelpFile = ^TCustomHTMLHelpFile;
     TCustomHTMLHelpFile = object(THelpFile)
       constructor Init(AID: word);
@@ -165,7 +168,7 @@ type
       CurFileName: string;
       TopicLinks: PTopicLinkCollection;
     end;
-   
+
     PHTMLHelpFile = ^THTMLHelpFile;
     THTMLHelpFile = object(TCustomHTMLHelpFile)
       constructor Init(AFileName: string; AID: word; ATOCEntry: string);
@@ -178,7 +181,7 @@ type
     PCHMHelpFile = ^TCHMHelpFile;
     TCHMHelpFile = object(TCustomHTMLHelpFile)
       constructor Init(AFileName: string; AID: word);
-      destructor  Done; virtual; 
+      destructor  Done; virtual;
     public
       function    LoadIndex: boolean; virtual;
       function    ReadTopic(T: PTopic): boolean; virtual;
@@ -624,6 +627,7 @@ end;
 
 procedure THTMLTopicRenderer.DocAnchor(Entered: boolean);
 var HRef,Name: string;
+    lfileid,llinkid : sw_integer;
 begin
   if Entered and InAnchor then DocAnchor(false);
   if Entered then
@@ -651,11 +655,13 @@ begin
 {$IFDEF WDEBUG}
               DebugMessageS({$i %file%},' Adding Link1 "'+HRef+'"'+' "'+url+'"',{$i %line%},'1',0,0);
 {$ENDIF WDEBUG}
-              
+
               if pos('#',HRef)=1 then
                 Href:=NameAndExtOf(GetFilename)+Href;
               HRef:=canonicalizeURL(URL,HRef);
-              LinkIndexes[LinkPtr]:=TopicLinks^.AddItem(HRef);
+              Resolve(Href,lfileid,llinkid);
+              LinkIndexes[LinkPtr]:=llinkid;
+              FileIDLinkIndexes[LinkPtr]:=lfileid;
 {$IFDEF WDEBUG}
               DebugMessageS({$i %file%},' Adding Link2 "'+HRef+'"',{$i %line%},'1',0,0);
 {$ENDIF WDEBUG}
@@ -717,12 +723,22 @@ begin
     end;
 end;
 
-Function  THTMLTopicRenderer.CanonicalizeURL(const Base,Relative:String):string; 
+Function  THTMLTopicRenderer.CanonicalizeURL(const Base,Relative:String):string;
 // uses info from filesystem (curdir) -> overriden for CHM.
 begin
  CanonicalizeURL:=CompleteURL(Base,relative);
 end;
 
+procedure THTMLTopicRenderer.Resolve( href: ansistring; var AFileId,ALinkId : sw_integer); 
+begin
+{$IFDEF WDEBUG}
+              DebugMessageS({$i %file%},' htmlresolve "'+HRef+'"',{$i %line%},'1',0,0);
+{$ENDIF WDEBUG}
+
+  Afileid:=Topic^.FileId;
+  ALinkId:=TopicLinks^.AddItem(HRef);
+end;
+
 procedure THTMLTopicRenderer.DocParagraph(Entered: boolean);
 var Align: string;
 begin
@@ -1302,11 +1318,17 @@ begin
           for I:=0 to Min(Topic^.LinkCount-1,High(LinkIndexes)-1) do
             begin
               {$IFDEF WDEBUG}
-                DebugMessageS({$i %file%},' Indexing links ('+inttostr(i)+')'+topiclinks^.at(linkindexes[i])^,{$i %line%},'1',0,0);
+                DebugMessageS({$i %file%},' Indexing links ('+inttostr(i)+')'+topiclinks^.at(linkindexes[i])^+' '+inttostr(i)+' '+inttostr(linkindexes[i]),{$i %line%},'1',0,0);
               {$endif WDEBUG}
-              Topic^.Links^[I].FileID:=Topic^.FileID;
-              Topic^.Links^[I].Context:=EncodeHTMLCtx(Topic^.FileID,LinkIndexes[I]+1);
+              Topic^.Links^[I].FileID:=FileIDLinkIndexes[i];
+              Topic^.Links^[I].Context:=EncodeHTMLCtx(FileIDLinkIndexes[i],LinkIndexes[I]+1);
             end;
+         {$IFDEF WDEBUG}
+          if Topic^.Linkcount>High(linkindexes) then
+           DebugMessageS({$i %file%},' Maximum links exceeded ('+inttostr(Topic^.LinkCount)+') '+URL,{$i %line%},'1',0,0);
+         {$endif WDEBUG}
+
+
           { --- topic text --- }
           GetMem(TP,TextPtr);
           Move(Topic^.Text^,TP^,TextPtr);
@@ -1322,14 +1344,41 @@ begin
   BuildTopic:=OK;
 end;
 
-Function  TCHMTopicRenderer.CanonicalizeURL(const Base,Relative:String):string; 
+Function  TCHMTopicRenderer.CanonicalizeURL(const Base,Relative:String):string;
 begin
- if copy(relative,1,7)<>'ms-its:' then 
+ if copy(relative,1,6)='http:/' then // external links don't need to be fixed since we can't load them.
+   begin
+     CanonicalizeUrl:=relative;
+     exit;
+   end;
+ if copy(relative,1,7)<>'ms-its:' then
    CanonicalizeUrl:=combinepaths(relative,base)
   else
-   CanonicalizeUrl:=relative; 
+   CanonicalizeUrl:=relative;
 end;
 
+procedure TCHMTopicRenderer.Resolve( href: ansistring; var AFileId,ALinkId : sw_integer); 
+var resolved:boolean;
+begin
+{$IFDEF WDEBUG}
+  DebugMessageS({$i %file%},' chmresolve "'+HRef+'"',{$i %line%},'1',0,0);
+{$ENDIF WDEBUG}
+  resolved:=false; AFileID:=0; ALinkID:=0;	
+  href:=stringreplace(href,'%20',' '); 
+  if copy(href,1,7)='ms-its:' then
+    resolved:=CHMResolve(Href,AFileId,ALinkID);
+  if not resolved then
+    begin
+    {$IFDEF WDEBUG}
+       DebugMessageS({$i %file%},' chmresolve not resolved "'+HRef+'"',{$i %line%},'1',0,0);
+    {$ENDIF WDEBUG}
+
+      Afileid:=Topic^.FileId;
+      ALinkId:=TopicLinks^.AddItem(HRef);
+    end;
+end;
+
+
 constructor TCustomHTMLHelpFile.Init(AID: word);
 begin
   inherited Init(AID);
@@ -1390,7 +1439,7 @@ begin
 {$IFDEF WDEBUG}
           DebugMessageS({$i %file%},'(Topicinfo) Link before formatpath "'+link+'"',{$i %line%},'1',0,0);
 {$ENDIF WDEBUG}
-          
+
           Link:=FormatLink(Link);
 {$IFDEF WDEBUG}
           DebugMessageS({$i %file%},'(Topicinfo) Link after formatpath "'+link+'"',{$i %line%},'1',0,0);
@@ -1584,21 +1633,21 @@ end;
 
 constructor TChmHelpFile.Init(AFileName: string; AID: word);
 begin
-  if inherited Init(AID)=false then 
+  if inherited Init(AID)=false then
     Fail;
   Dispose(renderer,done);
   renderer:=New(PCHMTopicRenderer, Init);
-  DefaultFileName:=AFileName; 
+  DefaultFileName:=AFileName;
   if (DefaultFileName='') or not ExistsFile(DefaultFilename) then
   begin
     Done;
     Fail;
   end
   else
-    chmw:=TCHMWrapper.Create(DefaultFileName);
+    chmw:=TCHMWrapper.Create(DefaultFileName,AID,TopicLinks);
 end;
 
-function    TChmHelpFile.LoadIndex: boolean; 
+function    TChmHelpFile.LoadIndex: boolean;
 begin
   loadindex:=false;
   if assigned(chmw) then
@@ -1705,6 +1754,9 @@ begin
           begin
             Bookmark:=copy(Link,P+1,length(Link));
             Link:=copy(Link,1,P-1);
+            {$IFDEF WDEBUG}
+              debugMessageS({$i %file%},' Removed label: "'+Link+'"',{$i %line%},'1',0,0);
+            {$endif WDEBUG}
           end;
 {          if CurFileName='' then Name:=Link else
           Name:=CompletePath(CurFileName,Link);}