/// <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> /// Dump the class data to a binary writer /// </summary> /// <param name="writer">writer to write the data</param> /// <param name="writeFilename">true if the chmfile name should be written</param> internal void Dump(ref BinaryWriter writer, bool writeFilename) { writer.Write((int)_tocMode); writer.Write(_topicOffset); writer.Write(_name); if ((_tocMode == DataMode.TextBased) || (_topicOffset < 0)) { writer.Write(_local); } writer.Write(_imageIndex); writer.Write(_mergeLink); if (writeFilename) { writer.Write(_chmFile); } writer.Write(_infoTypeStrings.Count); for (int i = 0; i < _infoTypeStrings.Count; i++) { writer.Write((_infoTypeStrings[i]).ToString()); } writer.Write(_children.Count); for (int i = 0; i < _children.Count; i++) { TOCItem child = ((TOCItem)(_children[i])); child.Dump(ref writer, writeFilename); } }
/// <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> /// 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); }
/// <summary> /// Reads the object data from a dump store /// </summary> /// <param name="reader">reader to read the data</param> /// <param name="readFilename">true if the chmfile name should be read</param> internal void ReadDump(ref BinaryReader reader, bool readFilename) { int i = 0; _tocMode = (DataMode)reader.ReadInt32(); _topicOffset = reader.ReadInt32(); _name = reader.ReadString(); if ((_tocMode == DataMode.TextBased) || (_topicOffset < 0)) { _local = reader.ReadString(); } _imageIndex = reader.ReadInt32(); _mergeLink = reader.ReadString(); if (readFilename) { _chmFile = reader.ReadString(); } int nCnt = reader.ReadInt32(); for (i = 0; i < nCnt; i++) { string sIT = reader.ReadString(); _infoTypeStrings.Add(sIT); } nCnt = reader.ReadInt32(); if (_associatedFile != null) { _chmFile = _associatedFile.ChmFilePath; } for (i = 0; i < nCnt; i++) { TOCItem child = new TOCItem(); child.AssociatedFile = _associatedFile; child.ReadDump(ref reader, readFilename); if (_associatedFile != null) { child.ChmFile = _associatedFile.ChmFilePath; } else if (!readFilename) { child.ChmFile = _chmFile; } child.Parent = this; _children.Add(child); if (child.MergeLink.Length > 0) { _associatedFile.MergLinks.Add(child); } } }
/// <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); } } } } } } } }