Orb/Doxygen/src/qhp.cpp
changeset 0 42188c7ea2d9
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /*
       
     2  * Copyright (C) 2008 by Sebastian Pipping.
       
     3  * Copyright (C) 2008 Dimitri van Heesch.
       
     4  *
       
     5  * Permission to use, copy, modify, and distribute this software and its
       
     6  * documentation under the terms of the GNU General Public License is hereby 
       
     7  * granted. No representations are made about the suitability of this software 
       
     8  * for any purpose. It is provided "as is" without express or implied warranty.
       
     9  * See the GNU General Public License for more details.
       
    10  *
       
    11  * Documents produced by Doxygen are derivative works derived from the
       
    12  * input used in their production; they are not affected by this license.
       
    13  *
       
    14  * Sebastian Pipping <sebastian@pipping.org>
       
    15  */
       
    16 
       
    17 #include "qhp.h"
       
    18 #include "qhpxmlwriter.h"
       
    19 #include "message.h"
       
    20 #include "config.h"
       
    21 #include "memberdef.h"
       
    22 #include "groupdef.h"
       
    23 #include "filedef.h"
       
    24 
       
    25 #include <qstringlist.h>
       
    26 #include <string.h>
       
    27 
       
    28 static QCString makeFileName(const char * withoutExtension)
       
    29 {
       
    30   if (!withoutExtension) return QCString();
       
    31   return QCString(withoutExtension)+".html";
       
    32 }
       
    33 
       
    34 static QCString makeRef(const char * withoutExtension, const char * anchor)
       
    35 {
       
    36   if (!withoutExtension) return QCString(); 
       
    37   QCString result = makeFileName(withoutExtension);
       
    38   if (!anchor) return result;
       
    39   return result+"#"+anchor;
       
    40 }
       
    41 
       
    42 Qhp::Qhp() : m_prevSectionLevel(0), m_sectionLevel(0)
       
    43 {
       
    44   m_doc.setIndentLevel(0);
       
    45   m_toc.setIndentLevel(2);
       
    46   m_index.setIndentLevel(2);
       
    47   m_files.setIndentLevel(2);
       
    48 }
       
    49 
       
    50 Qhp::~Qhp()
       
    51 {
       
    52   clearPrevSection();
       
    53 }
       
    54 
       
    55 void Qhp::initialize()
       
    56 {
       
    57   /*
       
    58   <QtHelpProject version="1.0">
       
    59     <namespace>mycompany.com.myapplication.1_0</namespace>
       
    60     <virtualFolder>doc</virtualFolder>
       
    61     <customFilter name="My Application 1.0">
       
    62       <filterAttribute>myapp</filterAttribute>
       
    63       <filterAttribute>1.0</filterAttribute>
       
    64     </customFilter>
       
    65     <filterSection>
       
    66       <filterAttribute>myapp</filterAttribute>
       
    67       <filterAttribute>1.0</filterAttribute>
       
    68   ..
       
    69   */
       
    70   QCString nameSpace       = Config_getString("QHP_NAMESPACE");
       
    71   QCString virtualFolder   = Config_getString("QHP_VIRTUAL_FOLDER");
       
    72 
       
    73   const char * rootAttributes[] =
       
    74   { "version", "1.0", 0 };
       
    75 
       
    76   m_doc.open("QtHelpProject", rootAttributes);
       
    77   m_doc.openCloseContent("namespace", nameSpace);
       
    78   m_doc.openCloseContent("virtualFolder", virtualFolder);
       
    79 
       
    80   // Add custom filter
       
    81   QCString filterName = Config_getString("QHP_CUST_FILTER_NAME");
       
    82   if (!filterName.isEmpty())
       
    83   {
       
    84     const char * tagAttributes[] = 
       
    85     { "name", filterName, 0 };
       
    86     m_doc.open("customFilter", tagAttributes);
       
    87 
       
    88     QStringList customFilterAttributes = QStringList::split(' ', Config_getString("QHP_CUST_FILTER_ATTRS"));
       
    89     for (int i = 0; i < (int)customFilterAttributes.count(); i++)
       
    90     {
       
    91       m_doc.openCloseContent("filterAttribute", customFilterAttributes[i]);
       
    92     }
       
    93     m_doc.close("customFilter");
       
    94   }
       
    95 
       
    96   m_doc.open("filterSection");
       
    97 
       
    98   // Add section attributes
       
    99   QStringList sectionFilterAttributes = QStringList::split(' ',
       
   100       Config_getString("QHP_SECT_FILTER_ATTRS"));
       
   101   if (!sectionFilterAttributes.contains(QString("doxygen")))
       
   102   {
       
   103     sectionFilterAttributes << "doxygen";
       
   104   }
       
   105   for (int i = 0; i < (int)sectionFilterAttributes.count(); i++)
       
   106   {
       
   107     m_doc.openCloseContent("filterAttribute", sectionFilterAttributes[i]);
       
   108   }
       
   109 
       
   110   m_toc.open("toc");
       
   111 
       
   112   // Add extra root node
       
   113   QCString fullProjectname = getFullProjectName();
       
   114   const char * const attributes[] =
       
   115   { "title", fullProjectname,
       
   116     "ref",   "index.html",
       
   117     NULL
       
   118   };
       
   119   m_toc.open("section", attributes);
       
   120   m_prevSectionLevel = 1;
       
   121   m_sectionLevel = 1;
       
   122 
       
   123   m_index.open("keywords");
       
   124   m_files.open("files");
       
   125 }
       
   126 
       
   127 void Qhp::finalize()
       
   128 {
       
   129   // Finish TOC
       
   130   handlePrevSection();
       
   131   for (int i = m_prevSectionLevel; i > 0; i--)
       
   132   {
       
   133     m_toc.close("section");
       
   134   }
       
   135   m_toc.close("toc");
       
   136   m_doc.insert(m_toc);
       
   137 
       
   138   // Finish index
       
   139   m_index.close("keywords");
       
   140   m_doc.insert(m_index);
       
   141 
       
   142   // Finish files
       
   143   m_files.close("files");
       
   144   m_doc.insert(m_files);
       
   145 
       
   146   m_doc.close("filterSection");
       
   147   m_doc.close("QtHelpProject");
       
   148 
       
   149   QCString fileName = Config_getString("HTML_OUTPUT") + "/" + getQhpFileName();
       
   150   QFile file(fileName);
       
   151   if (!file.open(IO_WriteOnly))
       
   152   {
       
   153     err("Could not open file %s for writing\n", fileName.data());
       
   154     exit(1);
       
   155   }
       
   156   m_doc.dumpTo(file);
       
   157 }
       
   158 
       
   159 void Qhp::incContentsDepth()
       
   160 {
       
   161   m_sectionLevel++;
       
   162 }
       
   163 
       
   164 void Qhp::decContentsDepth()
       
   165 {
       
   166   if (m_sectionLevel <= 0)
       
   167   {
       
   168     return;
       
   169   }
       
   170   m_sectionLevel--;
       
   171 }
       
   172 
       
   173 void Qhp::addContentsItem(bool /*isDir*/, const char * name, 
       
   174                           const char * /*ref*/, const char * file, 
       
   175                           const char * /*anchor*/)
       
   176 {
       
   177   // Backup difference before modification
       
   178   int diff = m_prevSectionLevel - m_sectionLevel;
       
   179 
       
   180   handlePrevSection();
       
   181   setPrevSection(name, file, m_sectionLevel);
       
   182 
       
   183   // Close sections as needed
       
   184   for (; diff > 0; diff--)
       
   185   {
       
   186     m_toc.close("section");
       
   187   }
       
   188 }
       
   189 
       
   190 void Qhp::addIndexItem(Definition *context,MemberDef *md,
       
   191                        const char *anc,const char *word)
       
   192 {
       
   193   (void)anc;
       
   194   (void)word;
       
   195 
       
   196   if (md) // member
       
   197   {
       
   198     static bool separateMemberPages = Config_getBool("SEPARATE_MEMBER_PAGES");
       
   199     if (context==0) // global member
       
   200     {
       
   201       if (md->getGroupDef())
       
   202         context = md->getGroupDef();
       
   203       else if (md->getFileDef())
       
   204         context = md->getFileDef();
       
   205     }
       
   206     if (context==0) return; // should not happen
       
   207     QCString cfname  = md->getOutputFileBase();
       
   208     QCString cfiname = context->getOutputFileBase();
       
   209     QCString level1  = context->name();
       
   210     QCString level2  = word ? QCString(word) : md->name();
       
   211     QCString contRef = separateMemberPages ? cfname : cfiname;
       
   212     QCString anchor  = anc;
       
   213 
       
   214     QCString ref;
       
   215 
       
   216     // <keyword name="foo" id="MyApplication::foo" ref="doc.html#foo"/>
       
   217     ref = makeRef(contRef, anchor);
       
   218     QCString id = level1+"::"+level2;
       
   219     const char * attributes[] =
       
   220     {
       
   221       "name", level2,
       
   222       "id",   id,
       
   223       "ref",  ref,
       
   224       0
       
   225     };
       
   226     m_index.openClose("keyword", attributes);
       
   227   }
       
   228   else if (context) // container
       
   229   {
       
   230     // <keyword name="Foo" id="Foo" ref="doc.html"/>
       
   231     QCString contRef = context->getOutputFileBase();
       
   232     QCString level1  = word ? QCString(word) : context->name();
       
   233     QCString ref;
       
   234     if (anc)
       
   235     {
       
   236       ref = makeRef(contRef,anc);
       
   237     }
       
   238     else
       
   239     {
       
   240       ref = makeFileName(contRef);
       
   241     }
       
   242     const char * attributes[] =
       
   243     {
       
   244       "name", level1,
       
   245       "id",   level1,
       
   246       "ref",  ref,
       
   247       0
       
   248     };
       
   249     m_index.openClose("keyword", attributes);
       
   250   }
       
   251 }
       
   252 
       
   253 void Qhp::addIndexFile(const char * name)
       
   254 {
       
   255   addFile(name);
       
   256 }
       
   257 
       
   258 QCString Qhp::getQhpFileName()
       
   259 {
       
   260   return "index.qhp";
       
   261 }
       
   262 
       
   263 QCString Qhp::getFullProjectName()
       
   264 {
       
   265   QCString projectName = Config_getString("PROJECT_NAME");
       
   266   QCString versionText = Config_getString("PROJECT_NUMBER");
       
   267   if (projectName.isEmpty()) projectName="Root";
       
   268   return projectName + (versionText.isEmpty()
       
   269       ? QCString("")
       
   270       : QCString(" ") + versionText);
       
   271 }
       
   272 
       
   273 void Qhp::handlePrevSection()
       
   274 {
       
   275   /*
       
   276   <toc>
       
   277     <section title="My Application Manual" ref="index.html">
       
   278       <section title="Chapter 1" ref="doc.html#chapter1"/>
       
   279       <section title="Chapter 2" ref="doc.html#chapter2"/>
       
   280       <section title="Chapter 3" ref="doc.html#chapter3"/>
       
   281     </section>
       
   282   </toc>
       
   283   */
       
   284 
       
   285   if (m_prevSectionTitle.isNull())
       
   286   {
       
   287     return;
       
   288   }
       
   289 
       
   290   // We skip "Main Page" as our extra root is pointing to that
       
   291   if (!((m_prevSectionLevel==1) && (m_prevSectionTitle=="Main Page")))
       
   292   {
       
   293     QCString finalRef = makeFileName(m_prevSectionRef);
       
   294 
       
   295     const char * const attributes[] =
       
   296     { "title", m_prevSectionTitle,
       
   297       "ref",   finalRef,
       
   298       NULL
       
   299     };
       
   300 
       
   301     if (m_prevSectionLevel < m_sectionLevel)
       
   302     {
       
   303       // Section with children
       
   304       m_toc.open("section", attributes);
       
   305     }
       
   306     else
       
   307     {
       
   308       // Section without children
       
   309       m_toc.openClose("section", attributes);
       
   310     }
       
   311   }
       
   312 
       
   313   clearPrevSection();
       
   314 }
       
   315 
       
   316 void Qhp::setPrevSection(const char * title, const char * ref, int level)
       
   317 {
       
   318   m_prevSectionTitle = title;
       
   319   m_prevSectionRef   = ref;
       
   320   m_prevSectionLevel = level;
       
   321 }
       
   322 
       
   323 void Qhp::clearPrevSection()
       
   324 {
       
   325   m_prevSectionTitle.resize(0);
       
   326   m_prevSectionRef.resize(0);
       
   327 }
       
   328 
       
   329 void Qhp::addFile(const char * fileName)
       
   330 {
       
   331   m_files.openCloseContent("file", fileName);
       
   332 }
       
   333 
       
   334 void Qhp::addImageFile(const char *fileName)
       
   335 {
       
   336   addFile(fileName);
       
   337 }
       
   338 
       
   339 void Qhp::addStyleSheetFile(const char *fileName)
       
   340 {
       
   341   addFile(fileName);
       
   342 }
       
   343