using System; using System.Diagnostics; using System.Collections; using HtmlHelp.ChmDecoding; namespace HtmlHelp { /// <summary> /// The class <c>TableOfContents</c> holds the TOC of the htmlhelp system class. /// </summary> public class TableOfContents { private ArrayList _toc = new ArrayList(); /// <summary> /// Standard constructor /// </summary> public TableOfContents() { } /// <summary> /// Constructor of the class /// </summary> /// <param name="toc"></param> public TableOfContents(ArrayList toc) { _toc = toc; } /// <summary> /// Gets the internal stored table of contents /// </summary> public ArrayList TOC { get { return _toc; } } /// <summary> /// Clears the current toc /// </summary> public void Clear() { if(_toc!=null) _toc.Clear(); } /// <summary> /// Gets the number of topics in the toc /// </summary> /// <returns>Returns the number of topics in the toc</returns> public int Count() { if(_toc!=null) return _toc.Count; else return 0; } /// <summary> /// Merges the <c>arrToC</c> list to the one in this instance /// </summary> /// <param name="arrToC">the toc list which should be merged with the current one</param> internal void MergeToC( ArrayList arrToC ) { if(_toc==null) _toc = new ArrayList(); MergeToC(_toc, arrToC, null); } /// <summary> /// Merges the <c>arrToC</c> list to the one in this instance (called if merged files /// were found in a CHM) /// </summary> /// <param name="arrToC">the toc list which should be merged with the current one</param> /// <param name="openFiles">An arraylist of CHMFile instances.</param> internal void MergeToC( ArrayList arrToC, ArrayList openFiles ) { if(_toc==null) _toc = new ArrayList(); MergeToC(_toc, arrToC, openFiles); } /// <summary> /// Internal method for recursive toc merging /// </summary> /// <param name="globalLevel">level of global toc</param> /// <param name="localLevel">level of local toc</param> /// <param name="openFiles">An arraylist of CHMFile instances.</param> private void MergeToC( ArrayList globalLevel, ArrayList localLevel, ArrayList openFiles ) { foreach( TOCItem curItem in localLevel) { // if it is a part of the merged-links, we have to do nothing, // because the method HtmlHelpSystem.RecalculateMergeLinks() has already // placed this item at its correct position. if(!IsMergedItem(curItem.Name, curItem.Local, openFiles)) { TOCItem globalItem = ContainsToC(globalLevel, curItem.Name); if(globalItem == null) { // the global toc doesn't have a topic with this name // so we need to add the complete toc node to the global toc globalLevel.Add( curItem ); } else { // the global toc contains the current topic // advance to the next level if( (globalItem.Local.Length <= 0) && (curItem.Local.Length > 0) ) { // set the associated url globalItem.Local = curItem.Local; globalItem.ChmFile = curItem.ChmFile; } MergeToC(globalItem.Children, curItem.Children); } } } } /// <summary> /// Checks if the item is part of the merged-links /// </summary> /// <param name="name">name of the topic</param> /// <param name="local">local of the topic</param> /// <param name="openFiles">An arraylist of CHMFile instances.</param> /// <returns>Returns true if this item is part of the merged-links</returns> private bool IsMergedItem(string name, string local, ArrayList openFiles) { if(openFiles==null) return false; foreach(CHMFile curFile in openFiles) { foreach(TOCItem curItem in curFile.MergLinks) if( (curItem.Name == name) && (curItem.Local == local) ) return true; } return false; } /// <summary> /// Checks if a topicname exists in a SINGLE toc level /// </summary> /// <param name="arrToC">toc list</param> /// <param name="Topic">topic to search</param> /// <returns>Returns the topic item if found, otherwise null</returns> private TOCItem ContainsToC(ArrayList arrToC, string Topic) { foreach(TOCItem curItem in arrToC) { if(curItem.Name == Topic) return curItem; } return null; } /// <summary> /// Searches the table of contents for a special topic /// </summary> /// <param name="topic">topic to search</param> /// <returns>Returns an instance of TOCItem if found, otherwise null</returns> public TOCItem SearchTopic(string topic) { return SearchTopic(topic, _toc); } /// <summary> /// Internal recursive tree search /// </summary> /// <param name="topic">topic to search</param> /// <param name="searchIn">tree level list to look in</param> /// <returns>Returns an instance of TOCItem if found, otherwise null</returns> private TOCItem SearchTopic(string topic, ArrayList searchIn) { foreach(TOCItem curItem in searchIn) { if(curItem.Name.ToLower() == topic.ToLower() ) return curItem; if(curItem.Children.Count>0) { TOCItem nf = SearchTopic(topic, curItem.Children); if(nf != null) return nf; } } return null; } } }