From abe254fbe2235f5b913653acd076d2acd579d5e1 Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Fri, 28 Aug 2015 10:20:26 +0200 Subject: [PATCH] Added support for directory dependency graphs to template engine --- src/context.cpp | 96 ++++++++++++++++++++++++++++++++++++-- src/dirdef.cpp | 9 +--- src/dirdef.h | 1 - src/dot.cpp | 18 ++++--- src/dot.h | 5 +- templates/html/htmldir.tpl | 13 +++++- 6 files changed, 119 insertions(+), 23 deletions(-) diff --git a/src/context.cpp b/src/context.cpp index 39d7b071da1..68e11676ff9 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -456,6 +456,18 @@ class TranslateContext::Private : public PropertyMapper } return TemplateVariant(); } + TemplateVariant handleDirDependencyGraphFor(const QValueList &args) const + { + if (args.count()==1) + { + return theTranslator->trDirDepGraph(args[0].toString()); + } + else + { + err("tr.dirDependencyGraphFor should take one argument, got %d!\n",args.count()); + } + return TemplateVariant(); + } TemplateVariant handleInheritsList(const QValueList &args) const { if (args.count()==1) @@ -571,6 +583,10 @@ class TranslateContext::Private : public PropertyMapper { return TemplateVariant::Delegate::fromMethod(this); } + TemplateVariant dirDependencyGraphFor() const + { + return TemplateVariant::Delegate::fromMethod(this); + } TemplateVariant search() const { return theTranslator->trSearch(); @@ -1138,6 +1154,8 @@ class TranslateContext::Private : public PropertyMapper addProperty("panelSyncOn", this,&Private::panelSyncOn); //%% string panelSyncOff addProperty("panelSyncOff", this,&Private::panelSyncOff); + //%% string dirDependencyGraph + addProperty("dirDependencyGraphFor", this,&Private::dirDependencyGraphFor); m_javaOpt = Config_getBool("OPTIMIZE_OUTPUT_JAVA"); m_fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN"); @@ -1819,6 +1837,7 @@ class ClassContext::Private : public DefinitionContext err("context.cpp: output format not yet supported"); break; } + g_globals.dynSectionId++; } else if (classDiagrams) { @@ -1850,8 +1869,8 @@ class ClassContext::Private : public DefinitionContext err("context.cpp: output format not yet supported"); break; } + g_globals.dynSectionId++; } - g_globals.dynSectionId++; return TemplateVariant(result.data(),TRUE); } DotClassGraph *getCollaborationGraph() const @@ -1900,8 +1919,8 @@ class ClassContext::Private : public DefinitionContext err("context.cpp: output format not yet supported"); break; } + g_globals.dynSectionId++; } - g_globals.dynSectionId++; return TemplateVariant(result.data(),TRUE); } @@ -2794,8 +2813,8 @@ class FileContext::Private : public DefinitionContext err("context.cpp: output format not yet supported"); break; } + g_globals.dynSectionId++; } - g_globals.dynSectionId++; return TemplateVariant(result.data(),TRUE); } DotInclDepGraph *getIncludedByGraph() const @@ -2845,8 +2864,8 @@ class FileContext::Private : public DefinitionContext err("context.cpp: output format not yet supported"); break; } + g_globals.dynSectionId++; } - g_globals.dynSectionId++; return TemplateVariant(result.data(),TRUE); } TemplateVariant hasDetails() const @@ -3109,6 +3128,8 @@ class DirContext::Private : public DefinitionContext addProperty("dirs", this,&Private::dirs); addProperty("files", this,&Private::files); addProperty("hasDetails", this,&Private::hasDetails); + addProperty("hasDirGraph", this,&Private::hasDirGraph); + addProperty("dirGraph", this,&Private::dirGraph); addProperty("compoundType", this,&Private::compoundType); } virtual ~Private() {} @@ -3176,6 +3197,70 @@ class DirContext::Private : public DefinitionContext { return ""; } + DotDirDeps *getDirDepsGraph() const + { + if (!m_cache.dirDepsGraph) + { + m_cache.dirDepsGraph.reset(new DotDirDeps(m_dirDef)); + } + return m_cache.dirDepsGraph.get(); + } + TemplateVariant hasDirGraph() const + { + bool result=FALSE; + static bool haveDot = Config_getBool("HAVE_DOT"); + static bool dirGraph = Config_getBool("DIRECTORY_GRAPH"); + if (haveDot && dirGraph) + { + DotDirDeps *graph = getDirDepsGraph(); + result = !graph->isTrivial(); + } + return result; + } + TemplateVariant dirGraph() const + { + QGString result; + static bool haveDot = Config_getBool("HAVE_DOT"); + static bool dirGraph = Config_getBool("DIRECTORY_GRAPH"); + if (haveDot && dirGraph) + { + DotDirDeps *graph = getDirDepsGraph(); + FTextStream t(&result); + switch (g_globals.outputFormat) + { + case ContextOutputFormat_Html: + { + graph->writeGraph(t,GOF_BITMAP, + EOF_Html, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_dirDef->getOutputFileBase()+Doxygen::htmlFileExtension, + relPathAsString(), + TRUE, + g_globals.dynSectionId, + FALSE); + } + break; + case ContextOutputFormat_Latex: + { + graph->writeGraph(t,GOF_EPS, + EOF_LaTeX, + g_globals.outputDir, + g_globals.outputDir+portable_pathSeparator()+m_dirDef->getOutputFileBase()+".tex", + relPathAsString(), + TRUE, + g_globals.dynSectionId, + FALSE); + } + break; + // TODO: support other generators + default: + err("context.cpp: output format not yet supported"); + break; + } + g_globals.dynSectionId++; + } + return TemplateVariant(result.data(),TRUE); + } private: DirDef *m_dirDef; @@ -3184,6 +3269,7 @@ class DirContext::Private : public DefinitionContext Cachable() {} SharedPtr dirs; SharedPtr files; + ScopedPtr dirDepsGraph; }; mutable Cachable m_cache; }; @@ -4687,8 +4773,8 @@ class ModuleContext::Private : public DefinitionContext err("context.cpp: output format not yet supported"); break; } + g_globals.dynSectionId++; } - g_globals.dynSectionId++; return TemplateVariant(result.data(),TRUE); } TemplateVariant hasDetails() const diff --git a/src/dirdef.cpp b/src/dirdef.cpp index 067daa0a799..28c073ef704 100644 --- a/src/dirdef.cpp +++ b/src/dirdef.cpp @@ -385,7 +385,7 @@ void DirDef::writeDocumentation(OutputList &ol) ol.pushGeneratorState(); QCString title=theTranslator->trDirReference(m_dispName); - startFile(ol,getOutputFileBase(),name(),title,HLI_None,!generateTreeView); + startFile(ol,getOutputFileBase(),name(),title,HLI_Files,!generateTreeView); if (!generateTreeView) { @@ -610,7 +610,7 @@ bool DirDef::isParentOf(DirDef *dir) const bool DirDef::depGraphIsTrivial() const { - return FALSE; + return m_usedDirs->count()==0; } //---------------------------------------------------------------------- @@ -696,11 +696,6 @@ DirDef *DirDef::mergeDirectoryInTree(const QCString &path) return dir; } -void DirDef::writeDepGraph(FTextStream &t) -{ - writeDotDirDepGraph(t,this); -} - //---------------------------------------------------------------------- static void writePartialDirPath(OutputList &ol,const DirDef *root,const DirDef *target) diff --git a/src/dirdef.h b/src/dirdef.h index 1a87f5b8118..611ba3e83e3 100644 --- a/src/dirdef.h +++ b/src/dirdef.h @@ -71,7 +71,6 @@ class DirDef : public Definition // generate output void writeDocumentation(OutputList &ol); - void writeDepGraph(FTextStream &t); void writeTagFile(FTextStream &t); static DirDef *mergeDirectoryInTree(const QCString &path); diff --git a/src/dot.cpp b/src/dot.cpp index 705aa27075b..701f86866e5 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -3965,6 +3965,7 @@ bool DotCallGraph::isTooBig() const } //------------------------------------------------------------- +static void writeDotDirDepGraph(FTextStream &t,DirDef *dd,bool linkRelations); DotDirDeps::DotDirDeps(DirDef *dir) : m_dir(dir) { @@ -3981,7 +3982,8 @@ QCString DotDirDeps::writeGraph(FTextStream &out, const char *fileName, const char *relPath, bool generateImageMap, - int graphId) const + int graphId, + bool linkRelations) const { QDir d(path); // store the original directory @@ -4006,7 +4008,8 @@ QCString DotDirDeps::writeGraph(FTextStream &out, // compute md5 checksum of the graph were are about to generate QGString theGraph; FTextStream md5stream(&theGraph); - m_dir->writeDepGraph(md5stream); + //m_dir->writeDepGraph(md5stream); + writeDotDirDepGraph(md5stream,m_dir,linkRelations); uchar md5_sig[16]; QCString sigStr(33); MD5Buffer((const unsigned char *)theGraph.data(),theGraph.length(),md5_sig); @@ -4764,7 +4767,7 @@ void DotGroupCollaboration::writeGraphHeader(FTextStream &t, t << " rankdir=LR;\n"; } -void writeDotDirDepGraph(FTextStream &t,DirDef *dd) +void writeDotDirDepGraph(FTextStream &t,DirDef *dd,bool linkRelations) { t << "digraph \"" << dd->displayName() << "\" {\n"; if (Config_getBool("DOT_TRANSPARENT")) @@ -4896,11 +4899,14 @@ void writeDotDirDepGraph(FTextStream &t,DirDef *dd) new DirRelation(relationName,dir,udir)); } int nrefs = udir->filePairs().count(); - t << " " << dir->getOutputFileBase() << "->" + t << " " << dir->getOutputFileBase() << "->" << usedDir->getOutputFileBase(); t << " [headlabel=\"" << nrefs << "\", labeldistance=1.5"; - t << " headhref=\"" << relationName << Doxygen::htmlFileExtension - << "\"];\n"; + if (linkRelations) + { + t << " headhref=\"" << relationName << Doxygen::htmlFileExtension << "\""; + } + t << "];\n"; } } } diff --git a/src/dot.h b/src/dot.h index 3de7d796327..64d6dd4543c 100644 --- a/src/dot.h +++ b/src/dot.h @@ -262,7 +262,8 @@ class DotDirDeps const char *fileName, const char *relPath, bool writeImageMap=TRUE, - int graphId=-1) const; + int graphId=-1, + bool linkRelations=TRUE) const; private: DirDef *m_dir; }; @@ -459,6 +460,4 @@ void writeDotImageMapFromFile(FTextStream &t, const QCString& relPath,const QCString& baseName, const QCString& context,int graphId=-1); -void writeDotDirDepGraph(FTextStream &t,DirDef *dd); - #endif diff --git a/templates/html/htmldir.tpl b/templates/html/htmldir.tpl index 7417f7b9a3a..a39975911ff 100644 --- a/templates/html/htmldir.tpl +++ b/templates/html/htmldir.tpl @@ -45,7 +45,18 @@ {% endif %} {% endif %} {# dir graph #} -{# TODO #} + {% if compound.hasDirGraph %} + {% with obj=compound %} + {% include 'htmldynheader.tpl' %} + {% endwith %} + {{ tr.dirDependencyGraphFor:compound.dirName }} + + {% with obj=compound %} + {% include 'htmldyncontents.tpl' %} + {% endwith %} + {{ compound.dirGraph }} + + {% endif %} {# member declarations #} {# directories #} {% with list=compound.dirs label='subdirs' title=tr.directories local=False %}