Root/
Source at commit 1322 created 12 years 8 months ago. By meklort, Add doxygen to utils folder | |
---|---|
1 | /******************************************************************************␊ |
2 | *␊ |
3 | * ␊ |
4 | *␊ |
5 | * Copyright (C) 1997-2011 by Dimitri van Heesch.␊ |
6 | *␊ |
7 | * Permission to use, copy, modify, and distribute this software and its␊ |
8 | * documentation under the terms of the GNU General Public License is hereby ␊ |
9 | * granted. No representations are made about the suitability of this software ␊ |
10 | * for any purpose. It is provided "as is" without express or implied warranty.␊ |
11 | * See the GNU General Public License for more details.␊ |
12 | *␊ |
13 | * Documents produced by Doxygen are derivative works derived from the␊ |
14 | * input used in their production; they are not affected by this license.␊ |
15 | *␊ |
16 | * The code is this file is largely based on a contribution from␊ |
17 | * Harm van der Heijden <H.v.d.Heijden@phys.tue.nl>␊ |
18 | * Please send thanks to him and bug reports to me :-)␊ |
19 | */␊ |
20 | ␊ |
21 | #include <stdio.h>␊ |
22 | #include <stdlib.h>␊ |
23 | #include <qlist.h>␊ |
24 | #include <qdict.h>␊ |
25 | #include <qregexp.h>␊ |
26 | #include "qtextcodec.h"␊ |
27 | #include "sortdict.h"␊ |
28 | ␊ |
29 | #include "htmlhelp.h"␊ |
30 | #include "config.h"␊ |
31 | #include "message.h"␊ |
32 | #include "doxygen.h"␊ |
33 | #include "language.h"␊ |
34 | #include "portable.h"␊ |
35 | ␊ |
36 | //----------------------------------------------------------------------------␊ |
37 | ␊ |
38 | struct IndexField␊ |
39 | {␊ |
40 | QCString name;␊ |
41 | QCString url;␊ |
42 | QCString anchor;␊ |
43 | bool link;␊ |
44 | bool reversed;␊ |
45 | };␊ |
46 | ␊ |
47 | class IndexFieldSDict : public SDict<IndexField>␊ |
48 | {␊ |
49 | public:␊ |
50 | IndexFieldSDict() : SDict<IndexField>(17) {}␊ |
51 | ~IndexFieldSDict() {}␊ |
52 | int compareItems(GCI item1, GCI item2)␊ |
53 | {␊ |
54 | return stricmp(((IndexField *)item1)->name,((IndexField *)item2)->name);␊ |
55 | }␊ |
56 | };␊ |
57 | ␊ |
58 | /*! A helper class for HtmlHelp that manages a two level index in ␊ |
59 | * alphabetical order ␊ |
60 | */␊ |
61 | class HtmlHelpIndex␊ |
62 | {␊ |
63 | public:␊ |
64 | HtmlHelpIndex();␊ |
65 | ~HtmlHelpIndex();␊ |
66 | void addItem(const char *first,const char *second, ␊ |
67 | const char *url, const char *anchor,␊ |
68 | bool hasLink,bool reversed);␊ |
69 | void writeFields(FTextStream &t);␊ |
70 | private:␊ |
71 | IndexFieldSDict *dict; ␊ |
72 | };␊ |
73 | ␊ |
74 | /*! Constructs a new HtmlHelp index */␊ |
75 | HtmlHelpIndex::HtmlHelpIndex()␊ |
76 | {␊ |
77 | dict = new IndexFieldSDict;␊ |
78 | dict->setAutoDelete(TRUE);␊ |
79 | }␊ |
80 | ␊ |
81 | /*! Destroys the HtmlHelp index */␊ |
82 | HtmlHelpIndex::~HtmlHelpIndex()␊ |
83 | {␊ |
84 | delete dict;␊ |
85 | }␊ |
86 | ␊ |
87 | /*! Stores an item in the index if it is not already present. ␊ |
88 | * Items are stored in alphetical order, by sorting on the␊ |
89 | * concatenation of \a level1 and \a level2 (if present).␊ |
90 | *␊ |
91 | * \param level1 the string at level 1 in the index.␊ |
92 | * \param level2 the string at level 2 in the index (or 0 if not applicable).␊ |
93 | * \param url the url of the documentation (without .html extension).␊ |
94 | * \param anchor the anchor of the documentation within the page.␊ |
95 | * \param hasLink if true, the url (without anchor) can be used in the ␊ |
96 | * level1 item, when writing the header of a list of level2 items.␊ |
97 | * \param reversed TRUE if level1 is the member name and level2 the compound␊ |
98 | * name.␊ |
99 | */␊ |
100 | void HtmlHelpIndex::addItem(const char *level1,const char *level2,␊ |
101 | const char *url,const char *anchor,bool hasLink,␊ |
102 | bool reversed)␊ |
103 | {␊ |
104 | QCString key = level1; ␊ |
105 | if (level2) key+= (QCString)"?" + level2;␊ |
106 | if (key.find(QRegExp("@[0-9]+"))!=-1) // skip anonymous stuff␊ |
107 | {␊ |
108 | return;␊ |
109 | }␊ |
110 | if (dict->find(key)==0) // new key␊ |
111 | {␊ |
112 | //printf(">>>>>>>>> HtmlHelpIndex::addItem(%s,%s,%s,%s)\n",␊ |
113 | // level1,level2,url,anchor);␊ |
114 | IndexField *f = new IndexField;␊ |
115 | f->name = key;␊ |
116 | f->url = url;␊ |
117 | f->anchor = anchor;␊ |
118 | f->link = hasLink;␊ |
119 | f->reversed = reversed;␊ |
120 | dict->append(key,f);␊ |
121 | }␊ |
122 | }␊ |
123 | ␊ |
124 | /*! Writes the sorted list of index items into a html like list.␊ |
125 | *␊ |
126 | * An list of calls with <code>name = level1,level2</code> as follows:␊ |
127 | * <pre>␊ |
128 | * a1,b1␊ |
129 | * a1,b2␊ |
130 | * a2,b1␊ |
131 | * a2,b2␊ |
132 | * a3␊ |
133 | * a4,b1␊ |
134 | * </pre>␊ |
135 | *␊ |
136 | * Will result in the following list:␊ |
137 | *␊ |
138 | * <pre>␊ |
139 | * a1 -> link to url if hasLink==TRUE␊ |
140 | * b1 -> link to url#anchor␊ |
141 | * b2 -> link to url#anchor␊ |
142 | * a2 -> link to url if hasLink==TRUE␊ |
143 | * b1 -> link to url#anchor␊ |
144 | * b2 -> link to url#anchor␊ |
145 | * a3 -> link to url if hasLink==TRUE␊ |
146 | * a4 -> link to url if hasLink==TRUE␊ |
147 | * b1 -> link to url#anchor ␊ |
148 | * </pre>␊ |
149 | */␊ |
150 | void HtmlHelpIndex::writeFields(FTextStream &t)␊ |
151 | {␊ |
152 | dict->sort();␊ |
153 | IndexFieldSDict::Iterator ifli(*dict);␊ |
154 | IndexField *f;␊ |
155 | QCString lastLevel1;␊ |
156 | bool level2Started=FALSE;␊ |
157 | for (;(f=ifli.current());++ifli)␊ |
158 | {␊ |
159 | QCString level1,level2;␊ |
160 | int i;␊ |
161 | if ((i=f->name.find('?'))!=-1)␊ |
162 | {␊ |
163 | level1 = f->name.left(i);␊ |
164 | level2 = f->name.right(f->name.length()-i-1); ␊ |
165 | }␊ |
166 | else␊ |
167 | {␊ |
168 | level1 = f->name.copy();␊ |
169 | }␊ |
170 | ␊ |
171 | if (level1!=lastLevel1)␊ |
172 | { // finish old list at level 2␊ |
173 | if (level2Started) t << " </UL>" << endl;␊ |
174 | level2Started=FALSE;␊ |
175 | ␊ |
176 | // <Antony>␊ |
177 | // Added this code so that an item with only one subitem is written␊ |
178 | // without any subitem.␊ |
179 | // For example:␊ |
180 | // a1, b1 -> will create only a1, not separate subitem for b1␊ |
181 | // a2, b2␊ |
182 | // a2, b3␊ |
183 | QCString nextLevel1;␊ |
184 | IndexField* fnext = ++ifli;␊ |
185 | if (fnext)␊ |
186 | {␊ |
187 | nextLevel1 = fnext->name.left(fnext->name.find('?'));␊ |
188 | --ifli;␊ |
189 | }␊ |
190 | if (level1 != nextLevel1)␊ |
191 | {␊ |
192 | level2 = "";␊ |
193 | }␊ |
194 | // </Antony>␊ |
195 | ␊ |
196 | if (level2.isEmpty())␊ |
197 | {␊ |
198 | t << " <LI><OBJECT type=\"text/sitemap\">";␊ |
199 | t << "<param name=\"Local\" value=\"" << f->url << Doxygen::htmlFileExtension;␊ |
200 | if (!f->anchor.isEmpty() && f->reversed) t << "#" << f->anchor; ␊ |
201 | t << "\">";␊ |
202 | t << "<param name=\"Name\" value=\"" << level1 << "\">"␊ |
203 | "</OBJECT>\n";␊ |
204 | }␊ |
205 | else␊ |
206 | {␊ |
207 | if (f->link)␊ |
208 | {␊ |
209 | t << " <LI><OBJECT type=\"text/sitemap\">";␊ |
210 | t << "<param name=\"Local\" value=\"" << f->url << Doxygen::htmlFileExtension;␊ |
211 | if (!f->anchor.isEmpty() && f->reversed) t << "#" << f->anchor; ␊ |
212 | t << "\">";␊ |
213 | t << "<param name=\"Name\" value=\"" << level1 << "\">"␊ |
214 | "</OBJECT>\n";␊ |
215 | }␊ |
216 | else␊ |
217 | {␊ |
218 | t << " <LI><OBJECT type=\"text/sitemap\">";␊ |
219 | t << "<param name=\"See Also\" value=\"" << level1 << "\">";␊ |
220 | t << "<param name=\"Name\" value=\"" << level1 << "\">"␊ |
221 | "</OBJECT>\n";␊ |
222 | }␊ |
223 | }␊ |
224 | }␊ |
225 | if (!level2Started && !level2.isEmpty())␊ |
226 | { // start new list at level 2␊ |
227 | t << " <UL>" << endl;␊ |
228 | level2Started=TRUE;␊ |
229 | }␊ |
230 | else if (level2Started && level2.isEmpty())␊ |
231 | { // end list at level 2␊ |
232 | t << " </UL>" << endl;␊ |
233 | level2Started=FALSE;␊ |
234 | }␊ |
235 | if (level2Started)␊ |
236 | {␊ |
237 | t << " <LI><OBJECT type=\"text/sitemap\">";␊ |
238 | t << "<param name=\"Local\" value=\"" << f->url << Doxygen::htmlFileExtension;␊ |
239 | if (!f->anchor.isEmpty()) t << "#" << f->anchor; ␊ |
240 | t << "\">";␊ |
241 | t << "<param name=\"Name\" value=\"" << level2 << "\">"␊ |
242 | "</OBJECT>\n";␊ |
243 | }␊ |
244 | lastLevel1 = level1.copy();␊ |
245 | } ␊ |
246 | if (level2Started) t << " </UL>" << endl;␊ |
247 | }␊ |
248 | ␊ |
249 | //----------------------------------------------------------------------------␊ |
250 | ␊ |
251 | HtmlHelp *HtmlHelp::theInstance = 0;␊ |
252 | ␊ |
253 | /*! Constructs an html object. ␊ |
254 | * The object has to be \link initialize() initialized\endlink before it can ␊ |
255 | * be used.␊ |
256 | */␊ |
257 | HtmlHelp::HtmlHelp() : indexFileDict(1009)␊ |
258 | {␊ |
259 | /* initial depth */␊ |
260 | dc = 0;␊ |
261 | cf = kf = 0;␊ |
262 | index = new HtmlHelpIndex;␊ |
263 | m_fromUtf8 = (void *)(-1);␊ |
264 | }␊ |
265 | ␊ |
266 | HtmlHelp::~HtmlHelp()␊ |
267 | {␊ |
268 | if (m_fromUtf8!=(void *)(-1)) portable_iconv_close(m_fromUtf8);␊ |
269 | }␊ |
270 | #if 0␊ |
271 | /*! return a reference to the one and only instance of this class. ␊ |
272 | */␊ |
273 | HtmlHelp *HtmlHelp::getInstance()␊ |
274 | {␊ |
275 | if (theInstance==0) theInstance = new HtmlHelp;␊ |
276 | return theInstance;␊ |
277 | }␊ |
278 | #endif␊ |
279 | ␊ |
280 | static QDict<QCString> s_languageDict;␊ |
281 | ␊ |
282 | /*! This will create a contents file (index.hhc) and a index file (index.hhk)␊ |
283 | * and write the header of those files. ␊ |
284 | * It also creates a project file (index.hhp)␊ |
285 | * \sa finalize()␊ |
286 | */␊ |
287 | void HtmlHelp::initialize()␊ |
288 | {␊ |
289 | const char *str = Config_getString("CHM_INDEX_ENCODING");␊ |
290 | if (!str) str = "CP1250"; // use safe and likely default␊ |
291 | m_fromUtf8 = portable_iconv_open(str,"UTF-8"); ␊ |
292 | if (m_fromUtf8==(void *)(-1))␊ |
293 | {␊ |
294 | err("Error: unsupported character conversion for CHM_INDEX_ENCODING: '%s'->'UTF-8'\n", str);␊ |
295 | exit(1);␊ |
296 | }␊ |
297 | ␊ |
298 | /* open the contents file */␊ |
299 | QCString fName = Config_getString("HTML_OUTPUT") + "/index.hhc";␊ |
300 | cf = new QFile(fName);␊ |
301 | if (!cf->open(IO_WriteOnly))␊ |
302 | {␊ |
303 | err("Could not open file %s for writing\n",fName.data());␊ |
304 | exit(1);␊ |
305 | }␊ |
306 | /* Write the header of the contents file */␊ |
307 | cts.setDevice(cf);␊ |
308 | cts << "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n"␊ |
309 | "<HTML><HEAD></HEAD><BODY>\n"␊ |
310 | "<OBJECT type=\"text/site properties\">\n"␊ |
311 | "<param name=\"FrameName\" value=\"right\">\n"␊ |
312 | "</OBJECT>\n"␊ |
313 | "<UL>\n";␊ |
314 | ␊ |
315 | /* open the contents file */␊ |
316 | fName = Config_getString("HTML_OUTPUT") + "/index.hhk";␊ |
317 | kf = new QFile(fName);␊ |
318 | if (!kf->open(IO_WriteOnly))␊ |
319 | {␊ |
320 | err("Could not open file %s for writing\n",fName.data());␊ |
321 | exit(1);␊ |
322 | }␊ |
323 | /* Write the header of the contents file */␊ |
324 | kts.setDevice(kf);␊ |
325 | kts << "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n"␊ |
326 | "<HTML><HEAD></HEAD><BODY>\n"␊ |
327 | "<OBJECT type=\"text/site properties\">\n"␊ |
328 | "<param name=\"FrameName\" value=\"right\">\n"␊ |
329 | "</OBJECT>\n"␊ |
330 | "<UL>\n";␊ |
331 | ␊ |
332 | /* language codes for Html help␊ |
333 | 0x405 Czech␊ |
334 | 0x406 Danish␊ |
335 | 0x413 Dutch␊ |
336 | 0xC09 English (Australia)␊ |
337 | 0x809 English (Britain)␊ |
338 | 0x1009 English (Canada)␊ |
339 | 0x1809 English (Ireland)␊ |
340 | 0x1409 English (New Zealand)␊ |
341 | 0x1C09 English (South Africa)␊ |
342 | 0x409 English (United States)␊ |
343 | 0x40B Finnish␊ |
344 | 0x40C French␊ |
345 | 0x407 German␊ |
346 | 0x408 Greece␊ |
347 | 0x40E Hungarian␊ |
348 | 0x410 Italian␊ |
349 | 0x814 Norwegian␊ |
350 | 0x415 Polish␊ |
351 | 0x816 Portuguese(Portugal)␊ |
352 | 0x416 Portuguese(Brazil)␊ |
353 | 0x419 Russian␊ |
354 | 0x80A Spanish(Mexico)␊ |
355 | 0xC0A Spanish(Modern Sort)␊ |
356 | 0x40A Spanish(Traditional Sort)␊ |
357 | 0x41D Swedish␊ |
358 | 0x41F Turkey␊ |
359 | 0x411 Japanese␊ |
360 | 0x412 Korean␊ |
361 | 0x804 Chinese (PRC)␊ |
362 | 0x404 Chinese (Taiwan)␊ |
363 | ␊ |
364 | New LCIDs:␊ |
365 | ␉ 0x421 Indonesian␊ |
366 | ␉ 0x41A Croatian␊ |
367 | ␉ 0x418 Romanian␊ |
368 | ␉ 0x424 Slovenian␊ |
369 | ␉ 0x41B Slovak␊ |
370 | ␉ 0x422 Ukrainian␊ |
371 | ␉ 0x81A Serbian (Serbia, Latin)␊ |
372 | ␉ 0x403 Catalan␊ |
373 | ␉ 0x427 Lithuanian␊ |
374 | ␉ 0x436 Afrikaans␊ |
375 | ␉ 0x42A Vietnamese␊ |
376 | ␉ 0x429 Persian (Iran)␊ |
377 | ␉ 0xC01 Arabic (Egypt) - I don't know which version of arabic is used inside translator_ar.h ,␊ |
378 | so I have chosen Egypt at random␊ |
379 | ␊ |
380 | */␊ |
381 | s_languageDict.setAutoDelete(TRUE);␊ |
382 | s_languageDict.clear();␊ |
383 | s_languageDict.insert("czech", new QCString("0x405 Czech"));␊ |
384 | s_languageDict.insert("danish", new QCString("0x406 Danish"));␊ |
385 | s_languageDict.insert("dutch", new QCString("0x413 Dutch"));␊ |
386 | s_languageDict.insert("finnish", new QCString("0x40B Finnish"));␊ |
387 | s_languageDict.insert("french", new QCString("0x40C French"));␊ |
388 | s_languageDict.insert("german", new QCString("0x407 German"));␊ |
389 | s_languageDict.insert("greek", new QCString("0x408 Greece"));␊ |
390 | s_languageDict.insert("hungarian", new QCString("0x40E Hungarian"));␊ |
391 | s_languageDict.insert("italian", new QCString("0x410 Italian"));␊ |
392 | s_languageDict.insert("norwegian", new QCString("0x814 Norwegian"));␊ |
393 | s_languageDict.insert("polish", new QCString("0x415 Polish"));␊ |
394 | s_languageDict.insert("portuguese", new QCString("0x816 Portuguese(Portugal)"));␊ |
395 | s_languageDict.insert("brazil", new QCString("0x416 Portuguese(Brazil)"));␊ |
396 | s_languageDict.insert("russian", new QCString("0x419 Russian"));␊ |
397 | s_languageDict.insert("spanish", new QCString("0x40A Spanish(Traditional Sort)"));␊ |
398 | s_languageDict.insert("swedish", new QCString("0x41D Swedish"));␊ |
399 | s_languageDict.insert("turkish", new QCString("0x41F Turkey"));␊ |
400 | s_languageDict.insert("japanese", new QCString("0x411 Japanese"));␊ |
401 | s_languageDict.insert("japanese-en", new QCString("0x411 Japanese"));␊ |
402 | s_languageDict.insert("korean", new QCString("0x412 Korean"));␊ |
403 | s_languageDict.insert("korean-en", new QCString("0x412 Korean"));␊ |
404 | s_languageDict.insert("chinese", new QCString("0x804 Chinese (PRC)"));␊ |
405 | s_languageDict.insert("chinese-traditional", new QCString("0x404 Chinese (Taiwan)"));␊ |
406 | ␊ |
407 | // new LCIDs␊ |
408 | s_languageDict.insert("indonesian", new QCString("0x412 Indonesian"));␊ |
409 | s_languageDict.insert("croatian", new QCString("0x41A Croatian"));␊ |
410 | s_languageDict.insert("romanian", new QCString("0x418 Romanian"));␊ |
411 | s_languageDict.insert("slovene", new QCString("0x424 Slovenian"));␊ |
412 | s_languageDict.insert("slovak", new QCString("0x41B Slovak"));␊ |
413 | s_languageDict.insert("ukrainian", new QCString("0x422 Ukrainian"));␊ |
414 | s_languageDict.insert("serbian", new QCString("0x81A Serbian (Serbia, Latin)"));␊ |
415 | s_languageDict.insert("catalan", new QCString("0x403 Catalan"));␊ |
416 | s_languageDict.insert("lithuanian", new QCString("0x427 Lithuanian"));␊ |
417 | s_languageDict.insert("afrikaans", new QCString("0x436 Afrikaans"));␊ |
418 | s_languageDict.insert("vietnamese", new QCString("0x42A Vietnamese"));␊ |
419 | s_languageDict.insert("persian", new QCString("0x429 Persian (Iran)"));␊ |
420 | s_languageDict.insert("arabic", new QCString("0xC01 Arabic (Egypt)"));␊ |
421 | }␊ |
422 | ␊ |
423 | ␊ |
424 | static QCString getLanguageString()␊ |
425 | {␊ |
426 | if (!theTranslator->idLanguage().isEmpty())␊ |
427 | {␊ |
428 | QCString *s = s_languageDict[theTranslator->idLanguage()];␊ |
429 | if (s)␊ |
430 | {␊ |
431 | return *s;␊ |
432 | }␊ |
433 | }␊ |
434 | // default language␊ |
435 | return "0x409 English (United States)";␊ |
436 | }␊ |
437 | ␊ |
438 | ␊ |
439 | ␊ |
440 | void HtmlHelp::createProjectFile()␊ |
441 | {␊ |
442 | /* Write the project file */␊ |
443 | QCString fName = Config_getString("HTML_OUTPUT") + "/index.hhp";␊ |
444 | QFile f(fName);␊ |
445 | if (f.open(IO_WriteOnly))␊ |
446 | {␊ |
447 | FTextStream t(&f);␊ |
448 | ␊ |
449 | QCString indexName="index"+Doxygen::htmlFileExtension;␊ |
450 | //if (Config_getBool("GENERATE_TREEVIEW")) indexName="main"+Doxygen::htmlFileExtension;␊ |
451 | t << "[OPTIONS]\n";␊ |
452 | if (!Config_getString("CHM_FILE").isEmpty())␊ |
453 | {␊ |
454 | t << "Compiled file=" << Config_getString("CHM_FILE") << "\n";␊ |
455 | }␊ |
456 | t << "Compatibility=1.1\n"␊ |
457 | "Full-text search=Yes\n"␊ |
458 | "Contents file=index.hhc\n"␊ |
459 | "Default Window=main\n"␊ |
460 | "Default topic=" << indexName << "\n"␊ |
461 | "Index file=index.hhk\n"␊ |
462 | "Language=" << getLanguageString() << endl;␊ |
463 | if (Config_getBool("BINARY_TOC")) t << "Binary TOC=YES\n";␊ |
464 | if (Config_getBool("GENERATE_CHI")) t << "Create CHI file=YES\n";␊ |
465 | t << "Title=" << recode(Config_getString("PROJECT_NAME")) << endl << endl;␊ |
466 | ␊ |
467 | t << "[WINDOWS]" << endl;␊ |
468 | ␊ |
469 | // NOTE: the 0x10387e number is a set of bits specifying the buttons␊ |
470 | // which should appear in the CHM viewer; that specific value␊ |
471 | // means "show all buttons including the font-size one";␊ |
472 | // the font-size one is not normally settable by the HTML Help Workshop␊ |
473 | // utility but the way to set it is described here:␊ |
474 | // http://support.microsoft.com/?scid=kb%3Ben-us%3B240062&x=17&y=18␊ |
475 | t << "main=\"" << recode(Config_getString("PROJECT_NAME")) << "\",\"index.hhc\","␊ |
476 | "\"index.hhk\",\"" << indexName << "\",\"" << ␊ |
477 | indexName << "\",,,,,0x23520,,0x10387e,,,,,,,,0" << endl << endl;␊ |
478 | ␊ |
479 | t << "[FILES]" << endl;␊ |
480 | char *s = indexFiles.first();␊ |
481 | while (s)␊ |
482 | {␊ |
483 | t << s << endl;␊ |
484 | s = indexFiles.next();␊ |
485 | }␊ |
486 | #if 0␊ |
487 | // items not found by the html help compiler scan.␊ |
488 | t << "tabs.css" << endl;␊ |
489 | t << "tab_a.png" << endl;␊ |
490 | t << "tab_b.png" << endl;␊ |
491 | t << "tab_h.png" << endl;␊ |
492 | t << "tab_s.png" << endl;␊ |
493 | t << "nav_h.png" << endl;␊ |
494 | t << "nav_f.png" << endl;␊ |
495 | t << "bc_s.png" << endl;␊ |
496 | if (Config_getBool("HTML_DYNAMIC_SECTIONS"))␊ |
497 | {␊ |
498 | t << "open.png" << endl;␊ |
499 | t << "closed.png" << endl;␊ |
500 | }␊ |
501 | if (Config_getBool("GENERATE_HTMLHELP"))␊ |
502 | {␊ |
503 | t << "ftv2blank.png" << endl;␊ |
504 | t << "ftv2doc.png" << endl;␊ |
505 | t << "ftv2folderclosed.png" << endl;␊ |
506 | t << "ftv2folderopen.png" << endl;␊ |
507 | t << "ftv2lastnode.png" << endl;␊ |
508 | t << "ftv2link.png" << endl;␊ |
509 | t << "ftv2mlastnode.png" << endl;␊ |
510 | t << "ftv2mnode.png" << endl;␊ |
511 | t << "ftv2node.png" << endl;␊ |
512 | t << "ftv2plastnode.png" << endl;␊ |
513 | t << "ftv2pnode.png" << endl;␊ |
514 | t << "ftv2vertline.png" << endl;␊ |
515 | }␊ |
516 | if (Config_getBool("SEARCHENGINE"))␊ |
517 | {␊ |
518 | t << "search_l.png" << endl;␊ |
519 | t << "search_m.png" << endl;␊ |
520 | t << "search_r.png" << endl;␊ |
521 | if (Config_getBool("SERVER_BASED_SEARCH"))␊ |
522 | {␊ |
523 | t << "mag.png" << endl;␊ |
524 | }␊ |
525 | else␊ |
526 | {␊ |
527 | t << "mag_sel.png" << endl;␊ |
528 | t << "close.png" << endl;␊ |
529 | }␊ |
530 | }␊ |
531 | #endif␊ |
532 | uint i;␊ |
533 | for (i=0;i<imageFiles.count();i++)␊ |
534 | {␊ |
535 | t << imageFiles.at(i) << endl;␊ |
536 | }␊ |
537 | f.close();␊ |
538 | }␊ |
539 | else␊ |
540 | {␊ |
541 | err("Could not open file %s for writing\n",fName.data());␊ |
542 | }␊ |
543 | }␊ |
544 | ␊ |
545 | void HtmlHelp::addIndexFile(const char *s)␊ |
546 | {␊ |
547 | if (indexFileDict.find(s)==0)␊ |
548 | {␊ |
549 | indexFiles.append(s);␊ |
550 | indexFileDict.insert(s,(void *)0x8);␊ |
551 | }␊ |
552 | }␊ |
553 | ␊ |
554 | /*! Finalizes the HTML help. This will finish and close the␊ |
555 | * contents file (index.hhc) and the index file (index.hhk).␊ |
556 | * \sa initialize()␊ |
557 | */␊ |
558 | void HtmlHelp::finalize()␊ |
559 | {␊ |
560 | // end the contents file␊ |
561 | cts << "</UL>\n";␊ |
562 | cts << "</BODY>\n";␊ |
563 | cts << "</HTML>\n";␊ |
564 | cts.unsetDevice();␊ |
565 | cf->close();␊ |
566 | delete cf;␊ |
567 | ␊ |
568 | index->writeFields(kts);␊ |
569 | ␊ |
570 | // end the index file␊ |
571 | kts << "</UL>\n";␊ |
572 | kts << "</BODY>\n";␊ |
573 | kts << "</HTML>\n";␊ |
574 | kts.unsetDevice();␊ |
575 | kf->close();␊ |
576 | delete kf;␊ |
577 | ␊ |
578 | createProjectFile();␊ |
579 | s_languageDict.clear();␊ |
580 | }␊ |
581 | ␊ |
582 | /*! Increase the level of the contents hierarchy. ␊ |
583 | * This will start a new unnumbered HTML list in contents file.␊ |
584 | * \sa decContentsDepth()␊ |
585 | */␊ |
586 | void HtmlHelp::incContentsDepth()␊ |
587 | {␊ |
588 | int i; for (i=0;i<dc+1;i++) cts << " ";␊ |
589 | cts << "<UL>\n";␊ |
590 | ++dc;␊ |
591 | }␊ |
592 | ␊ |
593 | /*! Decrease the level of the contents hierarchy.␊ |
594 | * This will end the unnumber HTML list.␊ |
595 | * \sa incContentsDepth()␊ |
596 | */␊ |
597 | void HtmlHelp::decContentsDepth()␊ |
598 | {␊ |
599 | int i; for (i=0;i<dc;i++) cts << " ";␊ |
600 | cts << "</UL>\n";␊ |
601 | --dc;␊ |
602 | }␊ |
603 | ␊ |
604 | QCString HtmlHelp::recode(const QCString &s) ␊ |
605 | {␊ |
606 | int iSize = s.length();␊ |
607 | int oSize = iSize*4+1;␊ |
608 | QCString output(oSize);␊ |
609 | size_t iLeft = iSize;␊ |
610 | size_t oLeft = oSize;␊ |
611 | const char *iPtr = s.data();␊ |
612 | char *oPtr = output.data();␊ |
613 | if (!portable_iconv(m_fromUtf8,&iPtr,&iLeft,&oPtr,&oLeft))␊ |
614 | {␊ |
615 | oSize -= oLeft;␊ |
616 | output.resize(oSize+1);␊ |
617 | output.at(oSize)='\0';␊ |
618 | return output;␊ |
619 | }␊ |
620 | else␊ |
621 | {␊ |
622 | return s;␊ |
623 | }␊ |
624 | }␊ |
625 | ␊ |
626 | /*! Add an list item to the contents file.␊ |
627 | * \param isDir boolean indicating if this is a dir or file entry␊ |
628 | * \param name the name of the item.␊ |
629 | * \param ref the URL of to the item.␊ |
630 | * \param file the file in which the item is defined.␊ |
631 | * \param anchor the anchor of the item.␊ |
632 | */␊ |
633 | void HtmlHelp::addContentsItem(bool isDir,␊ |
634 | const char *name,␊ |
635 | const char * /*ref*/, ␊ |
636 | const char *file,␊ |
637 | const char *anchor)␊ |
638 | {␊ |
639 | // If we're using a binary toc then folders cannot have links. ␊ |
640 | if(Config_getBool("BINARY_TOC") && isDir) ␊ |
641 | {␊ |
642 | file = 0;␊ |
643 | anchor = 0;␊ |
644 | }␊ |
645 | int i; for (i=0;i<dc;i++) cts << " ";␊ |
646 | cts << "<LI><OBJECT type=\"text/sitemap\">";␊ |
647 | cts << "<param name=\"Name\" value=\"" << recode(name) << "\">";␊ |
648 | if (file) // made file optional param - KPW␊ |
649 | {␊ |
650 | cts << "<param name=\"Local\" value=\"" << file << Doxygen::htmlFileExtension;␊ |
651 | if (anchor) cts << "#" << anchor; ␊ |
652 | cts << "\">";␊ |
653 | }␊ |
654 | cts << "<param name=\"ImageNumber\" value=\"";␊ |
655 | if (isDir) // added - KPW␊ |
656 | {␊ |
657 | cts << (int)BOOK_CLOSED ;␊ |
658 | }␊ |
659 | else␊ |
660 | {␊ |
661 | cts << (int)TEXT;␊ |
662 | }␊ |
663 | cts << "\">";␊ |
664 | cts << "</OBJECT>\n";␊ |
665 | }␊ |
666 | ␊ |
667 | ␊ |
668 | void HtmlHelp::addIndexItem(Definition *context,MemberDef *md,␊ |
669 | const char *word)␊ |
670 | {␊ |
671 | if (md)␊ |
672 | {␊ |
673 | static bool separateMemberPages = Config_getBool("SEPARATE_MEMBER_PAGES");␊ |
674 | if (context==0) // global member␊ |
675 | {␊ |
676 | if (md->getGroupDef())␊ |
677 | context = md->getGroupDef();␊ |
678 | else if (md->getFileDef())␊ |
679 | context = md->getFileDef();␊ |
680 | }␊ |
681 | if (context==0) return; // should not happen␊ |
682 | ␊ |
683 | QCString cfname = md->getOutputFileBase();␊ |
684 | QCString cfiname = context->getOutputFileBase();␊ |
685 | QCString level1 = context->name();␊ |
686 | QCString level2 = md->name();␊ |
687 | QCString contRef = separateMemberPages ? cfname : cfiname;␊ |
688 | QCString memRef = cfname;␊ |
689 | QCString anchor = md->anchor();␊ |
690 | index->addItem(level1,level2,contRef,anchor,TRUE,FALSE);␊ |
691 | index->addItem(level2,level1,memRef,anchor,TRUE,TRUE);␊ |
692 | }␊ |
693 | else if (context)␊ |
694 | {␊ |
695 | QCString level1 = word ? QCString(word) : context->name();␊ |
696 | index->addItem(level1,0,context->getOutputFileBase(),0,TRUE,FALSE);␊ |
697 | }␊ |
698 | }␊ |
699 | ␊ |
700 | void HtmlHelp::addImageFile(const char *fileName)␊ |
701 | {␊ |
702 | imageFiles.append(fileName);␊ |
703 | }␊ |
704 | ␊ |
705 |