fdc9f4c944ff79d84469e38e26a8aa69b4e408c5
[platform/upstream/doxygen.git] / src / layout.cpp
1 /******************************************************************************
2  *
3  * 
4  *
5  *
6  * Copyright (C) 1997-2015 by Dimitri van Heesch.
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation under the terms of the GNU General Public License is hereby 
10  * granted. No representations are made about the suitability of this software 
11  * for any purpose. It is provided "as is" without express or implied warranty.
12  * See the GNU General Public License for more details.
13  *
14  * Documents produced by Doxygen are derivative works derived from the
15  * input used in their production; they are not affected by this license.
16  *
17  */
18
19 #include "layout.h"
20 #include "message.h"
21 #include "language.h"
22 #include "vhdldocgen.h"
23 #include "util.h"
24 #include "doxygen.h"
25 #include "version.h"
26 #include "config.h"
27
28 #include <assert.h>
29 #include <qxml.h>
30 #include <qfile.h>
31 #include <qstring.h>
32 #include <qfileinfo.h>
33 #include <qtextstream.h>
34
35 static const char layout_default[] =
36 #include "layout_default.xml.h"
37 ;
38
39 #define ADD_OPTION(langId,text) "|"+QCString().setNum(langId)+"="+text
40
41 #define COMPILE_FOR_1_OPTION(def,langId1,text1) \
42   def+ADD_OPTION(langId1,text1)
43
44 #define COMPILE_FOR_2_OPTIONS(def,langId1,text1,langId2,text2) \
45   COMPILE_FOR_1_OPTION(def,langId1,text1)+ADD_OPTION(langId2,text2)
46
47 #define COMPILE_FOR_3_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3) \
48   COMPILE_FOR_2_OPTIONS(def,langId1,text1,langId2,text2)+ADD_OPTION(langId3,text3)
49
50 #define COMPILE_FOR_4_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3,langId4,text4) \
51   COMPILE_FOR_3_OPTIONS(def,langId1,text1,langId2,text2,langId3,text3)+ADD_OPTION(langId4,text4)
52
53 static bool elemIsVisible(const QXmlAttributes &attrib,bool defVal=TRUE)
54 {
55   QCString visible = attrib.value("visible").utf8();
56   if (visible.isEmpty()) return defVal;
57   if (visible.at(0)=='$' && visible.length()>1)
58   {
59     QCString id = visible.mid(1);
60     const ConfigValues::Info *opt = ConfigValues::instance().get(id);
61     if (opt && opt->type==ConfigValues::Info::Bool)
62     {
63       return ConfigValues::instance().*((ConfigValues::InfoBool*)opt)->item;
64     }
65     else if (!opt)
66     {
67       err("found unsupported value %s for visible attribute in layout file\n",
68           visible.data());
69     }
70   }
71   return visible!="no" && visible!="0";
72 }
73
74 //---------------------------------------------------------------------------------
75
76 LayoutNavEntry *LayoutNavEntry::find(LayoutNavEntry::Kind kind,
77     const char *file) const
78 {
79   LayoutNavEntry *result=0;
80   QListIterator<LayoutNavEntry> li(m_children);
81   LayoutNavEntry *entry;
82   for (li.toFirst();(entry=li.current());++li)
83   {
84     // depth first search, needed to find the entry furthest from the 
85     // root in case an entry is in the tree twice
86     result = entry->find(kind,file);
87     if (result) return result;
88     if (entry->kind()==kind && (file==0 || entry->baseFile()==file))
89     {
90       return entry;
91     }
92   }
93   return result;
94 }
95
96 QCString LayoutNavEntry::url() const
97 {
98   QCString url = baseFile().stripWhiteSpace();
99   if ((kind()!=LayoutNavEntry::User && kind()!=LayoutNavEntry::UserGroup) || 
100       (kind()==LayoutNavEntry::UserGroup && url.left(9)=="usergroup"))
101   {
102     url+=Doxygen::htmlFileExtension;
103   }
104   else if (url.left(5)=="@ref " || url.left(5)=="\\ref ")
105   {
106     Definition *d;
107     QCString anchor;
108     bool found=FALSE;
109     if (resolveLink(0,url.mid(5).stripWhiteSpace(),TRUE,&d,anchor))
110     {
111       if (d && d->isLinkable()) 
112       {
113         url=d->getOutputFileBase()+Doxygen::htmlFileExtension;
114         if (!anchor.isEmpty())
115         {
116           url+="#"+anchor;
117         }
118         found=TRUE;
119       }
120     }
121     if (!found)
122     {
123       msg("explicit link request to '%s' in layout file '%s' could not be resolved\n",qPrint(url.mid(5)),qPrint(Config_getString(LAYOUT_FILE)));
124     }
125   }
126   //printf("LayoutNavEntry::url()=%s\n",url.data());
127   return url;
128 }
129
130 //---------------------------------------------------------------------------------
131
132 class LayoutParser : public QXmlDefaultHandler
133 {
134   private:
135     class StartElementHandler
136     {
137         typedef void (LayoutParser::*Handler)(const QXmlAttributes &attrib); 
138       public:
139         StartElementHandler(LayoutParser *parent, Handler h) 
140           : m_parent(parent), m_handler(h) {}
141         virtual ~StartElementHandler() {}
142         virtual void operator()(const QXmlAttributes &attrib) 
143         { 
144           (m_parent->*m_handler)(attrib); 
145         }
146       protected:
147         StartElementHandler() : m_parent(0), m_handler(0) {}
148       private:
149         LayoutParser *m_parent;
150         Handler m_handler;
151     };
152
153     class StartElementHandlerKind : public StartElementHandler
154     {
155         typedef void (LayoutParser::*Handler)(LayoutDocEntry::Kind kind,
156                                               const QXmlAttributes &attrib); 
157       public:
158         StartElementHandlerKind(LayoutParser *parent, LayoutDocEntry::Kind k,Handler h) 
159           : m_parent(parent), m_kind(k), m_handler(h) {}
160         void operator()(const QXmlAttributes &attrib) 
161         { 
162           (m_parent->*m_handler)(m_kind,attrib); 
163         }
164       private:
165         LayoutParser *m_parent;
166         LayoutDocEntry::Kind m_kind;
167         Handler m_handler;
168     };
169
170     class StartElementHandlerSection : public StartElementHandler
171     {
172         typedef void (LayoutParser::*Handler)(LayoutDocEntry::Kind kind,
173                                               const QXmlAttributes &attrib,
174                                               const QCString &title); 
175       public:
176         StartElementHandlerSection(LayoutParser *parent, LayoutDocEntry::Kind k,Handler h,
177                                 const QCString &title) 
178           : m_parent(parent), m_kind(k), m_handler(h), m_title(title) {}
179         void operator()(const QXmlAttributes &attrib) 
180         { 
181           (m_parent->*m_handler)(m_kind,attrib,m_title); 
182         }
183       private:
184         LayoutParser *m_parent;
185         LayoutDocEntry::Kind m_kind;
186         Handler m_handler;
187         QCString m_title;
188     };
189
190     class StartElementHandlerMember : public StartElementHandler
191     {
192         typedef void (LayoutParser::*Handler)(const QXmlAttributes &attrib,
193                                               MemberListType type,
194                                               const QCString &title,
195                                               const QCString &subtitle); 
196       public:
197         StartElementHandlerMember(LayoutParser *parent, 
198                                   Handler h,
199                                   MemberListType type,
200                                   const QCString &tl,
201                                   const QCString &ss = QCString()
202                                  ) 
203           : m_parent(parent), m_handler(h), m_type(type),
204             m_title(tl), m_subscript(ss) {}
205         void operator()(const QXmlAttributes &attrib) 
206         { 
207           (m_parent->*m_handler)(attrib,m_type,m_title,m_subscript); 
208         }
209       private:
210         LayoutParser *m_parent;
211         Handler m_handler;
212         MemberListType m_type;
213         QCString m_title;
214         QCString m_subscript;
215     };
216
217     class StartElementHandlerNavEntry : public StartElementHandler
218     {
219         typedef void (LayoutParser::*Handler)(LayoutNavEntry::Kind kind,
220                                               const QXmlAttributes &attrib,
221                                               const QCString &title); 
222       public:
223         StartElementHandlerNavEntry(LayoutParser *parent,
224                                LayoutNavEntry::Kind kind, 
225                                Handler h,
226                                const QCString &tl
227                               ) 
228           : m_parent(parent), m_kind(kind), m_handler(h), m_title(tl) {}
229         void operator()(const QXmlAttributes &attrib) 
230         { 
231           (m_parent->*m_handler)(m_kind,attrib,m_title); 
232         }
233       private:
234         LayoutParser *m_parent;
235         LayoutNavEntry::Kind m_kind;
236         Handler m_handler;
237         QCString m_title;
238     };
239
240     class EndElementHandler
241     {
242         typedef void (LayoutParser::*Handler)(); 
243       public:
244         EndElementHandler(LayoutParser *parent, Handler h) : m_parent(parent), m_handler(h) {}
245         void operator()() { (m_parent->*m_handler)(); }
246       private:
247         LayoutParser *m_parent;
248         Handler m_handler;
249     };
250
251
252   public:
253     static LayoutParser &instance()
254     {
255       static LayoutParser *theInstance = new LayoutParser;
256       return *theInstance;
257     }
258     void init()
259     {
260       m_sHandler.setAutoDelete(TRUE);
261       m_eHandler.setAutoDelete(TRUE);
262       m_part = -1; // invalid
263       m_rootNav = 0;
264
265       //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
266       //bool vhdlOpt    = Config_getBool(OPTIMIZE_OUTPUT_VHDL);  
267       //bool javaOpt    = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
268
269       // start & end handlers
270       m_sHandler.insert("doxygenlayout", 
271           new StartElementHandler(this,&LayoutParser::startLayout));
272       m_eHandler.insert("doxygenlayout", 
273           new EndElementHandler(this,&LayoutParser::endLayout));
274
275       // class layout handlers
276       m_sHandler.insert("navindex", 
277           new StartElementHandler(this,&LayoutParser::startNavIndex));
278       m_sHandler.insert("navindex/tab", 
279           new StartElementHandler(this,&LayoutParser::startNavEntry));
280       m_eHandler.insert("navindex/tab", 
281           new EndElementHandler(this,&LayoutParser::endNavEntry));
282       m_eHandler.insert("navindex", 
283           new EndElementHandler(this,&LayoutParser::endNavIndex));
284
285       // class layout handlers
286       m_sHandler.insert("class", 
287           new StartElementHandler(this,&LayoutParser::startClass));
288       m_sHandler.insert("class/briefdescription", 
289           new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
290       m_sHandler.insert("class/detaileddescription", 
291           new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
292                                          theTranslator->trDetailedDescription()));
293       m_sHandler.insert("class/authorsection", 
294           new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry));
295       m_sHandler.insert("class/includes", 
296           new StartElementHandlerKind(this,LayoutDocEntry::ClassIncludes,&LayoutParser::startSimpleEntry));
297       m_sHandler.insert("class/inheritancegraph", 
298           new StartElementHandlerKind(this,LayoutDocEntry::ClassInheritanceGraph,&LayoutParser::startSimpleEntry));
299       m_sHandler.insert("class/collaborationgraph", 
300           new StartElementHandlerKind(this,LayoutDocEntry::ClassCollaborationGraph,&LayoutParser::startSimpleEntry));
301       m_sHandler.insert("class/allmemberslink", 
302           new StartElementHandlerKind(this,LayoutDocEntry::ClassAllMembersLink,&LayoutParser::startSimpleEntry));
303       m_sHandler.insert("class/usedfiles", 
304           new StartElementHandlerKind(this,LayoutDocEntry::ClassUsedFiles,&LayoutParser::startSimpleEntry));
305       m_sHandler.insert("class/memberdecl", 
306           new StartElementHandler(this,&LayoutParser::startMemberDecl));
307       m_sHandler.insert("class/memberdecl/membergroups", 
308           new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry));
309       m_sHandler.insert("class/memberdecl/nestedclasses", 
310           new StartElementHandlerSection(this,LayoutDocEntry::ClassNestedClasses,&LayoutParser::startSectionEntry,
311                                          COMPILE_FOR_2_OPTIONS(
312                                            theTranslator->trCompounds(),
313                                            SrcLangExt_VHDL,VhdlDocGen::trVhdlType(VhdlDocGen::ENTITY,FALSE),
314                                            SrcLangExt_Fortran,theTranslator->trDataTypes()
315                                          )));
316       m_sHandler.insert("class/memberdecl/services",
317           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
318                                         MemberListType_services,theTranslator->trServices()));
319       m_sHandler.insert("class/memberdecl/interfaces",
320           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
321                                         MemberListType_interfaces,theTranslator->trInterfaces()));
322       m_sHandler.insert("class/memberdecl/publictypes", 
323           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
324                                         MemberListType_pubTypes,theTranslator->trPublicTypes()));
325       m_sHandler.insert("class/memberdecl/publicslots", 
326           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
327                                         MemberListType_pubSlots,theTranslator->trPublicSlots())); 
328       m_sHandler.insert("class/memberdecl/signals", 
329           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
330                                         MemberListType_signals,theTranslator->trSignals())); 
331       m_sHandler.insert("class/memberdecl/publicmethods", 
332           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
333                                         MemberListType_pubMethods,
334                                         COMPILE_FOR_1_OPTION(
335                                           theTranslator->trPublicMembers(),
336                                           SrcLangExt_ObjC,theTranslator->trInstanceMethods()
337                                         ))); 
338       m_sHandler.insert("class/memberdecl/publicstaticmethods", 
339           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
340                                         MemberListType_pubStaticMethods,
341                                         COMPILE_FOR_1_OPTION(
342                                           theTranslator->trStaticPublicMembers(),
343                                           SrcLangExt_ObjC,theTranslator->trClassMethods()
344                                         ))); 
345       m_sHandler.insert("class/memberdecl/publicattributes", 
346           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
347                                         MemberListType_pubAttribs,theTranslator->trPublicAttribs())); 
348       m_sHandler.insert("class/memberdecl/publicstaticattributes", 
349           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
350                                         MemberListType_pubStaticAttribs,theTranslator->trStaticPublicAttribs())); 
351       m_sHandler.insert("class/memberdecl/protectedtypes", 
352           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
353                                         MemberListType_proTypes,theTranslator->trProtectedTypes())); 
354       m_sHandler.insert("class/memberdecl/protectedslots", 
355           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
356                                         MemberListType_proSlots,theTranslator->trProtectedSlots())); 
357       m_sHandler.insert("class/memberdecl/protectedmethods", 
358           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
359                                         MemberListType_proMethods,theTranslator->trProtectedMembers())); 
360       m_sHandler.insert("class/memberdecl/protectedstaticmethods", 
361           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
362                                         MemberListType_proStaticMethods,theTranslator->trStaticProtectedMembers()));
363       m_sHandler.insert("class/memberdecl/protectedattributes", 
364           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
365                                         MemberListType_proAttribs,theTranslator->trProtectedAttribs())); 
366       m_sHandler.insert("class/memberdecl/protectedstaticattributes", 
367           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
368                                         MemberListType_proStaticAttribs,theTranslator->trStaticProtectedAttribs())); 
369       m_sHandler.insert("class/memberdecl/packagetypes", 
370           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
371                                         MemberListType_pacTypes,theTranslator->trPackageTypes())); 
372       m_sHandler.insert("class/memberdecl/packagemethods", 
373           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
374                                         MemberListType_pacMethods,theTranslator->trPackageMembers())); 
375       m_sHandler.insert("class/memberdecl/packagestaticmethods", 
376           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
377                                         MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers())); 
378       m_sHandler.insert("class/memberdecl/packageattributes", 
379           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
380                                         MemberListType_pacAttribs,theTranslator->trPackageAttribs())); 
381       m_sHandler.insert("class/memberdecl/packagestaticattributes", 
382           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
383                                         MemberListType_pacStaticAttribs,theTranslator->trStaticPackageAttribs())); 
384       m_sHandler.insert("class/memberdecl/properties", 
385           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
386                                         MemberListType_properties,theTranslator->trProperties())); 
387       m_sHandler.insert("class/memberdecl/events", 
388           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
389                                         MemberListType_events,theTranslator->trEvents())); 
390       m_sHandler.insert("class/memberdecl/privatetypes", 
391           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
392                                         MemberListType_priTypes,theTranslator->trPrivateTypes())); 
393       m_sHandler.insert("class/memberdecl/privateslots", 
394           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
395                                         MemberListType_priSlots,theTranslator->trPrivateSlots())); 
396       m_sHandler.insert("class/memberdecl/privatemethods", 
397           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
398                                         MemberListType_priMethods,theTranslator->trPrivateMembers())); 
399       m_sHandler.insert("class/memberdecl/privatestaticmethods", 
400           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
401                                         MemberListType_priStaticMethods,theTranslator->trStaticPrivateMembers())); 
402       m_sHandler.insert("class/memberdecl/privateattributes", 
403           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
404                                         MemberListType_priAttribs,theTranslator->trPrivateAttribs())); 
405       m_sHandler.insert("class/memberdecl/privatestaticattributes", 
406           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
407                                         MemberListType_priStaticAttribs,theTranslator->trStaticPrivateAttribs())); 
408       m_sHandler.insert("class/memberdecl/friends", 
409           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
410                                         MemberListType_friends,theTranslator->trFriends()));
411       m_sHandler.insert("class/memberdecl/related", 
412           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
413                                         MemberListType_related,theTranslator->trRelatedFunctions(),
414                                         theTranslator->trRelatedSubscript())); 
415       m_eHandler.insert("class/memberdecl", 
416           new EndElementHandler(this,&LayoutParser::endMemberDecl));
417       m_sHandler.insert("class/memberdef", 
418           new StartElementHandler(this,&LayoutParser::startMemberDef));
419       m_sHandler.insert("class/memberdef/inlineclasses", 
420           new StartElementHandlerSection(this,LayoutDocEntry::ClassInlineClasses,&LayoutParser::startSectionEntry,
421                                          COMPILE_FOR_1_OPTION(
422                                            theTranslator->trClassDocumentation(),
423                                            SrcLangExt_Fortran,theTranslator->trTypeDocumentation()
424                                          )));
425       m_sHandler.insert("class/memberdef/typedefs", 
426           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
427                                         MemberListType_typedefMembers,theTranslator->trMemberTypedefDocumentation()));
428       m_sHandler.insert("class/memberdef/enums", 
429           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
430                                         MemberListType_enumMembers,theTranslator->trMemberEnumerationDocumentation()));
431       m_sHandler.insert("class/memberdef/services",
432           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
433                                         MemberListType_serviceMembers,theTranslator->trInterfaces()));
434       m_sHandler.insert("class/memberdef/interfaces",
435           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
436                                         MemberListType_interfaceMembers,theTranslator->trInterfaces()));
437       m_sHandler.insert("class/memberdef/constructors", 
438           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
439                                         MemberListType_constructors,theTranslator->trConstructorDocumentation()));
440       m_sHandler.insert("class/memberdef/functions", 
441           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
442                                         MemberListType_functionMembers,
443                                         COMPILE_FOR_2_OPTIONS(
444                                           theTranslator->trMemberFunctionDocumentation(),
445                                           SrcLangExt_ObjC,theTranslator->trMethodDocumentation(),
446                                           SrcLangExt_Fortran,theTranslator->trMemberFunctionDocumentationFortran()
447                                         )));
448       m_sHandler.insert("class/memberdef/related", 
449           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
450                                         MemberListType_relatedMembers,theTranslator->trRelatedFunctionDocumentation()));
451       m_sHandler.insert("class/memberdef/variables", 
452           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
453                                         MemberListType_variableMembers,theTranslator->trMemberDataDocumentation()));
454       m_sHandler.insert("class/memberdef/properties", 
455           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
456                                         MemberListType_propertyMembers,theTranslator->trPropertyDocumentation()));
457       m_sHandler.insert("class/memberdef/events", 
458           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
459                                         MemberListType_eventMembers,theTranslator->trEventDocumentation()));
460       m_eHandler.insert("class/memberdef", 
461           new EndElementHandler(this,&LayoutParser::endMemberDef));
462       m_eHandler.insert("class", 
463           new EndElementHandler(this,&LayoutParser::endClass));
464
465
466       // namespace layout handlers
467       m_sHandler.insert("namespace", 
468           new StartElementHandler(this,&LayoutParser::startNamespace));
469       m_sHandler.insert("namespace/briefdescription", 
470           new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
471       m_sHandler.insert("namespace/detaileddescription", 
472           new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
473                                          theTranslator->trDetailedDescription()));
474       m_sHandler.insert("namespace/authorsection", 
475           new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry));
476       m_sHandler.insert("namespace/memberdecl", 
477           new StartElementHandler(this,&LayoutParser::startMemberDecl));
478       m_sHandler.insert("namespace/memberdecl/nestednamespaces", 
479           new StartElementHandlerSection(this,LayoutDocEntry::NamespaceNestedNamespaces,&LayoutParser::startSectionEntry,
480                                          COMPILE_FOR_4_OPTIONS(
481                                            theTranslator->trNamespaces(),
482                                            SrcLangExt_Java,theTranslator->trPackages(),
483                                            SrcLangExt_VHDL,theTranslator->trPackages(),
484                                            SrcLangExt_IDL,theTranslator->trModules(),
485                                            SrcLangExt_Fortran,theTranslator->trModules()
486                                          )));
487       m_sHandler.insert("namespace/memberdecl/constantgroups",
488           new StartElementHandlerSection(this,LayoutDocEntry::NamespaceNestedConstantGroups,&LayoutParser::startSectionEntry,
489                                          theTranslator->trConstantGroups()));
490       m_sHandler.insert("namespace/memberdecl/classes", 
491           new StartElementHandlerSection(this,LayoutDocEntry::NamespaceClasses,&LayoutParser::startSectionEntry,
492                                          COMPILE_FOR_2_OPTIONS(
493                                            theTranslator->trCompounds(),
494                                            SrcLangExt_VHDL,VhdlDocGen::trVhdlType(VhdlDocGen::ENTITY,FALSE),
495                                            SrcLangExt_Fortran,theTranslator->trDataTypes()
496                                          )));
497       m_sHandler.insert("namespace/memberdecl/membergroups", 
498           new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry));
499       m_sHandler.insert("namespace/memberdecl/typedefs", 
500           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
501                                         MemberListType_decTypedefMembers,theTranslator->trTypedefs()));
502       m_sHandler.insert("namespace/memberdecl/enums", 
503           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
504                                         MemberListType_decEnumMembers,theTranslator->trEnumerations()));
505       m_sHandler.insert("namespace/memberdecl/functions", 
506           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
507                                         MemberListType_decFuncMembers,
508                                         COMPILE_FOR_2_OPTIONS(
509                                           theTranslator->trFunctions(),
510                                           SrcLangExt_Fortran,theTranslator->trSubprograms(),
511                                           SrcLangExt_VHDL,VhdlDocGen::trFunctionAndProc()
512                                         )));
513       m_sHandler.insert("namespace/memberdecl/variables", 
514           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
515                                         MemberListType_decVarMembers,theTranslator->trVariables()));
516       m_eHandler.insert("namespace/memberdecl", 
517           new EndElementHandler(this,&LayoutParser::endMemberDecl));
518       m_sHandler.insert("namespace/memberdef", 
519           new StartElementHandler(this,&LayoutParser::startMemberDef));
520       m_sHandler.insert("namespace/memberdef/inlineclasses", 
521           new StartElementHandlerSection(this,LayoutDocEntry::NamespaceInlineClasses,&LayoutParser::startSectionEntry,
522                                          COMPILE_FOR_1_OPTION(
523                                            theTranslator->trClassDocumentation(),
524                                            SrcLangExt_Fortran,theTranslator->trTypeDocumentation()
525                                          )));
526       m_sHandler.insert("namespace/memberdef/typedefs", 
527           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
528                                         MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation()));
529       m_sHandler.insert("namespace/memberdef/enums", 
530           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
531                                         MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation()));
532       m_sHandler.insert("namespace/memberdef/functions", 
533           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
534                                         MemberListType_docFuncMembers,
535                                         COMPILE_FOR_1_OPTION(
536                                           theTranslator->trFunctionDocumentation(),
537                                           SrcLangExt_Fortran,theTranslator->trSubprogramDocumentation()
538                                         )));
539       m_sHandler.insert("namespace/memberdef/variables", 
540           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
541                                         MemberListType_docVarMembers,theTranslator->trVariableDocumentation()));
542       m_eHandler.insert("namespace/memberdef", 
543           new EndElementHandler(this,&LayoutParser::endMemberDef));
544       m_eHandler.insert("namespace", 
545           new EndElementHandler(this,&LayoutParser::endNamespace));
546
547       // file layout handlers
548       m_sHandler.insert("file", 
549           new StartElementHandler(this,&LayoutParser::startFile));
550       m_sHandler.insert("file/briefdescription", 
551           new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
552       m_sHandler.insert("file/detaileddescription", 
553           new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
554                                          theTranslator->trDetailedDescription()));
555       m_sHandler.insert("file/authorsection", 
556           new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry));
557       m_sHandler.insert("file/includes", 
558           new StartElementHandlerKind(this,LayoutDocEntry::FileIncludes,&LayoutParser::startSimpleEntry));
559       m_sHandler.insert("file/includegraph", 
560           new StartElementHandlerKind(this,LayoutDocEntry::FileIncludeGraph,&LayoutParser::startSimpleEntry));
561       m_sHandler.insert("file/includedbygraph", 
562           new StartElementHandlerKind(this,LayoutDocEntry::FileIncludedByGraph,&LayoutParser::startSimpleEntry));
563       m_sHandler.insert("file/sourcelink", 
564           new StartElementHandlerKind(this,LayoutDocEntry::FileSourceLink,&LayoutParser::startSimpleEntry));
565       m_sHandler.insert("file/memberdecl/membergroups", 
566           new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry));
567       m_sHandler.insert("file/memberdecl", 
568           new StartElementHandler(this,&LayoutParser::startMemberDecl));
569       m_sHandler.insert("file/memberdecl/classes", 
570           new StartElementHandlerSection(this,LayoutDocEntry::FileClasses,&LayoutParser::startSectionEntry,
571                                          COMPILE_FOR_2_OPTIONS(
572                                            theTranslator->trCompounds(),
573                                            SrcLangExt_VHDL,VhdlDocGen::trVhdlType(VhdlDocGen::ENTITY,FALSE),
574                                            SrcLangExt_Fortran,theTranslator->trDataTypes()
575                                          )));
576       m_sHandler.insert("file/memberdecl/namespaces", 
577           new StartElementHandlerSection(this,LayoutDocEntry::FileNamespaces,&LayoutParser::startSectionEntry,
578                                          COMPILE_FOR_3_OPTIONS(
579                                            theTranslator->trNamespaces(),
580                                            SrcLangExt_Java,theTranslator->trPackages(),
581                                            SrcLangExt_IDL,theTranslator->trModules(),
582                                            SrcLangExt_Fortran,theTranslator->trModules()
583                                          )));
584       m_sHandler.insert("file/memberdecl/constantgroups",
585           new StartElementHandlerSection(this,LayoutDocEntry::FileConstantGroups,&LayoutParser::startSectionEntry,
586                                          theTranslator->trConstantGroups()));
587       m_sHandler.insert("file/memberdecl/defines", 
588           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
589                                         MemberListType_decDefineMembers,theTranslator->trDefines()));
590       m_sHandler.insert("file/memberdecl/typedefs", 
591           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
592                                         MemberListType_decTypedefMembers,theTranslator->trTypedefs()));
593       m_sHandler.insert("file/memberdecl/enums", 
594           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
595                                         MemberListType_decEnumMembers,theTranslator->trEnumerations()));
596       m_sHandler.insert("file/memberdecl/functions", 
597           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
598                                         MemberListType_decFuncMembers,
599                                         COMPILE_FOR_2_OPTIONS(
600                                           theTranslator->trFunctions(),
601                                           SrcLangExt_Fortran,theTranslator->trSubprograms(),
602                                           SrcLangExt_VHDL,VhdlDocGen::trFunctionAndProc()
603                                         )));
604       m_sHandler.insert("file/memberdecl/variables", 
605           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
606                                         MemberListType_decVarMembers,theTranslator->trVariables()));
607
608       m_eHandler.insert("file/memberdecl", 
609           new EndElementHandler(this,&LayoutParser::endMemberDecl));
610       m_sHandler.insert("file/memberdef", 
611           new StartElementHandler(this,&LayoutParser::startMemberDef));
612       m_sHandler.insert("file/memberdef/inlineclasses", 
613           new StartElementHandlerSection(this,LayoutDocEntry::FileInlineClasses,&LayoutParser::startSectionEntry,
614                                          COMPILE_FOR_1_OPTION(
615                                            theTranslator->trClassDocumentation(),
616                                            SrcLangExt_Fortran,theTranslator->trTypeDocumentation()
617                                          )));
618       m_sHandler.insert("file/memberdef/defines", 
619           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
620                                         MemberListType_docDefineMembers,theTranslator->trDefineDocumentation()));
621       m_sHandler.insert("file/memberdef/typedefs", 
622           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
623                                         MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation()));
624       m_sHandler.insert("file/memberdef/enums", 
625           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
626                                         MemberListType_docEnumMembers,
627                                         theTranslator->trEnumerationTypeDocumentation()));
628       m_sHandler.insert("file/memberdef/functions", 
629           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
630                                         MemberListType_docFuncMembers,
631                                         COMPILE_FOR_1_OPTION(
632                                           theTranslator->trFunctionDocumentation(),
633                                           SrcLangExt_Fortran,theTranslator->trSubprogramDocumentation()
634                                         )));
635       m_sHandler.insert("file/memberdef/variables", 
636           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
637                                         MemberListType_docVarMembers,theTranslator->trVariableDocumentation()));
638       m_eHandler.insert("file/memberdef", 
639           new EndElementHandler(this,&LayoutParser::endMemberDef));
640       m_eHandler.insert("file", 
641           new EndElementHandler(this,&LayoutParser::endFile));
642
643       // group layout handlers
644       m_sHandler.insert("group", 
645           new StartElementHandler(this,&LayoutParser::startGroup));
646       m_sHandler.insert("group/briefdescription", 
647           new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
648       m_sHandler.insert("group/detaileddescription", 
649           new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
650                                          theTranslator->trDetailedDescription()));
651       m_sHandler.insert("group/authorsection", 
652           new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry));
653       m_sHandler.insert("group/groupgraph", 
654           new StartElementHandlerKind(this,LayoutDocEntry::GroupGraph,&LayoutParser::startSimpleEntry));
655       m_sHandler.insert("group/memberdecl/membergroups", 
656           new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry));
657       m_sHandler.insert("group/memberdecl", 
658           new StartElementHandler(this,&LayoutParser::startMemberDecl));
659       m_sHandler.insert("group/memberdecl/classes", 
660           new StartElementHandlerSection(this,LayoutDocEntry::GroupClasses,&LayoutParser::startSectionEntry,
661                                          COMPILE_FOR_2_OPTIONS(
662                                            theTranslator->trCompounds(),
663                                            SrcLangExt_VHDL,VhdlDocGen::trVhdlType(VhdlDocGen::ENTITY,FALSE),
664                                            SrcLangExt_Fortran,theTranslator->trDataTypes()
665                                          )));
666       m_sHandler.insert("group/memberdecl/namespaces", 
667           new StartElementHandlerSection(this,LayoutDocEntry::GroupNamespaces,&LayoutParser::startSectionEntry,
668                                          COMPILE_FOR_2_OPTIONS(
669                                            theTranslator->trNamespaces(),
670                                            SrcLangExt_Java,theTranslator->trPackages(),
671                                            SrcLangExt_Fortran,theTranslator->trModules()
672                                          )));
673       m_sHandler.insert("group/memberdecl/dirs", 
674           new StartElementHandlerSection(this,LayoutDocEntry::GroupDirs,&LayoutParser::startSectionEntry,
675                                          theTranslator->trDirectories()
676                                          ));
677       m_sHandler.insert("group/memberdecl/nestedgroups", 
678           new StartElementHandlerSection(this,LayoutDocEntry::GroupNestedGroups,&LayoutParser::startSectionEntry,
679                                          theTranslator->trModules()
680                                          ));
681       m_sHandler.insert("group/memberdecl/files", 
682           new StartElementHandlerSection(this,LayoutDocEntry::GroupFiles,&LayoutParser::startSectionEntry,
683                                          theTranslator->trFile(TRUE,FALSE)
684                                          ));
685
686       m_sHandler.insert("group/memberdecl/defines", 
687           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
688                                         MemberListType_decDefineMembers,theTranslator->trDefines()));
689       m_sHandler.insert("group/memberdecl/typedefs", 
690           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
691                                         MemberListType_decTypedefMembers,theTranslator->trTypedefs()));
692       m_sHandler.insert("group/memberdecl/enums", 
693           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
694                                         MemberListType_decEnumMembers,theTranslator->trEnumerations()));
695       m_sHandler.insert("group/memberdecl/enumvalues", 
696           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
697                                         MemberListType_decEnumValMembers,theTranslator->trEnumerationValues()));
698       m_sHandler.insert("group/memberdecl/functions", 
699           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
700                                         MemberListType_decFuncMembers,
701                                         COMPILE_FOR_2_OPTIONS(
702                                           theTranslator->trFunctions(),
703                                           SrcLangExt_Fortran,theTranslator->trSubprograms(),
704                                           SrcLangExt_VHDL,VhdlDocGen::trFunctionAndProc()
705                                         )));
706       m_sHandler.insert("group/memberdecl/variables", 
707           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
708                                         MemberListType_decVarMembers,theTranslator->trVariables()));
709       m_sHandler.insert("group/memberdecl/signals", 
710           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
711                                         MemberListType_decSignalMembers,theTranslator->trSignals()));
712       m_sHandler.insert("group/memberdecl/publicslots", 
713           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
714                                         MemberListType_decPubSlotMembers,theTranslator->trPublicSlots()));
715       m_sHandler.insert("group/memberdecl/protectedslots", 
716           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
717                                         MemberListType_decProSlotMembers,theTranslator->trProtectedSlots()));
718       m_sHandler.insert("group/memberdecl/privateslots", 
719           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
720                                         MemberListType_decPriSlotMembers,theTranslator->trPrivateSlots()));
721       m_sHandler.insert("group/memberdecl/events", 
722           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
723                                         MemberListType_decEventMembers,theTranslator->trEvents()));
724       m_sHandler.insert("group/memberdecl/properties", 
725           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
726                                         MemberListType_decPropMembers,theTranslator->trProperties()));
727       m_sHandler.insert("group/memberdecl/friends", 
728           new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
729                                         MemberListType_decFriendMembers,theTranslator->trFriends()));
730       m_eHandler.insert("group/memberdecl", 
731           new EndElementHandler(this,&LayoutParser::endMemberDecl));
732       m_sHandler.insert("group/memberdef", 
733           new StartElementHandler(this,&LayoutParser::startMemberDef));
734       m_sHandler.insert("group/memberdef/pagedocs", 
735           new StartElementHandlerKind(this,LayoutDocEntry::GroupPageDocs,&LayoutParser::startSimpleEntry));
736       m_sHandler.insert("group/memberdef/inlineclasses", 
737           new StartElementHandlerSection(this,LayoutDocEntry::GroupInlineClasses,&LayoutParser::startSectionEntry,
738                                          COMPILE_FOR_1_OPTION(
739                                            theTranslator->trClassDocumentation(),
740                                            SrcLangExt_Fortran,theTranslator->trTypeDocumentation()
741                                          )));
742       m_sHandler.insert("group/memberdef/defines", 
743           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
744                                         MemberListType_docDefineMembers,theTranslator->trDefineDocumentation()));
745       m_sHandler.insert("group/memberdef/typedefs", 
746           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
747                                         MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation()));
748       m_sHandler.insert("group/memberdef/enums", 
749           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
750                                         MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation()));
751       m_sHandler.insert("group/memberdef/enumvalues", 
752           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
753                                         MemberListType_docEnumValMembers,theTranslator->trEnumerationValueDocumentation()));
754       m_sHandler.insert("group/memberdef/functions", 
755           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
756                                         MemberListType_docFuncMembers,
757                                         COMPILE_FOR_1_OPTION(
758                                           theTranslator->trFunctionDocumentation(),
759                                           SrcLangExt_Fortran,theTranslator->trSubprogramDocumentation()
760                                        )));
761       m_sHandler.insert("group/memberdef/variables", 
762           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
763                                         MemberListType_docVarMembers,theTranslator->trVariableDocumentation()));
764       m_sHandler.insert("group/memberdef/signals", 
765           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
766                                         MemberListType_docSignalMembers,theTranslator->trSignals())); 
767       m_sHandler.insert("group/memberdef/publicslots", 
768           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
769                                         MemberListType_docPubSlotMembers,theTranslator->trPublicSlots()));
770       m_sHandler.insert("group/memberdef/protectedslots", 
771           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
772                                         MemberListType_docProSlotMembers,theTranslator->trProtectedSlots()));
773       m_sHandler.insert("group/memberdef/privateslots", 
774           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
775                                         MemberListType_docPriSlotMembers,theTranslator->trPrivateSlots()));
776       m_sHandler.insert("group/memberdef/events", 
777           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
778                                         MemberListType_docEventMembers,theTranslator->trEvents()));
779       m_sHandler.insert("group/memberdef/properties", 
780           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
781                                         MemberListType_docPropMembers,theTranslator->trProperties()));
782       m_sHandler.insert("group/memberdef/friends", 
783           new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
784                                         MemberListType_docFriendMembers,theTranslator->trFriends()));
785       m_eHandler.insert("group/memberdef", 
786           new EndElementHandler(this,&LayoutParser::endMemberDef));
787       m_eHandler.insert("group", 
788           new EndElementHandler(this,&LayoutParser::endGroup));
789
790       // directory layout handlers
791       m_sHandler.insert("directory", 
792           new StartElementHandler(this,&LayoutParser::startDirectory));
793       m_sHandler.insert("directory/briefdescription", 
794           new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
795       m_sHandler.insert("directory/detaileddescription", 
796           new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
797                                          theTranslator->trDetailedDescription()));
798       m_sHandler.insert("directory/directorygraph", 
799           new StartElementHandlerKind(this,LayoutDocEntry::DirGraph,&LayoutParser::startSimpleEntry));
800       m_sHandler.insert("directory/memberdecl", 
801           new StartElementHandler(this,&LayoutParser::startMemberDecl));
802       m_sHandler.insert("directory/memberdecl/dirs", 
803           new StartElementHandlerKind(this,LayoutDocEntry::DirSubDirs,&LayoutParser::startSimpleEntry));
804       m_sHandler.insert("directory/memberdecl/files", 
805           new StartElementHandlerKind(this,LayoutDocEntry::DirFiles,&LayoutParser::startSimpleEntry));
806       m_eHandler.insert("directory/memberdecl", 
807           new EndElementHandler(this,&LayoutParser::endMemberDecl));
808       m_eHandler.insert("directory", 
809           new EndElementHandler(this,&LayoutParser::endDirectory));
810     }
811
812     void startSimpleEntry(LayoutDocEntry::Kind k,const QXmlAttributes &attrib)
813     {
814       bool isVisible = elemIsVisible(attrib);
815       if (m_part!=-1 && isVisible)
816       {
817         LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
818                                               new LayoutDocEntrySimple(k));
819       }
820     }
821
822     void startSectionEntry(LayoutDocEntry::Kind k,const QXmlAttributes &attrib,
823                            const QCString &title)
824     {
825       bool isVisible = elemIsVisible(attrib);
826       QCString userTitle = attrib.value("title").utf8();
827       //printf("startSectionEntry: title='%s' userTitle='%s'\n",
828       //    title.data(),userTitle.data());
829       if (userTitle.isEmpty())  userTitle = title;
830       if (m_part!=-1 && isVisible)
831       {
832         LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
833                                               new LayoutDocEntrySection(k,userTitle));
834       }
835     }
836
837
838     void startMemberDeclEntry(const QXmlAttributes &attrib,MemberListType type,
839                               const QCString &title,const QCString &subscript)
840     {
841       //QCString visible = convertToQCString(attrib.value("visible"));
842       //bool isVisible = visible.isEmpty() || (visible!="no" && visible!="0");
843       QCString userTitle     = attrib.value("title").utf8();
844       QCString userSubscript = attrib.value("subtitle").utf8();
845       if (userTitle.isEmpty())     userTitle     = title;
846       if (userSubscript.isEmpty()) userSubscript = subscript;
847       //printf("memberdecl: %s\n",userTitle.data());
848       if (m_part!=-1 /*&& isVisible*/)
849       {
850         LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
851                                               new LayoutDocEntryMemberDecl(type,userTitle,userSubscript));
852       }
853     }
854
855     void startMemberDefEntry(const QXmlAttributes &attrib,MemberListType type,
856                              const QCString &title,const QCString &)
857     {
858       QCString userTitle = attrib.value("title").utf8();
859       if (userTitle.isEmpty()) userTitle = title;
860       //printf("memberdef: %s\n",userTitle.data());
861       if (m_part!=-1 /*&& isVisible*/)
862       {
863         LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
864                                               new LayoutDocEntryMemberDef(type,userTitle));
865       }
866     }
867
868     void startLayout(const QXmlAttributes &)
869     {
870     }
871
872     void endLayout()
873     {
874     }
875
876     void startNavIndex(const QXmlAttributes &)
877     {
878       m_scope="navindex/";
879       m_rootNav = LayoutDocManager::instance().rootNavEntry();
880       if (m_rootNav) m_rootNav->clear();
881     }
882
883     void endNavIndex()
884     {
885       m_scope="";
886       if (m_rootNav && !m_rootNav->find(LayoutNavEntry::MainPage))
887       {
888         // no MainPage node... add one as the first item of the root node...
889         new LayoutNavEntry(m_rootNav,LayoutNavEntry::MainPage, TRUE, 
890             /*Config_getBool(GENERATE_TREEVIEW) ? "main" :*/ "index",
891             theTranslator->trMainPage(),"",TRUE);
892       }
893     }
894
895     void startNavEntry(const QXmlAttributes &attrib)
896     {
897       static bool javaOpt    = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
898       static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
899       static bool vhdlOpt    = Config_getBool(OPTIMIZE_OUTPUT_VHDL);  
900       static bool hasGraphicalHierarchy = Config_getBool(HAVE_DOT) &&
901                                           Config_getBool(GRAPHICAL_HIERARCHY);
902       static bool extractAll = Config_getBool(EXTRACT_ALL);
903       static struct NavEntryMap
904       {
905         const char *typeStr;       // type attribute name in the XML file
906         LayoutNavEntry::Kind kind; // corresponding enum name
907         QCString mainName;         // default title for an item if it has children
908         QCString subName;          // optional name for an item if it is rendered as a child
909         QCString intro;            // introduction text to be put on the index page
910         QCString baseFile;         // base name of the file containing the index page
911       } mapping[] =
912       {
913         { "mainpage",
914           LayoutNavEntry::MainPage,
915           theTranslator->trMainPage(),
916           QCString(),
917           QCString(),
918           "index"
919         },
920         { "pages",
921           LayoutNavEntry::Pages,
922           theTranslator->trRelatedPages(),
923           QCString(),
924           theTranslator->trRelatedPagesDescription(),
925           "pages"
926         },
927         { "modules",
928           LayoutNavEntry::Modules,
929           theTranslator->trModules(),
930           QCString(),
931           theTranslator->trModulesDescription(),
932           "modules"
933         },
934         { "namespaces",
935           LayoutNavEntry::Namespaces,
936           javaOpt || vhdlOpt   ? theTranslator->trPackages() : fortranOpt ? theTranslator->trModules() : theTranslator->trNamespaces(),
937           javaOpt || vhdlOpt   ? theTranslator->trPackages() : fortranOpt ? theTranslator->trModulesList() : theTranslator->trNamespaceList(),
938           javaOpt || vhdlOpt   ? theTranslator->trPackageListDescription() : fortranOpt ? theTranslator->trModulesListDescription(extractAll) : theTranslator->trNamespaceListDescription(extractAll),
939           "namespaces"
940         },
941         { "namespacelist",
942           LayoutNavEntry::NamespaceList,
943           javaOpt || vhdlOpt   ? theTranslator->trPackages() : fortranOpt ? theTranslator->trModulesList() : theTranslator->trNamespaceList(),
944           QCString(),
945           javaOpt || vhdlOpt   ? theTranslator->trPackageListDescription() : fortranOpt ? theTranslator->trModulesListDescription(extractAll) : theTranslator->trNamespaceListDescription(extractAll),
946           "namespaces"
947         },
948         { "namespacemembers",
949           LayoutNavEntry::NamespaceMembers,
950           javaOpt || vhdlOpt   ? theTranslator->trPackageMembers() : fortranOpt ? theTranslator->trModulesMembers() : theTranslator->trNamespaceMembers(),
951           QCString(),
952           fortranOpt ? theTranslator->trModulesMemberDescription(extractAll) : theTranslator->trNamespaceMemberDescription(extractAll),
953           "namespacemembers"
954         },
955         { "classindex",
956           LayoutNavEntry::ClassIndex,
957           fortranOpt ? theTranslator->trDataTypes() : vhdlOpt ? VhdlDocGen::trDesignUnits() : theTranslator->trCompoundIndex(),
958           QCString(),
959           QCString(),
960           "classes"
961         },
962         { "classes",
963           LayoutNavEntry::Classes,
964           fortranOpt ? theTranslator->trCompoundListFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitList() : theTranslator->trClasses(),
965           theTranslator->trCompoundList(),
966           fortranOpt ? theTranslator->trCompoundListDescriptionFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitListDescription() : theTranslator->trCompoundListDescription(),
967           "annotated"
968         },
969         { "classlist",
970           LayoutNavEntry::ClassList,
971           fortranOpt ? theTranslator->trCompoundListFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitList() : theTranslator->trCompoundList(),
972           QCString(),
973           fortranOpt ? theTranslator->trCompoundListDescriptionFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitListDescription() : theTranslator->trCompoundListDescription(),
974           "annotated"
975         },
976         { "hierarchy",
977           LayoutNavEntry::ClassHierarchy,
978           vhdlOpt    ? VhdlDocGen::trDesignUnitHierarchy() : theTranslator->trClassHierarchy(),
979           QCString(),
980           theTranslator->trClassHierarchyDescription(),
981           hasGraphicalHierarchy ? "inherits" : "hierarchy"
982         },
983         { "classmembers",
984           LayoutNavEntry::ClassMembers,
985           fortranOpt ? theTranslator->trCompoundMembersFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitMembers() : theTranslator->trCompoundMembers(),
986           QCString(),
987           fortranOpt ? theTranslator->trCompoundMembersDescriptionFortran(extractAll) : theTranslator->trCompoundMembersDescription(extractAll),
988           "functions"
989         },
990         { "files",
991           LayoutNavEntry::Files,
992           theTranslator->trFile(TRUE,FALSE),
993           theTranslator->trFileList(),
994           theTranslator->trFileListDescription(extractAll),
995           "files"
996         },
997         { "filelist",
998           LayoutNavEntry::FileList,
999           theTranslator->trFileList(),
1000           QCString(),
1001           theTranslator->trFileListDescription(extractAll),
1002           "files"
1003         },
1004         { "globals",
1005           LayoutNavEntry::FileGlobals,
1006           theTranslator->trFileMembers(),
1007           QCString(),
1008           theTranslator->trFileMembersDescription(extractAll),
1009           "globals"
1010         },
1011         //{ "dirs",
1012         //  LayoutNavEntry::Dirs,
1013         //  theTranslator->trDirectories(),
1014         //  QCString(),
1015         //  theTranslator->trDirDescription(),
1016         //  "dirs"
1017         //},
1018         { "examples",
1019           LayoutNavEntry::Examples,
1020           theTranslator->trExamples(),
1021           QCString(),
1022           theTranslator->trExamplesDescription(),
1023           "examples"
1024         },
1025         { "user",
1026           LayoutNavEntry::User,
1027           QCString(),
1028           QCString(),
1029           QCString(),
1030           "user"
1031         },
1032         { "usergroup",
1033           LayoutNavEntry::UserGroup,
1034           QCString(),
1035           QCString(),
1036           QCString(),
1037           "usergroup"
1038         },
1039         { 0, // end of list
1040           (LayoutNavEntry::Kind)0,
1041           QCString(),
1042           QCString(),
1043           QCString(),
1044           QCString()
1045         }
1046       };
1047       LayoutNavEntry::Kind kind;
1048       // find type in the table
1049       int i=0;
1050       QString type = attrib.value("type");
1051       while (mapping[i].typeStr)
1052       {
1053         if (mapping[i].typeStr==type)
1054         {
1055           kind = mapping[i].kind;
1056           break;
1057         }
1058         i++;
1059       }
1060       if (mapping[i].typeStr==0) 
1061       {
1062         if (type.isEmpty())
1063         {
1064           err("an entry tag within a navindex has no type attribute! Check your layout file!\n");
1065         }
1066         else
1067         {
1068           err("the type '%s' is not supported for the entry tag within a navindex! Check your layout file!\n",type.data());
1069         }
1070         m_invalidEntry=TRUE;
1071         return;
1072       }
1073       QCString baseFile = mapping[i].baseFile;
1074       QCString title = attrib.value("title").utf8();
1075       bool isVisible = elemIsVisible(attrib);
1076       if (title.isEmpty()) // use default title
1077       { 
1078         title = mapping[i].mainName; // use title for main row
1079         if (m_rootNav!=LayoutDocManager::instance().rootNavEntry() && !mapping[i].subName.isEmpty())
1080         {
1081           title = mapping[i].subName; // if this is a child of another row, use the subName if available
1082                                       // this is mainly done to get compatible naming with older versions.
1083         }
1084       }
1085       QCString intro = attrib.value("intro").utf8();
1086       if (intro.isEmpty()) // use default intro text
1087       {
1088         intro = mapping[i].intro;
1089       }
1090       QCString url = attrib.value("url").utf8();
1091       if (mapping[i].kind==LayoutNavEntry::User && !url.isEmpty())
1092       {
1093         baseFile=url;
1094       }
1095       else if (kind==LayoutNavEntry::UserGroup)
1096       {
1097         if (!url.isEmpty())
1098         {
1099           baseFile=url;
1100         }
1101         else
1102         {
1103           baseFile+=QCString().sprintf("%d",m_userGroupCount++);
1104         }
1105       }
1106       // create new item and make it the new root
1107       m_rootNav = new LayoutNavEntry(m_rootNav,kind,isVisible,baseFile,title,intro);
1108     }
1109
1110     void endNavEntry()
1111     {
1112       // set the root back to the parent
1113       if (m_rootNav && !m_invalidEntry) m_rootNav = m_rootNav->parent();
1114       m_invalidEntry=FALSE;
1115     }
1116
1117     void startClass(const QXmlAttributes &)
1118     {
1119       LayoutDocManager::instance().clear(LayoutDocManager::Class);
1120       m_scope="class/";
1121       m_part = (int)LayoutDocManager::Class;
1122     }
1123
1124     void endClass()
1125     {
1126       m_scope="";
1127       m_part = -1;
1128     }
1129
1130     void startNamespace(const QXmlAttributes &)
1131     {
1132       LayoutDocManager::instance().clear(LayoutDocManager::Namespace);
1133       m_scope="namespace/";
1134       m_part = (int)LayoutDocManager::Namespace;
1135     }
1136
1137     void endNamespace()
1138     {
1139       m_scope="";
1140       m_part = -1;
1141     }
1142
1143     void startFile(const QXmlAttributes &)
1144     {
1145       LayoutDocManager::instance().clear(LayoutDocManager::File);
1146       m_scope="file/";
1147       m_part = (int)LayoutDocManager::File;
1148     }
1149
1150     void endFile()
1151     {
1152       m_scope="";
1153       m_part = -1;
1154     }
1155
1156     void startGroup(const QXmlAttributes &)
1157     {
1158       LayoutDocManager::instance().clear(LayoutDocManager::Group);
1159       m_scope="group/";
1160       m_part = (int)LayoutDocManager::Group;
1161     }
1162
1163     void endGroup()
1164     {
1165       m_scope="";
1166       m_part = -1;
1167     }
1168
1169     void startDirectory(const QXmlAttributes &)
1170     {
1171       LayoutDocManager::instance().clear(LayoutDocManager::Directory);
1172       m_scope="directory/";
1173       m_part = (int)LayoutDocManager::Directory;
1174     }
1175
1176     void endDirectory()
1177     {
1178       m_scope="";
1179       m_part = -1;
1180     }
1181
1182     void startMemberDef(const QXmlAttributes &)
1183     {
1184       m_scope+="memberdef/";
1185       if (m_part!=-1)
1186       {
1187         LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
1188                                               new LayoutDocEntrySimple(LayoutDocEntry::MemberDefStart));
1189       }
1190     }
1191
1192     void endMemberDef()
1193     {
1194       int i=m_scope.findRev("memberdef/");
1195       if (i!=-1)
1196       {
1197         m_scope=m_scope.left(i);
1198         if (m_part!=-1)
1199         {
1200           LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
1201                                               new LayoutDocEntrySimple(LayoutDocEntry::MemberDefEnd));
1202         }
1203       }
1204     }
1205
1206     void startMemberDecl(const QXmlAttributes &)
1207     {
1208       m_scope+="memberdecl/";
1209       if (m_part!=-1)
1210       {
1211         LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
1212                                               new LayoutDocEntrySimple(LayoutDocEntry::MemberDeclStart));
1213       }
1214     }
1215
1216     void endMemberDecl()
1217     {
1218       int i=m_scope.findRev("memberdecl/");
1219       if (i!=-1)
1220       {
1221         m_scope=m_scope.left(i);
1222         if (m_part!=-1)
1223         {
1224           LayoutDocManager::instance().addEntry((LayoutDocManager::LayoutPart)m_part,
1225                                               new LayoutDocEntrySimple(LayoutDocEntry::MemberDeclEnd));
1226         }
1227       }
1228     }
1229
1230     // reimplemented from QXmlDefaultHandler
1231     bool startElement( const QString&, const QString&, 
1232                        const QString& name, const QXmlAttributes& attrib )
1233     {
1234       //printf("startElement [%s]::[%s]\n",m_scope.data(),name.data());
1235       StartElementHandler *handler = m_sHandler[m_scope+name.utf8()];
1236       if (handler)
1237       {
1238         (*handler)(attrib);
1239       }
1240       else
1241       {
1242         err("Unexpected start tag `%s' found in scope='%s'!\n",
1243             name.data(),m_scope.data());
1244       }
1245       return TRUE;
1246     }
1247     bool endElement( const QString&, const QString&, const QString& name )
1248     {
1249       //printf("endElement [%s]::[%s]\n",m_scope.data(),name.data());
1250       EndElementHandler *handler;
1251       if (!m_scope.isEmpty() && m_scope.right(name.length()+1)==name.utf8()+"/")
1252       { // element ends current scope
1253         handler = m_eHandler[m_scope.left(m_scope.length()-1)];
1254       }
1255       else // continue with current scope
1256       {
1257         handler = m_eHandler[m_scope+name.utf8()];
1258       }
1259       if (handler)
1260       {
1261         (*handler)();
1262       }
1263       return TRUE;
1264     }
1265     bool startDocument()
1266     {
1267       return TRUE;
1268     }
1269
1270   private:
1271     LayoutParser() : m_sHandler(163), m_eHandler(17), m_invalidEntry(FALSE) { }
1272    ~LayoutParser() { delete m_rootNav; }
1273
1274     QDict<StartElementHandler> m_sHandler;
1275     QDict<EndElementHandler>   m_eHandler;
1276     QCString m_scope;
1277     int m_part;
1278     LayoutNavEntry *m_rootNav;
1279     bool m_invalidEntry;
1280     static int m_userGroupCount;
1281 };
1282
1283 int LayoutParser::m_userGroupCount=0;
1284
1285 //---------------------------------------------------------------------------------
1286
1287 class LayoutErrorHandler : public QXmlErrorHandler
1288 {
1289   public:
1290     LayoutErrorHandler(const char *fn) : fileName(fn) {}
1291     bool warning( const QXmlParseException &exception )
1292     {
1293       warn_uncond("at line %d column %d of %s: %s\n",
1294           exception.lineNumber(),exception.columnNumber(),fileName.data(),
1295           exception.message().data());
1296       return FALSE;
1297     }
1298     bool error( const QXmlParseException &exception )
1299     {
1300       err("at line %d column %d of %s: %s\n",
1301           exception.lineNumber(),exception.columnNumber(),fileName.data(),
1302           exception.message().data());
1303       return FALSE;
1304     }
1305     bool fatalError( const QXmlParseException &exception )
1306     {
1307       err("fatal: at line %d column %d of %s: %s\n",
1308           exception.lineNumber(),exception.columnNumber(),fileName.data(),
1309           exception.message().data());
1310       return FALSE;
1311     }
1312     QString errorString() { return ""; }
1313
1314   private:
1315     QString errorMsg;
1316     QString fileName;
1317 };
1318
1319 //---------------------------------------------------------------------------------
1320
1321 class LayoutDocManager::Private
1322 {
1323   public:
1324     QList<LayoutDocEntry> docEntries[LayoutDocManager::NrParts];
1325     LayoutNavEntry *rootNav;
1326 };
1327
1328 LayoutDocManager::LayoutDocManager()
1329 {
1330   d = new Private;
1331   int i;
1332   for (i=0;i<LayoutDocManager::NrParts;i++)
1333   {
1334     d->docEntries[i].setAutoDelete(TRUE);
1335   }
1336   d->rootNav = new LayoutNavEntry;
1337   LayoutParser::instance().init();
1338 }
1339
1340
1341 void LayoutDocManager::init()
1342 {
1343   // parse the default layout
1344   LayoutErrorHandler errorHandler( "layout_default.xml" );
1345   QXmlInputSource source;
1346   source.setData( layout_default );
1347   QXmlSimpleReader reader;
1348   reader.setContentHandler( &LayoutParser::instance() );
1349   reader.setErrorHandler( &errorHandler );
1350   reader.parse( source );
1351 }
1352
1353 LayoutDocManager::~LayoutDocManager()
1354 {
1355   delete d->rootNav;
1356   delete d;
1357 }
1358
1359 LayoutDocManager & LayoutDocManager::instance()
1360 {
1361   static LayoutDocManager *theInstance = new LayoutDocManager;
1362   return *theInstance;
1363 }
1364
1365 const QList<LayoutDocEntry> &LayoutDocManager::docEntries(LayoutDocManager::LayoutPart part) const
1366 {
1367   return d->docEntries[(int)part];
1368 }
1369
1370 LayoutNavEntry* LayoutDocManager::rootNavEntry() const
1371 {
1372   return d->rootNav;
1373 }
1374
1375 void LayoutDocManager::addEntry(LayoutDocManager::LayoutPart p,LayoutDocEntry *e)
1376 {
1377   d->docEntries[(int)p].append(e);
1378 }
1379
1380 void LayoutDocManager::clear(LayoutDocManager::LayoutPart p)
1381 {
1382   d->docEntries[(int)p].clear();
1383 }
1384
1385 void LayoutDocManager::parse(QTextStream &t,const char *fileName)
1386 {
1387   LayoutErrorHandler errorHandler(fileName);
1388   QXmlInputSource source( t );
1389   QXmlSimpleReader reader;
1390   reader.setContentHandler( &LayoutParser::instance() );
1391   reader.setErrorHandler( &errorHandler );
1392   reader.parse( source );
1393 }
1394
1395 //---------------------------------------------------------------------------------
1396
1397 void writeDefaultLayoutFile(const char *fileName)
1398 {
1399   QFile f(fileName);
1400   bool ok = openOutputFile(fileName,f);
1401   if (!ok)
1402   {
1403     err("Failed to open file %s for writing!\n",fileName);
1404     return;
1405   }
1406   QTextStream t(&f);
1407   t << substitute(layout_default,"$doxygenversion",versionString);
1408 }
1409
1410 //----------------------------------------------------------------------------------
1411
1412 // Convert input to a title.
1413 // The format of input can be a simple title "A title" or in case there are different 
1414 // titles for some programming languages they can take the following form:
1415 // "A title|16=Another title|8=Yet Another title"
1416 // where the number is a value of SrcLangExt in decimal notation (i.e. 16=Java, 8=IDL).
1417 QCString extractLanguageSpecificTitle(const QCString &input,SrcLangExt lang)
1418 {
1419   int i,s=0,e=input.find('|');
1420   if (e==-1) return input; // simple title case
1421   int e1=e;
1422   while (e!=-1) // look for 'number=title' pattern separated by '|'
1423   {
1424     s=e+1;
1425     e=input.find('|',s);
1426     i=input.find('=',s);
1427     assert(i>s);
1428     int key=input.mid(s,i-s).toInt();
1429     if (key==(int)lang) // found matching key
1430     {
1431       if (e==-1) e=input.length();
1432       return input.mid(i+1,e-i-1);
1433     }
1434   }
1435   return input.left(e1); // fallback, no explicit language key found
1436 }
1437
1438 //----------------------------------------------------------------------------------
1439
1440 QCString LayoutDocEntrySection::title(SrcLangExt lang) const
1441 {
1442   return extractLanguageSpecificTitle(m_title,lang);
1443 }
1444
1445 //----------------------------------------------------------------------------------
1446
1447 QCString LayoutDocEntryMemberDecl::title(SrcLangExt lang) const
1448 {
1449   return extractLanguageSpecificTitle(m_title,lang);
1450 }
1451
1452 QCString LayoutDocEntryMemberDecl::subtitle(SrcLangExt lang) const
1453 {
1454   return extractLanguageSpecificTitle(m_subscript,lang);
1455 }
1456
1457 //----------------------------------------------------------------------------------
1458
1459 QCString LayoutDocEntryMemberDef::title(SrcLangExt lang) const
1460 {
1461   return extractLanguageSpecificTitle(m_title,lang);
1462 }
1463
1464
1465
1466