- Change dispatcher lock release to be more like documented in Windows Internals...
[reactos.git] / irc / TechBot / CHMLibrary / TableOfContents.cs
1 using System;
2 using System.Diagnostics;
3 using System.Collections;
4 using HtmlHelp.ChmDecoding;
5
6 namespace HtmlHelp
7 {
8 /// <summary>
9 /// The class <c>TableOfContents</c> holds the TOC of the htmlhelp system class.
10 /// </summary>
11 public class TableOfContents
12 {
13 private ArrayList _toc = new ArrayList();
14
15 /// <summary>
16 /// Standard constructor
17 /// </summary>
18 public TableOfContents()
19 {
20 }
21
22 /// <summary>
23 /// Constructor of the class
24 /// </summary>
25 /// <param name="toc"></param>
26 public TableOfContents(ArrayList toc)
27 {
28 _toc = toc;
29 }
30
31 /// <summary>
32 /// Gets the internal stored table of contents
33 /// </summary>
34 public ArrayList TOC
35 {
36 get { return _toc; }
37 }
38
39 /// <summary>
40 /// Clears the current toc
41 /// </summary>
42 public void Clear()
43 {
44 if(_toc!=null)
45 _toc.Clear();
46 }
47
48 /// <summary>
49 /// Gets the number of topics in the toc
50 /// </summary>
51 /// <returns>Returns the number of topics in the toc</returns>
52 public int Count()
53 {
54 if(_toc!=null)
55 return _toc.Count;
56 else
57 return 0;
58 }
59
60 /// <summary>
61 /// Merges the <c>arrToC</c> list to the one in this instance
62 /// </summary>
63 /// <param name="arrToC">the toc list which should be merged with the current one</param>
64 internal void MergeToC( ArrayList arrToC )
65 {
66 if(_toc==null)
67 _toc = new ArrayList();
68
69 MergeToC(_toc, arrToC, null);
70 }
71
72 /// <summary>
73 /// Merges the <c>arrToC</c> list to the one in this instance (called if merged files
74 /// were found in a CHM)
75 /// </summary>
76 /// <param name="arrToC">the toc list which should be merged with the current one</param>
77 /// <param name="openFiles">An arraylist of CHMFile instances.</param>
78 internal void MergeToC( ArrayList arrToC, ArrayList openFiles )
79 {
80 if(_toc==null)
81 _toc = new ArrayList();
82 MergeToC(_toc, arrToC, openFiles);
83 }
84
85 /// <summary>
86 /// Internal method for recursive toc merging
87 /// </summary>
88 /// <param name="globalLevel">level of global toc</param>
89 /// <param name="localLevel">level of local toc</param>
90 /// <param name="openFiles">An arraylist of CHMFile instances.</param>
91 private void MergeToC( ArrayList globalLevel, ArrayList localLevel, ArrayList openFiles )
92 {
93 foreach( TOCItem curItem in localLevel)
94 {
95 // if it is a part of the merged-links, we have to do nothing,
96 // because the method HtmlHelpSystem.RecalculateMergeLinks() has already
97 // placed this item at its correct position.
98 if(!IsMergedItem(curItem.Name, curItem.Local, openFiles))
99 {
100 TOCItem globalItem = ContainsToC(globalLevel, curItem.Name);
101 if(globalItem == null)
102 {
103 // the global toc doesn't have a topic with this name
104 // so we need to add the complete toc node to the global toc
105
106 globalLevel.Add( curItem );
107 }
108 else
109 {
110 // the global toc contains the current topic
111 // advance to the next level
112
113 if( (globalItem.Local.Length <= 0) && (curItem.Local.Length > 0) )
114 {
115 // set the associated url
116 globalItem.Local = curItem.Local;
117 globalItem.ChmFile = curItem.ChmFile;
118 }
119
120 MergeToC(globalItem.Children, curItem.Children);
121 }
122 }
123 }
124 }
125
126 /// <summary>
127 /// Checks if the item is part of the merged-links
128 /// </summary>
129 /// <param name="name">name of the topic</param>
130 /// <param name="local">local of the topic</param>
131 /// <param name="openFiles">An arraylist of CHMFile instances.</param>
132 /// <returns>Returns true if this item is part of the merged-links</returns>
133 private bool IsMergedItem(string name, string local, ArrayList openFiles)
134 {
135 if(openFiles==null)
136 return false;
137
138 foreach(CHMFile curFile in openFiles)
139 {
140 foreach(TOCItem curItem in curFile.MergLinks)
141 if( (curItem.Name == name) && (curItem.Local == local) )
142 return true;
143 }
144 return false;
145 }
146
147 /// <summary>
148 /// Checks if a topicname exists in a SINGLE toc level
149 /// </summary>
150 /// <param name="arrToC">toc list</param>
151 /// <param name="Topic">topic to search</param>
152 /// <returns>Returns the topic item if found, otherwise null</returns>
153 private TOCItem ContainsToC(ArrayList arrToC, string Topic)
154 {
155 foreach(TOCItem curItem in arrToC)
156 {
157 if(curItem.Name == Topic)
158 return curItem;
159 }
160
161 return null;
162 }
163
164 /// <summary>
165 /// Searches the table of contents for a special topic
166 /// </summary>
167 /// <param name="topic">topic to search</param>
168 /// <returns>Returns an instance of TOCItem if found, otherwise null</returns>
169 public TOCItem SearchTopic(string topic)
170 {
171 return SearchTopic(topic, _toc);
172 }
173
174 /// <summary>
175 /// Internal recursive tree search
176 /// </summary>
177 /// <param name="topic">topic to search</param>
178 /// <param name="searchIn">tree level list to look in</param>
179 /// <returns>Returns an instance of TOCItem if found, otherwise null</returns>
180 private TOCItem SearchTopic(string topic, ArrayList searchIn)
181 {
182 foreach(TOCItem curItem in searchIn)
183 {
184 if(curItem.Name.ToLower() == topic.ToLower() )
185 return curItem;
186
187 if(curItem.Children.Count>0)
188 {
189 TOCItem nf = SearchTopic(topic, curItem.Children);
190 if(nf != null)
191 return nf;
192 }
193 }
194
195 return null;
196 }
197 }
198 }