Commit 31198c21 authored by Dimitri van Heesch's avatar Dimitri van Heesch

More template and context updates

parent 7cda115a
...@@ -94,7 +94,7 @@ class ClassDefImpl ...@@ -94,7 +94,7 @@ class ClassDefImpl
ArgumentList *typeConstraints; ArgumentList *typeConstraints;
/*! Files that were used for generating the class documentation. */ /*! Files that were used for generating the class documentation. */
QStrList files; FileList files;
/*! Examples that use this class */ /*! Examples that use this class */
ExampleSDict *exampleSDict; ExampleSDict *exampleSDict;
...@@ -764,16 +764,17 @@ void ClassDef::findSectionsInDocumentation() ...@@ -764,16 +764,17 @@ void ClassDef::findSectionsInDocumentation()
// add a file name to the used files set // add a file name to the used files set
void ClassDef::insertUsedFile(const char *f) void ClassDef::insertUsedFile(FileDef *fd)
{ {
if (m_impl->files.find(f)==-1) m_impl->files.append(f); if (fd==0) return;
if (m_impl->files.find(fd)==-1) m_impl->files.append(fd);
if (m_impl->templateInstances) if (m_impl->templateInstances)
{ {
QDictIterator<ClassDef> qdi(*m_impl->templateInstances); QDictIterator<ClassDef> qdi(*m_impl->templateInstances);
ClassDef *cd; ClassDef *cd;
for (qdi.toFirst();(cd=qdi.current());++qdi) for (qdi.toFirst();(cd=qdi.current());++qdi)
{ {
cd->insertUsedFile(f); cd->insertUsedFile(fd);
} }
} }
} }
...@@ -916,12 +917,6 @@ static void writeTemplateSpec(OutputList &ol,Definition *d, ...@@ -916,12 +917,6 @@ static void writeTemplateSpec(OutputList &ol,Definition *d,
} }
} }
bool ClassDef::hasBriefDescription() const
{
static bool briefMemberDesc = Config_getBool("BRIEF_MEMBER_DESC");
return !briefDescription().isEmpty() && briefMemberDesc;
}
void ClassDef::writeBriefDescription(OutputList &ol,bool exampleFlag) void ClassDef::writeBriefDescription(OutputList &ol,bool exampleFlag)
{ {
if (hasBriefDescription()) if (hasBriefDescription())
...@@ -1039,45 +1034,49 @@ void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &/*pageTy ...@@ -1039,45 +1034,49 @@ void ClassDef::writeDetailedDescription(OutputList &ol, const QCString &/*pageTy
} }
} }
void ClassDef::showUsedFiles(OutputList &ol) QCString ClassDef::generatedFromFiles() const
{ {
ol.pushGeneratorState(); QCString result;
ol.disable(OutputGenerator::Man);
SrcLangExt lang = getLanguage(); SrcLangExt lang = getLanguage();
ol.writeRuler();
if (lang==SrcLangExt_Fortran) if (lang==SrcLangExt_Fortran)
{ {
ol.parseText(theTranslator->trGeneratedFromFilesFortran( result = theTranslator->trGeneratedFromFilesFortran(
getLanguage()==SrcLangExt_ObjC && m_impl->compType==Interface ? Class : m_impl->compType, getLanguage()==SrcLangExt_ObjC && m_impl->compType==Interface ? Class : m_impl->compType,
m_impl->files.count()==1)); m_impl->files.count()==1);
} }
else if (isJavaEnum()) else if (isJavaEnum())
{ {
ol.parseText(theTranslator->trEnumGeneratedFromFiles(m_impl->files.count()==1)); result = theTranslator->trEnumGeneratedFromFiles(m_impl->files.count()==1);
} }
else if (m_impl->compType==Service) else if (m_impl->compType==Service)
{ {
ol.parseText(theTranslator->trServiceGeneratedFromFiles(m_impl->files.count()==1)); result = theTranslator->trServiceGeneratedFromFiles(m_impl->files.count()==1);
} }
else if (m_impl->compType==Singleton) else if (m_impl->compType==Singleton)
{ {
ol.parseText(theTranslator->trSingletonGeneratedFromFiles(m_impl->files.count()==1)); result = theTranslator->trSingletonGeneratedFromFiles(m_impl->files.count()==1);
} }
else else
{ {
ol.parseText(theTranslator->trGeneratedFromFiles( result = theTranslator->trGeneratedFromFiles(
getLanguage()==SrcLangExt_ObjC && m_impl->compType==Interface ? Class : m_impl->compType, getLanguage()==SrcLangExt_ObjC && m_impl->compType==Interface ? Class : m_impl->compType,
m_impl->files.count()==1)); m_impl->files.count()==1);
} }
return result;
}
void ClassDef::showUsedFiles(OutputList &ol)
{
ol.pushGeneratorState();
ol.disable(OutputGenerator::Man);
ol.writeRuler();
ol.parseText(generatedFromFiles());
bool first=TRUE; bool first=TRUE;
const char *file = m_impl->files.first(); FileDef *fd = m_impl->files.first();
while (file) while (fd)
{
bool ambig;
FileDef *fd=findFileDef(Doxygen::inputNameDict,file,ambig);
if (fd)
{ {
if (first) if (first)
{ {
...@@ -1131,18 +1130,16 @@ void ClassDef::showUsedFiles(OutputList &ol) ...@@ -1131,18 +1130,16 @@ void ClassDef::showUsedFiles(OutputList &ol)
ol.popGeneratorState(); ol.popGeneratorState();
ol.endItemListItem(); ol.endItemListItem();
}
file=m_impl->files.next(); fd=m_impl->files.next();
} }
if (!first) ol.endItemList(); if (!first) ol.endItemList();
ol.popGeneratorState(); ol.popGeneratorState();
} }
int ClassDef::countInheritanceNodes()
void ClassDef::writeInheritanceGraph(OutputList &ol)
{ {
// count direct inheritance relations
int count=0; int count=0;
BaseClassDef *ibcd; BaseClassDef *ibcd;
if (m_impl->inheritedBy) if (m_impl->inheritedBy)
...@@ -1165,7 +1162,13 @@ void ClassDef::writeInheritanceGraph(OutputList &ol) ...@@ -1165,7 +1162,13 @@ void ClassDef::writeInheritanceGraph(OutputList &ol)
ibcd=m_impl->inherits->next(); ibcd=m_impl->inherits->next();
} }
} }
return count;
}
void ClassDef::writeInheritanceGraph(OutputList &ol)
{
// count direct inheritance relations
int count=countInheritanceNodes();
bool renderDiagram = FALSE; bool renderDiagram = FALSE;
if (Config_getBool("HAVE_DOT") && if (Config_getBool("HAVE_DOT") &&
...@@ -1322,6 +1325,24 @@ void ClassDef::writeCollaborationGraph(OutputList &ol) ...@@ -1322,6 +1325,24 @@ void ClassDef::writeCollaborationGraph(OutputList &ol)
} }
} }
QCString ClassDef::includeStatement() const
{
SrcLangExt lang = getLanguage();
bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
if (isIDLorJava)
{
return "import";
}
else if (isObjectiveC())
{
return "#import ";
}
else
{
return "#include ";
}
}
void ClassDef::writeIncludeFiles(OutputList &ol) void ClassDef::writeIncludeFiles(OutputList &ol)
{ {
if (m_impl->incInfo /*&& Config_getBool("SHOW_INCLUDE_FILES")*/) if (m_impl->incInfo /*&& Config_getBool("SHOW_INCLUDE_FILES")*/)
...@@ -1335,20 +1356,9 @@ void ClassDef::writeIncludeFiles(OutputList &ol) ...@@ -1335,20 +1356,9 @@ void ClassDef::writeIncludeFiles(OutputList &ol)
{ {
ol.startParagraph(); ol.startParagraph();
ol.startTypewriter(); ol.startTypewriter();
ol.docify(includeStatement());
SrcLangExt lang = getLanguage(); SrcLangExt lang = getLanguage();
bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java; bool isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
if (isIDLorJava)
{
ol.docify("import ");
}
else if (isObjectiveC())
{
ol.docify("#import ");
}
else
{
ol.docify("#include ");
}
if (m_impl->incInfo->local || isIDLorJava) if (m_impl->incInfo->local || isIDLorJava)
ol.docify("\""); ol.docify("\"");
else else
...@@ -4743,3 +4753,8 @@ const ClassSDict *ClassDef::innerClasses() const ...@@ -4743,3 +4753,8 @@ const ClassSDict *ClassDef::innerClasses() const
return m_impl->innerClasses; return m_impl->innerClasses;
} }
const FileList &ClassDef::usedFiles() const
{
return m_impl->files;
}
...@@ -31,6 +31,7 @@ class ClassList; ...@@ -31,6 +31,7 @@ class ClassList;
class ClassSDict; class ClassSDict;
class OutputList; class OutputList;
class FileDef; class FileDef;
class FileList;
class BaseClassList; class BaseClassList;
class NamespaceDef; class NamespaceDef;
class MemberDef; class MemberDef;
...@@ -125,9 +126,6 @@ class ClassDef : public Definition ...@@ -125,9 +126,6 @@ class ClassDef : public Definition
/** returns TRUE if this class has documentation */ /** returns TRUE if this class has documentation */
bool hasDocumentation() const; bool hasDocumentation() const;
/** returns TRUE if this class has a brief description */
bool hasBriefDescription() const;
/** returns TRUE if this class has a non-empty detailed description */ /** returns TRUE if this class has a non-empty detailed description */
bool hasDetailedDescription() const; bool hasDetailedDescription() const;
...@@ -310,6 +308,11 @@ class ClassDef : public Definition ...@@ -310,6 +308,11 @@ class ClassDef : public Definition
const ClassSDict *innerClasses() const; const ClassSDict *innerClasses() const;
QCString title() const; QCString title() const;
QCString generatedFromFiles() const;
const FileList &usedFiles() const;
QCString includeStatement() const;
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
// --- setters ---- // --- setters ----
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
...@@ -318,7 +321,7 @@ class ClassDef : public Definition ...@@ -318,7 +321,7 @@ class ClassDef : public Definition
void insertSubClass(ClassDef *,Protection p,Specifier s,const char *t=0); void insertSubClass(ClassDef *,Protection p,Specifier s,const char *t=0);
void setIncludeFile(FileDef *fd,const char *incName,bool local,bool force); void setIncludeFile(FileDef *fd,const char *incName,bool local,bool force);
void insertMember(MemberDef *); void insertMember(MemberDef *);
void insertUsedFile(const char *); void insertUsedFile(FileDef *);
bool addExample(const char *anchor,const char *name, const char *file); bool addExample(const char *anchor,const char *name, const char *file);
void mergeCategory(ClassDef *category); void mergeCategory(ClassDef *category);
void setNamespace(NamespaceDef *nd); void setNamespace(NamespaceDef *nd);
...@@ -375,6 +378,7 @@ class ClassDef : public Definition ...@@ -375,6 +378,7 @@ class ClassDef : public Definition
void addGroupedInheritedMembers(OutputList &ol,MemberListType lt, void addGroupedInheritedMembers(OutputList &ol,MemberListType lt,
ClassDef *inheritedFrom,const QCString &inheritId); ClassDef *inheritedFrom,const QCString &inheritId);
int countMembersIncludingGrouped(MemberListType lt,ClassDef *inheritedFrom,bool additional); int countMembersIncludingGrouped(MemberListType lt,ClassDef *inheritedFrom,bool additional);
int countInheritanceNodes();
bool visited; bool visited;
......
...@@ -17,6 +17,46 @@ ...@@ -17,6 +17,46 @@
#include "docparser.h" #include "docparser.h"
#include "htmlgen.h" #include "htmlgen.h"
#include "htmldocvisitor.h" #include "htmldocvisitor.h"
#include "dot.h"
#include "diagram.h"
struct ContextGlobals
{
enum OutputFormat
{
Html,
LateX,
Rtf,
ManPage,
DocBook,
Xml,
TagFile
};
int dynSectionId;
QCString outputDir;
OutputFormat outputFormat;
} g_globals;
/** @brief Scoped smart pointer */
template<class T> class ScopedPtr
{
private:
T *m_ptr;
ScopedPtr(const ScopedPtr &);
ScopedPtr &operator=(const ScopedPtr &);
void operator==(const ScopedPtr &) const;
void operator!=(const ScopedPtr &) const;
public:
typedef T Type;
explicit ScopedPtr(T *p=0) : m_ptr(p) {}
~ScopedPtr() { delete m_ptr; };
T &operator*() const { return *m_ptr; }
T *operator->() const { return m_ptr; }
T *get() const { return m_ptr; }
operator bool() const { return m_ptr!=0; }
void reset(T *p=0) { if (p!=m_ptr) { delete m_ptr; m_ptr = p; } }
};
// iterator support // iterator support
template<class T> template<class T>
...@@ -105,11 +145,16 @@ class GenericNodeListContext : public TemplateListIntf ...@@ -105,11 +145,16 @@ class GenericNodeListContext : public TemplateListIntf
//------------------------------------------------------------------------ //------------------------------------------------------------------------
/** @brief Helper class to map a property name to a handler member function */ /** @brief Helper class to map a property name to a handler member function */
template<typename T>
class PropertyMapper class PropertyMapper
{ {
public: private:
struct PropertyFunc struct PropertyFuncIntf
{
virtual ~PropertyFuncIntf() {}
virtual TemplateVariant operator()() const = 0;
};
template<typename T>
struct PropertyFunc : public PropertyFuncIntf
{ {
typedef TemplateVariant (T::*Handler)() const; typedef TemplateVariant (T::*Handler)() const;
PropertyFunc(const T *o,Handler h) : obj(o), handler(h) {} PropertyFunc(const T *o,Handler h) : obj(o), handler(h) {}
...@@ -120,24 +165,41 @@ class PropertyMapper ...@@ -120,24 +165,41 @@ class PropertyMapper
const T *obj; const T *obj;
Handler handler; Handler handler;
}; };
public:
PropertyMapper() { m_map.setAutoDelete(TRUE); } PropertyMapper() { m_map.setAutoDelete(TRUE); }
TemplateVariant get(const char *n)
/** Add a property to the map
* @param[in] name The name of the property to add.
* @param[in] obj The object handling access to the property.
* @param[in] handle The method to call when the property is accessed.
*/
template<typename T>
void addProperty(const char *name,const T* obj,
typename PropertyFunc<T>::Handler handle)
{
m_map.insert(name,new PropertyFunc<T>(obj,handle));
}
/** Gets the value of a property.
* @param[in] name The name of the property.
* @returns A variant representing the properties value or an
* invalid variant if it was not found.
*/
TemplateVariant get(const char *name) const
{ {
//printf("PropertyMapper::get(%s)\n",n); //printf("PropertyMapper::get(%s)\n",name);
TemplateVariant result; TemplateVariant result;
PropertyFunc *func = m_map.find(n); PropertyFuncIntf *func = m_map.find(name);
if (func) if (func)
{ {
result = (*func)(); result = (*func)();
} }
return result; return result;
} }
void insert(const char *name,const PropertyFunc *func)
{
m_map.insert(name,func);
}
private: private:
QDict<PropertyFunc> m_map; QDict<PropertyFuncIntf> m_map;
}; };
...@@ -213,7 +275,7 @@ TemplateVariant ConfigContext::get(const char *name) const ...@@ -213,7 +275,7 @@ TemplateVariant ConfigContext::get(const char *name) const
//%% struct Doxygen: global information //%% struct Doxygen: global information
//%% { //%% {
class DoxygenContext::Private : public PropertyMapper<DoxygenContext::Private> class DoxygenContext::Private : public PropertyMapper
{ {
public: public:
TemplateVariant version() const TemplateVariant version() const
...@@ -227,9 +289,9 @@ class DoxygenContext::Private : public PropertyMapper<DoxygenContext::Private> ...@@ -227,9 +289,9 @@ class DoxygenContext::Private : public PropertyMapper<DoxygenContext::Private>
Private() Private()
{ {
//%% string version //%% string version
insert("version",new PropertyFunc(this,&Private::version)); addProperty("version",this,&Private::version); //makeProperty(this,&Private::version));
//%% string date //%% string date
insert("date", new PropertyFunc(this,&Private::date)); addProperty("date", this,&Private::date);
} }
}; };
//%% } //%% }
...@@ -253,14 +315,31 @@ TemplateVariant DoxygenContext::get(const char *n) const ...@@ -253,14 +315,31 @@ TemplateVariant DoxygenContext::get(const char *n) const
//%% struct Translator: translation methods //%% struct Translator: translation methods
//%% { //%% {
class TranslateContext::Private : public PropertyMapper<TranslateContext::Private> class TranslateContext::Private : public PropertyMapper
{ {
public: public:
static QCString generatedAtFunc(const void *obj,const QValueList<TemplateVariant> &args)
static TemplateVariant generatedAtFunc(const void *obj,const QValueList<TemplateVariant> &args)
{ {
return ((TranslateContext::Private*)obj)->generatedAt(args); return ((TranslateContext::Private*)obj)->generatedAt(args);
} }
QCString generatedAt(const QValueList<TemplateVariant> &args) const static TemplateVariant inheritanceDiagramForFunc(const void *obj,const QValueList<TemplateVariant> &args)
{
return ((TranslateContext::Private*)obj)->inheritanceDiagramFor(args);
}
static TemplateVariant inheritsListFunc(const void *obj,const QValueList<TemplateVariant> &args)
{
return ((TranslateContext::Private*)obj)->inheritsList(args);
}
static TemplateVariant inheritedByListFunc(const void *obj,const QValueList<TemplateVariant> &args)
{
return ((TranslateContext::Private*)obj)->inheritedByList(args);
}
static TemplateVariant collaborationDiagramForFunc(const void *obj,const QValueList<TemplateVariant> &args)
{
return ((TranslateContext::Private*)obj)->collaborationDiagramFor(args);
}
TemplateVariant generatedAt(const QValueList<TemplateVariant> &args) const
{ {
if (args.count()==2) if (args.count()==2)
{ {
...@@ -268,11 +347,61 @@ class TranslateContext::Private : public PropertyMapper<TranslateContext::Privat ...@@ -268,11 +347,61 @@ class TranslateContext::Private : public PropertyMapper<TranslateContext::Privat
} }
else else
{ {
err("tr.generateAt should take two parameters!\n"); err("tr.generateAt should take two parameters, got %d!\n",args.count());
}
return TemplateVariant();
}
TemplateVariant inheritanceDiagramFor(const QValueList<TemplateVariant> &args) const
{
if (args.count()==1)
{
return theTranslator->trClassDiagram(args[0].toString());
}
else
{
err("tr.inheritanceDiagramFor should take one parameter, got %d!\n",args.count());
}
return TemplateVariant();
}
TemplateVariant collaborationDiagramFor(const QValueList<TemplateVariant> &args) const
{
if (args.count()==1)
{
return theTranslator->trCollaborationDiagram(args[0].toString());
}
else
{
err("tr.collaborationDiagramFor should take one parameter, got %d!\n",args.count());
}
return TemplateVariant();
}
TemplateVariant inheritsList(const QValueList<TemplateVariant> &args) const
{
if (args.count()==1)
{
return theTranslator->trInheritsList(args[0].toInt());
}
else
{
err("tr.inheritsList should take one integer parameter, got %d!\n",args.count());
}
return TemplateVariant();
}
QCString inheritedByList(const QValueList<TemplateVariant> &args) const
{
if (args.count()==1)
{
return theTranslator->trInheritedByList(args[0].toInt());
}
else
{
err("tr.inheritedByList should take one integer parameter, got %d!\n",args.count());
} }
return QCString(); return QCString();
} }
TemplateVariant generatedBy() const TemplateVariant generatedBy() const
{ {
return theTranslator->trGeneratedBy(); return theTranslator->trGeneratedBy();
...@@ -281,6 +410,14 @@ class TranslateContext::Private : public PropertyMapper<TranslateContext::Privat ...@@ -281,6 +410,14 @@ class TranslateContext::Private : public PropertyMapper<TranslateContext::Privat
{ {
return TemplateVariant(this,&Private::generatedAtFunc); return TemplateVariant(this,&Private::generatedAtFunc);
} }
TemplateVariant inheritanceDiagramFor() const
{
return TemplateVariant(this,&Private::inheritanceDiagramForFunc);
}
TemplateVariant collaborationDiagramFor() const
{
return TemplateVariant(this,&Private::collaborationDiagramForFunc);
}
TemplateVariant search() const TemplateVariant search() const
{ {
return theTranslator->trSearch(); return theTranslator->trSearch();
...@@ -390,50 +527,66 @@ class TranslateContext::Private : public PropertyMapper<TranslateContext::Privat ...@@ -390,50 +527,66 @@ class TranslateContext::Private : public PropertyMapper<TranslateContext::Privat
{ {
return theTranslator->trDetailedDescription(); return theTranslator->trDetailedDescription();
} }
TemplateVariant inheritsList() const
{
return TemplateVariant(this,&Private::inheritsListFunc);
}
TemplateVariant inheritedByList() const
{
return TemplateVariant(this,&Private::inheritedByListFunc);
}
Private() Private()
{ {
//%% string generatedBy //%% string generatedBy
insert("generatedby", new PropertyFunc(this,&Private::generatedBy)); addProperty("generatedby", this,&Private::generatedBy);
//%% string generatedAt //%% string generatedAt
insert("generatedAt", new PropertyFunc(this,&Private::generatedAt)); addProperty("generatedAt", this,&Private::generatedAt);
//%% string search //%% string search
insert("search", new PropertyFunc(this,&Private::search)); addProperty("search", this,&Private::search);
//%% string mainPage //%% string mainPage
insert("mainPage", new PropertyFunc(this,&Private::mainPage)); addProperty("mainPage", this,&Private::mainPage);
//%% string classes //%% string classes
insert("classes", new PropertyFunc(this,&Private::classes)); addProperty("classes", this,&Private::classes);
//%% string classList //%% string classList
insert("classList", new PropertyFunc(this,&Private::classList)); addProperty("classList", this,&Private::classList);
//%% string classIndex //%% string classIndex
insert("classIndex", new PropertyFunc(this,&Private::classIndex)); addProperty("classIndex", this,&Private::classIndex);
//%% string classHierarchy //%% string classHierarchy
insert("classHierarchy", new PropertyFunc(this,&Private::classHierarchy)); addProperty("classHierarchy", this,&Private::classHierarchy);
//%% string classMembers //%% string classMembers
insert("classMembers", new PropertyFunc(this,&Private::classMembers)); addProperty("classMembers", this,&Private::classMembers);
//%% string modules //%% string modules
insert("modules", new PropertyFunc(this,&Private::modules)); addProperty("modules", this,&Private::modules);
//%% string namespaces //%% string namespaces
insert("namespaces", new PropertyFunc(this,&Private::namespaces)); addProperty("namespaces", this,&Private::namespaces);
//%% string files //%% string files
insert("files", new PropertyFunc(this,&Private::files)); addProperty("files", this,&Private::files);
//%% string pages //%% string pages
insert("pages", new PropertyFunc(this,&Private::pages)); addProperty("pages", this,&Private::pages);
//%% string examples //%% string examples
insert("examples", new PropertyFunc(this,&Private::examples)); addProperty("examples", this,&Private::examples);
//%% string namespaceList //%% string namespaceList
insert("namespaceList", new PropertyFunc(this,&Private::namespaceList)); addProperty("namespaceList", this,&Private::namespaceList);
//%% string namespaceMembers //%% string namespaceMembers
insert("namespaceMembers",new PropertyFunc(this,&Private::namespaceMembers)); addProperty("namespaceMembers", this,&Private::namespaceMembers);
//%% srting fileList //%% srting fileList
insert("fileList", new PropertyFunc(this,&Private::fileList)); addProperty("fileList", this,&Private::fileList);
//%% string fileMembers //%% string fileMembers
insert("fileMembers", new PropertyFunc(this,&Private::fileMembers)); addProperty("fileMembers", this,&Private::fileMembers);
//%% string relatedPagesDescripiton //%% string relatedPagesDescripiton
insert("relatedPagesDesc",new PropertyFunc(this,&Private::relatedPagesDesc)); addProperty("relatedPagesDesc", this,&Private::relatedPagesDesc);
//%% string more //%% string more
insert("more", new PropertyFunc(this,&Private::more)); addProperty("more", this,&Private::more);
//%% string detailedDescription //%% string detailedDescription
insert("detailedDesc", new PropertyFunc(this,&Private::detailedDesc)); addProperty("detailedDesc", this,&Private::detailedDesc);
//%% string inheritanceDiagramFor
addProperty("inheritanceDiagramFor", this,&Private::inheritanceDiagramFor);
//%% string collaborationDiagramFor
addProperty("collaborationDiagramFor", this,&Private::collaborationDiagramFor);
//%% string inheritsList
addProperty("inheritsList", this,&Private::inheritsList);
//%% string inheritedByList
addProperty("inheritedByList", this,&Private::inheritedByList);
m_javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA"); m_javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
m_fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN"); m_fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
...@@ -478,8 +631,7 @@ static TemplateVariant parseDoc(Definition *def,const QCString &file,int line, ...@@ -478,8 +631,7 @@ static TemplateVariant parseDoc(Definition *def,const QCString &file,int line,
if (isEmpty) if (isEmpty)
result = ""; result = "";
else else
result = TemplateVariant(docs); result = TemplateVariant(docs,TRUE);
result.setRaw(TRUE);
delete root; delete root;
return result; return result;
} }
...@@ -489,79 +641,258 @@ static TemplateVariant parseDoc(Definition *def,const QCString &file,int line, ...@@ -489,79 +641,258 @@ static TemplateVariant parseDoc(Definition *def,const QCString &file,int line,
//%% struct Symbol: shared info for all symbols //%% struct Symbol: shared info for all symbols
//%% { //%% {
template<typename T> template<typename T>
class DefinitionContext : public PropertyMapper<T> class DefinitionContext : public PropertyMapper
{ {
public: public:
DefinitionContext(const T *super,Definition *d) : m_def(d), m_detailsCached(FALSE) DefinitionContext(Definition *d) : m_def(d)
{ {
//%% string name: the name of the symbol //%% string name: the name of the symbol
PropertyMapper<T>::insert("name", new typename PropertyMapper<T>::PropertyFunc(super,&DefinitionContext::name)); addProperty("name",this,&DefinitionContext::name);
//%% string bareName: the bare name of the symbol with scope info
addProperty("bareName",this,&DefinitionContext::bareName);
//%% string relPath: the relative path to the root of the output (CREATE_SUBDIRS) //%% string relPath: the relative path to the root of the output (CREATE_SUBDIRS)
PropertyMapper<T>::insert("relPath", new typename PropertyMapper<T>::PropertyFunc(super,&DefinitionContext::relPath)); addProperty("relPath",this,&DefinitionContext::relPath);
//%% string fileName: the file name of the output file associated with the symbol (without extension) //%% string fileName: the file name of the output file associated with the symbol (without extension)
PropertyMapper<T>::insert("fileName", new typename PropertyMapper<T>::PropertyFunc(super,&DefinitionContext::fileName)); addProperty("fileName",this,&DefinitionContext::fileName);
//%% string anchor: anchor within the page
addProperty("anchor",this,&DefinitionContext::anchor);
//%% string details: the detailed documentation for this symbol //%% string details: the detailed documentation for this symbol
PropertyMapper<T>::insert("details", new typename PropertyMapper<T>::PropertyFunc(super,&DefinitionContext::details)); addProperty("details",this,&DefinitionContext::details);
//%% string brief: the brief description for this symbol //%% string brief: the brief description for this symbol
PropertyMapper<T>::insert("brief", new typename PropertyMapper<T>::PropertyFunc(super,&DefinitionContext::brief)); addProperty("brief",this,&DefinitionContext::brief);
//%% string sourceFileName: the file name of the source file (without extension)
addProperty("sourceFileName",this,&DefinitionContext::sourceFileName);
//%% bool isLinkable: can the symbol be linked to?
addProperty("isLinkable",this,&DefinitionContext::isLinkable);
//%% bool isLinkableInProject: can the symbol be linked within this project?
addProperty("isLinkableInProject",this,&DefinitionContext::isLinkableInProject);
//%% int dynSectionId: identifier that can be used for collapsable sections
addProperty("dynSectionId",this,&DefinitionContext::dynSectionId);
//%% string language: the programming language in which the symbol is written
addProperty("language",this,&DefinitionContext::language);
} }
TemplateVariant fileName() const TemplateVariant fileName() const
{ {
return TemplateVariant(m_def->getOutputFileBase()); return m_def->getOutputFileBase();
}
TemplateVariant anchor() const
{
return m_def->anchor();
}
TemplateVariant sourceFileName() const
{
return m_def->getSourceFileBase();
}
TemplateVariant isLinkable() const
{
return m_def->isLinkable();
}
TemplateVariant isLinkableInProject() const
{
return m_def->isLinkableInProject();
} }
TemplateVariant name() const TemplateVariant name() const
{ {
return m_def->displayName(); return m_def->displayName(TRUE);
} }
TemplateVariant relPath() const TemplateVariant bareName() const
{
return m_def->displayName(FALSE);
}
QCString relPathAsString() const
{ {
static bool createSubdirs = Config_getBool("CREATE_SUBDIRS"); static bool createSubdirs = Config_getBool("CREATE_SUBDIRS");
return createSubdirs ? TemplateVariant("../../") : TemplateVariant(""); return createSubdirs ? QCString("../../") : QCString("");
}
TemplateVariant relPath() const
{
return relPathAsString();
} }
TemplateVariant details() const TemplateVariant details() const
{ {
if (!m_detailsCached) if (!m_details)
{ {
m_details = parseDoc(m_def,m_def->docFile(),m_def->docLine(), m_details.reset(new TemplateVariant(parseDoc(m_def,m_def->docFile(),m_def->docLine(),
relPath().toString(),m_def->documentation(),FALSE); relPathAsString(),m_def->documentation(),FALSE)));
m_detailsCached = TRUE;
} }
return m_details; return *m_details;
} }
TemplateVariant brief() const TemplateVariant brief() const
{ {
if (!m_briefCached) if (!m_brief)
{
if (m_def->hasBriefDescription())
{
m_brief.reset(new TemplateVariant(parseDoc(m_def,m_def->briefFile(),m_def->briefLine(),
relPathAsString(),m_def->briefDescription(),TRUE)));
}
else
{
m_brief.reset(new TemplateVariant(""));
}
}
return *m_brief;
}
TemplateVariant dynSectionId() const
{
return g_globals.dynSectionId;
}
TemplateVariant language() const
{
SrcLangExt lang = m_def->getLanguage();
QCString result = "unknown";
switch (lang)
{ {
m_brief = parseDoc(m_def,m_def->briefFile(),m_def->briefLine(), case SrcLangExt_Unknown: break;
relPath().toString(),m_def->briefDescription(),TRUE); case SrcLangExt_IDL: result="idl"; break;
m_briefCached = TRUE; case SrcLangExt_Java: result="java"; break;
case SrcLangExt_CSharp: result="csharp"; break;
case SrcLangExt_D: result="d"; break;
case SrcLangExt_PHP: result="php"; break;
case SrcLangExt_ObjC: result="objc"; break;
case SrcLangExt_Cpp: result="cpp"; break;
case SrcLangExt_JS: result="js"; break;
case SrcLangExt_Python: result="python"; break;
case SrcLangExt_Fortran: result="fortran"; break;
case SrcLangExt_VHDL: result="vhdl"; break;
case SrcLangExt_XML: result="xml"; break;
case SrcLangExt_Tcl: result="tcl"; break;
case SrcLangExt_Markdown: result="markdown"; break;
} }
return m_brief; return result;
} }
private: private:
Definition *m_def; Definition *m_def;
mutable bool m_detailsCached; mutable ScopedPtr<TemplateVariant> m_details;
mutable TemplateVariant m_details; mutable ScopedPtr<TemplateVariant> m_brief;
mutable bool m_briefCached;
mutable TemplateVariant m_brief;
}; };
//%% } //%% }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
//%% struct IncludeInfo: include file information
//%% {
class IncludeInfoContext::Private : public PropertyMapper
{
public:
Private(IncludeInfo *info,SrcLangExt lang) :
m_info(info),
m_fileContext(info && info->fileDef ? info->fileDef : 0),
m_lang(lang)
{
if (m_info)
{
addProperty("file",this,&Private::file);
addProperty("name",this,&Private::name);
addProperty("isImport",this,&Private::isImport);
addProperty("isLocal",this,&Private::isLocal);
}
}
TemplateVariant isLocal() const
{
bool isIDLorJava = m_lang==SrcLangExt_IDL || m_lang==SrcLangExt_Java;
return m_info->local || isIDLorJava;
}
TemplateVariant isImport() const
{
return m_info->imported;
}
TemplateVariant file() const
{
if (m_info->fileDef)
{
return &m_fileContext;
}
else
{
return FALSE;
}
}
TemplateVariant name() const
{
return m_info->includeName;
}
private:
IncludeInfo *m_info;
FileContext m_fileContext;
SrcLangExt m_lang;
};
IncludeInfoContext::IncludeInfoContext(IncludeInfo *info,SrcLangExt lang)
{
p = new Private(info,lang);
}
IncludeInfoContext::~IncludeInfoContext()
{
delete p;
}
TemplateVariant IncludeInfoContext::get(const char *n) const
{
return p->get(n);
}
//%% }
//------------------------------------------------------------------------
//%% struct Class(Symbol): class information //%% struct Class(Symbol): class information
//%% { //%% {
class ClassContext::Private : public DefinitionContext<ClassContext::Private> class ClassContext::Private : public DefinitionContext<ClassContext::Private>
{ {
public: public:
Private(ClassDef *cd) : DefinitionContext(this,cd) , m_classDef(cd) Private(ClassDef *cd) : DefinitionContext(cd) ,
{ m_classDef(cd), m_usedFiles(cd),
insert("title", new PropertyFunc(this,&Private::title)); m_includeInfo(cd ? cd->includeInfo() : 0, cd ? cd->getLanguage() : SrcLangExt_Unknown)
insert("highlight", new PropertyFunc(this,&Private::highlight)); {
insert("subhighlight", new PropertyFunc(this,&Private::subHighlight)); addProperty("title", this,&Private::title);
insert("hasBrief", new PropertyFunc(this,&Private::hasBrief)); addProperty("highlight", this,&Private::highlight);
insert("hasDetails", new PropertyFunc(this,&Private::hasDetails)); addProperty("subhighlight", this,&Private::subHighlight);
addProperty("hasDetails", this,&Private::hasDetails);
addProperty("generatedFromFiles", this,&Private::generatedFromFiles);
addProperty("usedFiles", this,&Private::usedFiles);
addProperty("hasInheritanceDiagram", this,&Private::hasInheritanceDiagram);
addProperty("inheritanceDiagram", this,&Private::inheritanceDiagram);
addProperty("hasCollaborationDiagram", this,&Private::hasCollaborationDiagram);
addProperty("collaborationDiagram", this,&Private::collaborationDiagram);
addProperty("includeInfo", this,&Private::includeInfo);
addProperty("includeStatement", this,&Private::includeStatement);
addProperty("inherits", this,&Private::inherits);
addProperty("inheritedBy", this,&Private::inheritedBy);
addProperty("unoIDLServices", this,&Private::unoIDLServices);
addProperty("unoIDLInterfaces", this,&Private::unoIDLInterfaces);
addProperty("signals", this,&Private::signals);
addProperty("publicTypes", this,&Private::publicTypes);
addProperty("publicMethods", this,&Private::publicMethods);
addProperty("publicStaticMethods", this,&Private::publicStaticMethods);
addProperty("publicAttributes", this,&Private::publicAttributes);
addProperty("publicStaticAttributes", this,&Private::publicStaticAttributes);
addProperty("publicSlots", this,&Private::publicSlots);
addProperty("protectedTypes", this,&Private::protectedTypes);
addProperty("protectedMethods", this,&Private::protectedMethods);
addProperty("protectedStaticMethods", this,&Private::protectedStaticMethods);
addProperty("protectedAttributes", this,&Private::protectedAttributes);
addProperty("protectedStaticAttributes", this,&Private::protectedStaticAttributes);
addProperty("protectedSlots", this,&Private::protectedSlots);
addProperty("privateTypes", this,&Private::privateTypes);
addProperty("privateMethods", this,&Private::privateMethods);
addProperty("privateStaticMethods", this,&Private::privateStaticMethods);
addProperty("privateAttributes", this,&Private::privateAttributes);
addProperty("privateStaticAttributes", this,&Private::privateStaticAttributes);
addProperty("privateSlots", this,&Private::privateSlots);
addProperty("packageTypes", this,&Private::packageTypes);
addProperty("packageMethods", this,&Private::packageMethods);
addProperty("packageStaticMethods", this,&Private::packageStaticMethods);
addProperty("packageAttributes", this,&Private::packageAttributes);
addProperty("packageStaticAttributes", this,&Private::packageStaticAttributes);
addProperty("properties", this,&Private::properties);
addProperty("events", this,&Private::events);
addProperty("friends", this,&Private::friends);
addProperty("related", this,&Private::related);
addProperty("nestedClasses", this,&Private::nestedClasses);
addProperty("compoundType", this,&Private::compoundType);
addProperty("templateDecls", this,&Private::templateDecls);
} }
TemplateVariant title() const TemplateVariant title() const
{ {
...@@ -575,21 +906,422 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private> ...@@ -575,21 +906,422 @@ class ClassContext::Private : public DefinitionContext<ClassContext::Private>
{ {
return TemplateVariant(""); return TemplateVariant("");
} }
TemplateVariant hasBrief() const
{
return m_classDef->hasBriefDescription();
}
TemplateVariant hasDetails() const TemplateVariant hasDetails() const
{ {
return m_classDef->hasDetailedDescription(); return m_classDef->hasDetailedDescription();
} }
TemplateVariant generatedFromFiles() const
{
return m_classDef->generatedFromFiles();
}
TemplateVariant usedFiles() const
{
return TemplateVariant(&m_usedFiles);
}
DotClassGraph *getClassGraph() const
{
if (!m_cache.classGraph)
{
m_cache.classGraph.reset(new DotClassGraph(m_classDef,DotNode::Inheritance));
}
return m_cache.classGraph.get();
}
int numInheritanceNodes() const
{
if (m_cache.inheritanceNodes==-1)
{
m_cache.inheritanceNodes=m_classDef->countInheritanceNodes();
}
return m_cache.inheritanceNodes>0;
}
TemplateVariant hasInheritanceDiagram() const
{
bool result=FALSE;
static bool haveDot = Config_getBool("HAVE_DOT");
static bool classDiagrams = Config_getBool("CLASS_DIAGRAMS");
static bool classGraph = Config_getBool("CLASS_GRAPH");
if (haveDot && (classDiagrams || classGraph))
{
DotClassGraph *cg = getClassGraph();
result = !cg->isTrivial() && !cg->isTooBig();
}
else if (classDiagrams)
{
result = numInheritanceNodes()>0;
}
return result;
}
TemplateVariant inheritanceDiagram() const
{
QGString result;
static bool haveDot = Config_getBool("HAVE_DOT");
static bool classDiagrams = Config_getBool("CLASS_DIAGRAMS");
static bool classGraph = Config_getBool("CLASS_GRAPH");
if (haveDot && (classDiagrams || classGraph))
{
DotClassGraph *cg = getClassGraph();
FTextStream t(&result);
cg->writeGraph(t,BITMAP,
g_globals.outputDir,
m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension,
relPathAsString(),TRUE,TRUE,g_globals.dynSectionId
);
}
else if (classDiagrams)
{
ClassDiagram d(m_classDef);
FTextStream t(&result);
QCString name = convertToHtml(m_classDef->displayName());
t << "<div class=\"center\">" << endl;
t << "<img src=\"";
t << relPathAsString() << m_classDef->getOutputFileBase();
t << ".png\" usemap=\"#" << name << "_map\" alt=\"\"/>" << endl;
t << "<map id=\"" << name << "_map\" name=\"" << name << "_map\">" << endl;
d.writeImage(t,g_globals.outputDir,
relPathAsString(),
m_classDef->getOutputFileBase());
t << "</div>";
}
g_globals.dynSectionId++;
return TemplateVariant(result.data(),TRUE);
}
DotClassGraph *getCollaborationGraph() const
{
if (!m_cache.collaborationGraph)
{
m_cache.collaborationGraph.reset(new DotClassGraph(m_classDef,DotNode::Collaboration));
}
return m_cache.collaborationGraph.get();
}
TemplateVariant hasCollaborationDiagram() const
{
static bool haveDot = Config_getBool("HAVE_DOT");
return haveDot && !getCollaborationGraph()->isTrivial();
}
TemplateVariant collaborationDiagram() const
{
static bool haveDot = Config_getBool("HAVE_DOT");
QGString result;
if (haveDot)
{
DotClassGraph *cg = getCollaborationGraph();
FTextStream t(&result);
cg->writeGraph(t,BITMAP,
g_globals.outputDir,
m_classDef->getOutputFileBase()+Doxygen::htmlFileExtension,
relPathAsString(),TRUE,TRUE,g_globals.dynSectionId
);
}
g_globals.dynSectionId++;
return TemplateVariant(result.data(),TRUE);
}
TemplateVariant includeInfo() const
{
if (m_classDef->includeInfo())
{
return TemplateVariant(&m_includeInfo);
}
else
{
return TemplateVariant(FALSE);
}
}
TemplateVariant includeStatement() const
{
return m_classDef->includeStatement();
}
TemplateVariant inherits() const
{
if (!m_cache.inheritsList)
{
m_cache.inheritsList.reset(new InheritanceListContext(m_classDef->baseClasses(),TRUE));
}
return m_cache.inheritsList.get();
}
TemplateVariant inheritedBy() const
{
if (!m_cache.inheritedByList)
{
m_cache.inheritedByList.reset(new InheritanceListContext(m_classDef->subClasses(),FALSE));
}
return m_cache.inheritedByList.get();
}
TemplateVariant getMemberList(ScopedPtr<MemberListInfoContext> &list,
MemberListType type,const char *title) const
{
if (!list)
{
MemberList *ml = m_classDef->getMemberList(type);
if (ml)
{
list.reset(new MemberListInfoContext(ml,title));
}
}
if (list)
{
return list.get();
}
else
{
return TemplateVariant(FALSE);
}
}
TemplateVariant unoIDLServices() const
{
return getMemberList(m_cache.unoIDLServices,MemberListType_services,theTranslator->trServices());
}
TemplateVariant unoIDLInterfaces() const
{
return getMemberList(m_cache.unoIDLInterfaces,MemberListType_interfaces,theTranslator->trInterfaces());
}
TemplateVariant signals() const
{
return getMemberList(m_cache.signals,MemberListType_signals,theTranslator->trSignals());
}
TemplateVariant publicTypes() const
{
return getMemberList(m_cache.publicTypes,MemberListType_pubTypes,theTranslator->trPublicTypes());
}
TemplateVariant publicMethods() const
{
return getMemberList(m_cache.publicMethods,MemberListType_pubMethods,
m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trInstanceMethods()
: theTranslator->trPublicMembers());
}
TemplateVariant publicStaticMethods() const
{
return getMemberList(m_cache.publicStaticMethods,MemberListType_pubStaticMethods,
m_classDef->getLanguage()==SrcLangExt_ObjC ? theTranslator->trClassMethods()
: theTranslator->trStaticPublicMembers());
}
TemplateVariant publicAttributes() const
{
return getMemberList(m_cache.publicAttributes,MemberListType_pubAttribs,theTranslator->trPublicAttribs());
}
TemplateVariant publicStaticAttributes() const
{
return getMemberList(m_cache.publicStaticAttributes,MemberListType_pubStaticAttribs,theTranslator->trStaticPublicAttribs());
}
TemplateVariant publicSlots() const
{
return getMemberList(m_cache.publicSlots,MemberListType_pubSlots,theTranslator->trPublicSlots());
}
TemplateVariant protectedTypes() const
{
return getMemberList(m_cache.protectedTypes,MemberListType_proTypes,theTranslator->trProtectedTypes());
}
TemplateVariant protectedMethods() const
{
return getMemberList(m_cache.protectedMethods,MemberListType_proMethods,theTranslator->trProtectedMembers());
}
TemplateVariant protectedStaticMethods() const
{
return getMemberList(m_cache.protectedStaticMethods,MemberListType_proStaticMethods,theTranslator->trStaticProtectedMembers());
}
TemplateVariant protectedAttributes() const
{
return getMemberList(m_cache.protectedAttributes,MemberListType_proAttribs,theTranslator->trProtectedAttribs());
}
TemplateVariant protectedStaticAttributes() const
{
return getMemberList(m_cache.protectedStaticAttributes,MemberListType_proStaticAttribs,theTranslator->trStaticProtectedAttribs());
}
TemplateVariant protectedSlots() const
{
return getMemberList(m_cache.protectedSlots,MemberListType_proSlots,theTranslator->trProtectedSlots());
}
TemplateVariant privateTypes() const
{
return getMemberList(m_cache.privateTypes,MemberListType_priTypes,theTranslator->trPrivateTypes());
}
TemplateVariant privateSlots() const
{
return getMemberList(m_cache.privateSlots,MemberListType_priSlots,theTranslator->trPrivateSlots());
}
TemplateVariant privateMethods() const
{
return getMemberList(m_cache.privateMethods,MemberListType_priMethods,theTranslator->trPrivateMembers());
}
TemplateVariant privateStaticMethods() const
{
return getMemberList(m_cache.privateStaticMethods,MemberListType_priStaticMethods,theTranslator->trStaticPrivateMembers());
}
TemplateVariant privateAttributes() const
{
return getMemberList(m_cache.privateAttributes,MemberListType_priAttribs,theTranslator->trPrivateAttribs());
}
TemplateVariant privateStaticAttributes() const
{
return getMemberList(m_cache.privateStaticAttributes,MemberListType_priStaticAttribs,theTranslator->trStaticPrivateAttribs());
}
TemplateVariant packageTypes() const
{
return getMemberList(m_cache.packageTypes,MemberListType_pacTypes,theTranslator->trPackageTypes());
}
TemplateVariant packageMethods() const
{
return getMemberList(m_cache.packageMethods,MemberListType_pacMethods,theTranslator->trPackageMembers());
}
TemplateVariant packageStaticMethods() const
{
return getMemberList(m_cache.packageStaticMethods,MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers());
}
TemplateVariant packageAttributes() const
{
return getMemberList(m_cache.packageAttributes,MemberListType_pacAttribs,theTranslator->trPackageAttribs());
}
TemplateVariant packageStaticAttributes() const
{
return getMemberList(m_cache.packageStaticAttributes,MemberListType_pacStaticAttribs,theTranslator->trStaticPackageAttribs());
}
TemplateVariant properties() const
{
return getMemberList(m_cache.properties,MemberListType_properties,theTranslator->trProperties());
}
TemplateVariant events() const
{
return getMemberList(m_cache.events,MemberListType_events,theTranslator->trEvents());
}
TemplateVariant friends() const
{
return getMemberList(m_cache.events,MemberListType_friends,theTranslator->trFriends());
}
TemplateVariant related() const
{
return getMemberList(m_cache.events,MemberListType_related,theTranslator->trRelatedFunctions());
}
TemplateVariant nestedClasses() const
{
static bool extractPrivate = Config_getBool("EXTRACT_PRIVATE");
static bool hideUndocClasses = Config_getBool("HIDE_UNDOC_CLASSES");
static bool extractLocalClasses = Config_getBool("EXTRACT_LOCAL_CLASSES");
if (!m_cache.nestedClasses)
{
if (m_classDef->getClassSDict())
{
NestedClassListContext *classList = new NestedClassListContext;
ClassSDict::Iterator sdi(*m_classDef->getClassSDict());
ClassDef *cd;
for (sdi.toFirst();(cd=sdi.current());++sdi)
{
bool linkable = cd->isLinkable();
if (cd->name().find('@')==-1 && !cd->isExtension() &&
(cd->protection()!=::Private || extractPrivate) &&
(linkable ||
(!hideUndocClasses && (!cd->isLocal() || extractLocalClasses)))
)
{
classList->append(cd);
}
}
m_cache.nestedClasses.reset(classList);
}
}
if (m_cache.nestedClasses)
{
return m_cache.nestedClasses.get();
}
else
{
return TemplateVariant(FALSE);
}
}
TemplateVariant compoundType() const
{
return m_classDef->compoundTypeString();
}
void addTemplateDecls(Definition *d,TemplateList *tl) const
{
if (d->definitionType()==Definition::TypeClass)
{
Definition *parent = d->getOuterScope();
if (parent)
{
addTemplateDecls(parent,tl);
}
ClassDef *cd=(ClassDef *)d;
if (cd->templateArguments())
{
ArgumentListContext *al = new ArgumentListContext(cd->templateArguments());
// since a TemplateVariant does take ownership of the object, we add it
// a separate list just to be able to delete it and avoid a memory leak
m_cache.templateArgList.append(al);
tl->append(al);
}
}
}
TemplateVariant templateDecls() const
{
if (!m_cache.templateDecls)
{
TemplateList *tl = new TemplateList;
addTemplateDecls(m_classDef,tl);
m_cache.templateDecls.reset(tl);
}
if (m_cache.templateDecls)
{
return m_cache.templateDecls.get();
}
else
{
return TemplateVariant(FALSE);
}
}
private: private:
ClassDef *m_classDef; ClassDef *m_classDef;
UsedFilesContext m_usedFiles;
IncludeInfoContext m_includeInfo;
struct Cachable
{
Cachable() : inheritanceNodes(-1) { templateArgList.setAutoDelete(TRUE); }
ScopedPtr<InheritanceListContext> inheritsList;
ScopedPtr<InheritanceListContext> inheritedByList;
ScopedPtr<DotClassGraph> classGraph;
ScopedPtr<DotClassGraph> collaborationGraph;
ScopedPtr<NestedClassListContext> nestedClasses;
ScopedPtr<MemberListInfoContext> publicTypes;
ScopedPtr<MemberListInfoContext> publicMethods;
ScopedPtr<MemberListInfoContext> publicStaticMethods;
ScopedPtr<MemberListInfoContext> publicAttributes;
ScopedPtr<MemberListInfoContext> publicStaticAttributes;
ScopedPtr<MemberListInfoContext> publicSlots;
ScopedPtr<MemberListInfoContext> protectedTypes;
ScopedPtr<MemberListInfoContext> protectedMethods;
ScopedPtr<MemberListInfoContext> protectedStaticMethods;
ScopedPtr<MemberListInfoContext> protectedAttributes;
ScopedPtr<MemberListInfoContext> protectedStaticAttributes;
ScopedPtr<MemberListInfoContext> protectedSlots;
ScopedPtr<MemberListInfoContext> privateTypes;
ScopedPtr<MemberListInfoContext> privateMethods;
ScopedPtr<MemberListInfoContext> privateStaticMethods;
ScopedPtr<MemberListInfoContext> privateAttributes;
ScopedPtr<MemberListInfoContext> privateStaticAttributes;
ScopedPtr<MemberListInfoContext> privateSlots;
ScopedPtr<MemberListInfoContext> packageTypes;
ScopedPtr<MemberListInfoContext> packageMethods;
ScopedPtr<MemberListInfoContext> packageStaticMethods;
ScopedPtr<MemberListInfoContext> packageAttributes;
ScopedPtr<MemberListInfoContext> packageStaticAttributes;
ScopedPtr<MemberListInfoContext> unoIDLServices;
ScopedPtr<MemberListInfoContext> unoIDLInterfaces;
ScopedPtr<MemberListInfoContext> signals;
ScopedPtr<MemberListInfoContext> properties;
ScopedPtr<MemberListInfoContext> events;
ScopedPtr<MemberListInfoContext> friends;
ScopedPtr<MemberListInfoContext> related;
ScopedPtr<TemplateList> templateDecls;
int inheritanceNodes;
QList<ArgumentListContext> templateArgList;
};
mutable Cachable m_cache;
}; };
//%% } //%% }
ClassContext::ClassContext(ClassDef *cd) ClassContext::ClassContext(ClassDef *cd)
{ {
//printf("ClassContext::ClassContext(%s)\n",cd?cd->name().data():"<none>");
p = new Private(cd); p = new Private(cd);
} }
...@@ -610,11 +1342,11 @@ TemplateVariant ClassContext::get(const char *n) const ...@@ -610,11 +1342,11 @@ TemplateVariant ClassContext::get(const char *n) const
class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Private> class NamespaceContext::Private : public DefinitionContext<NamespaceContext::Private>
{ {
public: public:
Private(NamespaceDef *nd) : DefinitionContext(this,nd) , m_namespaceDef(nd) Private(NamespaceDef *nd) : DefinitionContext(nd) , m_namespaceDef(nd)
{ {
insert("title", new PropertyFunc(this,&Private::title)); addProperty("title",this,&Private::title);
insert("highlight", new PropertyFunc(this,&Private::highlight)); addProperty("highlight",this,&Private::highlight);
insert("subhighlight", new PropertyFunc(this,&Private::subHighlight)); addProperty("subhighlight",this,&Private::subHighlight);
} }
TemplateVariant title() const TemplateVariant title() const
{ {
...@@ -655,15 +1387,16 @@ TemplateVariant NamespaceContext::get(const char *n) const ...@@ -655,15 +1387,16 @@ TemplateVariant NamespaceContext::get(const char *n) const
class FileContext::Private : public DefinitionContext<FileContext::Private> class FileContext::Private : public DefinitionContext<FileContext::Private>
{ {
public: public:
Private(FileDef *fd) : DefinitionContext(this,fd) , m_fileDef(fd) Private(FileDef *fd) : DefinitionContext(fd) , m_fileDef(fd)
{ {
insert("title", new PropertyFunc(this,&Private::title)); addProperty("title",this,&Private::title);
insert("highlight", new PropertyFunc(this,&Private::highlight)); addProperty("highlight",this,&Private::highlight);
insert("subhighlight", new PropertyFunc(this,&Private::subHighlight)); addProperty("subhighlight",this,&Private::subHighlight);
addProperty("versionInfo",this,&Private::versionInfo);
} }
TemplateVariant title() const TemplateVariant title() const
{ {
return TemplateVariant(m_fileDef->title()); return m_fileDef->title();
} }
TemplateVariant highlight() const TemplateVariant highlight() const
{ {
...@@ -673,6 +1406,10 @@ class FileContext::Private : public DefinitionContext<FileContext::Private> ...@@ -673,6 +1406,10 @@ class FileContext::Private : public DefinitionContext<FileContext::Private>
{ {
return TemplateVariant(""); return TemplateVariant("");
} }
TemplateVariant versionInfo() const
{
return m_fileDef->getVersion();
}
private: private:
FileDef *m_fileDef; FileDef *m_fileDef;
}; };
...@@ -700,12 +1437,12 @@ TemplateVariant FileContext::get(const char *n) const ...@@ -700,12 +1437,12 @@ TemplateVariant FileContext::get(const char *n) const
class DirContext::Private : public DefinitionContext<DirContext::Private> class DirContext::Private : public DefinitionContext<DirContext::Private>
{ {
public: public:
Private(DirDef *dd) : DefinitionContext(this,dd) , m_dirDef(dd) Private(DirDef *dd) : DefinitionContext(dd) , m_dirDef(dd)
{ {
insert("title", new PropertyFunc(this,&Private::title)); addProperty("title",this,&Private::title);
insert("highlight", new PropertyFunc(this,&Private::highlight)); addProperty("highlight",this,&Private::highlight);
insert("subhighlight", new PropertyFunc(this,&Private::subHighlight)); addProperty("subhighlight",this,&Private::subHighlight);
insert("dirName", new PropertyFunc(this,&Private::dirName)); addProperty("dirName",this,&Private::dirName);
} }
TemplateVariant title() const TemplateVariant title() const
{ {
...@@ -751,11 +1488,11 @@ TemplateVariant DirContext::get(const char *n) const ...@@ -751,11 +1488,11 @@ TemplateVariant DirContext::get(const char *n) const
class PageContext::Private : public DefinitionContext<PageContext::Private> class PageContext::Private : public DefinitionContext<PageContext::Private>
{ {
public: public:
Private(PageDef *pd) : DefinitionContext(this,pd) , m_pageDef(pd) Private(PageDef *pd) : DefinitionContext(pd) , m_pageDef(pd)
{ {
insert("title", new PropertyFunc(this,&Private::title)); addProperty("title",this,&Private::title);
insert("highlight", new PropertyFunc(this,&Private::highlight)); addProperty("highlight",this,&Private::highlight);
insert("subhighlight", new PropertyFunc(this,&Private::subHighlight)); addProperty("subhighlight",this,&Private::subHighlight);
} }
TemplateVariant title() const TemplateVariant title() const
{ {
...@@ -789,6 +1526,256 @@ TemplateVariant PageContext::get(const char *n) const ...@@ -789,6 +1526,256 @@ TemplateVariant PageContext::get(const char *n) const
return p->get(n); return p->get(n);
} }
//------------------------------------------------------------------------
class TextGeneratorHtml : public TextGeneratorIntf
{
public:
TextGeneratorHtml(FTextStream &ts,const QCString &relPath)
: m_ts(ts), m_relPath(relPath) {}
void writeString(const char *s,bool keepSpaces) const
{
if (s==0) return;
//printf("TextGeneratorOlImpl::writeString('%s',%d)\n",s,keepSpaces);
if (keepSpaces)
{
const char *p=s;
char c;
while ((c=*p++))
{
switch(c)
{
case '<': m_ts << "&lt;"; break;
case '>': m_ts << "&gt;"; break;
case '\'': m_ts << "&#39;"; break;
case '"': m_ts << "&quot;"; break;
case '&': m_ts << "&amp;"; break;
case ' ': m_ts << "&#160;"; break;
}
}
}
else
{
m_ts << convertToHtml(s);
}
}
void writeBreak(int indent) const
{
m_ts << "<br/>";
for (int i=0;i<indent;i++)
{
m_ts << "&#160;";
}
}
void writeLink(const char *ref,const char *f,
const char *anchor,const char *name
) const
{
if (ref)
{
m_ts << "<a class=\"elRef\" ";
m_ts << externalLinkTarget() << externalRef(m_relPath,ref,FALSE);
}
else
{
m_ts << "<a class=\"el\" ";
}
m_ts << "href=\"";
m_ts << externalRef(m_relPath,ref,TRUE);
if (f) m_ts << f << Doxygen::htmlFileExtension;
if (anchor) m_ts << "#" << anchor;
m_ts << "\">";
m_ts << convertToHtml(name);
m_ts << "</a>";
}
private:
FTextStream &m_ts;
QCString m_relPath;
};
class TextGeneratorFactory
{
public:
static TextGeneratorFactory *instance()
{
static TextGeneratorFactory *instance = 0;
if (instance==0) instance = new TextGeneratorFactory;
return instance;
}
TextGeneratorIntf *create(FTextStream &ts,const QCString &relPath)
{
switch (g_globals.outputFormat)
{
case ContextGlobals::Html:
return new TextGeneratorHtml(ts,relPath);
break;
default:
break;
}
return 0;
}
private:
TextGeneratorFactory() {}
virtual ~TextGeneratorFactory() {}
};
TemplateVariant createLinkedText(Definition *def,const QCString &relPath,const QCString &text)
{
QGString s;
FTextStream ts(&s);
TextGeneratorIntf *tg = TextGeneratorFactory::instance()->create(ts,relPath);
if (tg)
{
linkifyText(*tg,def->getOuterScope(),def->getBodyDef(),def,text);
return TemplateVariant(s.data(),TRUE);
}
else
{
return text;
}
}
//%% struct Member(Symbol): member information
//%% {
class MemberContext::Private : public DefinitionContext<MemberContext::Private>
{
public:
Private(MemberDef *md) : DefinitionContext(md) , m_memberDef(md)
{
addProperty("declType", this,&Private::declType);
addProperty("declArgs", this,&Private::declArgs);
addProperty("isStatic", this,&Private::isStatic);
addProperty("isObjCMethod", this,&Private::isObjCMethod);
addProperty("isObjCProperty", this,&Private::isObjCProperty);
addProperty("isImplementation", this,&Private::isImplementation);
addProperty("isEvent", this,&Private::isEvent);
addProperty("isProperty", this,&Private::isProperty);
addProperty("hasDetails", this,&Private::hasDetails);
addProperty("exception", this,&Private::exception);
addProperty("bitfields", this,&Private::bitfields);
addProperty("initializer", this,&Private::initializer);
addProperty("oneLineInitializer",this,&Private::oneLineInitializer);
addProperty("templateArgs", this,&Private::templateArgs);
addProperty("templateAlias", this,&Private::templateAlias);
addProperty("propertyAttrs", this,&Private::propertyAttrs);
addProperty("eventAttrs", this,&Private::eventAttrs);
if (md && md->isProperty())
{
if (md->isGettable()) m_propertyAttrs.append("get");
if (md->isSettable()) m_propertyAttrs.append("set");
}
if (md && md->isEvent())
{
if (md->isAddable()) m_eventAttrs.append("add");
if (md->isRemovable()) m_eventAttrs.append("remove");
if (md->isRaisable()) m_eventAttrs.append("raise");
}
}
TemplateVariant declType() const
{
return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->getDeclType());
}
TemplateVariant declArgs() const
{
return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->argsString());
}
TemplateVariant exception() const
{
return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->excpString());
}
TemplateVariant bitfields() const
{
return createLinkedText(m_memberDef,relPathAsString(),m_memberDef->bitfieldString());
}
TemplateVariant isStatic() const
{
return m_memberDef->isStatic();
}
TemplateVariant isObjCMethod() const
{
return m_memberDef->isObjCMethod();
}
TemplateVariant isObjCProperty() const
{
return m_memberDef->isObjCProperty();
}
TemplateVariant isImplementation() const
{
return m_memberDef->isImplementation();
}
TemplateVariant isEvent() const
{
return m_memberDef->isEvent();
}
TemplateVariant isProperty() const
{
return m_memberDef->isProperty();
}
TemplateVariant hasDetails() const
{
return m_memberDef->isDetailedSectionLinkable();
}
TemplateVariant initializer() const
{
return m_memberDef->initializer();
}
TemplateVariant oneLineInitializer() const
{
return m_memberDef->hasOneLineInitializer();
}
TemplateVariant templateArgs() const
{
if (!m_templateArgs)
{
m_templateArgs.reset(new ArgumentListContext(m_memberDef->templateArguments()));
}
return m_templateArgs.get();
}
TemplateVariant templateAlias() const
{
if (m_memberDef->isAlias())
{
return createLinkedText(m_memberDef,relPathAsString(),
QCString(" = ")+m_memberDef->typeString());
}
return "";
}
TemplateVariant propertyAttrs() const
{
return &m_propertyAttrs;
}
TemplateVariant eventAttrs() const
{
return &m_eventAttrs;
}
private:
MemberDef *m_memberDef;
mutable ScopedPtr<ArgumentListContext> m_templateArgs;
TemplateList m_propertyAttrs;
TemplateList m_eventAttrs;
};
//%% }
MemberContext::MemberContext(MemberDef *md)
{
p = new Private(md);
}
MemberContext::~MemberContext()
{
delete p;
}
TemplateVariant MemberContext::get(const char *n) const
{
return p->get(n);
}
//------------------------------------------------------------------------ //------------------------------------------------------------------------
//%% struct Module(Symbol): group information //%% struct Module(Symbol): group information
...@@ -796,11 +1783,11 @@ TemplateVariant PageContext::get(const char *n) const ...@@ -796,11 +1783,11 @@ TemplateVariant PageContext::get(const char *n) const
class ModuleContext::Private : public DefinitionContext<ModuleContext::Private> class ModuleContext::Private : public DefinitionContext<ModuleContext::Private>
{ {
public: public:
Private(GroupDef *gd) : DefinitionContext(this,gd) , m_groupDef(gd) Private(GroupDef *gd) : DefinitionContext(gd) , m_groupDef(gd)
{ {
insert("title", new PropertyFunc(this,&Private::title)); addProperty("title",this,&Private::title);
insert("highlight", new PropertyFunc(this,&Private::highlight)); addProperty("highlight",this,&Private::highlight);
insert("subhighlight", new PropertyFunc(this,&Private::subHighlight)); addProperty("subhighlight",this,&Private::subHighlight);
} }
TemplateVariant title() const TemplateVariant title() const
{ {
...@@ -836,6 +1823,47 @@ TemplateVariant ModuleContext::get(const char *n) const ...@@ -836,6 +1823,47 @@ TemplateVariant ModuleContext::get(const char *n) const
//------------------------------------------------------------------------ //------------------------------------------------------------------------
//%% list NestedClassList[Class] : list of nested classes
class NestedClassListContext::Private : public GenericNodeListContext<ClassContext>
{
};
NestedClassListContext::NestedClassListContext()
{
p = new Private;
}
NestedClassListContext::~NestedClassListContext()
{
delete p;
}
// TemplateListIntf
int NestedClassListContext::count() const
{
return p->count();
}
TemplateVariant NestedClassListContext::at(int index) const
{
return p->at(index);
}
TemplateListIntf::ConstIterator *NestedClassListContext::createIterator() const
{
return p->createIterator();
}
void NestedClassListContext::append(ClassDef *cd)
{
if (cd)
{
p->append(new ClassContext(cd));
}
}
//------------------------------------------------------------------------
//%% list ClassList[Class] : list of classes //%% list ClassList[Class] : list of classes
class ClassListContext::Private : public GenericNodeListContext<ClassContext> class ClassListContext::Private : public GenericNodeListContext<ClassContext>
{ {
...@@ -893,17 +1921,17 @@ TemplateListIntf::ConstIterator *ClassListContext::createIterator() const ...@@ -893,17 +1921,17 @@ TemplateListIntf::ConstIterator *ClassListContext::createIterator() const
//%% struct ClassInheritanceNode: node in inheritance tree //%% struct ClassInheritanceNode: node in inheritance tree
//%% { //%% {
class ClassInheritanceNodeContext::Private : public PropertyMapper<ClassInheritanceNodeContext::Private> class ClassInheritanceNodeContext::Private : public PropertyMapper
{ {
public: public:
Private(ClassDef *cd) : m_classContext(cd) Private(ClassDef *cd) : m_classContext(cd)
{ {
//%% bool is_leaf_node: true if this node does not have any children //%% bool is_leaf_node: true if this node does not have any children
insert("is_leaf_node", new PropertyFunc(this,&Private::isLeafNode)); addProperty("is_leaf_node",this,&Private::isLeafNode);
//%% ClassInheritance children: list of nested classes/namespaces //%% ClassInheritance children: list of nested classes/namespaces
insert("children", new PropertyFunc(this,&Private::children)); addProperty("children",this,&Private::children);
//%% Class class: class info //%% Class class: class info
insert("class", new PropertyFunc(this,&Private::getClass)); addProperty("class",this,&Private::getClass);
} }
void addChildren(const BaseClassList *bcl,bool hideSuper) void addChildren(const BaseClassList *bcl,bool hideSuper)
{ {
...@@ -1077,7 +2105,7 @@ TemplateListIntf::ConstIterator *ClassInheritanceContext::createIterator() const ...@@ -1077,7 +2105,7 @@ TemplateListIntf::ConstIterator *ClassInheritanceContext::createIterator() const
//%% struct ClassHierarchy: inheritance tree //%% struct ClassHierarchy: inheritance tree
//%% { //%% {
class ClassHierarchyContext::Private : public PropertyMapper<ClassHierarchyContext::Private> class ClassHierarchyContext::Private : public PropertyMapper
{ {
public: public:
TemplateVariant tree() const TemplateVariant tree() const
...@@ -1115,12 +2143,12 @@ class ClassHierarchyContext::Private : public PropertyMapper<ClassHierarchyConte ...@@ -1115,12 +2143,12 @@ class ClassHierarchyContext::Private : public PropertyMapper<ClassHierarchyConte
Private() Private()
{ {
//%% ClassInheritance tree //%% ClassInheritance tree
insert("tree",new PropertyFunc(this,&Private::tree)); addProperty("tree",this,&Private::tree);
insert("fileName",new PropertyFunc(this,&Private::fileName)); addProperty("fileName",this,&Private::fileName);
insert("relPath",new PropertyFunc(this,&Private::relPath)); addProperty("relPath",this,&Private::relPath);
insert("highlight",new PropertyFunc(this,&Private::highlight)); addProperty("highlight",this,&Private::highlight);
insert("subhighlight",new PropertyFunc(this,&Private::subhighlight)); addProperty("subhighlight",this,&Private::subhighlight);
insert("title",new PropertyFunc(this,&Private::title)); addProperty("title",this,&Private::title);
} }
private: private:
ClassInheritanceContext m_classTree; ClassInheritanceContext m_classTree;
...@@ -1146,7 +2174,7 @@ TemplateVariant ClassHierarchyContext::get(const char *name) const ...@@ -1146,7 +2174,7 @@ TemplateVariant ClassHierarchyContext::get(const char *name) const
//%% struct NestingNode: node is a nesting relation tree //%% struct NestingNode: node is a nesting relation tree
//%% { //%% {
class NestingNodeContext::Private : public PropertyMapper<NestingNodeContext::Private> class NestingNodeContext::Private : public PropertyMapper
{ {
public: public:
Private(Definition *d,bool addCls) : m_def(d), Private(Definition *d,bool addCls) : m_def(d),
...@@ -1154,13 +2182,13 @@ class NestingNodeContext::Private : public PropertyMapper<NestingNodeContext::Pr ...@@ -1154,13 +2182,13 @@ class NestingNodeContext::Private : public PropertyMapper<NestingNodeContext::Pr
m_namespaceContext(m_def->definitionType()==Definition::TypeNamespace?(NamespaceDef*)d:0) m_namespaceContext(m_def->definitionType()==Definition::TypeNamespace?(NamespaceDef*)d:0)
{ {
//%% bool is_leaf_node: true if this node does not have any children //%% bool is_leaf_node: true if this node does not have any children
insert("is_leaf_node", new PropertyFunc(this,&Private::isLeafNode)); addProperty("is_leaf_node",this,&Private::isLeafNode);
//%% Nesting children: list of nested classes/namespaces //%% Nesting children: list of nested classes/namespaces
insert("children", new PropertyFunc(this,&Private::children)); addProperty("children",this,&Private::children);
//%% [optional] Class class: class info (if this node represents a class) //%% [optional] Class class: class info (if this node represents a class)
insert("class", new PropertyFunc(this,&Private::getClass)); addProperty("class",this,&Private::getClass);
//%% [optional] Namespace namespace: namespace info (if this node represents a namespace) //%% [optional] Namespace namespace: namespace info (if this node represents a namespace)
insert("namespace", new PropertyFunc(this,&Private::getNamespace)); addProperty("namespace",this,&Private::getNamespace);
addNamespaces(addCls); addNamespaces(addCls);
addClasses(); addClasses();
} }
...@@ -1332,7 +2360,7 @@ void NestingContext::addNamespaces(const NamespaceSDict &nsDict,bool rootOnly,bo ...@@ -1332,7 +2360,7 @@ void NestingContext::addNamespaces(const NamespaceSDict &nsDict,bool rootOnly,bo
//%% struct ClassTree: Class nesting relations //%% struct ClassTree: Class nesting relations
//%% { //%% {
class ClassTreeContext::Private : public PropertyMapper<ClassTreeContext::Private> class ClassTreeContext::Private : public PropertyMapper
{ {
public: public:
TemplateVariant tree() const TemplateVariant tree() const
...@@ -1383,12 +2411,12 @@ class ClassTreeContext::Private : public PropertyMapper<ClassTreeContext::Privat ...@@ -1383,12 +2411,12 @@ class ClassTreeContext::Private : public PropertyMapper<ClassTreeContext::Privat
m_classTree.addClasses(*Doxygen::classSDict,TRUE); m_classTree.addClasses(*Doxygen::classSDict,TRUE);
} }
//%% Nesting tree //%% Nesting tree
insert("tree", new PropertyFunc(this,&Private::tree)); addProperty("tree",this,&Private::tree);
insert("fileName", new PropertyFunc(this,&Private::fileName)); addProperty("fileName",this,&Private::fileName);
insert("relPath", new PropertyFunc(this,&Private::relPath)); addProperty("relPath",this,&Private::relPath);
insert("highlight", new PropertyFunc(this,&Private::highlight)); addProperty("highlight",this,&Private::highlight);
insert("subhighlight",new PropertyFunc(this,&Private::subhighlight)); addProperty("subhighlight",this,&Private::subhighlight);
insert("title", new PropertyFunc(this,&Private::title)); addProperty("title",this,&Private::title);
} }
private: private:
NestingContext m_classTree; NestingContext m_classTree;
...@@ -1461,7 +2489,7 @@ TemplateListIntf::ConstIterator *NamespaceListContext::createIterator() const ...@@ -1461,7 +2489,7 @@ TemplateListIntf::ConstIterator *NamespaceListContext::createIterator() const
//%% struct NamespaceTree: tree of nested namespace //%% struct NamespaceTree: tree of nested namespace
//%% { //%% {
class NamespaceTreeContext::Private : public PropertyMapper<NamespaceTreeContext::Private> class NamespaceTreeContext::Private : public PropertyMapper
{ {
public: public:
TemplateVariant tree() const TemplateVariant tree() const
...@@ -1509,12 +2537,12 @@ class NamespaceTreeContext::Private : public PropertyMapper<NamespaceTreeContext ...@@ -1509,12 +2537,12 @@ class NamespaceTreeContext::Private : public PropertyMapper<NamespaceTreeContext
m_namespaceTree.addNamespaces(*Doxygen::namespaceSDict,TRUE,FALSE); m_namespaceTree.addNamespaces(*Doxygen::namespaceSDict,TRUE,FALSE);
} }
//%% Nesting tree //%% Nesting tree
insert("tree", new PropertyFunc(this,&Private::tree)); addProperty("tree",this,&Private::tree);
insert("fileName", new PropertyFunc(this,&Private::fileName)); addProperty("fileName",this,&Private::fileName);
insert("relPath", new PropertyFunc(this,&Private::relPath)); addProperty("relPath",this,&Private::relPath);
insert("highlight", new PropertyFunc(this,&Private::highlight)); addProperty("highlight",this,&Private::highlight);
insert("subhighlight",new PropertyFunc(this,&Private::subhighlight)); addProperty("subhighlight",this,&Private::subhighlight);
insert("title", new PropertyFunc(this,&Private::title)); addProperty("title",this,&Private::title);
} }
private: private:
NestingContext m_namespaceTree; NestingContext m_namespaceTree;
...@@ -1560,43 +2588,96 @@ class FileListContext::Private : public GenericNodeListContext<FileContext> ...@@ -1560,43 +2588,96 @@ class FileListContext::Private : public GenericNodeListContext<FileContext>
{ {
append(new FileContext(fd)); append(new FileContext(fd));
} }
} }
} }
} }
};
FileListContext::FileListContext()
{
p = new Private;
if (Doxygen::inputNameList) p->addFiles(*Doxygen::inputNameList);
}
FileListContext::~FileListContext()
{
delete p;
}
// TemplateListIntf
int FileListContext::count() const
{
return p->count();
}
TemplateVariant FileListContext::at(int index) const
{
return p->at(index);
}
TemplateListIntf::ConstIterator *FileListContext::createIterator() const
{
return p->createIterator();
}
//------------------------------------------------------------------------
//%% list UsedFiles[File] : list of files
class UsedFilesContext::Private : public GenericNodeListContext<FileContext>
{
public:
void addFile(FileDef *fd)
{
append(new FileContext(fd));
}
}; };
FileListContext::FileListContext() UsedFilesContext::UsedFilesContext(ClassDef *cd)
{ {
p = new Private; p = new Private;
if (Doxygen::inputNameList) p->addFiles(*Doxygen::inputNameList); if (cd)
{
QListIterator<FileDef> li(cd->usedFiles());
FileDef *fd;
for (li.toFirst();(fd=li.current());++li)
{
p->addFile(fd);
}
}
} }
FileListContext::~FileListContext() UsedFilesContext::~UsedFilesContext()
{ {
delete p; delete p;
} }
// TemplateListIntf // TemplateListIntf
int FileListContext::count() const int UsedFilesContext::count() const
{ {
return p->count(); return p->count();
} }
TemplateVariant FileListContext::at(int index) const TemplateVariant UsedFilesContext::at(int index) const
{ {
return p->at(index); return p->at(index);
} }
TemplateListIntf::ConstIterator *FileListContext::createIterator() const TemplateListIntf::ConstIterator *UsedFilesContext::createIterator() const
{ {
return p->createIterator(); return p->createIterator();
} }
void UsedFilesContext::addFile(FileDef *fd)
{
p->addFile(fd);
}
//------------------------------------------------------------------------ //------------------------------------------------------------------------
//%% struct DirFileNode: node is a directory hierarchy //%% struct DirFileNode: node is a directory hierarchy
//%% { //%% {
class DirFileNodeContext::Private : public PropertyMapper<DirFileNodeContext::Private> class DirFileNodeContext::Private : public PropertyMapper
{ {
public: public:
Private(Definition *d) : m_def(d), Private(Definition *d) : m_def(d),
...@@ -1604,13 +2685,13 @@ class DirFileNodeContext::Private : public PropertyMapper<DirFileNodeContext::Pr ...@@ -1604,13 +2685,13 @@ class DirFileNodeContext::Private : public PropertyMapper<DirFileNodeContext::Pr
m_fileContext(m_def->definitionType()==Definition::TypeFile ? (FileDef*)d : 0) m_fileContext(m_def->definitionType()==Definition::TypeFile ? (FileDef*)d : 0)
{ {
//%% bool is_leaf_node: true if this node does not have any children //%% bool is_leaf_node: true if this node does not have any children
insert("is_leaf_node", new PropertyFunc(this,&Private::isLeafNode)); addProperty("is_leaf_node",this,&Private::isLeafNode);
//%% DirFile children: list of nested classes/namespaces //%% DirFile children: list of nested classes/namespaces
insert("children", new PropertyFunc(this,&Private::children)); addProperty("children",this,&Private::children);
//%% [optional] Dir dir: directory info (if this node represents a directory) //%% [optional] Dir dir: directory info (if this node represents a directory)
insert("dir", new PropertyFunc(this,&Private::getDir)); addProperty("dir",this,&Private::getDir);
//%% [optional] File file: file info (if this node represents a file) //%% [optional] File file: file info (if this node represents a file)
insert("file", new PropertyFunc(this,&Private::getFile)); addProperty("file",this,&Private::getFile);
addDirFiles(); addDirFiles();
} }
TemplateVariant isLeafNode() const TemplateVariant isLeafNode() const
...@@ -1785,7 +2866,7 @@ void DirFileContext::addFiles(const FileList &files) ...@@ -1785,7 +2866,7 @@ void DirFileContext::addFiles(const FileList &files)
//%% struct FileTree: tree of directories and files //%% struct FileTree: tree of directories and files
//%% { //%% {
class FileTreeContext::Private : public PropertyMapper<FileTreeContext::Private> class FileTreeContext::Private : public PropertyMapper
{ {
public: public:
TemplateVariant tree() const TemplateVariant tree() const
...@@ -1824,12 +2905,12 @@ class FileTreeContext::Private : public PropertyMapper<FileTreeContext::Private> ...@@ -1824,12 +2905,12 @@ class FileTreeContext::Private : public PropertyMapper<FileTreeContext::Private>
m_dirFileTree.addFiles(*Doxygen::inputNameList); m_dirFileTree.addFiles(*Doxygen::inputNameList);
} }
//%% DirFile tree: //%% DirFile tree:
insert("tree", new PropertyFunc(this,&Private::tree)); addProperty("tree",this,&Private::tree);
insert("fileName", new PropertyFunc(this,&Private::fileName)); addProperty("fileName",this,&Private::fileName);
insert("relPath", new PropertyFunc(this,&Private::relPath)); addProperty("relPath",this,&Private::relPath);
insert("highlight", new PropertyFunc(this,&Private::highlight)); addProperty("highlight",this,&Private::highlight);
insert("subhighlight",new PropertyFunc(this,&Private::subhighlight)); addProperty("subhighlight",this,&Private::subhighlight);
insert("title", new PropertyFunc(this,&Private::title)); addProperty("title",this,&Private::title);
} }
private: private:
DirFileContext m_dirFileTree; DirFileContext m_dirFileTree;
...@@ -1855,17 +2936,17 @@ TemplateVariant FileTreeContext::get(const char *name) const ...@@ -1855,17 +2936,17 @@ TemplateVariant FileTreeContext::get(const char *name) const
//%% struct PageNode: node is a directory hierarchy //%% struct PageNode: node is a directory hierarchy
//%% { //%% {
class PageNodeContext::Private : public PropertyMapper<PageNodeContext::Private> class PageNodeContext::Private : public PropertyMapper
{ {
public: public:
Private(PageDef *pd) : m_pageDef(pd), m_pageContext(pd) Private(PageDef *pd) : m_pageDef(pd), m_pageContext(pd)
{ {
//%% bool is_leaf_node: true if this node does not have any children //%% bool is_leaf_node: true if this node does not have any children
insert("is_leaf_node", new PropertyFunc(this,&Private::isLeafNode)); addProperty("is_leaf_node",this,&Private::isLeafNode);
//%% PageList children: list of nested classes/namespaces //%% PageList children: list of nested classes/namespaces
insert("children", new PropertyFunc(this,&Private::children)); addProperty("children",this,&Private::children);
//%% Page page: page info //%% Page page: page info
insert("page", new PropertyFunc(this,&Private::getPage)); addProperty("page",this,&Private::getPage);
addPages(); addPages();
} }
TemplateVariant isLeafNode() const TemplateVariant isLeafNode() const
...@@ -1966,7 +3047,7 @@ void PageNodeListContext::addPages(const PageSDict &pages,bool rootOnly) ...@@ -1966,7 +3047,7 @@ void PageNodeListContext::addPages(const PageSDict &pages,bool rootOnly)
//%% struct PageTree: tree of related pages //%% struct PageTree: tree of related pages
//%% { //%% {
class PageTreeContext::Private : public PropertyMapper<PageTreeContext::Private> class PageTreeContext::Private : public PropertyMapper
{ {
public: public:
TemplateVariant tree() const TemplateVariant tree() const
...@@ -2002,12 +3083,12 @@ class PageTreeContext::Private : public PropertyMapper<PageTreeContext::Private> ...@@ -2002,12 +3083,12 @@ class PageTreeContext::Private : public PropertyMapper<PageTreeContext::Private>
} }
//%% PageNodeList tree: //%% PageNodeList tree:
insert("tree", new PropertyFunc(this,&Private::tree)); addProperty("tree",this,&Private::tree);
insert("fileName", new PropertyFunc(this,&Private::fileName)); addProperty("fileName",this,&Private::fileName);
insert("relPath", new PropertyFunc(this,&Private::relPath)); addProperty("relPath",this,&Private::relPath);
insert("highlight", new PropertyFunc(this,&Private::highlight)); addProperty("highlight",this,&Private::highlight);
insert("subhighlight",new PropertyFunc(this,&Private::subhighlight)); addProperty("subhighlight",this,&Private::subhighlight);
insert("title", new PropertyFunc(this,&Private::title)); addProperty("title",this,&Private::title);
} }
private: private:
PageNodeListContext m_pageList; PageNodeListContext m_pageList;
...@@ -2033,7 +3114,7 @@ TemplateVariant PageTreeContext::get(const char *name) const ...@@ -2033,7 +3114,7 @@ TemplateVariant PageTreeContext::get(const char *name) const
//%% struct PageList: list of related pages //%% struct PageList: list of related pages
//%% { //%% {
class PageListContext::Private : public PropertyMapper<PageListContext::Private> class PageListContext::Private : public PropertyMapper
{ {
public: public:
TemplateVariant items() const TemplateVariant items() const
...@@ -2074,12 +3155,12 @@ class PageListContext::Private : public PropertyMapper<PageListContext::Private> ...@@ -2074,12 +3155,12 @@ class PageListContext::Private : public PropertyMapper<PageListContext::Private>
} }
//%% list[Page] items: //%% list[Page] items:
insert("items", new PropertyFunc(this,&Private::items)); addProperty("items",this,&Private::items);
insert("fileName", new PropertyFunc(this,&Private::fileName)); addProperty("fileName",this,&Private::fileName);
insert("relPath", new PropertyFunc(this,&Private::relPath)); addProperty("relPath",this,&Private::relPath);
insert("highlight", new PropertyFunc(this,&Private::highlight)); addProperty("highlight",this,&Private::highlight);
insert("subhighlight",new PropertyFunc(this,&Private::subhighlight)); addProperty("subhighlight",this,&Private::subhighlight);
insert("title", new PropertyFunc(this,&Private::title)); addProperty("title",this,&Private::title);
} }
private: private:
GenericNodeListContext<PageContext> m_pageList; GenericNodeListContext<PageContext> m_pageList;
...@@ -2106,17 +3187,17 @@ TemplateVariant PageListContext::get(const char *name) const ...@@ -2106,17 +3187,17 @@ TemplateVariant PageListContext::get(const char *name) const
//%% struct ModuleNode: node is a directory hierarchy //%% struct ModuleNode: node is a directory hierarchy
//%% { //%% {
class ModuleNodeContext::Private : public PropertyMapper<ModuleNodeContext::Private> class ModuleNodeContext::Private : public PropertyMapper
{ {
public: public:
Private(GroupDef *gd) : m_groupDef(gd), m_moduleContext(gd) Private(GroupDef *gd) : m_groupDef(gd), m_moduleContext(gd)
{ {
//%% bool is_leaf_node: true if this node does not have any children //%% bool is_leaf_node: true if this node does not have any children
insert("is_leaf_node", new PropertyFunc(this,&Private::isLeafNode)); addProperty("is_leaf_node",this,&Private::isLeafNode);
//%% ModuleList children: list of submodules //%% ModuleList children: list of submodules
insert("children", new PropertyFunc(this,&Private::children)); addProperty("children",this,&Private::children);
//%% Module module: module info //%% Module module: module info
insert("module", new PropertyFunc(this,&Private::getModule)); addProperty("module",this,&Private::getModule);
addModules(); addModules();
} }
TemplateVariant isLeafNode() const TemplateVariant isLeafNode() const
...@@ -2231,7 +3312,7 @@ void ModuleListContext::addModules(const GroupList &modules) ...@@ -2231,7 +3312,7 @@ void ModuleListContext::addModules(const GroupList &modules)
//%% struct ModuleTree: tree of modules //%% struct ModuleTree: tree of modules
//%% { //%% {
class ModuleTreeContext::Private : public PropertyMapper<ModuleTreeContext::Private> class ModuleTreeContext::Private : public PropertyMapper
{ {
public: public:
TemplateVariant tree() const TemplateVariant tree() const
...@@ -2267,12 +3348,12 @@ class ModuleTreeContext::Private : public PropertyMapper<ModuleTreeContext::Priv ...@@ -2267,12 +3348,12 @@ class ModuleTreeContext::Private : public PropertyMapper<ModuleTreeContext::Priv
} }
//%% ModuleList tree: //%% ModuleList tree:
insert("tree", new PropertyFunc(this,&Private::tree)); addProperty("tree",this,&Private::tree);
insert("fileName", new PropertyFunc(this,&Private::fileName)); addProperty("fileName",this,&Private::fileName);
insert("relPath", new PropertyFunc(this,&Private::relPath)); addProperty("relPath",this,&Private::relPath);
insert("highlight", new PropertyFunc(this,&Private::highlight)); addProperty("highlight",this,&Private::highlight);
insert("subhighlight",new PropertyFunc(this,&Private::subhighlight)); addProperty("subhighlight",this,&Private::subhighlight);
insert("title", new PropertyFunc(this,&Private::title)); addProperty("title",this,&Private::title);
} }
private: private:
ModuleListContext m_moduleList; ModuleListContext m_moduleList;
...@@ -2298,7 +3379,7 @@ TemplateVariant ModuleTreeContext::get(const char *name) const ...@@ -2298,7 +3379,7 @@ TemplateVariant ModuleTreeContext::get(const char *name) const
//%% struct ExampleList: list of examples page //%% struct ExampleList: list of examples page
//%% { //%% {
class ExampleListContext::Private : public PropertyMapper<ExampleListContext::Private> class ExampleListContext::Private : public PropertyMapper
{ {
public: public:
TemplateVariant items() const TemplateVariant items() const
...@@ -2334,12 +3415,12 @@ class ExampleListContext::Private : public PropertyMapper<ExampleListContext::Pr ...@@ -2334,12 +3415,12 @@ class ExampleListContext::Private : public PropertyMapper<ExampleListContext::Pr
} }
//%% PageNodeList items: //%% PageNodeList items:
insert("items", new PropertyFunc(this,&Private::items)); addProperty("items",this,&Private::items);
insert("fileName", new PropertyFunc(this,&Private::fileName)); addProperty("fileName",this,&Private::fileName);
insert("relPath", new PropertyFunc(this,&Private::relPath)); addProperty("relPath",this,&Private::relPath);
insert("highlight", new PropertyFunc(this,&Private::highlight)); addProperty("highlight",this,&Private::highlight);
insert("subhighlight",new PropertyFunc(this,&Private::subhighlight)); addProperty("subhighlight",this,&Private::subhighlight);
insert("title", new PropertyFunc(this,&Private::title)); addProperty("title",this,&Private::title);
} }
private: private:
PageNodeListContext m_pageList; PageNodeListContext m_pageList;
...@@ -2361,6 +3442,307 @@ TemplateVariant ExampleListContext::get(const char *name) const ...@@ -2361,6 +3442,307 @@ TemplateVariant ExampleListContext::get(const char *name) const
return p->get(name); return p->get(name);
} }
//------------------------------------------------------------------------
//%% struct InheritanceNode: a class in the inheritance list
//%% {
class InheritanceNodeContext::Private : public PropertyMapper
{
public:
Private(ClassDef *cd,const QCString &name) : m_classContext(cd), m_name(name)
{
addProperty("class",this,&Private::getClass);
addProperty("name",this,&Private::name);
}
TemplateVariant getClass() const
{
return &m_classContext;
}
TemplateVariant name() const
{
return m_name;
}
private:
ClassContext m_classContext;
QCString m_name;
};
//%% }
InheritanceNodeContext::InheritanceNodeContext(ClassDef *cd,const QCString &name)
{
p = new Private(cd,name);
}
InheritanceNodeContext::~InheritanceNodeContext()
{
delete p;
}
TemplateVariant InheritanceNodeContext::get(const char *name) const
{
return p->get(name);
}
//------------------------------------------------------------------------
//%% list InheritanceList[InheritanceNode] : list of inherited classes
class InheritanceListContext::Private : public GenericNodeListContext<InheritanceNodeContext>
{
public:
void addClass(ClassDef *cd,const QCString &name)
{
append(new InheritanceNodeContext(cd,name));
}
};
InheritanceListContext::InheritanceListContext(const BaseClassList *list, bool baseClasses)
{
p = new Private;
if (list)
{
BaseClassListIterator li(*list);
BaseClassDef *bcd;
for (li.toFirst();(bcd=li.current());++li)
{
ClassDef *cd=bcd->classDef;
QCString name;
if (baseClasses)
{
name = insertTemplateSpecifierInScope(
cd->displayName(),bcd->templSpecifiers);
}
else
{
name = cd->displayName();
}
//printf("InheritanceListContext: adding %s baseClass=%d\n",name.data(),baseClasses);
p->addClass(cd,name);
}
}
}
InheritanceListContext::~InheritanceListContext()
{
delete p;
}
// TemplateListIntf
int InheritanceListContext::count() const
{
return p->count();
}
TemplateVariant InheritanceListContext::at(int index) const
{
return p->at(index);
}
TemplateListIntf::ConstIterator *InheritanceListContext::createIterator() const
{
return p->createIterator();
}
//------------------------------------------------------------------------
//%% list MemberList[Member] : list of inherited classes
class MemberListContext::Private : public GenericNodeListContext<MemberContext>
{
public:
void addMember(MemberDef *md)
{
append(new MemberContext(md));
}
};
MemberListContext::MemberListContext(const MemberList *list)
{
p = new Private;
if (list)
{
MemberListIterator mli(*list);
MemberDef *md;
for (mli.toFirst();(md=mli.current());++mli)
{
if (md->isBriefSectionVisible())
{
p->addMember(md);
}
}
}
}
MemberListContext::~MemberListContext()
{
delete p;
}
// TemplateListIntf
int MemberListContext::count() const
{
return p->count();
}
TemplateVariant MemberListContext::at(int index) const
{
return p->at(index);
}
TemplateListIntf::ConstIterator *MemberListContext::createIterator() const
{
return p->createIterator();
}
//------------------------------------------------------------------------
//%% struct MemberListInfo: member list information
//%% {
class MemberListInfoContext::Private : public PropertyMapper
{
public:
Private(const MemberList *ml,const QCString &title,const QCString &subtitle) :
m_memberListContext(ml), m_memberList(ml), m_title(title), m_subtitle(subtitle)
{
addProperty("members", this,&Private::members);
addProperty("title", this,&Private::title);
addProperty("subtitle",this,&Private::subtitle);
addProperty("anchor", this,&Private::anchor);
// TODO: member groups
}
TemplateVariant members() const
{
return &m_memberListContext;
}
TemplateVariant title() const
{
return m_title;
}
TemplateVariant subtitle() const
{
return m_subtitle;
}
TemplateVariant anchor() const
{
return m_memberList->listTypeAsString(m_memberList->listType());
}
private:
MemberListContext m_memberListContext;
const MemberList *m_memberList;
QCString m_title;
QCString m_subtitle;
};
//%% }
MemberListInfoContext::MemberListInfoContext(const MemberList *ml,
const QCString &title,const QCString &subtitle)
{
p = new Private(ml,title,subtitle);
}
MemberListInfoContext::~MemberListInfoContext()
{
delete p;
}
TemplateVariant MemberListInfoContext::get(const char *name) const
{
return p->get(name);
}
//------------------------------------------------------------------------
//%% struct Argument: member list information
//%% {
class ArgumentContext::Private : public PropertyMapper
{
public:
Private(const Argument *arg) :
m_argument(arg)
{
addProperty("type", this,&Private::type);
addProperty("name", this,&Private::name);
addProperty("defVal",this,&Private::defVal);
}
TemplateVariant type() const
{
return m_argument->type;
}
TemplateVariant name() const
{
return m_argument->name;
}
TemplateVariant defVal() const
{
return m_argument->defval;
}
private:
const Argument *m_argument;
};
//%% }
ArgumentContext::ArgumentContext(const Argument *al)
{
p = new Private(al);
}
ArgumentContext::~ArgumentContext()
{
delete p;
}
TemplateVariant ArgumentContext::get(const char *name) const
{
return p->get(name);
}
//------------------------------------------------------------------------
//%% list ArgumentList[Argument] : list of inherited classes
class ArgumentListContext::Private : public GenericNodeListContext<ArgumentContext>
{
public:
void addArgument(const Argument *arg)
{
append(new ArgumentContext(arg));
}
};
ArgumentListContext::ArgumentListContext(const ArgumentList *list)
{
p = new Private;
if (list)
{
ArgumentListIterator ali(*list);
const Argument *arg;
for (ali.toFirst();(arg=ali.current());++ali)
{
p->addArgument(arg);
}
}
}
ArgumentListContext::~ArgumentListContext()
{
delete p;
}
// TemplateListIntf
int ArgumentListContext::count() const
{
return p->count();
}
TemplateVariant ArgumentListContext::at(int index) const
{
return p->at(index);
}
TemplateListIntf::ConstIterator *ArgumentListContext::createIterator() const
{
return p->createIterator();
}
//------------------------------------------------------------------------ //------------------------------------------------------------------------
class HtmlEscaper : public TemplateEscapeIntf class HtmlEscaper : public TemplateEscapeIntf
...@@ -2374,12 +3756,78 @@ class HtmlEscaper : public TemplateEscapeIntf ...@@ -2374,12 +3756,78 @@ class HtmlEscaper : public TemplateEscapeIntf
//------------------------------------------------------------------------ //------------------------------------------------------------------------
class HtmlSpaceless : public TemplateSpacelessIntf
{
public:
HtmlSpaceless() : m_insideTag(FALSE), m_insideString('\0'), m_removeSpaces(TRUE) {}
QCString remove(const QCString &s)
{
QGString result;
const char *p = s.data();
char c;
while ((c=*p++))
{
switch(c)
{
case '<': // start of a tag
if (!m_insideString) m_insideTag=TRUE,m_removeSpaces=FALSE;
result+=c;
break;
case '>': // end of a tag
if (!m_insideString) m_insideTag=FALSE,m_removeSpaces=TRUE;
result+=c;
break;
case '\\': // escaped character in a string
result+=c;
if (m_insideString && *p) result+=*p++;
break;
case '"': case '\'':
if (m_insideTag)
{
if (m_insideString==c) // end of string
{
m_insideString='\0';
}
else // start of string
{
m_insideString=c;
}
}
result+=c;
break;
case ' ': case '\t': case '\n': // whitespace
if (!m_removeSpaces)
{
result+=' ';
}
if (!m_insideTag) // outside tags strip consecutive whitespace
{
m_removeSpaces=TRUE;
}
break;
default:
result+=c;
m_removeSpaces=FALSE;
break;
}
}
result+='\0';
//printf("HtmlSpaceless::remove('%s')='%s' m_insideTag=%d m_insideString=%d removeSpaces=%d\n",s.data(),result.data(),
// m_insideTag,m_insideString,m_removeSpaces);
return result.data();
}
private:
bool m_insideTag;
char m_insideString;
bool m_removeSpaces;
};
//------------------------------------------------------------------------
void generateOutputViaTemplate() void generateOutputViaTemplate()
{ {
TemplateEngine e; TemplateEngine e;
TemplateContext *ctx = e.createContext(); TemplateContext *ctx = e.createContext();
HtmlEscaper esc;
ctx->setEscapeIntf(&esc);
if (ctx) if (ctx)
{ {
DoxygenContext doxygen; DoxygenContext doxygen;
...@@ -2431,7 +3879,14 @@ void generateOutputViaTemplate() ...@@ -2431,7 +3879,14 @@ void generateOutputViaTemplate()
Template *tpl = e.loadByName("htmllayout.tpl"); Template *tpl = e.loadByName("htmllayout.tpl");
if (tpl) if (tpl)
{ {
ctx->setOutputDirectory(Config_getString("HTML_OUTPUT")); g_globals.outputFormat = ContextGlobals::Html;
g_globals.dynSectionId = 0;
g_globals.outputDir = Config_getString("HTML_OUTPUT");
HtmlEscaper esc;
ctx->setEscapeIntf(&esc);
HtmlSpaceless spl;
ctx->setSpacelessIntf(&spl);
ctx->setOutputDirectory(g_globals.outputDir);
FTextStream ts; FTextStream ts;
tpl->render(ts,ctx); tpl->render(ts,ctx);
} }
......
#ifndef CONTEXT_H #ifndef CONTEXT_H
#define CONTEXT_H #define CONTEXT_H
#include "types.h"
#include "template.h" #include "template.h"
class Definition; class Definition;
class ClassDef; class ClassDef;
class ClassSDict; class ClassSDict;
class BaseClassList;
class PageDef; class PageDef;
class GroupDef; class GroupDef;
class NamespaceDef; class NamespaceDef;
...@@ -21,6 +23,11 @@ class PageSDict; ...@@ -21,6 +23,11 @@ class PageSDict;
class GroupSDict; class GroupSDict;
class GroupDef; class GroupDef;
class GroupList; class GroupList;
struct IncludeInfo;
class MemberList;
class MemberDef;
struct Argument;
class ArgumentList;
//---------------------------------------------------- //----------------------------------------------------
...@@ -72,6 +79,42 @@ class TranslateContext : public TemplateStructIntf ...@@ -72,6 +79,42 @@ class TranslateContext : public TemplateStructIntf
//---------------------------------------------------- //----------------------------------------------------
class UsedFilesContext : public TemplateListIntf
{
public:
UsedFilesContext(ClassDef *cd);
~UsedFilesContext();
// TemplateListIntf
virtual int count() const;
virtual TemplateVariant at(int index) const;
virtual TemplateListIntf::ConstIterator *createIterator() const;
void addFile(FileDef *fd);
private:
class Private;
Private *p;
};
//----------------------------------------------------
class IncludeInfoContext : public TemplateStructIntf
{
public:
IncludeInfoContext(IncludeInfo *,SrcLangExt lang);
~IncludeInfoContext();
// TemplateStructIntf methods
virtual TemplateVariant get(const char *name) const;
private:
class Private;
Private *p;
};
//----------------------------------------------------
class ClassContext : public TemplateStructIntf class ClassContext : public TemplateStructIntf
{ {
public: public:
...@@ -150,6 +193,23 @@ class PageContext : public TemplateStructIntf ...@@ -150,6 +193,23 @@ class PageContext : public TemplateStructIntf
Private *p; Private *p;
}; };
//----------------------------------------------------
class MemberContext : public TemplateStructIntf
{
public:
MemberContext(MemberDef *);
~MemberContext();
// TemplateStructIntf methods
virtual TemplateVariant get(const char *name) const;
private:
class Private;
Private *p;
};
//---------------------------------------------------- //----------------------------------------------------
class ModuleContext : public TemplateStructIntf class ModuleContext : public TemplateStructIntf
...@@ -168,6 +228,26 @@ class ModuleContext : public TemplateStructIntf ...@@ -168,6 +228,26 @@ class ModuleContext : public TemplateStructIntf
//---------------------------------------------------- //----------------------------------------------------
class NestedClassListContext : public TemplateListIntf
{
public:
NestedClassListContext();
~NestedClassListContext();
// TemplateListIntf
virtual int count() const;
virtual TemplateVariant at(int index) const;
virtual TemplateListIntf::ConstIterator *createIterator() const;
void append(ClassDef *cd);
private:
class Private;
Private *p;
};
//----------------------------------------------------
class ClassListContext : public TemplateListIntf class ClassListContext : public TemplateListIntf
{ {
public: public:
...@@ -530,6 +610,109 @@ class ExampleListContext : public TemplateStructIntf ...@@ -530,6 +610,109 @@ class ExampleListContext : public TemplateStructIntf
//---------------------------------------------------- //----------------------------------------------------
class InheritanceNodeContext : public TemplateStructIntf
{
public:
InheritanceNodeContext(ClassDef *cd,const QCString &name);
~InheritanceNodeContext();
// TemplateStructIntf methods
virtual TemplateVariant get(const char *name) const;
private:
class Private;
Private *p;
};
//----------------------------------------------------
class InheritanceListContext : public TemplateListIntf
{
public:
InheritanceListContext(const BaseClassList *list,bool baseClasses);
~InheritanceListContext();
// TemplateListIntf
virtual int count() const;
virtual TemplateVariant at(int index) const;
virtual TemplateListIntf::ConstIterator *createIterator() const;
private:
class Private;
Private *p;
};
//----------------------------------------------------
class MemberListContext : public TemplateListIntf
{
public:
MemberListContext(const MemberList *ml);
~MemberListContext();
// TemplateListIntf
virtual int count() const;
virtual TemplateVariant at(int index) const;
virtual TemplateListIntf::ConstIterator *createIterator() const;
private:
class Private;
Private *p;
};
//----------------------------------------------------
class MemberListInfoContext : public TemplateStructIntf
{
public:
MemberListInfoContext(const MemberList *ml,const QCString &title,
const QCString &subtitle=QCString());
~MemberListInfoContext();
// TemplateStructIntf methods
virtual TemplateVariant get(const char *name) const;
private:
class Private;
Private *p;
};
//----------------------------------------------------
class ArgumentContext : public TemplateStructIntf
{
public:
ArgumentContext(const Argument *arg);
~ArgumentContext();
// TemplateStructIntf methods
virtual TemplateVariant get(const char *name) const;
private:
class Private;
Private *p;
};
//----------------------------------------------------
class ArgumentListContext : public TemplateListIntf
{
public:
ArgumentListContext(const ArgumentList *al);
~ArgumentListContext();
// TemplateListIntf
virtual int count() const;
virtual TemplateVariant at(int index) const;
virtual TemplateListIntf::ConstIterator *createIterator() const;
private:
class Private;
Private *p;
};
//----------------------------------------------------
void generateOutputViaTemplate(); void generateOutputViaTemplate();
#endif #endif
...@@ -1876,4 +1876,10 @@ void Definition::_setSymbolName(const QCString &name) ...@@ -1876,4 +1876,10 @@ void Definition::_setSymbolName(const QCString &name)
m_symbolName=name; m_symbolName=name;
} }
bool Definition::hasBriefDescription() const
{
static bool briefMemberDesc = Config_getBool("BRIEF_MEMBER_DESC");
return !briefDescription().isEmpty() && briefMemberDesc;
}
...@@ -260,6 +260,9 @@ class Definition : public DefinitionIntf ...@@ -260,6 +260,9 @@ class Definition : public DefinitionIntf
bool hasSections() const; bool hasSections() const;
/** returns TRUE if this class has a brief description */
bool hasBriefDescription() const;
QCString id() const; QCString id() const;
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
......
...@@ -1336,8 +1336,7 @@ static void addClassToContext(EntryNav *rootNav) ...@@ -1336,8 +1336,7 @@ static void addClassToContext(EntryNav *rootNav)
// see if the class is found inside a namespace // see if the class is found inside a namespace
//bool found=addNamespace(root,cd); //bool found=addNamespace(root,cd);
// the empty string test is needed for extract all case cd->insertUsedFile(fd);
cd->insertUsedFile(root->fileName);
// add class to the list // add class to the list
//printf("ClassDict.insert(%s)\n",resolveDefines(fullName).data()); //printf("ClassDict.insert(%s)\n",resolveDefines(fullName).data());
...@@ -1537,7 +1536,6 @@ static ClassDef *createTagLessInstance(ClassDef *rootCd,ClassDef *templ,const QC ...@@ -1537,7 +1536,6 @@ static ClassDef *createTagLessInstance(ClassDef *rootCd,ClassDef *templ,const QC
gd->addClass(cd); gd->addClass(cd);
} }
} }
//cd->insertUsedFile(root->fileName);
//printf("** adding class %s based on %s\n",fullName.data(),templ->name().data()); //printf("** adding class %s based on %s\n",fullName.data(),templ->name().data());
Doxygen::classSDict->append(fullName,cd); Doxygen::classSDict->append(fullName,cd);
...@@ -1776,7 +1774,7 @@ static void buildNamespaceList(EntryNav *rootNav) ...@@ -1776,7 +1774,7 @@ static void buildNamespaceList(EntryNav *rootNav)
// the empty string test is needed for extract all case // the empty string test is needed for extract all case
nd->setBriefDescription(root->brief,root->briefFile,root->briefLine); nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
nd->insertUsedFile(root->fileName); nd->insertUsedFile(fd);
nd->setBodySegment(root->bodyLine,root->endBodyLine); nd->setBodySegment(root->bodyLine,root->endBodyLine);
nd->setBodyDef(fd); nd->setBodyDef(fd);
// add class to the list // add class to the list
...@@ -1954,7 +1952,7 @@ static void findUsingDirectives(EntryNav *rootNav) ...@@ -1954,7 +1952,7 @@ static void findUsingDirectives(EntryNav *rootNav)
// the empty string test is needed for extract all case // the empty string test is needed for extract all case
nd->setBriefDescription(root->brief,root->briefFile,root->briefLine); nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
nd->insertUsedFile(root->fileName); nd->insertUsedFile(fd);
// add class to the list // add class to the list
Doxygen::namespaceSDict->inSort(name,nd); Doxygen::namespaceSDict->inSort(name,nd);
nd->setRefItems(root->sli); nd->setRefItems(root->sli);
...@@ -2373,7 +2371,7 @@ static MemberDef *addVariableToClass( ...@@ -2373,7 +2371,7 @@ static MemberDef *addVariableToClass(
md->setRefItems(root->sli); md->setRefItems(root->sli);
//TODO: insert FileDef instead of filename strings. //TODO: insert FileDef instead of filename strings.
cd->insertUsedFile(root->fileName); cd->insertUsedFile(rootNav->fileDef());
rootNav->changeSection(Entry::EMPTY_SEC); rootNav->changeSection(Entry::EMPTY_SEC);
return md; return md;
} }
...@@ -3114,7 +3112,7 @@ static void addInterfaceOrServiceToServiceOrSingleton( ...@@ -3114,7 +3112,7 @@ static void addInterfaceOrServiceToServiceOrSingleton(
findClassRelation(rootNav,cd,cd,&base,0,DocumentedOnly,true) findClassRelation(rootNav,cd,cd,&base,0,DocumentedOnly,true)
|| findClassRelation(rootNav,cd,cd,&base,0,Undocumented,true); || findClassRelation(rootNav,cd,cd,&base,0,Undocumented,true);
// add file to list of used files // add file to list of used files
cd->insertUsedFile(root->fileName); cd->insertUsedFile(fd);
addMemberToGroups(root,md); addMemberToGroups(root,md);
rootNav->changeSection(Entry::EMPTY_SEC); rootNav->changeSection(Entry::EMPTY_SEC);
...@@ -3357,7 +3355,7 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd, ...@@ -3357,7 +3355,7 @@ static void addMethodToClass(EntryNav *rootNav,ClassDef *cd,
// add member to the class cd // add member to the class cd
cd->insertMember(md); cd->insertMember(md);
// add file to list of used files // add file to list of used files
cd->insertUsedFile(root->fileName); cd->insertUsedFile(fd);
addMemberToGroups(root,md); addMemberToGroups(root,md);
rootNav->changeSection(Entry::EMPTY_SEC); rootNav->changeSection(Entry::EMPTY_SEC);
...@@ -4831,7 +4829,7 @@ static bool findClassRelation( ...@@ -4831,7 +4829,7 @@ static bool findClassRelation(
// add this class as super class to the base class // add this class as super class to the base class
baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec); baseClass->insertSubClass(cd,bi->prot,bi->virt,templSpec);
// the undocumented base was found in this file // the undocumented base was found in this file
baseClass->insertUsedFile(root->fileName); baseClass->insertUsedFile(rootNav->fileDef());
baseClass->setOuterScope(Doxygen::globalScope); baseClass->setOuterScope(Doxygen::globalScope);
if (baseClassName.right(2)=="-p") if (baseClassName.right(2)=="-p")
{ {
...@@ -5344,7 +5342,7 @@ static void addMemberDocs(EntryNav *rootNav, ...@@ -5344,7 +5342,7 @@ static void addMemberDocs(EntryNav *rootNav,
md->mergeMemberSpecifiers(root->spec); md->mergeMemberSpecifiers(root->spec);
md->addSectionsToDefinition(root->anchors); md->addSectionsToDefinition(root->anchors);
addMemberToGroups(root,md); addMemberToGroups(root,md);
if (cd) cd->insertUsedFile(root->fileName); if (cd) cd->insertUsedFile(rfd);
//printf("root->mGrpId=%d\n",root->mGrpId); //printf("root->mGrpId=%d\n",root->mGrpId);
if (root->mGrpId!=-1) if (root->mGrpId!=-1)
{ {
...@@ -6424,7 +6422,7 @@ static void findMember(EntryNav *rootNav, ...@@ -6424,7 +6422,7 @@ static void findMember(EntryNav *rootNav,
md->setMemberGroupId(root->mGrpId); md->setMemberGroupId(root->mGrpId);
mn->append(md); mn->append(md);
cd->insertMember(md); cd->insertMember(md);
cd->insertUsedFile(root->fileName); cd->insertUsedFile(fd);
md->setRefItems(root->sli); md->setRefItems(root->sli);
} }
} }
...@@ -6621,7 +6619,7 @@ static void findMember(EntryNav *rootNav, ...@@ -6621,7 +6619,7 @@ static void findMember(EntryNav *rootNav,
//md->setMemberDefTemplateArguments(root->mtArgList); //md->setMemberDefTemplateArguments(root->mtArgList);
mn->append(md); mn->append(md);
cd->insertMember(md); cd->insertMember(md);
cd->insertUsedFile(root->fileName); cd->insertUsedFile(fd);
md->setRefItems(root->sli); md->setRefItems(root->sli);
if (root->relatesType == Duplicate) md->setRelatedAlso(cd); if (root->relatesType == Duplicate) md->setRelatedAlso(cd);
if (!isDefine) if (!isDefine)
...@@ -6693,7 +6691,7 @@ localObjCMethod: ...@@ -6693,7 +6691,7 @@ localObjCMethod:
md->setMemberSpecifiers(root->spec); md->setMemberSpecifiers(root->spec);
md->setMemberGroupId(root->mGrpId); md->setMemberGroupId(root->mGrpId);
cd->insertMember(md); cd->insertMember(md);
cd->insertUsedFile(root->fileName); cd->insertUsedFile(fd);
md->setRefItems(root->sli); md->setRefItems(root->sli);
if ((mn=Doxygen::memberNameSDict->find(root->name))) if ((mn=Doxygen::memberNameSDict->find(root->name)))
{ {
...@@ -7077,7 +7075,7 @@ static void findEnums(EntryNav *rootNav) ...@@ -7077,7 +7075,7 @@ static void findEnums(EntryNav *rootNav)
md->setDefinition(cd->name()+"::"+name+baseType); md->setDefinition(cd->name()+"::"+name+baseType);
} }
cd->insertMember(md); cd->insertMember(md);
cd->insertUsedFile(root->fileName); cd->insertUsedFile(fd);
} }
md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocumentation(root->doc,root->docFile,root->docLine);
md->setDocsForDefinition(!root->proto); md->setDocsForDefinition(!root->proto);
......
...@@ -1390,6 +1390,33 @@ bool MemberDef::isBriefSectionVisible() const ...@@ -1390,6 +1390,33 @@ bool MemberDef::isBriefSectionVisible() const
return visible; return visible;
} }
QCString MemberDef::getDeclType() const
{
QCString ltype(m_impl->type);
if (m_impl->mtype==MemberType_Typedef)
{
ltype.prepend("typedef ");
}
if (isAlias())
{
ltype="using";
}
// strip `friend' keyword from ltype
ltype.stripPrefix("friend ");
if (ltype=="@") // rename type from enum values
{
ltype="";
}
else
{
if (isObjCMethod())
{
ltype.prepend("(");
ltype.append(")");
}
}
return ltype;
}
void MemberDef::writeDeclaration(OutputList &ol, void MemberDef::writeDeclaration(OutputList &ol,
ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd, ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
...@@ -1678,7 +1705,7 @@ void MemberDef::writeDeclaration(OutputList &ol, ...@@ -1678,7 +1705,7 @@ void MemberDef::writeDeclaration(OutputList &ol,
// *** write bitfields // *** write bitfields
if (!m_impl->bitfields.isEmpty()) // add bitfields if (!m_impl->bitfields.isEmpty()) // add bitfields
{ {
linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->bitfields.simplifyWhiteSpace()); linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),this,m_impl->bitfields);
} }
else if (hasOneLineInitializer() else if (hasOneLineInitializer()
//!init.isEmpty() && initLines==0 && // one line initializer //!init.isEmpty() && initLines==0 && // one line initializer
...@@ -2978,7 +3005,7 @@ void MemberDef::writeMemberDocSimple(OutputList &ol, Definition *container) ...@@ -2978,7 +3005,7 @@ void MemberDef::writeMemberDocSimple(OutputList &ol, Definition *container)
} }
if (!m_impl->bitfields.isEmpty()) // add bitfields if (!m_impl->bitfields.isEmpty()) // add bitfields
{ {
linkifyText(TextGeneratorOLImpl(ol),getOuterScope(),getBodyDef(),this,m_impl->bitfields.simplifyWhiteSpace()); linkifyText(TextGeneratorOLImpl(ol),getOuterScope(),getBodyDef(),this,m_impl->bitfields);
} }
ol.endInlineMemberName(); ol.endInlineMemberName();
...@@ -4433,7 +4460,7 @@ void MemberDef::mergeMemberSpecifiers(uint64 s) ...@@ -4433,7 +4460,7 @@ void MemberDef::mergeMemberSpecifiers(uint64 s)
void MemberDef::setBitfields(const char *s) void MemberDef::setBitfields(const char *s)
{ {
m_impl->bitfields = s; m_impl->bitfields = QCString(s).simplifyWhiteSpace();
} }
void MemberDef::setMaxInitLines(int lines) void MemberDef::setMaxInitLines(int lines)
......
...@@ -241,6 +241,7 @@ class MemberDef : public Definition ...@@ -241,6 +241,7 @@ class MemberDef : public Definition
MemberDef *categoryRelation() const; MemberDef *categoryRelation() const;
QCString displayName(bool=TRUE) const; QCString displayName(bool=TRUE) const;
QCString getDeclType() const;
//----------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------
// ---- setters ----- // ---- setters -----
......
...@@ -115,14 +115,15 @@ void NamespaceDef::findSectionsInDocumentation() ...@@ -115,14 +115,15 @@ void NamespaceDef::findSectionsInDocumentation()
} }
} }
void NamespaceDef::insertUsedFile(const char *f) void NamespaceDef::insertUsedFile(FileDef *fd)
{ {
if (files.find(f)==-1) if (fd==0) return;
if (files.find(fd)==-1)
{ {
if (Config_getBool("SORT_MEMBER_DOCS")) if (Config_getBool("SORT_MEMBER_DOCS"))
files.inSort(f); files.inSort(fd);
else else
files.append(f); files.append(fd);
} }
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <qdict.h> #include <qdict.h>
#include "sortdict.h" #include "sortdict.h"
#include "definition.h" #include "definition.h"
#include "filedef.h"
class MemberList; class MemberList;
class ClassDef; class ClassDef;
...@@ -45,7 +46,7 @@ class NamespaceDef : public Definition ...@@ -45,7 +46,7 @@ class NamespaceDef : public Definition
DefType definitionType() const { return TypeNamespace; } DefType definitionType() const { return TypeNamespace; }
QCString getOutputFileBase() const; QCString getOutputFileBase() const;
QCString anchor() const { return QCString(); } QCString anchor() const { return QCString(); }
void insertUsedFile(const char *fname); void insertUsedFile(FileDef *fd);
void writeDocumentation(OutputList &ol); void writeDocumentation(OutputList &ol);
void writeMemberPages(OutputList &ol); void writeMemberPages(OutputList &ol);
...@@ -117,7 +118,7 @@ class NamespaceDef : public Definition ...@@ -117,7 +118,7 @@ class NamespaceDef : public Definition
void addNamespaceAttributes(OutputList &ol); void addNamespaceAttributes(OutputList &ol);
QCString fileName; QCString fileName;
QStrList files; FileList files;
NamespaceSDict *usingDirList; NamespaceSDict *usingDirList;
SDict<Definition> *usingDeclList; SDict<Definition> *usingDeclList;
......
...@@ -129,18 +129,20 @@ TemplateVariant::TemplateVariant(int v) ...@@ -129,18 +129,20 @@ TemplateVariant::TemplateVariant(int v)
p->intVal = v; p->intVal = v;
} }
TemplateVariant::TemplateVariant(const char *s) TemplateVariant::TemplateVariant(const char *s,bool raw)
{ {
p = new Private; p = new Private;
p->type = String; p->type = String;
p->strVal = s; p->strVal = s;
p->raw = raw;
} }
TemplateVariant::TemplateVariant(const QCString &s) TemplateVariant::TemplateVariant(const QCString &s,bool raw)
{ {
p = new Private; p = new Private;
p->type = String; p->type = String;
p->strVal = s; p->strVal = s;
p->raw = raw;
} }
TemplateVariant::TemplateVariant(const TemplateStructIntf *s) TemplateVariant::TemplateVariant(const TemplateStructIntf *s)
...@@ -301,10 +303,10 @@ const TemplateListIntf *TemplateVariant::toList() const ...@@ -301,10 +303,10 @@ const TemplateListIntf *TemplateVariant::toList() const
return p->type==List ? p->list : 0; return p->type==List ? p->list : 0;
} }
QCString TemplateVariant::call(const QValueList<TemplateVariant> &args) TemplateVariant TemplateVariant::call(const QValueList<TemplateVariant> &args)
{ {
if (p->type==Function) return p->func(p->obj,args); if (p->type==Function) return p->func(p->obj,args);
return QCString(); return TemplateVariant();
} }
bool TemplateVariant::operator==(TemplateVariant &other) bool TemplateVariant::operator==(TemplateVariant &other)
...@@ -507,11 +509,12 @@ class Operator ...@@ -507,11 +509,12 @@ class Operator
==, !=, <, >, <=, >= ==, !=, <, >, <=, >=
| |
: :
,
*/ */
enum Type enum Type
{ {
Or, And, Not, In, Equal, NotEqual, Less, Greater, LessEqual, Or, And, Not, In, Equal, NotEqual, Less, Greater, LessEqual,
GreaterEqual, Filter, Colon, Last GreaterEqual, Filter, Colon, Comma, Last
}; };
static const char *toString(Type op) static const char *toString(Type op)
...@@ -530,6 +533,7 @@ class Operator ...@@ -530,6 +533,7 @@ class Operator
case GreaterEqual: return ">="; case GreaterEqual: return ">=";
case Filter: return "|"; case Filter: return "|";
case Colon: return ":"; case Colon: return ":";
case Comma: return ",";
case Last: return "?"; case Last: return "?";
} }
return "?"; return "?";
...@@ -574,6 +578,8 @@ class TemplateContextImpl : public TemplateContext ...@@ -574,6 +578,8 @@ class TemplateContextImpl : public TemplateContext
{ m_outputDir = dir; } { m_outputDir = dir; }
void setEscapeIntf(TemplateEscapeIntf *intf) void setEscapeIntf(TemplateEscapeIntf *intf)
{ m_escapeIntf = intf; } { m_escapeIntf = intf; }
void setSpacelessIntf(TemplateSpacelessIntf *intf)
{ m_spacelessIntf = intf; }
// internal methods // internal methods
TemplateBlockContext *blockContext(); TemplateBlockContext *blockContext();
...@@ -584,6 +590,9 @@ class TemplateContextImpl : public TemplateContext ...@@ -584,6 +590,9 @@ class TemplateContextImpl : public TemplateContext
int line() const { return m_line; } int line() const { return m_line; }
QCString outputDirectory() const { return m_outputDir; } QCString outputDirectory() const { return m_outputDir; }
TemplateEscapeIntf *escapeIntf() const { return m_escapeIntf; } TemplateEscapeIntf *escapeIntf() const { return m_escapeIntf; }
TemplateSpacelessIntf *spacelessIntf() const { return m_spacelessIntf; }
void enableSpaceless(bool b) { m_spacelessEnabled=b; }
bool spacelessEnabled() const { return m_spacelessEnabled && m_spacelessIntf; }
private: private:
QCString m_templateName; QCString m_templateName;
...@@ -592,6 +601,8 @@ class TemplateContextImpl : public TemplateContext ...@@ -592,6 +601,8 @@ class TemplateContextImpl : public TemplateContext
QList< QDict<TemplateVariant> > m_contextStack; QList< QDict<TemplateVariant> > m_contextStack;
TemplateBlockContext m_blockContext; TemplateBlockContext m_blockContext;
TemplateEscapeIntf *m_escapeIntf; TemplateEscapeIntf *m_escapeIntf;
TemplateSpacelessIntf *m_spacelessIntf;
bool m_spacelessEnabled;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -802,7 +813,7 @@ static TemplateFilterFactory::AutoRegister<FilterAdd> fAdd("add"); ...@@ -802,7 +813,7 @@ static TemplateFilterFactory::AutoRegister<FilterAdd> fAdd("add");
static TemplateFilterFactory::AutoRegister<FilterPrepend> fPrepend("prepend"); static TemplateFilterFactory::AutoRegister<FilterPrepend> fPrepend("prepend");
static TemplateFilterFactory::AutoRegister<FilterLength> fLength("length"); static TemplateFilterFactory::AutoRegister<FilterLength> fLength("length");
static TemplateFilterFactory::AutoRegister<FilterDefault> fDefault("default"); static TemplateFilterFactory::AutoRegister<FilterDefault> fDefault("default");
static TemplateFilterFactory::AutoRegister<FilterStripPath> fStripPath("strippath"); static TemplateFilterFactory::AutoRegister<FilterStripPath> fStripPath("stripPath");
static TemplateFilterFactory::AutoRegister<FilterNoWrap> fNoWrap("nowrap"); static TemplateFilterFactory::AutoRegister<FilterNoWrap> fNoWrap("nowrap");
//-------------------------------------------------------------------- //--------------------------------------------------------------------
...@@ -850,6 +861,34 @@ class ExprAstVariable : public ExprAst ...@@ -850,6 +861,34 @@ class ExprAstVariable : public ExprAst
QCString m_name; QCString m_name;
}; };
class ExprAstFunctionVariable : public ExprAst
{
public:
ExprAstFunctionVariable(ExprAst *var,const QList<ExprAst> &args)
: m_var(var), m_args(args)
{ TRACE(("ExprAstFunctionVariable(%s)\n",var->name().data()));
m_args.setAutoDelete(TRUE);
}
virtual TemplateVariant resolve(TemplateContext *c)
{
QValueList<TemplateVariant> args;
for (uint i=0;i<m_args.count();i++)
{
TemplateVariant v = m_args.at(i)->resolve(c);
args.append(v);
}
TemplateVariant v = m_var->resolve(c);
if (v.type()==TemplateVariant::Function)
{
v = v.call(args);
}
return v;
}
private:
ExprAst *m_var;
QList<ExprAst> m_args;
};
/** @brief Class representing a filter in the AST */ /** @brief Class representing a filter in the AST */
class ExprAstFilter : public ExprAst class ExprAstFilter : public ExprAst
{ {
...@@ -1189,10 +1228,37 @@ class ExpressionParser ...@@ -1189,10 +1228,37 @@ class ExpressionParser
return lit; return lit;
} }
ExprAst *parseIdentifierOptionalArgs()
{
TRACE(("{parseIdentifierOptionalArgs(%s)\n",m_curToken.id.data()));
ExprAst *expr = parseIdentifier();
if (expr)
{
if (m_curToken.type==ExprToken::Operator &&
m_curToken.op==Operator::Colon)
{
getNextToken();
ExprAst *argExpr = parsePrimaryExpression();
QList<ExprAst> args;
args.append(argExpr);
while (m_curToken.type==ExprToken::Operator &&
m_curToken.op==Operator::Comma)
{
getNextToken();
argExpr = parsePrimaryExpression();
args.append(argExpr);
}
expr = new ExprAstFunctionVariable(expr,args);
}
}
TRACE(("}parseIdentifierOptionalArgs()\n"));
return expr;
}
ExprAst *parseFilteredVariable() ExprAst *parseFilteredVariable()
{ {
TRACE(("{parseFilteredVariable()\n")); TRACE(("{parseFilteredVariable()\n"));
ExprAst *expr = parseIdentifier(); ExprAst *expr = parseIdentifierOptionalArgs();
if (expr) if (expr)
{ {
while (m_curToken.type==ExprToken::Operator && while (m_curToken.type==ExprToken::Operator &&
...@@ -1300,6 +1366,12 @@ class ExpressionParser ...@@ -1300,6 +1366,12 @@ class ExpressionParser
m_curToken.op = Operator::Colon; m_curToken.op = Operator::Colon;
p++; p++;
} }
else if (c==',')
{
m_curToken.type = ExprToken::Operator;
m_curToken.op = Operator::Comma;
p++;
}
else if ((c=='-' && *(p+1)>='0' && *(p+1)<='9') || (c>='0' && c<='9')) else if ((c=='-' && *(p+1)>='0' && *(p+1)<='9') || (c>='0' && c<='9'))
{ {
m_curToken.type = ExprToken::Number; m_curToken.type = ExprToken::Number;
...@@ -1471,7 +1543,8 @@ class TemplateImpl : public TemplateNode, public Template ...@@ -1471,7 +1543,8 @@ class TemplateImpl : public TemplateNode, public Template
TemplateContextImpl::TemplateContextImpl() TemplateContextImpl::TemplateContextImpl()
: m_templateName("<unknown>"), m_line(1), m_escapeIntf(0) : m_templateName("<unknown>"), m_line(1), m_escapeIntf(0),
m_spacelessIntf(0), m_spacelessEnabled(FALSE)
{ {
m_contextStack.setAutoDelete(TRUE); m_contextStack.setAutoDelete(TRUE);
push(); push();
...@@ -1611,11 +1684,19 @@ class TemplateNodeText : public TemplateNode ...@@ -1611,11 +1684,19 @@ class TemplateNodeText : public TemplateNode
TRACE(("TemplateNodeText('%s')\n",replace(data,'\n',' ').data())); TRACE(("TemplateNodeText('%s')\n",replace(data,'\n',' ').data()));
} }
void render(FTextStream &ts, TemplateContext *) void render(FTextStream &ts, TemplateContext *c)
{ {
//printf("TemplateNodeText::render(%s)\n",m_data.data()); //printf("TemplateNodeText::render(%s)\n",m_data.data());
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
if (ci->spacelessEnabled())
{
ts << ci->spacelessIntf()->remove(m_data);
}
else
{
ts << m_data; ts << m_data;
} }
}
private: private:
QCString m_data; QCString m_data;
}; };
...@@ -1631,26 +1712,8 @@ class TemplateNodeVariable : public TemplateNode ...@@ -1631,26 +1712,8 @@ class TemplateNodeVariable : public TemplateNode
{ {
TRACE(("TemplateNodeVariable(%s)\n",var.data())); TRACE(("TemplateNodeVariable(%s)\n",var.data()));
ExpressionParser expParser(m_templateName,line); ExpressionParser expParser(m_templateName,line);
int i=var.find(':');
int j=var.find('|');
if (i==-1 || (j!=-1 && j<i)) // no arguments or arg belongs to filter
{
m_var = expParser.parseVariable(var); m_var = expParser.parseVariable(var);
} }
else
{
QValueList<QCString> args = split(var.mid(i+1),",");
for (uint j=0;j<args.count();j++)
{
ExprAst *expr = expParser.parsePrimary(args[j]);
if (expr)
{
m_args.append(expr);
}
}
m_var = expParser.parseVariable(var.left(i));
}
}
~TemplateNodeVariable() ~TemplateNodeVariable()
{ {
delete m_var; delete m_var;
...@@ -1660,30 +1723,19 @@ class TemplateNodeVariable : public TemplateNode ...@@ -1660,30 +1723,19 @@ class TemplateNodeVariable : public TemplateNode
{ {
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c); TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
ci->setLocation(m_templateName,m_line); ci->setLocation(m_templateName,m_line);
QValueList<TemplateVariant> args;
for (uint i=0;i<m_args.count();i++)
{
TemplateVariant v = m_args.at(i)->resolve(c);
args.append(v);
}
TemplateVariant v = m_var->resolve(c); TemplateVariant v = m_var->resolve(c);
QCString value;
if (v.type()==TemplateVariant::Function) if (v.type()==TemplateVariant::Function)
{ {
value = v.call(args); v = v.call(QValueList<TemplateVariant>());
}
else
{
value = v.toString();
} }
//printf("TemplateNodeVariable::render(%s) raw=%d\n",value.data(),v.raw()); //printf("TemplateNodeVariable::render(%s) raw=%d\n",value.data(),v.raw());
if (ci->escapeIntf() && !v.raw()) if (ci->escapeIntf() && !v.raw())
{ {
ts << ci->escapeIntf()->escape(value); ts << ci->escapeIntf()->escape(v.toString());
} }
else else
{ {
ts << value; ts << v.toString();
} }
} }
...@@ -1935,6 +1987,37 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor> ...@@ -1935,6 +1987,37 @@ class TemplateNodeFor : public TemplateNodeCreator<TemplateNodeFor>
TemplateNodeList m_emptyNodes; TemplateNodeList m_emptyNodes;
}; };
//----------------------------------------------------------
/** @brief Class representing an 'markers' tag in a template */
class TemplateNodeMsg : public TemplateNodeCreator<TemplateNodeMsg>
{
public:
TemplateNodeMsg(TemplateParser *parser,TemplateNode *parent,int line,const QCString &)
: TemplateNodeCreator<TemplateNodeMsg>(parser,parent,line)
{
TRACE(("{TemplateNodeMsg()\n"));
QStrList stopAt;
stopAt.append("endmsg");
parser->parse(this,line,stopAt,m_nodes);
parser->removeNextToken(); // skip over endmarkers
TRACE(("}TemplateNodeMsg()\n"));
}
void render(FTextStream &, TemplateContext *c)
{
TemplateContextImpl* ci = dynamic_cast<TemplateContextImpl*>(c);
TemplateEscapeIntf *escIntf = ci->escapeIntf();
ci->setEscapeIntf(0); // avoid escaping things we send to standard out
FTextStream ts(stdout);
m_nodes.render(ts,c);
ts << endl;
ci->setEscapeIntf(escIntf);
}
private:
TemplateNodeList m_nodes;
};
//---------------------------------------------------------- //----------------------------------------------------------
/** @brief Class representing a 'block' tag in a template */ /** @brief Class representing a 'block' tag in a template */
...@@ -2065,6 +2148,11 @@ class TemplateNodeExtend : public TemplateNodeCreator<TemplateNodeExtend> ...@@ -2065,6 +2148,11 @@ class TemplateNodeExtend : public TemplateNodeCreator<TemplateNodeExtend>
{ {
bc->add(nb); bc->add(nb);
} }
TemplateNodeMsg *msg = dynamic_cast<TemplateNodeMsg*>(n);
if (msg)
{
msg->render(ts,c);
}
} }
// render the base template with the given context // render the base template with the given context
...@@ -2140,7 +2228,7 @@ class TemplateNodeInclude : public TemplateNodeCreator<TemplateNodeInclude> ...@@ -2140,7 +2228,7 @@ class TemplateNodeInclude : public TemplateNodeCreator<TemplateNodeInclude>
//---------------------------------------------------------- //----------------------------------------------------------
/** @brief Class representing an 'instantiate' tag in a template */ /** @brief Class representing an 'create' tag in a template */
class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate> class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate>
{ {
public: public:
...@@ -2237,7 +2325,7 @@ class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate> ...@@ -2237,7 +2325,7 @@ class TemplateNodeCreate : public TemplateNodeCreator<TemplateNodeCreate>
//---------------------------------------------------------- //----------------------------------------------------------
/** @brief Class representing an 'instantiate' tag in a template */ /** @brief Class representing an 'tree' tag in a template */
class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree> class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree>
{ {
struct TreeContext struct TreeContext
...@@ -2269,9 +2357,10 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree> ...@@ -2269,9 +2357,10 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree>
{ {
delete m_treeExpr; delete m_treeExpr;
} }
static QCString renderChildrenStub(const void *ctx, const QValueList<TemplateVariant> &) static TemplateVariant renderChildrenStub(const void *ctx, const QValueList<TemplateVariant> &)
{ {
return ((TreeContext*)ctx)->object->renderChildren((const TreeContext*)ctx); return TemplateVariant(((TreeContext*)ctx)->object->
renderChildren((const TreeContext*)ctx),TRUE);
} }
QCString renderChildren(const TreeContext *ctx) QCString renderChildren(const TreeContext *ctx)
{ {
...@@ -2339,7 +2428,7 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree> ...@@ -2339,7 +2428,7 @@ class TemplateNodeTree : public TemplateNodeCreator<TemplateNodeTree>
//---------------------------------------------------------- //----------------------------------------------------------
/** @brief Class representing an 'instantiate' tag in a template */ /** @brief Class representing an 'with' tag in a template */
class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith> class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith>
{ {
struct Mapping struct Mapping
...@@ -2353,6 +2442,7 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith> ...@@ -2353,6 +2442,7 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith>
TemplateNodeWith(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data) TemplateNodeWith(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeWith>(parser,parent,line) : TemplateNodeCreator<TemplateNodeWith>(parser,parent,line)
{ {
TRACE(("{TemplateNodeWith(%s)\n",data.data()));
m_args.setAutoDelete(TRUE); m_args.setAutoDelete(TRUE);
ExpressionParser expParser(parser->templateName(),line); ExpressionParser expParser(parser->templateName(),line);
QValueList<QCString> args = split(data," "); QValueList<QCString> args = split(data," ");
...@@ -2379,6 +2469,7 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith> ...@@ -2379,6 +2469,7 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith>
stopAt.append("endwith"); stopAt.append("endwith");
parser->parse(this,line,stopAt,m_nodes); parser->parse(this,line,stopAt,m_nodes);
parser->removeNextToken(); // skip over endwith parser->removeNextToken(); // skip over endwith
TRACE(("}TemplateNodeWith(%s)\n",data.data()));
} }
~TemplateNodeWith() ~TemplateNodeWith()
{ {
...@@ -2404,6 +2495,129 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith> ...@@ -2404,6 +2495,129 @@ class TemplateNodeWith : public TemplateNodeCreator<TemplateNodeWith>
//---------------------------------------------------------- //----------------------------------------------------------
/** @brief Class representing an 'spaceless' tag in a template */
class TemplateNodeSpaceless : public TemplateNodeCreator<TemplateNodeSpaceless>
{
public:
TemplateNodeSpaceless(TemplateParser *parser,TemplateNode *parent,int line,const QCString &)
: TemplateNodeCreator<TemplateNodeSpaceless>(parser,parent,line)
{
TRACE(("{TemplateNodeSpaceless()\n"));
QStrList stopAt;
stopAt.append("endspaceless");
parser->parse(this,line,stopAt,m_nodes);
parser->removeNextToken(); // skip over endwith
TRACE(("}TemplateNodeSpaceless()\n"));
}
void render(FTextStream &ts, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
bool wasSpaceless = ci->spacelessEnabled();
ci->enableSpaceless(TRUE);
m_nodes.render(ts,c);
ci->enableSpaceless(wasSpaceless);
}
private:
TemplateNodeList m_nodes;
};
//----------------------------------------------------------
/** @brief Class representing an 'markers' tag in a template */
class TemplateNodeMarkers : public TemplateNodeCreator<TemplateNodeMarkers>
{
public:
TemplateNodeMarkers(TemplateParser *parser,TemplateNode *parent,int line,const QCString &data)
: TemplateNodeCreator<TemplateNodeMarkers>(parser,parent,line)
{
TRACE(("{TemplateNodeMarkers(%s)\n",data.data()));
int i = data.find(" in ");
int w = data.find(" with ");
if (i==-1 || w==-1 || w<i)
{
warn(m_templateName,line,"markers tag as wrong format. Expected: markers <var> in <list> with <string_with_markers>");
}
else
{
ExpressionParser expParser(parser->templateName(),line);
m_var = data.left(i);
m_listExpr = expParser.parseVariable(data.mid(i+4,w-i-4));
m_patternExpr = expParser.parseVariable(data.right(data.length()-w-6));
}
QStrList stopAt;
stopAt.append("endmarkers");
parser->parse(this,line,stopAt,m_nodes);
parser->removeNextToken(); // skip over endmarkers
TRACE(("}TemplateNodeMarkers(%s)\n",data.data()));
}
void render(FTextStream &ts, TemplateContext *c)
{
TemplateContextImpl *ci = dynamic_cast<TemplateContextImpl*>(c);
ci->setLocation(m_templateName,m_line);
if (!m_var.isEmpty() && m_listExpr && m_patternExpr)
{
TemplateVariant v = m_listExpr->resolve(c);
const TemplateListIntf *list = v.toList();
TemplateVariant patternStr = m_patternExpr->resolve(c);
if (list)
{
if (patternStr.type()==TemplateVariant::String)
{
TemplateListIntf::ConstIterator *it = list->createIterator();
c->push();
QCString str = patternStr.toString();
QRegExp marker("@[0-9]+"); // pattern for a marker, i.e. @0, @1 ... @12, etc
int index=0,newIndex,matchLen;
while ((newIndex=marker.match(str,index,&matchLen))!=-1)
{
ts << str.mid(index,newIndex-index); // write text before marker
bool ok;
uint entryIndex = str.mid(newIndex+1,matchLen-1).toUInt(&ok); // get marker id
TemplateVariant var;
uint i=0;
// search for list element at position id
for (it->toFirst(); (it->current(var)) && i<entryIndex; it->toNext(),i++) {}
if (ok && i==entryIndex) // found element
{
c->set(m_var,var); // define local variable to hold element of list type
bool wasSpaceless = ci->spacelessEnabled();
ci->enableSpaceless(TRUE);
m_nodes.render(ts,c);
ci->enableSpaceless(wasSpaceless);
}
else if (!ok)
{
warn(m_templateName,m_line,"markers pattern string has invalid markers '%s'",str.data());
}
else if (i<entryIndex)
{
warn(m_templateName,m_line,"markers list does not an element for marker position %d",i);
}
index=newIndex+matchLen; // set index just after marker
}
ts << str.right(str.length()-index); // write text after last marker
c->pop();
}
else
{
warn(m_templateName,m_line,"markers requires a parameter of string type after 'with'!");
}
}
else
{
warn(m_templateName,m_line,"markers requires a parameter of list type after 'in'!");
}
}
}
private:
TemplateNodeList m_nodes;
QCString m_var;
ExprAst *m_listExpr;
ExprAst *m_patternExpr;
};
//----------------------------------------------------------
/** @brief Factory class for creating tag AST nodes found in a template */ /** @brief Factory class for creating tag AST nodes found in a template */
class TemplateNodeFactory class TemplateNodeFactory
{ {
...@@ -2452,12 +2666,15 @@ class TemplateNodeFactory ...@@ -2452,12 +2666,15 @@ class TemplateNodeFactory
// register a handler for each start tag we support // register a handler for each start tag we support
static TemplateNodeFactory::AutoRegister<TemplateNodeIf> autoRefIf("if"); static TemplateNodeFactory::AutoRegister<TemplateNodeIf> autoRefIf("if");
static TemplateNodeFactory::AutoRegister<TemplateNodeFor> autoRefFor("for"); static TemplateNodeFactory::AutoRegister<TemplateNodeFor> autoRefFor("for");
static TemplateNodeFactory::AutoRegister<TemplateNodeMsg> autoRefMsg("msg");
static TemplateNodeFactory::AutoRegister<TemplateNodeTree> autoRefTree("recursetree"); static TemplateNodeFactory::AutoRegister<TemplateNodeTree> autoRefTree("recursetree");
static TemplateNodeFactory::AutoRegister<TemplateNodeWith> autoRefWith("with"); static TemplateNodeFactory::AutoRegister<TemplateNodeWith> autoRefWith("with");
static TemplateNodeFactory::AutoRegister<TemplateNodeBlock> autoRefBlock("block"); static TemplateNodeFactory::AutoRegister<TemplateNodeBlock> autoRefBlock("block");
static TemplateNodeFactory::AutoRegister<TemplateNodeExtend> autoRefExtend("extend"); static TemplateNodeFactory::AutoRegister<TemplateNodeExtend> autoRefExtend("extend");
static TemplateNodeFactory::AutoRegister<TemplateNodeCreate> autoRefCreate("create"); static TemplateNodeFactory::AutoRegister<TemplateNodeCreate> autoRefCreate("create");
static TemplateNodeFactory::AutoRegister<TemplateNodeInclude> autoRefInclude("include"); static TemplateNodeFactory::AutoRegister<TemplateNodeInclude> autoRefInclude("include");
static TemplateNodeFactory::AutoRegister<TemplateNodeMarkers> autoRefMarkers("markers");
static TemplateNodeFactory::AutoRegister<TemplateNodeSpaceless> autoRefSpaceless("spaceless");
//---------------------------------------------------------- //----------------------------------------------------------
...@@ -2816,7 +3033,8 @@ void TemplateParser::parse( ...@@ -2816,7 +3033,8 @@ void TemplateParser::parse(
else if (command=="empty" || command=="else" || else if (command=="empty" || command=="else" ||
command=="endif" || command=="endfor" || command=="endif" || command=="endfor" ||
command=="endblock" || command=="endwith" || command=="endblock" || command=="endwith" ||
command=="endrecursetree") command=="endrecursetree" || command=="endspaceless" ||
command=="endmarkers" || command=="endmsg")
{ {
warn(m_templateName,tok->line,"Found tag '%s' without matching start tag",command.data()); warn(m_templateName,tok->line,"Found tag '%s' without matching start tag",command.data());
} }
......
...@@ -42,8 +42,10 @@ class TemplateEngine; ...@@ -42,8 +42,10 @@ class TemplateEngine;
* - `for ... empty ... endfor` * - `for ... empty ... endfor`
* - `if ... else ... endif` * - `if ... else ... endif`
* - `block ... endblock` * - `block ... endblock`
* - `extends` * - `extend`
* - `include` * - `include`
* - `with ... endwith`
* - `spaceless ... endspaceless`
* *
* Supported Django filters: * Supported Django filters:
* - `default` * - `default`
...@@ -53,6 +55,13 @@ class TemplateEngine; ...@@ -53,6 +55,13 @@ class TemplateEngine;
* Extension tags: * Extension tags:
* - `create` which instantiates a template and writes the result to a file. * - `create` which instantiates a template and writes the result to a file.
* The syntax is `{% create 'filename' from 'template' %}`. * The syntax is `{% create 'filename' from 'template' %}`.
* - `recursetree`
* - `markers`
*
* Extension filters:
* - `stripPath`
* - `nowrap`
* - `prepend`
* *
* @{ * @{
*/ */
...@@ -62,7 +71,7 @@ class TemplateVariant ...@@ -62,7 +71,7 @@ class TemplateVariant
{ {
public: public:
/** Signature of the callback function, used for function type variants */ /** Signature of the callback function, used for function type variants */
typedef QCString (*FuncType)(const void *obj, const QValueList<TemplateVariant> &args); typedef TemplateVariant (*FuncType)(const void *obj, const QValueList<TemplateVariant> &args);
/** Types of data that can be stored in a TemplateVariant */ /** Types of data that can be stored in a TemplateVariant */
enum Type { None, Bool, Integer, String, Struct, List, Function }; enum Type { None, Bool, Integer, String, Struct, List, Function };
...@@ -83,10 +92,10 @@ class TemplateVariant ...@@ -83,10 +92,10 @@ class TemplateVariant
TemplateVariant(int v); TemplateVariant(int v);
/** Constructs a new variant with a string value \a s. */ /** Constructs a new variant with a string value \a s. */
TemplateVariant(const char *s); TemplateVariant(const char *s,bool raw=FALSE);
/** Constructs a new variant with a string value \a s. */ /** Constructs a new variant with a string value \a s. */
TemplateVariant(const QCString &s); TemplateVariant(const QCString &s,bool raw=FALSE);
/** Constructs a new variant with a struct value \a s. /** Constructs a new variant with a struct value \a s.
* @note. Only a pointer to the struct is stored. The caller * @note. Only a pointer to the struct is stored. The caller
...@@ -146,7 +155,7 @@ class TemplateVariant ...@@ -146,7 +155,7 @@ class TemplateVariant
/** Return the result of apply this function with \a args. /** Return the result of apply this function with \a args.
* Returns an empty string if the variant type is not a function. * Returns an empty string if the variant type is not a function.
*/ */
QCString call(const QValueList<TemplateVariant> &args); TemplateVariant call(const QValueList<TemplateVariant> &args);
/** Sets whether or not the value of the Variant should be /** Sets whether or not the value of the Variant should be
* escaped or written as-is (raw). * escaped or written as-is (raw).
...@@ -283,6 +292,16 @@ class TemplateEscapeIntf ...@@ -283,6 +292,16 @@ class TemplateEscapeIntf
//------------------------------------------------------------------------ //------------------------------------------------------------------------
/** @brief Interface used to remove redundant spaces inside a spaceless block */
class TemplateSpacelessIntf
{
public:
/** Returns the \a input after removing redundant whitespace */
virtual QCString remove(const QCString &input) = 0;
};
//------------------------------------------------------------------------
/** @brief Abstract interface for a template context. /** @brief Abstract interface for a template context.
* *
* A Context consists of a stack of dictionaries. * A Context consists of a stack of dictionaries.
...@@ -333,6 +352,11 @@ class TemplateContext ...@@ -333,6 +352,11 @@ class TemplateContext
* of variable expansion before writing it to the output. * of variable expansion before writing it to the output.
*/ */
virtual void setEscapeIntf(TemplateEscapeIntf *intf) = 0; virtual void setEscapeIntf(TemplateEscapeIntf *intf) = 0;
/** Sets the interface that will be used inside a spaceless block
* to remove any redundant whitespace.
*/
virtual void setSpacelessIntf(TemplateSpacelessIntf *intf) = 0;
}; };
//------------------------------------------------------------------------ //------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment