diff options
Diffstat (limited to 'src/htmlhelp.cpp')
-rw-r--r-- | src/htmlhelp.cpp | 604 |
1 files changed, 310 insertions, 294 deletions
diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp index 066e6f7..a1b0deb 100644 --- a/src/htmlhelp.cpp +++ b/src/htmlhelp.cpp @@ -1,12 +1,10 @@ /****************************************************************************** * - * - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. + * Copyright (C) 1997-2020 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * @@ -17,15 +15,14 @@ * Harm van der Heijden. */ +#include <algorithm> + #include <stdio.h> #include <stdlib.h> -#include <qlist.h> -#include <qdict.h> #include <qregexp.h> #include <qfile.h> +#include <qfileinfo.h> -#include "qtextcodec.h" -#include "sortdict.h" #include "htmlhelp.h" #include "config.h" #include "message.h" @@ -36,12 +33,75 @@ #include "memberdef.h" #include "filedef.h" #include "util.h" +#include "linkedmap.h" + +//---------------------------------------------------------------------------- + +/** Helper class to deal with recoding the UTF8 encoded text back to the native encoding + * specified by CHM_INDEX_ENCODING. + */ +class HtmlHelpRecoder +{ + public: + HtmlHelpRecoder() {} + ~HtmlHelpRecoder() { finalize(); } + HtmlHelpRecoder(const HtmlHelpRecoder &) = delete; + HtmlHelpRecoder &operator=(const HtmlHelpRecoder &) = delete; + + void initialize() + { + const char *str = Config_getString(CHM_INDEX_ENCODING); + if (!str) str = "CP1250"; // use safe and likely default + m_fromUtf8 = portable_iconv_open(str,"UTF-8"); + if (m_fromUtf8==m_iconv_null) + { + term("unsupported character conversion for CHM_INDEX_ENCODING: '%s'->'UTF-8'\n", str); + } + } + void finalize() + { + if (m_fromUtf8!=m_iconv_null) + { + portable_iconv_close(m_fromUtf8); + m_fromUtf8 = m_iconv_null; + } + } + + QCString recode(const QCString &s) + { + int iSize = s.length(); + int oSize = iSize*4+1; + QCString output(oSize); + size_t iLeft = iSize; + size_t oLeft = oSize; + char *iPtr = s.rawData(); + char *oPtr = output.rawData(); + if (!portable_iconv(m_fromUtf8,&iPtr,&iLeft,&oPtr,&oLeft)) + { + oSize -= (int)oLeft; + output.resize(oSize+1); + output.at(oSize)='\0'; + return output; + } + else + { + return s; + } + } + private: + void *m_iconv_null = (void*)(-1); + void *m_fromUtf8 = m_iconv_null; + +}; //---------------------------------------------------------------------------- /** Class representing a field in the HTML help index. */ struct IndexField { + IndexField(const char *k,const char *n,const char *u,const char *a,bool l,bool r) : + key(k), name(n), url(u), anchor(a), link(l), reversed(r) {} + QCString key; QCString name; QCString url; QCString anchor; @@ -62,37 +122,35 @@ class IndexFieldSDict : public SDict<IndexField> } }; -/** A helper class for HtmlHelp that manages a two level index in +/** A helper class for HtmlHelp that manages a two level index in * alphabetical order. */ class HtmlHelpIndex { public: - HtmlHelpIndex(HtmlHelp *help); + HtmlHelpIndex(HtmlHelpRecoder &recoder); ~HtmlHelpIndex(); - void addItem(const char *first,const char *second, + void addItem(const char *first,const char *second, const char *url, const char *anchor, bool hasLink,bool reversed); void writeFields(FTextStream &t); + size_t size() const { return m_map.size(); } private: - IndexFieldSDict *dict; - HtmlHelp *m_help; + LinkedMap<IndexField> m_map; + HtmlHelpRecoder &m_recoder; }; /*! Constructs a new HtmlHelp index */ -HtmlHelpIndex::HtmlHelpIndex(HtmlHelp *help) : m_help(help) +HtmlHelpIndex::HtmlHelpIndex(HtmlHelpRecoder &recoder) : m_recoder(recoder) { - dict = new IndexFieldSDict; - dict->setAutoDelete(TRUE); } /*! Destroys the HtmlHelp index */ HtmlHelpIndex::~HtmlHelpIndex() { - delete dict; } -/*! Stores an item in the index if it is not already present. +/*! Stores an item in the index if it is not already present. * Items are stored in alphabetical order, by sorting on the * concatenation of \a level1 and \a level2 (if present). * @@ -100,7 +158,7 @@ HtmlHelpIndex::~HtmlHelpIndex() * \param level2 the string at level 2 in the index (or 0 if not applicable). * \param url the url of the documentation (without .html extension). * \param anchor the anchor of the documentation within the page. - * \param hasLink if true, the url (without anchor) can be used in the + * \param hasLink if true, the url (without anchor) can be used in the * level1 item, when writing the header of a list of level2 items. * \param reversed TRUE if level1 is the member name and level2 the compound * name. @@ -109,30 +167,19 @@ void HtmlHelpIndex::addItem(const char *level1,const char *level2, const char *url,const char *anchor,bool hasLink, bool reversed) { - QCString key = level1; + QCString key = level1; if (level2) key+= (QCString)"?" + level2; if (key.find(QRegExp("@[0-9]+"))!=-1) // skip anonymous stuff { return; } - if (dict->find(key+anchor)==0) // new key - { - //printf(">>>>>>>>> HtmlHelpIndex::addItem(%s,%s,%s,%s)\n", - // level1,level2,url,anchor); - IndexField *f = new IndexField; - f->name = key; - f->url = url; - f->anchor = anchor; - f->link = hasLink; - f->reversed = reversed; - dict->append(key+anchor,f); - } + m_map.add(key+anchor,key,url,anchor,hasLink,reversed); } static QCString field2URL(const IndexField *f,bool checkReversed) { QCString result = f->url + Doxygen::htmlFileExtension; - if (!f->anchor.isEmpty() && (!checkReversed || f->reversed)) + if (!f->anchor.isEmpty() && (!checkReversed || f->reversed)) { // HTML Help needs colons in link anchors to be escaped in the .hhk file. result+="#"+substitute(f->anchor,":","%3A"); @@ -163,31 +210,32 @@ static QCString field2URL(const IndexField *f,bool checkReversed) * b2 -> link to url#anchor * a3 -> link to url if hasLink==TRUE * a4 -> link to url if hasLink==TRUE - * b1 -> link to url#anchor + * b1 -> link to url#anchor * </pre> */ void HtmlHelpIndex::writeFields(FTextStream &t) { - dict->sort(); - IndexFieldSDict::Iterator ifli(*dict); - IndexField *f; - QCString lastLevel1; + std::sort(std::begin(m_map), + std::end(m_map), + [](const auto &e1,const auto &e2) { return e1->name < e2->name; } + ); + QCString prevLevel1; bool level2Started=FALSE; - for (;(f=ifli.current());++ifli) + for (auto it = std::begin(m_map); it!=std::end(m_map); ++it) { + auto &f = *it; QCString level1,level2; int i; if ((i=f->name.find('?'))!=-1) { level1 = f->name.left(i); - level2 = f->name.right(f->name.length()-i-1); + level2 = f->name.right(f->name.length()-i-1); } else { - level1 = f->name.copy(); + level1 = f->name; } - //if (level1!=lastLevel1) { // finish old list at level 2 if (level2Started) t << " </UL>" << endl; level2Started=FALSE; @@ -200,24 +248,25 @@ void HtmlHelpIndex::writeFields(FTextStream &t) // a2, b2 // a2, b3 QCString nextLevel1; - IndexField* fnext = ++ifli; - if (fnext) + auto it_next = std::next(it); + if (it_next!=std::end(m_map)) { + auto &fnext = *it_next; nextLevel1 = fnext->name.left(fnext->name.find('?')); - --ifli; } - if (level1 != nextLevel1) + if (!(level1 == prevLevel1 || level1 == nextLevel1)) { level2 = ""; } + prevLevel1 = level1; // </Antony> if (level2.isEmpty()) { t << " <LI><OBJECT type=\"text/sitemap\">"; - t << "<param name=\"Local\" value=\"" << field2URL(f,FALSE); + t << "<param name=\"Local\" value=\"" << field2URL(f.get(),FALSE); t << "\">"; - t << "<param name=\"Name\" value=\"" << m_help->recode(level1) << "\">" + t << "<param name=\"Name\" value=\"" << m_recoder.recode(level1) << "\">" "</OBJECT>\n"; } else @@ -225,16 +274,16 @@ void HtmlHelpIndex::writeFields(FTextStream &t) if (f->link) { t << " <LI><OBJECT type=\"text/sitemap\">"; - t << "<param name=\"Local\" value=\"" << field2URL(f,TRUE); + t << "<param name=\"Local\" value=\"" << field2URL(f.get(),TRUE); t << "\">"; - t << "<param name=\"Name\" value=\"" << m_help->recode(level1) << "\">" + t << "<param name=\"Name\" value=\"" << m_recoder.recode(level1) << "\">" "</OBJECT>\n"; } else { t << " <LI><OBJECT type=\"text/sitemap\">"; - t << "<param name=\"See Also\" value=\"" << m_help->recode(level1) << "\">"; - t << "<param name=\"Name\" value=\"" << m_help->recode(level1) << "\">" + t << "<param name=\"See Also\" value=\"" << m_recoder.recode(level1) << "\">"; + t << "<param name=\"Name\" value=\"" << m_recoder.recode(level1) << "\">" "</OBJECT>\n"; } } @@ -252,195 +301,185 @@ void HtmlHelpIndex::writeFields(FTextStream &t) if (level2Started) { t << " <LI><OBJECT type=\"text/sitemap\">"; - t << "<param name=\"Local\" value=\"" << field2URL(f,FALSE); + t << "<param name=\"Local\" value=\"" << field2URL(f.get(),FALSE); t << "\">"; - t << "<param name=\"Name\" value=\"" << m_help->recode(level2) << "\">" + t << "<param name=\"Name\" value=\"" << m_recoder.recode(level2) << "\">" "</OBJECT>\n"; } - lastLevel1 = level1.copy(); - } + } if (level2Started) t << " </UL>" << endl; } //---------------------------------------------------------------------------- +// +class HtmlHelp::Private +{ + public: + Private() : index(recoder) {} + void createProjectFile(); + QFile cf; + QFile kf; + FTextStream cts,kts; + bool ctsItemPresent = false; + int dc = 0; + StringSet indexFiles; + StringSet imageFiles; + HtmlHelpIndex index; + HtmlHelpRecoder recoder; +}; -HtmlHelp *HtmlHelp::theInstance = 0; -/*! Constructs an html object. - * The object has to be \link initialize() initialized\endlink before it can +/*! Constructs an html object. + * The object has to be \link initialize() initialized\endlink before it can * be used. */ -HtmlHelp::HtmlHelp() : indexFileDict(1009) +HtmlHelp::HtmlHelp() : p(std::make_unique<Private>()) { - /* initial depth */ - dc = 0; - cf = kf = 0; - index = new HtmlHelpIndex(this); - m_fromUtf8 = (void *)(-1); } HtmlHelp::~HtmlHelp() { - if (m_fromUtf8!=(void *)(-1)) portable_iconv_close(m_fromUtf8); - delete index; } -#if 0 -/*! return a reference to the one and only instance of this class. - */ -HtmlHelp *HtmlHelp::getInstance() -{ - if (theInstance==0) theInstance = new HtmlHelp; - return theInstance; -} -#endif -static QDict<QCString> s_languageDict; +/* language codes for Html help + 0x405 Czech + 0x406 Danish + 0x413 Dutch + 0xC09 English (Australia) + 0x809 English (Britain) + 0x1009 English (Canada) + 0x1809 English (Ireland) + 0x1409 English (New Zealand) + 0x1C09 English (South Africa) + 0x409 English (United States) + 0x40B Finnish + 0x40C French + 0x407 German + 0x408 Greece + 0x40E Hungarian + 0x410 Italian + 0x814 Norwegian + 0x415 Polish + 0x816 Portuguese(Portugal) + 0x416 Portuguese(Brazil) + 0x419 Russian + 0x80A Spanish(Mexico) + 0xC0A Spanish(Modern Sort) + 0x40A Spanish(Traditional Sort) + 0x41D Swedish + 0x41F Turkey + 0x411 Japanese + 0x412 Korean + 0x804 Chinese (PRC) + 0x404 Chinese (Taiwan) + + New LCIDs: + 0x421 Indonesian + 0x41A Croatian + 0x418 Romanian + 0x424 Slovenian + 0x41B Slovak + 0x422 Ukrainian + 0x81A Serbian (Serbia, Latin) + 0x403 Catalan + 0x426 Latvian + 0x427 Lithuanian + 0x436 Afrikaans + 0x42A Vietnamese + 0x429 Persian (Iran) + 0xC01 Arabic (Egypt) - I don't know which version of arabic is used inside translator_ar.h , + so I have chosen Egypt at random + +*/ +static StringUnorderedMap s_languageDict = +{ + { "czech", "0x405 Czech" }, + { "danish", "0x406 Danish" }, + { "dutch", "0x413 Dutch" }, + { "finnish", "0x40B Finnish" }, + { "french", "0x40C French" }, + { "german", "0x407 German" }, + { "greek", "0x408 Greece" }, + { "hungarian", "0x40E Hungarian" }, + { "italian", "0x410 Italian" }, + { "norwegian", "0x814 Norwegian" }, + { "polish", "0x415 Polish" }, + { "portuguese", "0x816 Portuguese(Portugal)" }, + { "brazilian", "0x416 Portuguese(Brazil)" }, + { "russian", "0x419 Russian" }, + { "spanish", "0x40A Spanish(Traditional Sort)" }, + { "swedish", "0x41D Swedish" }, + { "turkish", "0x41F Turkey" }, + { "japanese", "0x411 Japanese" }, + { "japanese-en", "0x411 Japanese" }, + { "korean", "0x412 Korean" }, + { "korean-en", "0x412 Korean" }, + { "chinese", "0x804 Chinese (PRC)" }, + { "chinese-traditional", "0x404 Chinese (Taiwan)" }, + { "indonesian", "0x421 Indonesian" }, + { "croatian", "0x41A Croatian" }, + { "romanian", "0x418 Romanian" }, + { "slovene", "0x424 Slovenian" }, + { "slovak", "0x41B Slovak" }, + { "ukrainian", "0x422 Ukrainian" }, + { "serbian", "0x81A Serbian (Serbia, Latin)" }, + { "catalan", "0x403 Catalan" }, + { "lithuanian", "0x427 Lithuanian" }, + { "afrikaans", "0x436 Afrikaans" }, + { "vietnamese", "0x42A Vietnamese" }, + { "persian", "0x429 Persian (Iran)" }, + { "arabic", "0xC01 Arabic (Egypt)" }, + { "latvian", "0x426 Latvian" }, + { "macedonian", "0x042f Macedonian (Former Yugoslav Republic of Macedonia)" }, + { "armenian", "0x42b Armenian" }, + //Code for Esperanto should be as shown below but the htmlhelp compiler 1.3 does not support this + // (and no newer version is available). + //So do a fallback to the default language (see getLanguageString()) + //{ "esperanto", "0x48f Esperanto" }, + { "serbian-cyrillic", "0xC1A Serbian (Serbia, Cyrillic)" } +}; /*! This will create a contents file (index.hhc) and a index file (index.hhk) - * and write the header of those files. + * and write the header of those files. * It also creates a project file (index.hhp) * \sa finalize() */ void HtmlHelp::initialize() { - const char *str = Config_getString(CHM_INDEX_ENCODING); - if (!str) str = "CP1250"; // use safe and likely default - m_fromUtf8 = portable_iconv_open(str,"UTF-8"); - if (m_fromUtf8==(void *)(-1)) - { - term("unsupported character conversion for CHM_INDEX_ENCODING: '%s'->'UTF-8'\n", str); - } + p->recoder.initialize(); /* open the contents file */ QCString fName = Config_getString(HTML_OUTPUT) + "/index.hhc"; - cf = new QFile(fName); - if (!cf->open(IO_WriteOnly)) + p->cf.setName(fName); + if (!p->cf.open(IO_WriteOnly)) { term("Could not open file %s for writing\n",fName.data()); } /* Write the header of the contents file */ - cts.setDevice(cf); - cts << "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n" + p->cts.setDevice(&p->cf); + p->cts << "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n" "<HTML><HEAD></HEAD><BODY>\n" "<OBJECT type=\"text/site properties\">\n" "<param name=\"FrameName\" value=\"right\">\n" "</OBJECT>\n" "<UL>\n"; - + /* open the contents file */ fName = Config_getString(HTML_OUTPUT) + "/index.hhk"; - kf = new QFile(fName); - if (!kf->open(IO_WriteOnly)) + p->kf.setName(fName); + if (!p->kf.open(IO_WriteOnly)) { term("Could not open file %s for writing\n",fName.data()); } /* Write the header of the contents file */ - kts.setDevice(kf); - kts << "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n" + p->kts.setDevice(&p->kf); + p->kts << "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n" "<HTML><HEAD></HEAD><BODY>\n" "<OBJECT type=\"text/site properties\">\n" "<param name=\"FrameName\" value=\"right\">\n" "</OBJECT>\n" "<UL>\n"; - /* language codes for Html help - 0x405 Czech - 0x406 Danish - 0x413 Dutch - 0xC09 English (Australia) - 0x809 English (Britain) - 0x1009 English (Canada) - 0x1809 English (Ireland) - 0x1409 English (New Zealand) - 0x1C09 English (South Africa) - 0x409 English (United States) - 0x40B Finnish - 0x40C French - 0x407 German - 0x408 Greece - 0x40E Hungarian - 0x410 Italian - 0x814 Norwegian - 0x415 Polish - 0x816 Portuguese(Portugal) - 0x416 Portuguese(Brazil) - 0x419 Russian - 0x80A Spanish(Mexico) - 0xC0A Spanish(Modern Sort) - 0x40A Spanish(Traditional Sort) - 0x41D Swedish - 0x41F Turkey - 0x411 Japanese - 0x412 Korean - 0x804 Chinese (PRC) - 0x404 Chinese (Taiwan) - - New LCIDs: - 0x421 Indonesian - 0x41A Croatian - 0x418 Romanian - 0x424 Slovenian - 0x41B Slovak - 0x422 Ukrainian - 0x81A Serbian (Serbia, Latin) - 0x403 Catalan - 0x426 Latvian - 0x427 Lithuanian - 0x436 Afrikaans - 0x42A Vietnamese - 0x429 Persian (Iran) - 0xC01 Arabic (Egypt) - I don't know which version of arabic is used inside translator_ar.h , - so I have chosen Egypt at random - - */ - s_languageDict.setAutoDelete(TRUE); - s_languageDict.clear(); - s_languageDict.insert("czech", new QCString("0x405 Czech")); - s_languageDict.insert("danish", new QCString("0x406 Danish")); - s_languageDict.insert("dutch", new QCString("0x413 Dutch")); - s_languageDict.insert("finnish", new QCString("0x40B Finnish")); - s_languageDict.insert("french", new QCString("0x40C French")); - s_languageDict.insert("german", new QCString("0x407 German")); - s_languageDict.insert("greek", new QCString("0x408 Greece")); - s_languageDict.insert("hungarian", new QCString("0x40E Hungarian")); - s_languageDict.insert("italian", new QCString("0x410 Italian")); - s_languageDict.insert("norwegian", new QCString("0x814 Norwegian")); - s_languageDict.insert("polish", new QCString("0x415 Polish")); - s_languageDict.insert("portuguese", new QCString("0x816 Portuguese(Portugal)")); - s_languageDict.insert("brazilian", new QCString("0x416 Portuguese(Brazil)")); - s_languageDict.insert("russian", new QCString("0x419 Russian")); - s_languageDict.insert("spanish", new QCString("0x40A Spanish(Traditional Sort)")); - s_languageDict.insert("swedish", new QCString("0x41D Swedish")); - s_languageDict.insert("turkish", new QCString("0x41F Turkey")); - s_languageDict.insert("japanese", new QCString("0x411 Japanese")); - s_languageDict.insert("japanese-en", new QCString("0x411 Japanese")); - s_languageDict.insert("korean", new QCString("0x412 Korean")); - s_languageDict.insert("korean-en", new QCString("0x412 Korean")); - s_languageDict.insert("chinese", new QCString("0x804 Chinese (PRC)")); - s_languageDict.insert("chinese-traditional", new QCString("0x404 Chinese (Taiwan)")); - - // new LCIDs - s_languageDict.insert("indonesian", new QCString("0x412 Indonesian")); - s_languageDict.insert("croatian", new QCString("0x41A Croatian")); - s_languageDict.insert("romanian", new QCString("0x418 Romanian")); - s_languageDict.insert("slovene", new QCString("0x424 Slovenian")); - s_languageDict.insert("slovak", new QCString("0x41B Slovak")); - s_languageDict.insert("ukrainian", new QCString("0x422 Ukrainian")); - s_languageDict.insert("serbian", new QCString("0x81A Serbian (Serbia, Latin)")); - s_languageDict.insert("catalan", new QCString("0x403 Catalan")); - s_languageDict.insert("lithuanian", new QCString("0x427 Lithuanian")); - s_languageDict.insert("afrikaans", new QCString("0x436 Afrikaans")); - s_languageDict.insert("vietnamese", new QCString("0x42A Vietnamese")); - s_languageDict.insert("persian", new QCString("0x429 Persian (Iran)")); - s_languageDict.insert("arabic", new QCString("0xC01 Arabic (Egypt)")); - s_languageDict.insert("latvian", new QCString("0x426 Latvian")); - s_languageDict.insert("macedonian", new QCString("0x042f Macedonian (Former Yugoslav Republic of Macedonia)")); - s_languageDict.insert("armenian", new QCString("0x42b Armenian")); - //Code for Esperanto should be as shown below but the htmlhelp compiler 1.3 does not support this - // (and no newer version is available). - //So do a fallback to the default language (see getLanguageString()) - //s_languageDict.insert("esperanto", new QCString("0x48f Esperanto")); - s_languageDict.insert("serbian-cyrillic", new QCString("0xC1A Serbian (Serbia, Cyrillic)")); } @@ -448,19 +487,19 @@ QCString HtmlHelp::getLanguageString() { if (!theTranslator->idLanguage().isEmpty()) { - QCString *s = s_languageDict[theTranslator->idLanguage()]; - if (s) + auto it = s_languageDict.find(theTranslator->idLanguage().str()); + if (it!=s_languageDict.end()) { - return *s; + return it->second; } } // default language return "0x409 English (United States)"; } - -void HtmlHelp::createProjectFile() + +void HtmlHelp::Private::createProjectFile() { /* Write the project file */ QCString fName = Config_getString(HTML_OUTPUT) + "/index.hhp"; @@ -468,7 +507,13 @@ void HtmlHelp::createProjectFile() if (f.open(IO_WriteOnly)) { FTextStream t(&f); - + + const char *hhcFile = "\"index.hhc\""; + const char *hhkFile = "\"index.hhk\""; + bool hhkPresent = index.size()>0; + if (!ctsItemPresent) hhcFile = ""; + if (!hhkPresent) hhkFile = ""; + QCString indexName="index"+Doxygen::htmlFileExtension; t << "[OPTIONS]\n"; if (!Config_getString(CHM_FILE).isEmpty()) @@ -476,16 +521,16 @@ void HtmlHelp::createProjectFile() t << "Compiled file=" << Config_getString(CHM_FILE) << "\n"; } t << "Compatibility=1.1\n" - "Full-text search=Yes\n" - "Contents file=index.hhc\n" - "Default Window=main\n" - "Default topic=" << indexName << "\n" - "Index file=index.hhk\n" - "Language=" << getLanguageString() << endl; + "Full-text search=Yes\n"; + if (ctsItemPresent) t << "Contents file=index.hhc\n"; + t << "Default Window=main\n" + "Default topic=" << indexName << "\n"; + if (hhkPresent) t << "Index file=index.hhk\n"; + t << "Language=" << getLanguageString() << endl; if (Config_getBool(BINARY_TOC)) t << "Binary TOC=YES\n"; if (Config_getBool(GENERATE_CHI)) t << "Create CHI file=YES\n"; - t << "Title=" << recode(Config_getString(PROJECT_NAME)) << endl << endl; - + t << "Title=" << recoder.recode(Config_getString(PROJECT_NAME)) << endl << endl; + t << "[WINDOWS]" << endl; // NOTE: the 0x10387e number is a set of bits specifying the buttons @@ -500,28 +545,25 @@ void HtmlHelp::createProjectFile() // Value has been taken from htmlhelp.h file of the HTML Help Workshop if (Config_getBool(BINARY_TOC)) { - t << "main=\"" << recode(Config_getString(PROJECT_NAME)) << "\",\"index.hhc\"," - "\"index.hhk\",\"" << indexName << "\",\"" << + t << "main=\"" << recoder.recode(Config_getString(PROJECT_NAME)) << "\"," << hhcFile << "," + << hhkFile << ",\"" << indexName << "\",\"" << indexName << "\",,,,,0x23520,,0x70387e,,,,,,,,0" << endl << endl; } else { - t << "main=\"" << recode(Config_getString(PROJECT_NAME)) << "\",\"index.hhc\"," - "\"index.hhk\",\"" << indexName << "\",\"" << + t << "main=\"" << recoder.recode(Config_getString(PROJECT_NAME)) << "\"," << hhcFile << "," + << hhkFile << ",\"" << indexName << "\",\"" << indexName << "\",,,,,0x23520,,0x10387e,,,,,,,,0" << endl << endl; } - + t << "[FILES]" << endl; - char *s = indexFiles.first(); - while (s) + for (auto &s : indexFiles) { - t << s << endl; - s = indexFiles.next(); + t << s.c_str() << endl; } - uint i; - for (i=0;i<imageFiles.count();i++) + for (auto &s : imageFiles) { - t << imageFiles.at(i) << endl; + t << QFileInfo(s.c_str()).fileName().data() << endl; } f.close(); } @@ -533,11 +575,7 @@ void HtmlHelp::createProjectFile() void HtmlHelp::addIndexFile(const char *s) { - if (indexFileDict.find(s)==0) - { - indexFiles.append(s); - indexFileDict.insert(s,(void *)0x8); - } + p->indexFiles.insert(s); } /*! Finalizes the HTML help. This will finish and close the @@ -547,36 +585,35 @@ void HtmlHelp::addIndexFile(const char *s) void HtmlHelp::finalize() { // end the contents file - cts << "</UL>\n"; - cts << "</BODY>\n"; - cts << "</HTML>\n"; - cts.unsetDevice(); - cf->close(); - delete cf; - - index->writeFields(kts); - + p->cts << "</UL>\n"; + p->cts << "</BODY>\n"; + p->cts << "</HTML>\n"; + p->cts.unsetDevice(); + p->cf.close(); + + p->index.writeFields(p->kts); + // end the index file - kts << "</UL>\n"; - kts << "</BODY>\n"; - kts << "</HTML>\n"; - kts.unsetDevice(); - kf->close(); - delete kf; - - createProjectFile(); - s_languageDict.clear(); + p->kts << "</UL>\n"; + p->kts << "</BODY>\n"; + p->kts << "</HTML>\n"; + p->kts.unsetDevice(); + p->kf.close(); + + p->createProjectFile(); + + p->recoder.finalize(); } -/*! Increase the level of the contents hierarchy. +/*! Increase the level of the contents hierarchy. * This will start a new unnumbered HTML list in contents file. * \sa decContentsDepth() */ void HtmlHelp::incContentsDepth() { - int i; for (i=0;i<dc+1;i++) cts << " "; - cts << "<UL>\n"; - ++dc; + int i; for (i=0;i<p->dc+1;i++) p->cts << " "; + p->cts << "<UL>\n"; + ++p->dc; } /*! Decrease the level of the contents hierarchy. @@ -585,31 +622,9 @@ void HtmlHelp::incContentsDepth() */ void HtmlHelp::decContentsDepth() { - int i; for (i=0;i<dc;i++) cts << " "; - cts << "</UL>\n"; - --dc; -} - -QCString HtmlHelp::recode(const QCString &s) -{ - int iSize = s.length(); - int oSize = iSize*4+1; - QCString output(oSize); - size_t iLeft = iSize; - size_t oLeft = oSize; - char *iPtr = s.rawData(); - char *oPtr = output.rawData(); - if (!portable_iconv(m_fromUtf8,&iPtr,&iLeft,&oPtr,&oLeft)) - { - oSize -= (int)oLeft; - output.resize(oSize+1); - output.at(oSize)='\0'; - return output; - } - else - { - return s; - } + int i; for (i=0;i<p->dc;i++) p->cts << " "; + p->cts << "</UL>\n"; + --p->dc; } /*! Add an list item to the contents file. @@ -624,53 +639,54 @@ QCString HtmlHelp::recode(const QCString &s) */ void HtmlHelp::addContentsItem(bool isDir, const char *name, - const char * /*ref*/, + const char * /*ref*/, const char *file, const char *anchor, bool /* separateIndex */, bool /* addToNavIndex */, const Definition * /* def */) { - // If we're using a binary toc then folders cannot have links. + // If we're using a binary toc then folders cannot have links. // Tried this and I didn't see any problems, when not using // the resetting of file and anchor the TOC works better // (prev / next button) - //if(Config_getBool(BINARY_TOC) && isDir) + //if(Config_getBool(BINARY_TOC) && isDir) //{ //file = 0; //anchor = 0; //} - int i; for (i=0;i<dc;i++) cts << " "; - cts << "<LI><OBJECT type=\"text/sitemap\">"; - cts << "<param name=\"Name\" value=\"" << convertToHtml(recode(name),TRUE) << "\">"; + p->ctsItemPresent = true; + int i; for (i=0;i<p->dc;i++) p->cts << " "; + p->cts << "<LI><OBJECT type=\"text/sitemap\">"; + p->cts << "<param name=\"Name\" value=\"" << convertToHtml(p->recoder.recode(name),TRUE) << "\">"; if (file) // made file optional param - KPW { if (file && (file[0]=='!' || file[0]=='^')) // special markers for user defined URLs { - cts << "<param name=\""; - if (file[0]=='^') cts << "URL"; else cts << "Local"; - cts << "\" value=\""; - cts << &file[1]; + p->cts << "<param name=\""; + if (file[0]=='^') p->cts << "URL"; else p->cts << "Local"; + p->cts << "\" value=\""; + p->cts << &file[1]; } else { - cts << "<param name=\"Local\" value=\""; - cts << file << Doxygen::htmlFileExtension; - if (anchor) cts << "#" << anchor; + p->cts << "<param name=\"Local\" value=\""; + p->cts << file << Doxygen::htmlFileExtension; + if (anchor) p->cts << "#" << anchor; } - cts << "\">"; + p->cts << "\">"; } - cts << "<param name=\"ImageNumber\" value=\""; + p->cts << "<param name=\"ImageNumber\" value=\""; if (isDir) // added - KPW { - cts << (int)BOOK_CLOSED ; + p->cts << (int)BOOK_CLOSED ; } else { - cts << (int)TEXT; + p->cts << (int)TEXT; } - cts << "\">"; - cts << "</OBJECT>\n"; + p->cts << "\">"; + p->cts << "</OBJECT>\n"; } @@ -696,18 +712,18 @@ void HtmlHelp::addIndexItem(const Definition *context,const MemberDef *md, QCString contRef = separateMemberPages ? cfname : cfiname; QCString memRef = cfname; QCString anchor = sectionAnchor ? QCString(sectionAnchor) : md->anchor(); - index->addItem(level1,level2,contRef,anchor,TRUE,FALSE); - index->addItem(level2,level1,memRef,anchor,TRUE,TRUE); + p->index.addItem(level1,level2,contRef,anchor,TRUE,FALSE); + p->index.addItem(level2,level1,memRef,anchor,TRUE,TRUE); } else if (context) { QCString level1 = word ? QCString(word) : context->name(); - index->addItem(level1,0,context->getOutputFileBase(),sectionAnchor,TRUE,FALSE); + p->index.addItem(level1,0,context->getOutputFileBase(),sectionAnchor,TRUE,FALSE); } } void HtmlHelp::addImageFile(const char *fileName) { - if (!imageFiles.contains(fileName)) imageFiles.append(fileName); + p->imageFiles.insert(fileName); } |