34using DirDefMap = std::map<std::string,const DirDef *>;
55 operator DotDirProperty() {
return std::move(
m_property); }
61typedef std::vector< std::pair< std::unique_ptr<DirRelation>,
bool> >
DirRelations;
69 assert(depthIndex>=0 && depthIndex<=
Config_getInt(DIR_GRAPH_MAX_DEPTH));
70 float fraction =
static_cast<float>(depthIndex)/
static_cast<float>(
Config_getInt(DIR_GRAPH_MAX_DEPTH));
71 const char hex[] =
"0123456789abcdef";
73 int luma = 0xef-
static_cast<int>(fraction*
static_cast<float>(range));
76 pow(luma/255.0,gamma/100.0),&r,&g,&b);
77 int red =
static_cast<int>(r*255.0);
78 int green =
static_cast<int>(g*255.0);
79 int blue =
static_cast<int>(b*255.0);
80 assert(red>=0 && red<=255);
81 assert(green>=0 && green<=255);
82 assert(blue>=0 && blue<=255);
85 colStr[1]=
hex[red>>4];
86 colStr[2]=
hex[red&0xf];
87 colStr[3]=
hex[green>>4];
88 colStr[4]=
hex[green&0xf];
89 colStr[5]=
hex[blue>>4];
90 colStr[6]=
hex[blue&0xf];
121 std::string style =
"filled";
143 "URL=\"" << url <<
"\","
156 DirDefMap &directoriesInGraph,
int startLevel)
191 outputStream <<
"\", "
217 for (
const auto &usedDirectory : srcDir->
usedDirs())
219 const auto dstDir = usedDirectory->dir();
220 if (!dstDir->isParentOf(srcDir) && (isLeaf || usedDirectory->hasDirectSrcDeps()))
223 relationName.
sprintf(
"dir_%06d_%06d", srcDir->
dirIndex(), dstDir->dirIndex());
224 bool directRelation = isLeaf ? usedDirectory->hasDirectDstDeps() : usedDirectory->hasDirectDeps();
225 dependencies.emplace_back(
226 std::make_unique<DirRelation>(relationName, srcDir, usedDirectory.get()),
234 int startLevel,
DirDefMap &directoriesInGraph,
const bool isTreeRoot)
239 drawDirectory(t, directory, directoryProperty, directoriesInGraph,startLevel);
247 drawDirectory(t, directory, directoryProperty, directoriesInGraph,startLevel);
255 drawClusterOpening(t, directory, directoryProperty, directoriesInGraph,
false, startLevel);
260 for (
const auto subDirectory : directory->
subDirs())
262 drawTree(dependencies, t, subDirectory, startLevel, directoriesInGraph,
false);
293 std::vector<const DirDef *> usedDirsNotDrawn, usedDirsDrawn;
294 for (
const auto& usedDir : dd->
usedDirs())
296 usedDirsNotDrawn.push_back(usedDir->dir());
299 auto moveDrawnDirs = [&usedDirsDrawn,&usedDirsNotDrawn](
const std::vector<const DirDef *>::iterator &newEnd)
304 std::move(newEnd, std::end(usedDirsNotDrawn), std::back_inserter(usedDirsDrawn));
305 usedDirsNotDrawn.erase(newEnd, usedDirsNotDrawn.end());
314 makeOrphaned(
parent->parent()!=
nullptr);
319 const auto newEnd = std::stable_partition(usedDirsNotDrawn.begin(), usedDirsNotDrawn.end(),
320 [&](
const DirDef *
const usedDir)
322 if (dd!=usedDir && dd->parent()==usedDir->parent())
324 const DotDirProperty usedDirProperty = DotDirPropertyBuilder().makeTruncated(usedDir->hasSubdirs());
325 drawDirectory(t, usedDir, usedDirProperty, dirsInGraph, parent->level());
330 moveDrawnDirs(newEnd);
336 drawTree(dependencies, t, dd, dd->level(), dirsInGraph,
true);
345 const auto newEnd = std::stable_partition(usedDirsNotDrawn.begin(), usedDirsNotDrawn.end(),
346 [&](
const DirDef *
const usedDir)
348 const DirDef *dir=dd;
351 if (dir!=usedDir && dir->parent()==usedDir->parent())
353 const DotDirProperty usedDirProperty = DotDirPropertyBuilder().
354 makeOrphaned(usedDir->parent()!=nullptr).
355 makeTruncated(usedDir->hasSubdirs()).
357 drawDirectory(t, usedDir, usedDirProperty, dirsInGraph, dir->level());
364 moveDrawnDirs(newEnd);
369 for (
const auto &relationPair : dependencies)
371 const auto &relation = relationPair.first;
372 const bool directRelation = relationPair.second;
373 const auto udir = relation->destination();
374 const auto usedDir = udir->dir();
375 const bool destIsSibling = std::find(std::begin(usedDirsDrawn), std::end(usedDirsDrawn), usedDir) != std::end(usedDirsDrawn);
376 const bool destIsDrawn = dirsInGraph.find(usedDir->getOutputFileBase().str())!=dirsInGraph.end();
377 const bool atMaxDepth =
isAtMaxDepth(usedDir, dd->level());
379 if (destIsSibling || (destIsDrawn && (directRelation || atMaxDepth)))
381 const auto relationName = relation->getOutputFileBase();
382 const auto dir = relation->source();
384 std::make_unique<DirRelation>(
385 relationName,dir,udir));
386 size_t nrefs = udir->filePairs().size();
387 t <<
" " << dir->getOutputFileBase() <<
"->"
388 << usedDir->getOutputFileBase();
389 t <<
" [headlabel=\"" << nrefs <<
"\", labeldistance=1.5";
394 t <<
" headhref=\"" << fn <<
"\"";
395 t <<
" href=\"" << fn <<
"\"";
397 t <<
" color=\"steelblue1\" fontcolor=\"steelblue1\"];\n";
413 return m_dir->getOutputFileBase()+
"_dep";
420 TextStream md5stream;
422 md5stream <<
" compound=true\n";
440 int graphId,
bool linkRelations)
444 return DotGraph::writeGraph(out, graphFormat, textFormat, path, fileName, relPath, generateImageMap, graphId);
449 return m_dir->depGraphIsTrivial();
static void hsl2rgb(double h, double s, double l, double *pRed, double *pGreen, double *pBlue)
virtual QCString briefDescriptionAsTooltip() const =0
virtual QCString getOutputFileBase() const =0
A model of a directory symbol.
virtual int level() const =0
virtual int dirIndex() const =0
virtual DirDef * parent() const =0
virtual const QCString shortName() const =0
virtual const DirList & subDirs() const =0
virtual const UsedDirLinkedMap & usedDirs() const =0
virtual bool hasSubdirs() const =0
QCString getImgAltText() const override
QCString getMapLabel() const override
QCString writeGraph(TextStream &out, GraphOutputFormat gf, EmbeddedOutputFormat ef, const QCString &path, const QCString &fileName, const QCString &relPath, bool writeImageMap=TRUE, int graphId=-1, bool linkRelations=TRUE)
void computeTheGraph() override
DotDirDeps(const DirDef *dir)
QCString getBaseName() const override
Builder helper to create instances of the DotDirProperty struct.
DotDirPropertyBuilder & makeOriginal(bool b=true)
DotDirProperty m_property
DotDirPropertyBuilder & makePeripheral(bool b=true)
DotDirPropertyBuilder & makeOrphaned(bool b=true)
DotDirPropertyBuilder & makeIncomplete(bool b=true)
DotDirPropertyBuilder & makeTruncated(bool b=true)
static void writeGraphFooter(TextStream &t)
static void writeGraphHeader(TextStream &t, const QCString &title=QCString())
QCString writeGraph(TextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const QCString &path, const QCString &fileName, const QCString &relPath, bool writeImageMap=TRUE, int graphId=-1)
static QCString convertLabel(const QCString &, bool htmlLike=false)
static DirRelationLinkedMap dirRelations
This is an alternative implementation of QCString.
const std::string & str() const
QCString & sprintf(const char *format,...)
Text streaming class that buffers data.
std::string str() const
Return the contents of the buffer as a std::string object.
#define Config_getInt(name)
#define Config_getString(name)
static constexpr auto hex
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
std::vector< std::pair< std::unique_ptr< DirRelation >, bool > > DirRelations
Elements consist of (1) directory relation and (2) whether it is pointing only to inherited dependees...
static TextStream & common_attributes(TextStream &t, const DirDef *const dir, const DotDirProperty &prop)
static bool isAtMaxDepth(const DirDef *const directory, const int startLevel)
Checks, if the directory is a the maximum drawn directory level.
static void drawClusterClosing(TextStream &t)
static void addDependencies(DirRelations &dependencies, const DirDef *const srcDir, bool isLeaf)
Assembles a list of the directory relations and whether or not they result from "inheritance".
static QCString getDirectoryBackgroundColor(int depthIndex)
Returns a DOT color name according to the directory depth.
static std::string getDirectoryBorderStyle(const DotDirProperty &property)
Returns a DOT node style according to the directory properties.
static void drawDirectory(TextStream &t, const DirDef *const directory, const DotDirProperty &property, DirDefMap &directoriesInGraph, int startLevel)
Puts DOT code for drawing directory to stream and adds it to the list.
static void drawClusterOpening(TextStream &outputStream, const DirDef *const directory, const DotDirProperty &directoryProperty, DirDefMap &directoriesInGraph, const bool isAncestor, int startLevel)
Writes DOT code for opening a cluster subgraph to stream.
std::map< std::string, const DirDef * > DirDefMap
static void drawTree(DirRelations &dependencies, TextStream &t, const DirDef *const directory, int startLevel, DirDefMap &directoriesInGraph, const bool isTreeRoot)
Recursively draws directory tree.
void writeDotDirDepGraph(TextStream &t, const DirDef *dd, bool linkRelations)
Write DOT code for directory dependency graph.
static const char * getDirectoryBorderColor(const DotDirProperty &property)
Returns a DOT color name according to the directory properties.
QCString escapeTooltip(const QCString &tooltip)
Properties are used to format the directories in the graph distinctively.
bool isTruncated
true has successors, none is drawn
bool isOrphaned
true if parent is not drawn
bool isOriginal
true if is the directory for which the graph is drawn
bool isPeripheral
true if no successor of parent of original directory
bool isIncomplete
true if not all successors of a cluster are drawn
QCString escapeCharsInString(const QCString &name, bool allowDots, bool allowUnderscore)
QCString convertToXML(const QCString &s, bool keepEntities)
void addHtmlExtensionIfMissing(QCString &fName)
A bunch of utility functions.