mirror of
https://github.com/reactos/reactos.git
synced 2025-06-12 15:08:29 +00:00
Import TechBot
svn path=/trunk/; revision=13064
This commit is contained in:
parent
568b27baeb
commit
9dab4509fa
94 changed files with 24386 additions and 0 deletions
894
irc/TechBot/CHMLibrary/HtmlHelpSystem.cs
Normal file
894
irc/TechBot/CHMLibrary/HtmlHelpSystem.cs
Normal file
|
@ -0,0 +1,894 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using System.Data;
|
||||
|
||||
using HtmlHelp.ChmDecoding;
|
||||
|
||||
namespace HtmlHelp
|
||||
{
|
||||
/// <summary>
|
||||
/// The class <c>HtmlHelpSystem</c> implements the main object for reading chm files
|
||||
/// </summary>
|
||||
public sealed class HtmlHelpSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// Private shared instance of current HtmlHelpSystem class
|
||||
/// </summary>
|
||||
private static HtmlHelpSystem _current=null;
|
||||
/// <summary>
|
||||
/// Internal member storing the attached files
|
||||
/// </summary>
|
||||
private ArrayList _chmFiles = new ArrayList();
|
||||
/// <summary>
|
||||
/// Internal member storing a merged table of contents
|
||||
/// </summary>
|
||||
private TableOfContents _toc = new TableOfContents();
|
||||
/// <summary>
|
||||
/// Internal member storing a merged index
|
||||
/// </summary>
|
||||
private Index _index = new Index();
|
||||
/// <summary>
|
||||
/// URL prefix for specifying a chm destination
|
||||
/// </summary>
|
||||
private static string _urlPrefix = "ms-its:";
|
||||
/// <summary>
|
||||
/// Internal flag specifying if the system should use the tree-images list
|
||||
/// from HtmlHelp2. If false the standard CHM-Viewer pics will be used.
|
||||
/// </summary>
|
||||
private static bool _useHH2TreePics = false;
|
||||
/// <summary>
|
||||
/// Internal member storing the read information types
|
||||
/// </summary>
|
||||
private ArrayList _informationTypes = new ArrayList();
|
||||
/// <summary>
|
||||
/// Internal member storing the read categories
|
||||
/// </summary>
|
||||
private ArrayList _categories = new ArrayList();
|
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the url prefix for specifying a chm destination
|
||||
/// </summary>
|
||||
public static string UrlPrefix
|
||||
{
|
||||
get { return _urlPrefix; }
|
||||
set { _urlPrefix = value; }
|
||||
}
|
||||
|
||||
public CHMStream.CHMStream BaseStream
|
||||
{
|
||||
get
|
||||
{
|
||||
CHMFile chm=(CHMFile)_chmFiles[0];
|
||||
return chm.BaseStream;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the flag specifying if the system should use the tree-images list
|
||||
/// from HtmlHelp2. If false the standard CHM-Viewer pics will be used.
|
||||
/// </summary>
|
||||
public static bool UseHH2TreePics
|
||||
{
|
||||
get { return _useHH2TreePics; }
|
||||
set { _useHH2TreePics = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current HtmlHelpSystem instance
|
||||
/// </summary>
|
||||
public static HtmlHelpSystem Current
|
||||
{
|
||||
get
|
||||
{
|
||||
return _current;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Standard constructor
|
||||
/// </summary>
|
||||
public HtmlHelpSystem() : this("")
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor of the reader class
|
||||
/// </summary>
|
||||
/// <param name="chmFile">chm file to attach with the reader</param>
|
||||
public HtmlHelpSystem(string chmFile)
|
||||
{
|
||||
_current = this;
|
||||
OpenFile(chmFile);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Opens a chm file and creates
|
||||
/// </summary>
|
||||
/// <param name="chmFile">full file path of the chm file to open</param>
|
||||
/// <remarks>If you call this method, all existing merged files will be cleared.</remarks>
|
||||
public void OpenFile(string chmFile)
|
||||
{
|
||||
OpenFile(chmFile, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a chm file and creates
|
||||
/// </summary>
|
||||
/// <param name="chmFile">full file path of the chm file to open</param>
|
||||
/// <param name="dmpInfo">dumping info</param>
|
||||
/// <remarks>If you call this method, all existing merged files will be cleared.</remarks>
|
||||
public void OpenFile(string chmFile, DumpingInfo dmpInfo)
|
||||
{
|
||||
if( File.Exists(chmFile ) )
|
||||
{
|
||||
_chmFiles.Clear();
|
||||
_toc.Clear();
|
||||
_index.Clear();
|
||||
_informationTypes.Clear();
|
||||
_categories.Clear();
|
||||
|
||||
CHMFile newFile = new CHMFile(this, chmFile, dmpInfo);
|
||||
|
||||
_toc = new TableOfContents( newFile.TOC );
|
||||
_index = new Index( newFile.IndexKLinks, newFile.IndexALinks );
|
||||
|
||||
_chmFiles.Add(newFile);
|
||||
// add all infotypes and categories of the read file to this system instance
|
||||
MergeFileInfoTypesCategories(newFile);
|
||||
|
||||
// check if the file has a merged files list
|
||||
if( newFile.MergedFiles.Length > 0 )
|
||||
{
|
||||
// extract the path of the chm file (usually merged files are in the same path)
|
||||
FileInfo fi = new FileInfo(chmFile);
|
||||
string sPath = fi.DirectoryName;
|
||||
|
||||
for(int i=0; i<newFile.MergedFiles.Length; i++)
|
||||
{
|
||||
string sFile = newFile.MergedFiles[i];
|
||||
|
||||
if(sFile.Length > 0)
|
||||
{
|
||||
if(sFile[1] != ':') // no full path setting
|
||||
{
|
||||
sFile = Path.Combine(sPath, sFile);
|
||||
}
|
||||
|
||||
MergeFile(sFile, dmpInfo, true);
|
||||
}
|
||||
}
|
||||
|
||||
// if (newFile.MergLinks.Count>0)
|
||||
// RecalculateMergeLinks(newFile);
|
||||
|
||||
RemoveMergeLinks(); // clear all merge-links which have no target !
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges a chm file to the current help contents
|
||||
/// </summary>
|
||||
/// <param name="chmFile">full file path of the chm file to merge</param>
|
||||
public void MergeFile(string chmFile)
|
||||
{
|
||||
MergeFile(chmFile, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges a chm file to the current help contents
|
||||
/// </summary>
|
||||
/// <param name="chmFile">full file path of the chm file to merge</param>
|
||||
/// <param name="dmpInfo">dumping info</param>
|
||||
public void MergeFile(string chmFile, DumpingInfo dmpInfo)
|
||||
{
|
||||
MergeFile(chmFile, dmpInfo, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges a chm file to the current help contents
|
||||
/// </summary>
|
||||
/// <param name="chmFile">full file path of the chm file to merge</param>
|
||||
/// <param name="dmpInfo">dumping info</param>
|
||||
/// <param name="mergedFileList">true if the merge is done because a merged file list
|
||||
/// was found in the previously loaded CHM.</param>
|
||||
internal void MergeFile(string chmFile, DumpingInfo dmpInfo, bool mergedFileList)
|
||||
{
|
||||
if( File.Exists(chmFile ) )
|
||||
{
|
||||
if( _chmFiles.Count == 1)
|
||||
{
|
||||
// if we open the first file, we directly point into the toc and index of this file.
|
||||
// So that we don't merge the new toc's indexe's into the first file, we have to
|
||||
// clone the internal arraylists first to a new instance of the toc/index holder classes.
|
||||
ArrayList atoc = _toc.TOC;
|
||||
ArrayList alinks = _index.ALinks;
|
||||
ArrayList klinks = _index.KLinks;
|
||||
|
||||
_toc = new TableOfContents();
|
||||
_index = new Index();
|
||||
|
||||
_toc.MergeToC( atoc );
|
||||
_index.MergeIndex( alinks, IndexType.AssiciativeLinks );
|
||||
_index.MergeIndex( klinks, IndexType.KeywordLinks );
|
||||
}
|
||||
|
||||
CHMFile newFile = new CHMFile(this, chmFile, dmpInfo);
|
||||
|
||||
if(mergedFileList) // if we've called this method due to a merged file list merge
|
||||
{
|
||||
RecalculateMergeLinks(newFile);
|
||||
|
||||
_toc.MergeToC( newFile.TOC, _chmFiles );
|
||||
_index.MergeIndex( newFile.IndexALinks, IndexType.AssiciativeLinks );
|
||||
_index.MergeIndex( newFile.IndexKLinks, IndexType.KeywordLinks );
|
||||
|
||||
_chmFiles.Add(newFile);
|
||||
|
||||
// add all infotypes and categories of the read file to this system instance
|
||||
MergeFileInfoTypesCategories(newFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
_toc.MergeToC( newFile.TOC, _chmFiles );
|
||||
_index.MergeIndex( newFile.IndexALinks, IndexType.AssiciativeLinks );
|
||||
_index.MergeIndex( newFile.IndexKLinks, IndexType.KeywordLinks );
|
||||
|
||||
_chmFiles.Add(newFile);
|
||||
|
||||
// add all infotypes and categories of the read file to this system instance
|
||||
MergeFileInfoTypesCategories(newFile);
|
||||
|
||||
// check if the file has a merged files list
|
||||
if( newFile.MergedFiles.Length > 0 )
|
||||
{
|
||||
// extract the path of the chm file (usually merged files are in the same path)
|
||||
FileInfo fi = new FileInfo(chmFile);
|
||||
string sPath = fi.DirectoryName;
|
||||
|
||||
for(int i=0; i<newFile.MergedFiles.Length; i++)
|
||||
{
|
||||
string sFile = newFile.MergedFiles[i];
|
||||
|
||||
if(sFile.Length > 0)
|
||||
{
|
||||
if(sFile[1] != ':') // no full path setting
|
||||
{
|
||||
sFile = Path.Combine(sPath, sFile);
|
||||
}
|
||||
|
||||
MergeFile(sFile, dmpInfo, true);
|
||||
}
|
||||
}
|
||||
|
||||
RemoveMergeLinks(); // clear all merge-links which have no target !
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks all Merg-links read till now. Checks if the merg-link points to the
|
||||
/// file <c>currentFile</c>. If yes the link will be replaced by the contents of the
|
||||
/// merged file.
|
||||
/// </summary>
|
||||
/// <param name="currentFile">Current CHMFile instance</param>
|
||||
internal void RecalculateMergeLinks(CHMFile currentFile)
|
||||
{
|
||||
foreach(CHMFile curFile in _chmFiles)
|
||||
{
|
||||
if( curFile.MergLinks.Count > 0)
|
||||
{
|
||||
for(int i=0; i<curFile.MergLinks.Count; i++)
|
||||
{
|
||||
TOCItem curItem = curFile.MergLinks[i] as TOCItem;
|
||||
|
||||
string sMerge = curItem.MergeLink;
|
||||
string [] sSplit = sMerge.Split( new char[]{':'} );
|
||||
|
||||
string sFName = "";
|
||||
string sTarget = "";
|
||||
|
||||
if( sSplit.Length > 3) // merge info contains path name
|
||||
{
|
||||
sFName = sSplit[0] + ":" + sSplit[1];
|
||||
sTarget = sSplit[3];
|
||||
}
|
||||
else if( sSplit.Length == 3)// merge info contains only file name
|
||||
{
|
||||
FileInfo fi = new FileInfo(currentFile.ChmFilePath);
|
||||
string sPath = fi.DirectoryName;
|
||||
|
||||
string sFile = sSplit[0];
|
||||
|
||||
if(sFile.Length > 0)
|
||||
{
|
||||
if(sFile[1] != ':') // no full path setting
|
||||
{
|
||||
sFile = Path.Combine(sPath, sFile);
|
||||
}
|
||||
}
|
||||
|
||||
sFName = sFile;
|
||||
sTarget = sSplit[2];
|
||||
}
|
||||
|
||||
ArrayList arrToc = null;
|
||||
if( (sFName.Length>0) && (sTarget.Length>0) )
|
||||
{
|
||||
// if this link points into the current file
|
||||
if( sFName.ToLower() == currentFile.ChmFilePath.ToLower() )
|
||||
{
|
||||
if(sTarget.ToLower().IndexOf(".hhc") >= 0)
|
||||
{
|
||||
string sfCheck = sTarget;
|
||||
|
||||
// remove prefixing ./
|
||||
while( (sfCheck[0]=='.') || (sfCheck[0]=='/') )
|
||||
{
|
||||
sfCheck = sfCheck.Substring(1);
|
||||
}
|
||||
|
||||
if( currentFile.ContentsFile.ToLower() != sfCheck )
|
||||
{
|
||||
arrToc = currentFile.ParseHHC( sTarget );
|
||||
|
||||
if( arrToc.Count > 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
arrToc = currentFile.TOC;
|
||||
}
|
||||
|
||||
// target points to a complete TOC
|
||||
int nCnt = 0;
|
||||
|
||||
foreach(TOCItem chkItem in arrToc)
|
||||
{
|
||||
if(nCnt == 0)
|
||||
{
|
||||
curItem.AssociatedFile = currentFile;
|
||||
curItem.Children = chkItem.Children;
|
||||
curItem.ChmFile = currentFile.ChmFilePath;
|
||||
curItem.ImageIndex = chkItem.ImageIndex;
|
||||
curItem.Local = chkItem.Local;
|
||||
curItem.MergeLink = chkItem.MergeLink;
|
||||
curItem.Name = chkItem.Name;
|
||||
curItem.TocMode = chkItem.TocMode;
|
||||
curItem.TopicOffset = chkItem.TopicOffset;
|
||||
|
||||
MarkChildrenAdded(chkItem.Children, curFile.MergLinks);
|
||||
}
|
||||
else
|
||||
{
|
||||
ArrayList checkList = null;
|
||||
|
||||
if(curItem.Parent != null)
|
||||
checkList = curItem.Parent.Children;
|
||||
else
|
||||
checkList = curFile.TOC;
|
||||
|
||||
int nIdx = checkList.IndexOf(curItem);
|
||||
if((nIdx+nCnt)>checkList.Count)
|
||||
checkList.Add(chkItem);
|
||||
else
|
||||
checkList.Insert(nIdx+nCnt, chkItem);
|
||||
|
||||
curFile.MergLinks.Add(chkItem);
|
||||
MarkChildrenAdded(chkItem.Children, curFile.MergLinks);
|
||||
}
|
||||
|
||||
nCnt++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// target points to a single topic
|
||||
TOCItem chkItem = currentFile.GetTOCItemByLocal(sTarget);
|
||||
if(chkItem != null)
|
||||
{
|
||||
curItem.AssociatedFile = currentFile;
|
||||
curItem.Children = chkItem.Children;
|
||||
curItem.ChmFile = currentFile.ChmFilePath;
|
||||
curItem.ImageIndex = chkItem.ImageIndex;
|
||||
curItem.Local = chkItem.Local;
|
||||
curItem.MergeLink = chkItem.MergeLink;
|
||||
curItem.Name = chkItem.Name;
|
||||
curItem.TocMode = chkItem.TocMode;
|
||||
curItem.TopicOffset = chkItem.TopicOffset;
|
||||
|
||||
curFile.MergLinks.Add(chkItem);
|
||||
MarkChildrenAdded(chkItem.Children, curFile.MergLinks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds sub-items of an TOC-entry to the merg-linked list.
|
||||
/// This will mark this item as "added" during the extra merge run
|
||||
/// of the HtmlHelpSystem class.
|
||||
/// </summary>
|
||||
/// <param name="tocs">TOCItem list</param>
|
||||
/// <param name="merged">Arraylist which holds the merged-items</param>
|
||||
internal void MarkChildrenAdded(ArrayList tocs, ArrayList merged)
|
||||
{
|
||||
foreach(TOCItem curItem in tocs)
|
||||
{
|
||||
if(!merged.Contains(curItem))
|
||||
{
|
||||
merged.Add(curItem);
|
||||
|
||||
MarkChildrenAdded(curItem.Children, merged);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes merge-links from the toc of files which were not loaded
|
||||
/// </summary>
|
||||
internal void RemoveMergeLinks()
|
||||
{
|
||||
foreach(CHMFile curFile in _chmFiles)
|
||||
{
|
||||
if( curFile.MergLinks.Count > 0)
|
||||
{
|
||||
while(curFile.MergLinks.Count > 0)
|
||||
{
|
||||
TOCItem curItem = curFile.MergLinks[0] as TOCItem;
|
||||
if(curItem.MergeLink.Length > 0)
|
||||
curFile.RemoveTOCItem(curItem);
|
||||
|
||||
curFile.MergLinks.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges the information types and categories read by the CHMFile instance
|
||||
/// into the system instance
|
||||
/// </summary>
|
||||
/// <param name="chmFile">file instance</param>
|
||||
private void MergeFileInfoTypesCategories(CHMFile chmFile)
|
||||
{
|
||||
if(chmFile.HasInformationTypes)
|
||||
{
|
||||
for(int i=0; i<chmFile.InformationTypes.Count;i++)
|
||||
{
|
||||
InformationType curType = chmFile.InformationTypes[i] as InformationType;
|
||||
InformationType sysType = GetInformationType( curType.Name );
|
||||
|
||||
if( sysType == null)
|
||||
_informationTypes.Add(curType);
|
||||
else
|
||||
curType.ReferenceCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if(chmFile.HasCategories)
|
||||
{
|
||||
for(int i=0; i<chmFile.Categories.Count;i++)
|
||||
{
|
||||
Category curCat = chmFile.Categories[i] as Category;
|
||||
Category sysCat = GetCategory( curCat.Name );
|
||||
|
||||
if(sysCat == null)
|
||||
_categories.Add(curCat);
|
||||
else
|
||||
curCat.ReferenceCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the information types and categories read by the CHMFile instance
|
||||
/// </summary>
|
||||
/// <param name="chmFile">file instance</param>
|
||||
private void RemoveFileInfoTypesCategories(CHMFile chmFile)
|
||||
{
|
||||
if(chmFile.HasInformationTypes)
|
||||
{
|
||||
for(int i=0; i<chmFile.InformationTypes.Count;i++)
|
||||
{
|
||||
InformationType curType = chmFile.InformationTypes[i] as InformationType;
|
||||
InformationType sysType = GetInformationType( curType.Name );
|
||||
|
||||
if(sysType != null)
|
||||
{
|
||||
sysType.ReferenceCount--;
|
||||
|
||||
if(sysType.ReferenceCount<=0)
|
||||
_informationTypes.Remove(sysType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(chmFile.HasCategories)
|
||||
{
|
||||
for(int i=0; i<chmFile.Categories.Count;i++)
|
||||
{
|
||||
Category curCat = chmFile.Categories[i] as Category;
|
||||
Category sysCat = GetCategory( curCat.Name );
|
||||
|
||||
if(sysCat != null)
|
||||
{
|
||||
sysCat.ReferenceCount--;
|
||||
|
||||
if(sysCat.ReferenceCount<=0)
|
||||
_categories.Remove(sysCat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a chm file from the internal file collection
|
||||
/// </summary>
|
||||
/// <param name="chmFile">full file path of the chm file to remove</param>
|
||||
public void RemoveFile(string chmFile)
|
||||
{
|
||||
int nIdx = -1;
|
||||
CHMFile removeInstance=null;
|
||||
|
||||
foreach(CHMFile curFile in _chmFiles)
|
||||
{
|
||||
nIdx++;
|
||||
|
||||
if( curFile.ChmFilePath.ToLower() == chmFile.ToLower() )
|
||||
{
|
||||
removeInstance = curFile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(nIdx >= 0)
|
||||
{
|
||||
_toc.Clear(); // forces a rebuild of the merged toc
|
||||
_index.Clear(); // force a rebuild of the merged index
|
||||
|
||||
RemoveFileInfoTypesCategories(removeInstance);
|
||||
_chmFiles.RemoveAt(nIdx);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes all files and destroys TOC/index
|
||||
/// </summary>
|
||||
public void CloseAllFiles()
|
||||
{
|
||||
for(int i=0; i < _chmFiles.Count; i++)
|
||||
{
|
||||
CHMFile curFile = _chmFiles[i] as CHMFile;
|
||||
|
||||
_chmFiles.RemoveAt(i);
|
||||
curFile.Dispose();
|
||||
i--;
|
||||
}
|
||||
|
||||
_chmFiles.Clear();
|
||||
_toc.Clear();
|
||||
_index.Clear();
|
||||
_informationTypes.Clear();
|
||||
_categories.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an array of loaded chm files.
|
||||
/// </summary>
|
||||
public CHMFile[] FileList
|
||||
{
|
||||
get
|
||||
{
|
||||
CHMFile[] ret = new CHMFile[ _chmFiles.Count ];
|
||||
for(int i=0;i<_chmFiles.Count;i++)
|
||||
ret[i] = (CHMFile)_chmFiles[i];
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the HtmlHelpSystem instance contains 1 or more information types
|
||||
/// </summary>
|
||||
public bool HasInformationTypes
|
||||
{
|
||||
get { return (_informationTypes.Count>0); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the HtmlHelpSystem instance contains 1 or more categories
|
||||
/// </summary>
|
||||
public bool HasCategories
|
||||
{
|
||||
get { return (_categories.Count>0); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an ArrayList of <see cref="InformationType">InformationType</see> items
|
||||
/// </summary>
|
||||
public ArrayList InformationTypes
|
||||
{
|
||||
get { return _informationTypes; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an ArrayList of <see cref="Category">Category</see> items
|
||||
/// </summary>
|
||||
public ArrayList Categories
|
||||
{
|
||||
get { return _categories; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the information type specified by its name
|
||||
/// </summary>
|
||||
/// <param name="name">name of the information type to receive</param>
|
||||
/// <returns>Returns the Instance for the name or null if not found</returns>
|
||||
public InformationType GetInformationType(string name)
|
||||
{
|
||||
if(HasInformationTypes)
|
||||
{
|
||||
for(int i=0; i<_informationTypes.Count;i++)
|
||||
{
|
||||
InformationType iT = _informationTypes[i] as InformationType;
|
||||
|
||||
if(iT.Name == name)
|
||||
return iT;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the category specifiyd by its name
|
||||
/// </summary>
|
||||
/// <param name="name">name of the category</param>
|
||||
/// <returns>Returns the Instance for the name or null if not found</returns>
|
||||
public Category GetCategory(string name)
|
||||
{
|
||||
if(HasCategories)
|
||||
{
|
||||
for(int i=0; i<_categories.Count;i++)
|
||||
{
|
||||
Category cat = _categories[i] as Category;
|
||||
|
||||
if(cat.Name == name)
|
||||
return cat;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default topic
|
||||
/// </summary>
|
||||
public string DefaultTopic
|
||||
{
|
||||
get
|
||||
{
|
||||
if( _chmFiles.Count > 0 )
|
||||
{
|
||||
foreach(CHMFile curFile in _chmFiles)
|
||||
{
|
||||
if( curFile.DefaultTopic.Length > 0)
|
||||
{
|
||||
return curFile.FormURL( curFile.DefaultTopic );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "about:blank";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a merged table of contents of all opened chm files
|
||||
/// </summary>
|
||||
public TableOfContents TableOfContents
|
||||
{
|
||||
get
|
||||
{
|
||||
if( _chmFiles.Count > 0 )
|
||||
{
|
||||
if( _toc.Count() <= 0)
|
||||
{
|
||||
// merge toc of files
|
||||
foreach(CHMFile curFile in _chmFiles)
|
||||
{
|
||||
_toc.MergeToC( curFile.TOC );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _toc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a merged index of all opened chm files
|
||||
/// </summary>
|
||||
public Index Index
|
||||
{
|
||||
get
|
||||
{
|
||||
if( _chmFiles.Count > 0 )
|
||||
{
|
||||
if( (_index.Count(IndexType.KeywordLinks)+_index.Count(IndexType.AssiciativeLinks)) <= 0)
|
||||
{
|
||||
// merge index files
|
||||
foreach(CHMFile curFile in _chmFiles)
|
||||
{
|
||||
_index.MergeIndex( curFile.IndexKLinks, IndexType.KeywordLinks);
|
||||
_index.MergeIndex( curFile.IndexALinks, IndexType.AssiciativeLinks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _index;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag if the current instance offers a table of contents
|
||||
/// </summary>
|
||||
public bool HasTableOfContents
|
||||
{
|
||||
get
|
||||
{
|
||||
return (TableOfContents.Count() > 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag if the current instance offers an index
|
||||
/// </summary>
|
||||
public bool HasIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return (HasALinks || HasKLinks);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag if the index holds klinks
|
||||
/// </summary>
|
||||
public bool HasKLinks
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_index.Count(IndexType.KeywordLinks) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag if the index holds alinks
|
||||
/// </summary>
|
||||
public bool HasALinks
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_index.Count(IndexType.AssiciativeLinks) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag if the current instance supports fulltext searching
|
||||
/// </summary>
|
||||
public bool FullTextSearch
|
||||
{
|
||||
get
|
||||
{
|
||||
bool bRet = false;
|
||||
|
||||
foreach(CHMFile curFile in _chmFiles)
|
||||
{
|
||||
bRet |= curFile.FullTextSearch;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a full-text search over the chm files
|
||||
/// </summary>
|
||||
/// <param name="words">words to search</param>
|
||||
/// <param name="partialMatches">true if partial word should be matched also
|
||||
/// ( if this is true a search of 'support' will match 'supports', otherwise not )</param>
|
||||
/// <param name="titleOnly">true if titles only</param>
|
||||
/// <returns>A DataTable containing the search hits</returns>
|
||||
public DataTable PerformSearch(string words, bool partialMatches, bool titleOnly)
|
||||
{
|
||||
return PerformSearch(words, -1, partialMatches, titleOnly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a full-text search over the chm files
|
||||
/// </summary>
|
||||
/// <param name="words">words to search</param>
|
||||
/// <param name="MaxResults">maximal number of hits to return</param>
|
||||
/// <param name="partialMatches">true if partial word should be matched also
|
||||
/// ( if this is true a search of 'support' will match 'supports', otherwise not )</param>
|
||||
/// <param name="titleOnly">true if titles only</param>
|
||||
/// <returns>A DataTable containing the search hits</returns>
|
||||
public DataTable PerformSearch(string words, int MaxResults, bool partialMatches, bool titleOnly)
|
||||
{
|
||||
if( ! FullTextSearch )
|
||||
return null;
|
||||
|
||||
DataTable dtResult = null;
|
||||
|
||||
int nCnt = 0;
|
||||
|
||||
foreach(CHMFile curFile in _chmFiles)
|
||||
{
|
||||
if(nCnt == 0)
|
||||
{
|
||||
if(curFile.FullTextSearchEngine.CanSearch)
|
||||
{
|
||||
if(curFile.FullTextSearchEngine.Search(words, MaxResults, partialMatches, titleOnly))
|
||||
{
|
||||
dtResult = curFile.FullTextSearchEngine.Hits;
|
||||
dtResult.DefaultView.Sort = "Rating DESC";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(curFile.FullTextSearchEngine.CanSearch)
|
||||
{
|
||||
if(curFile.FullTextSearchEngine.Search(words, MaxResults, partialMatches, titleOnly))
|
||||
{
|
||||
DataTable table = curFile.FullTextSearchEngine.Hits;
|
||||
|
||||
// append rows from 2nd file
|
||||
foreach(DataRow curRow in table.Rows)
|
||||
{
|
||||
dtResult.ImportRow( curRow );
|
||||
}
|
||||
|
||||
dtResult.DefaultView.Sort = "Rating DESC";
|
||||
|
||||
// adjust max hits
|
||||
if(MaxResults >= 0)
|
||||
{
|
||||
if(dtResult.DefaultView.Count > MaxResults)
|
||||
{
|
||||
for(int i=MaxResults-1; i<dtResult.DefaultView.Count-1;i++)
|
||||
{
|
||||
if(dtResult.DefaultView[i].Row.RowState != DataRowState.Deleted)
|
||||
{
|
||||
dtResult.DefaultView[i].Row.Delete();
|
||||
dtResult.DefaultView[i].Row.AcceptChanges();
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
dtResult.AcceptChanges();
|
||||
dtResult.DefaultView.Sort = "Rating DESC";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nCnt++;
|
||||
}
|
||||
|
||||
return dtResult;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue