using System; using System.IO; using System.Text; using System.Collections; using HtmlHelp.ChmDecoding; namespace HtmlHelp { /// <summary> /// The class <c>IndexItem</c> implements an help-index item /// </summary> public sealed class IndexItem : IComparable { /// <summary> /// Internal member storing the keyword /// </summary> private string _keyWord = ""; /// <summary> /// Internal member storing all associated information type strings /// </summary> private ArrayList _infoTypeStrings = new ArrayList(); /// <summary> /// Internal member storing the flag if this is a see-also keyword /// </summary> private bool _isSeeAlso = false; /// <summary> /// Internal member storing the indent of the keyword /// </summary> private int _indent = 0; /// <summary> /// Internal member storing the last index of the keyword in the seperated list /// </summary> private int _charIndex = 0; /// <summary> /// Internal member storing the entry index /// </summary> private int _entryIndex = 0; /// <summary> /// Internal member storing an array of see-also values /// </summary> private string[] _seeAlso = new string[0]; /// <summary> /// Internal member storing an array of topic offsets /// </summary> private int[] _nTopics = new int[0]; /// <summary> /// Internal member storing the topics /// </summary> private ArrayList _Topics = null; /// <summary> /// Associated CHMFile instance /// </summary> private CHMFile _chmFile = null; /// <summary> /// Internal flag specifying the chm file path /// </summary> private string _chmFileName = ""; /// <summary> /// Constructor of the class /// </summary> /// <param name="chmFile">associated CHMFile instance</param> /// <param name="keyWord">keyword</param> /// <param name="isSeeAlso">true if it is a see-also keyword</param> /// <param name="indent">indent of the entry</param> /// <param name="charIndex">char index of the last keyword in the separated list</param> /// <param name="entryIndex">index of the entry</param> /// <param name="seeAlsoValues">string array with see-also values</param> /// <param name="topicOffsets">integer array with topic offsets</param> internal IndexItem(CHMFile chmFile, string keyWord, bool isSeeAlso, int indent, int charIndex, int entryIndex, string[] seeAlsoValues, int[] topicOffsets) { _chmFile = chmFile; _chmFileName = _chmFile.ChmFilePath; _keyWord = keyWord; _isSeeAlso = isSeeAlso; _indent = indent; _charIndex = charIndex; _entryIndex = entryIndex; _seeAlso = seeAlsoValues; _nTopics = topicOffsets; } /// <summary> /// Standard constructor /// </summary> public IndexItem() { } #region Data dumping /// <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 chm filename should be written</param> internal void Dump(ref BinaryWriter writer, bool writeFileName) { int i=0; writer.Write(_keyWord); writer.Write(_isSeeAlso); writer.Write(_indent); if(writeFileName) writer.Write(_chmFileName); writer.Write(_infoTypeStrings.Count); for(i=0; i<_infoTypeStrings.Count; i++) writer.Write( (_infoTypeStrings[i]).ToString() ); writer.Write(_seeAlso.Length); for(i=0; i<_seeAlso.Length; i++) { if(_seeAlso[i] == null) writer.Write(""); else writer.Write( _seeAlso[i] ); } writer.Write(Topics.Count); for(i=0; i<Topics.Count; i++) { IndexTopic topic = ((IndexTopic)(Topics[i])); topic.Dump(ref writer); } } /// <summary> /// Dump the class data to a binary writer /// </summary> /// <param name="writer">writer to write the data</param> internal void Dump(ref BinaryWriter writer) { Dump(ref writer, false); } /// <summary> /// Reads the object data from a dump store /// </summary> /// <param name="reader">reader to read the data</param> /// <param name="filesList">filelist from helpsystem</param> internal bool ReadDump(ref BinaryReader reader, ArrayList filesList) { int i=0; _keyWord = reader.ReadString(); _isSeeAlso = reader.ReadBoolean(); _indent = reader.ReadInt32(); _chmFileName = reader.ReadString(); foreach(CHMFile curFile in filesList) { if(curFile.ChmFilePath == _chmFileName) { _chmFile = curFile; break; } } if(_chmFile==null) return false; int nCnt = reader.ReadInt32(); for(i=0; i<nCnt; i++) { string sIT = reader.ReadString(); _infoTypeStrings.Add(sIT); } nCnt = reader.ReadInt32(); _seeAlso = new string[nCnt]; for(i=0; i<nCnt; i++) { _seeAlso[i] = reader.ReadString(); } nCnt = reader.ReadInt32(); for(i=0; i<nCnt; i++) { IndexTopic topic = new IndexTopic("","","",""); topic.SetChmInfo( _chmFile.CompileFile, _chmFile.ChmFilePath); topic.AssociatedFile = _chmFile; topic.ReadDump(ref reader); Topics.Add(topic); } return true; } /// <summary> /// Reads the object data from a dump store /// </summary> /// <param name="reader">reader to read the data</param> internal void ReadDump(ref BinaryReader reader) { int i=0; _keyWord = reader.ReadString(); _isSeeAlso = reader.ReadBoolean(); _indent = reader.ReadInt32(); int nCnt = reader.ReadInt32(); for(i=0; i<nCnt; i++) { string sIT = reader.ReadString(); _infoTypeStrings.Add(sIT); } nCnt = reader.ReadInt32(); _seeAlso = new string[nCnt]; for(i=0; i<nCnt; i++) { _seeAlso[i] = reader.ReadString(); } nCnt = reader.ReadInt32(); for(i=0; i<nCnt; i++) { IndexTopic topic = new IndexTopic("","","",""); topic.AssociatedFile = _chmFile; topic.SetChmInfo( _chmFile.CompileFile, _chmFile.ChmFilePath); topic.ReadDump(ref reader); Topics.Add(topic); } } #endregion /// <summary> /// Implements the compareto method which allows sorting. /// </summary> /// <param name="obj">object to compare to</param> /// <returns>See <see cref="System.IComparable">IComparable.CompareTo()</see></returns> public int CompareTo(object obj) { if( obj.GetType() == this.GetType() ) { IndexItem cmp = (IndexItem)obj; return this.KeyWordPath.CompareTo( cmp.KeyWordPath ); } return 0; } /// <summary> /// Gets/Sets the associated CHMFile instance /// </summary> internal CHMFile ChmFile { get { return _chmFile; } set { _chmFile = value; } } /// <summary> /// Gets the ArrayList which holds all information types/categories this item is associated /// </summary> internal ArrayList InfoTypeStrings { get { return _infoTypeStrings; } } /// <summary> /// Adds a see-also string to the index item and marks it as see also item /// </summary> /// <param name="seeAlsoString">see also string to add</param> internal void AddSeeAlso(string seeAlsoString) { string[] seeAlso = new string[ _seeAlso.Length +1 ]; for(int i=0; i<_seeAlso.Length; i++) seeAlso[i] = _seeAlso[i]; seeAlso[_seeAlso.Length] = seeAlsoString; _seeAlso = seeAlso; _isSeeAlso = true; } /// <summary> /// Gets/Sets the full keyword-path of this item ( ", " separated list) /// </summary> public string KeyWordPath { get { return _keyWord; } set { _keyWord = value; } } /// <summary> /// Gets the keyword of this item /// </summary> public string KeyWord { get { return _keyWord.Substring(_charIndex, _keyWord.Length-_charIndex); } } /// <summary> /// Gets the keyword of this item with prefixing indent spaces /// </summary> public string IndentKeyWord { get { string sKW = this.KeyWord; StringBuilder sb = new StringBuilder("",this.Indent*3 + sKW.Length); for(int i=0; i<this.Indent; i++) sb.Append(" "); sb.Append(sKW); return sb.ToString(); } } /// <summary> /// Gets/Sets the see-also flag of this item /// </summary> public bool IsSeeAlso { get { return _isSeeAlso; } set { _isSeeAlso = value; } } /// <summary> /// Gets/Sets the listbox indent for this item /// </summary> public int Indent { get { return _indent; } set { _indent = value; } } /// <summary> /// Gets/Sets the character index of an indent keyword /// </summary> public int CharIndex { get { return _charIndex; } set { _charIndex = value; } } /// <summary> /// Gets the see-also values of this item /// </summary> public string[] SeeAlso { get { return _seeAlso; } } /// <summary> /// Gets an array with the associated topics /// </summary> public ArrayList Topics { get { if( _Topics == null ) { if(IsSeeAlso) { _Topics = new ArrayList(); } else { if( (_chmFile != null) && (_chmFile.TopicsFile != null) ) { _Topics = new ArrayList(); for(int i=0; i<_nTopics.Length; i++) { IndexTopic newTopic = IndexTopic.FromTopicEntry((TopicEntry)_chmFile.TopicsFile.TopicTable[ _nTopics[i] ]); newTopic.AssociatedFile = _chmFile; _Topics.Add( newTopic ); } } else { _Topics = new ArrayList(); } } } return _Topics; } } } }