51 #define MAP_CMD "cmapx" 54 #define FONTNAME getDotFontName() 55 #define FONTSIZE getDotFontSize() 60 "<svg id=\"main\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:space=\"preserve\" onload=\"init(evt)\">\n" 61 "<style type=\"text/css\"><![CDATA[\n" 62 ".edge:hover path { stroke: red; }\n" 63 ".edge:hover polygon { stroke: red; fill: red; }\n" 65 "<script type=\"text/javascript\"><![CDATA[\n" 66 "var edges = document.getElementsByTagName('g');\n" 67 "if (edges && edges.length) {\n" 68 " for (var i=0;i<edges.length;i++) {\n" 69 " if (edges[i].id.substr(0,4)=='edge') {\n" 70 " edges[i].setAttribute('class','edge');\n" 76 " <circle id=\"rim\" cx=\"0\" cy=\"0\" r=\"7\"/>\n" 77 " <circle id=\"rim2\" cx=\"0\" cy=\"0\" r=\"3.5\"/>\n" 78 " <g id=\"zoomPlus\">\n" 79 " <use xlink:href=\"#rim\" fill=\"#404040\">\n" 80 " <set attributeName=\"fill\" to=\"#808080\" begin=\"zoomplus.mouseover\" end=\"zoomplus.mouseout\"/>\n" 82 " <path d=\"M-4,0h8M0,-4v8\" fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" pointer-events=\"none\"/>\n" 84 " <g id=\"zoomMin\">\n" 85 " <use xlink:href=\"#rim\" fill=\"#404040\">\n" 86 " <set attributeName=\"fill\" to=\"#808080\" begin=\"zoomminus.mouseover\" end=\"zoomminus.mouseout\"/>\n" 88 " <path d=\"M-4,0h8\" fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" pointer-events=\"none\"/>\n" 90 " <g id=\"dirArrow\">\n" 91 " <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" 93 " <g id=\"resetDef\">\n" 94 " <use xlink:href=\"#rim2\" fill=\"#404040\">\n" 95 " <set attributeName=\"fill\" to=\"#808080\" begin=\"reset.mouseover\" end=\"reset.mouseout\"/>\n" 100 "<script type=\"text/javascript\">\n" 105 " <g id=\"navigator\" transform=\"translate(0 0)\" fill=\"#404254\">\n" 106 " <rect fill=\"#f2f5e9\" fill-opacity=\"0.5\" stroke=\"#606060\" stroke-width=\".5\" x=\"0\" y=\"0\" width=\"60\" height=\"60\"/>\n" 108 " <use id=\"zoomplus\" xlink:href=\"#zoomPlus\" x=\"17\" y=\"9\" onmousedown=\"handleZoom(evt,'in')\"/>\n" 110 " <use id=\"zoomminus\" xlink:href=\"#zoomMin\" x=\"42\" y=\"9\" onmousedown=\"handleZoom(evt,'out')\"/>\n" 112 " <use id=\"reset\" xlink:href=\"#resetDef\" x=\"30\" y=\"36\" onmousedown=\"handleReset()\"/>\n" 114 " <g id=\"arrowUp\" xlink:href=\"#dirArrow\" transform=\"translate(30 24)\" onmousedown=\"handlePan(0,-1)\">\n" 115 " <use xlink:href=\"#rim\" fill=\"#404040\">\n" 116 " <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowUp.mouseover\" end=\"arrowUp.mouseout\"/>\n" 118 " <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" 121 " <g id=\"arrowRight\" xlink:href=\"#dirArrow\" transform=\"rotate(90) translate(36 -43)\" onmousedown=\"handlePan(1,0)\">\n" 122 " <use xlink:href=\"#rim\" fill=\"#404040\">\n" 123 " <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowRight.mouseover\" end=\"arrowRight.mouseout\"/>\n" 125 " <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" 128 " <g id=\"arrowDown\" xlink:href=\"#dirArrow\" transform=\"rotate(180) translate(-30 -48)\" onmousedown=\"handlePan(0,1)\">\n" 129 " <use xlink:href=\"#rim\" fill=\"#404040\">\n" 130 " <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowDown.mouseover\" end=\"arrowDown.mouseout\"/>\n" 132 " <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" 135 " <g id=\"arrowLeft\" xlink:href=\"#dirArrow\" transform=\"rotate(270) translate(-36 17)\" onmousedown=\"handlePan(-1,0)\">\n" 136 " <use xlink:href=\"#rim\" fill=\"#404040\">\n" 137 " <set attributeName=\"fill\" to=\"#808080\" begin=\"arrowLeft.mouseover\" end=\"arrowLeft.mouseout\"/>\n" 139 " <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n" 143 " <svg viewBox=\"0 0 15 15\" width=\"100%\" height=\"30px\" preserveAspectRatio=\"xMaxYMin meet\">\n" 144 " <g id=\"arrow_out\" transform=\"scale(0.3 0.3)\">\n" 145 " <a xlink:href=\"$orgname\" target=\"_base\">\n" 146 " <rect id=\"button\" ry=\"5\" rx=\"5\" y=\"6\" x=\"6\" height=\"38\" width=\"38\"\n" 147 " fill=\"#f2f5e9\" fill-opacity=\"0.5\" stroke=\"#606060\" stroke-width=\"1.0\"/>\n" 148 " <path id=\"arrow\"\n" 149 " d=\"M 11.500037,31.436501 C 11.940474,20.09759 22.043105,11.32322 32.158766,21.979434 L 37.068811,17.246167 C 37.068811,17.246167 37.088388,32 37.088388,32 L 22.160133,31.978069 C 22.160133,31.978069 26.997745,27.140456 26.997745,27.140456 C 18.528582,18.264221 13.291696,25.230495 11.500037,31.436501 z\"\n" 150 " style=\"fill:#404040;\"/>\n" 239 dotFontName=
"Helvetica";
247 if (dotFontSize<4) dotFontSize=4;
257 t <<
"\"Dot Graph\"";
267 t <<
" // INTERACTIVE_SVG=YES\n";
271 t <<
" bgcolor=\"transparent\";" <<
endl;
273 t <<
" edge [fontname=\"" <<
FONTNAME <<
"\"," 275 "labelfontname=\"" <<
FONTNAME <<
"\"," 276 "labelfontsize=\"" <<
FONTSIZE <<
"\"];\n";
277 t <<
" node [fontname=\"" <<
FONTNAME <<
"\"," 278 "fontsize=\"" << FONTSIZE <<
"\",shape=record];\n";
293 int indexS = buf.
find(
"href=\""), indexE;
294 if (indexS>5 && buf.
find(
"xlink:href=\"")!=-1)
301 if (indexS>=0 && (indexE=buf.
find(
'"',indexS+len))!=-1)
303 QCString link = buf.
mid(indexS+len,indexE-indexS-len);
307 if (link.
left(5)==
"\\ref " || link.
left(5)==
"@ref ")
316 result +=
"#" + df->
anchor();
322 result = href+
"=\"" + link +
"\"";
327 int marker = link.
find(
'$');
342 result = href+
"=\"" + link +
"\"";
347 result+=
" target=\""+
target+
"\"";
351 return leftPart + result + rightPart;
377 err(
"problems opening map file %s for inclusion in the docs!\n" 378 "If you installed Graphviz/dot after a previous failing run, \n" 379 "try deleting the output directory and rerun doxygen.\n",mapName);
382 const int maxLineLen=10240;
391 if (buf.
left(5)==
"<area")
411 int s = s_newNumber.
size();
418 ns = number * 3 / 2 + 5;
421 for (
int i=s;i<
ns;i++)
426 int i = s_newNumber.
at(number);
430 s_newNumber.
at(number) = i;
439 s_newNumber.
resize(s_max_newNumber);
481 QCString bb = isEps ?
QCString(
"%%PageBoundingBox:") : QCString(
"/MediaBox [");
488 const int maxLineLen=1024;
489 char buf[maxLineLen];
492 int numBytes = f.
readLine(buf,maxLineLen-1);
496 const char *
p = strstr(buf,bb);
500 if (sscanf(p+bb.
length(),
"%d %d %d %d",&
x,&
y,width,height)!=4)
514 err(
"Failed to extract bounding box from generated diagram file %s\n",fileName);
521 int width=400,height=550;
542 out <<
"\\nopagebreak\n" 543 "\\begin{figure}[H]\n" 546 if (width>maxWidth || height>maxHeight)
549 if (width*maxHeight>height*maxWidth)
551 out <<
"\\includegraphics[width=" << maxWidth <<
"pt]";
555 out <<
"\\includegraphics[height=" << maxHeight <<
"pt]";
560 out <<
"\\includegraphics[width=" << width <<
"pt]";
563 out <<
"{" << baseName <<
"}\n" 580 const int maxLineLen=4096;
581 char buf[maxLineLen];
584 int numBytes = f.
readLine(buf,maxLineLen-1);
588 if (
qstrncmp(buf,
"<!--zoomable ",13)==0)
592 sscanf(buf,
"<!--zoomable %d",height);
596 else if (sscanf(buf,
"<svg width=\"%dpt\" height=\"%dpt\"",width,height)==2)
613 out <<
"<p><b>This browser is not able to show SVG: try Firefox, Chrome, Safari, or Opera instead.</b></p>";
621 int width=600,height=600;
632 if (height>600) height=600;
633 out <<
"<div class=\"zoom\">";
636 out <<
"<iframe scrolling=\"no\" frameborder=\"0\" src=\"" 637 << relPath << baseName <<
".svg\" width=\"100%\" height=\"" << height <<
"\">";
643 out <<
"<iframe scrolling=\"no\" frameborder=\"0\" src=\"" 644 << relPath << baseName <<
".svg\" width=\"" 645 << ((width*96+48)/72) <<
"\" height=\"" 646 << ((height*96+48)/72) <<
"\">";
670 if (fread(data,1,4,f)==4)
672 if (!(data[1]==
'P' && data[2]==
'N' && data[3]==
'G'))
674 err(
"Image `%s' produced by dot is not a valid PNG!\n" 675 "You should either select a different format " 676 "(DOT_IMAGE_FORMAT in the config file) or install a more " 677 "recent version of graphviz (1.7+)\n",imgName
683 err(
"Could not read image `%s' generated by dot!\n",imgName);
689 err(
"Could not open image `%s' generated by dot!\n",imgName);
705 out <<
"<map name=\"" << mapLabel <<
"\" id=\"" << mapLabel <<
"\">" <<
endl;
707 out <<
"</map>" <<
endl;
742 if (bytesRead==32 && md5==md5stored)
768 if (!file2.isEmpty())
773 return file1Ok && file2Ok;
780 if ( !m_parents )
return -1;
781 return m_parents->find(n);
794 bool checkResult,
const QCString &imageName)
796 m_file(file), m_path(path),
797 m_checkResult(checkResult), m_imageName(imageName),
801 static bool dotMultiTargets =
Config_getBool(
"DOT_MULTI_TARGETS");
852 err(
"Problems running '%s' as a post-processing step for dot output\n",
m_postCmd.
data());
868 err(
"Problems running dot: exit code=%d, command='%s', arguments='%s'\n",
876 : m_patchFile(patchFile)
903 const QCString &figureName,
bool heightCheck)
917 const QCString &context,
bool zoomable,
956 interactiveSVG = interactiveSVG && map->
zoomable;
973 err(
"problem opening file %s for patching!\n",tmpName.
data());
984 const int maxLineLen=100*1024;
987 bool insideHeader=
FALSE;
988 bool replacedHeader=
FALSE;
989 bool foundSize=
FALSE;
1002 ASSERT(numBytes<maxLineLen);
1007 if (line.
find(
"<svg")!=-1 && !replacedHeader)
1010 count = sscanf(line.
data(),
"<svg width=\"%dpt\" height=\"%dpt\"",&width,&height);
1012 foundSize = count==2 && (width>500 || height>450);
1013 if (foundSize) insideHeader=
TRUE;
1015 else if (insideHeader && !replacedHeader && line.
find(
"<title>")!=-1)
1020 t <<
"<!--zoomable " << height <<
" -->\n";
1022 t <<
"var viewWidth = " << width <<
";\n";
1023 t <<
"var viewHeight = " << height <<
";\n";
1026 t <<
"var sectionId = 'dynsection-" << graphId <<
"';\n";
1029 t <<
"<script xlink:href=\"" << relPath <<
"svgpan.js\"/>\n";
1030 t <<
"<svg id=\"graph\" class=\"graph\">\n";
1031 t <<
"<g id=\"viewport\">\n";
1034 replacedHeader=
TRUE;
1037 if (!insideHeader || !foundSize)
1045 else if ((i=line.
find(
"<!-- SVG"))!=-1 || (i=line.
find(
"[!-- SVG"))!=-1)
1050 int n = sscanf(line.
data()+i+1,
"!-- SVG %d",&mapId);
1051 if (n==1 && mapId>=0 && mapId<(
int)
m_maps.count())
1059 err(
"Problem extracting size from SVG file %s\n",map->mapFile.data());
1061 if (e!=-1) t << line.
mid(e+3);
1069 else if ((i=line.
find(
"<!-- MAP"))!=-1)
1073 int n = sscanf(line.
data()+i,
"<!-- MAP %d",&mapId);
1074 if (n==1 && mapId>=0 && mapId<(
int)
m_maps.count())
1079 t <<
"<map name=\"" << map->
label <<
"\" id=\"" << map->
label <<
"\">" <<
endl;
1081 t <<
"</map>" <<
endl;
1089 else if ((i=line.
find(
"% FIG"))!=-1)
1092 int n = sscanf(line.
data()+i+2,
"FIG %d",&mapId);
1094 if (n==1 && mapId>=0 && mapId<(
int)
m_maps.count())
1101 err(
"problem writing FIG %d figure!\n",mapId);
1118 if (isSVGFile && interactiveSVG && replacedHeader)
1129 err(
"problem opening file %s for reading!\n",tmpName.
data());
1134 err(
"problem opening file %s for writing!\n",orgName.
data());
1163 m_queue.enqueue(runner);
1164 m_bufferNotEmpty.wakeAll();
1170 while (m_queue.isEmpty())
1173 m_bufferNotEmpty.wait(&m_mutex);
1182 return m_queue.count();
1227 return m_theInstance;
1240 for (i=0;i<numThreads;i++)
1277 return map->
addMap(mapFile,relPath,urlOnly,context,label);
1281 const QCString &figureName,
bool heightCheck)
1289 return map->
addFigure(baseName,figureName,heightCheck);
1293 bool urlOnly,
const QCString &context,
bool zoomable,
1321 if (numDotRuns+numDotMaps>1)
1325 msg(
"Generating dot graphs in single threaded mode...\n");
1329 msg(
"Generating dot graphs using %d parallel threads...\n",
QMIN(numDotRuns+numDotMaps,
m_workers.
count()));
1359 msg(
"Running dot for graph %d/%d\n",prev,numDotRuns);
1376 msg(
"Running dot for graph %d/%d\n",prev,numDotRuns);
1381 while ((
int)numDotRuns>=prev)
1383 msg(
"Running dot for graph %d/%d\n",prev,numDotRuns);
1416 for (di.toFirst();(map=di.current());++di)
1420 msg(
"Patching output file %d/%d\n",i,numDotMaps);
1425 for (di.toFirst();(map=di.current());++di)
1429 msg(
"Patching output file %d/%d\n",i,numDotMaps);
1449 deletedNodes.
clear();
1483 const char *edgeLab,
1484 const char *edgeURL,
1499 ei->
m_url = edgeURL;
1552 if (skipNodes==0 || skipNodes->
find((
char*)
this)==0)
1555 deletedList.
append(
this);
1567 QCString bBefore(
"\\_/<({[: =-+@%#~?$");
1569 const char *
p=l.
data();
1583 case '\\': replacement=
"\\\\";
break;
1584 case '\n': replacement=
"\\n";
break;
1585 case '<': replacement=
"\\<";
break;
1586 case '>': replacement=
"\\>";
break;
1587 case '|': replacement=
"\\|";
break;
1588 case '{': replacement=
"\\{";
break;
1589 case '}': replacement=
"\\}";
break;
1590 case '"': replacement=
"\\\"";
break;
1591 default: cs[0]=
c; replacement=
cs;
break;
1597 result+=replacement;
1598 foldLen = (3*foldLen+sinceLast+2)/4;
1601 else if ((pc!=
':' || c!=
':') && charsLeft>foldLen/3 && sinceLast>foldLen && bBefore.
contains(c))
1604 result+=replacement;
1605 foldLen = (foldLen+sinceLast+1)/2;
1608 else if (charsLeft>1+foldLen/4 && sinceLast>foldLen+foldLen/3 &&
1609 !isupper(c) && isupper(*p))
1611 result+=replacement;
1613 foldLen = (foldLen+sinceLast+1)/2;
1616 else if (charsLeft>foldLen/3 && sinceLast>foldLen && bAfter.
contains(c) && (c!=
':' || *p!=
':'))
1618 result+=replacement;
1620 foldLen = (foldLen+sinceLast+1)/2;
1625 result+=replacement;
1637 const char *
p=tooltip.
data();
1644 case '"': result+=
"\\\"";
break;
1645 default: result+=
c;
break;
1653 bool isStatic=
FALSE,
const QDict<void> *skipNames=0)
1664 (skipNames==0 || skipNames->find(mma->
name())==0))
1674 (skipNames==0 || skipNames->find(mma->
name())==0))
1677 if (limit>0 && (totalCount>limit*3/2 && count>=limit))
1712 if (!s.
isEmpty() && (s[0]==
'-' || s[0]==
'+' || s[0]==
'~' || s[0]==
'#'))
1725 bool hasNonReachableChildren,
1728 const char *labCol =
1731 (hasNonReachableChildren) ?
"red" :
"black" 1740 QDict<void> arrowNames(17);
1756 arrowNames.
insert(lab,(
void*)0x8);
1760 arrowNames.insert(lab,(
void*)0x8);
1801 for (mgdi.toFirst();(mg=mgdi.current());++mgdi)
1815 t <<
"\",height=0.2,width=0.4";
1818 t <<
",color=\"black\", fillcolor=\"grey75\", style=\"filled\", fontcolor=\"black\"";
1823 if (!dotTransparent)
1825 t <<
",color=\"" << labCol <<
"\", fillcolor=\"";
1827 t <<
"\", style=\"filled\"";
1831 t <<
",color=\"" << labCol <<
"\"";
1879 bool umlUseArrow = aStyle==
"odiamond";
1881 if (pointBack && !umlUseArrow) t <<
"dir=\"back\",";
1883 <<
"\",fontsize=\"" <<
FONTSIZE <<
"\",";
1894 bool rev = pointBack;
1895 if (umlUseArrow) rev=!rev;
1935 cn->
write(t,gt,format,topDown,toChildren,backArrows,reNumber);
1971 const char *refPtr = url.
data();
1972 char *urlPtr = strchr(url.
rawData(),
'$');
1976 t <<
" <link refid=\"" <<
convertToXML(urlPtr) <<
"\"";
1990 for (;(childNode=nli.
current());++nli,++eli)
1993 t <<
" <childnode refid=\"" << childNode->
m_number <<
"\" relation=\"";
2020 <<
"</edgelabel>" << endl;
2025 <<
"</edgelabel>" <<
endl;
2027 t <<
" </childnode>" <<
endl;
2030 t <<
" </node>" <<
endl;
2040 const char *refPtr = url.
data();
2041 char *urlPtr = strchr(url.
rawData(),
'$');
2045 t <<
" <link refid=\"" <<
convertToXML(urlPtr) <<
"\"";
2059 for (;(childNode=nli.
current());++nli,++eli)
2062 t <<
" <childnode refid=\"" << childNode->
m_number <<
"\" relation=\"";
2089 <<
"</edgelabel>" << endl;
2094 <<
"</edgelabel>" <<
endl;
2096 t <<
" </childnode>" <<
endl;
2099 t <<
" </node>" <<
endl;
2105 const char* nodePrefix =
" node-";
2107 t <<
" node = {" <<
endl;
2109 t << nodePrefix <<
"label = '" <<
m_label <<
"';" <<
endl;
2114 const char *refPtr = url.
data();
2115 char *urlPtr = strchr(url.
rawData(),
'$');
2119 t << nodePrefix <<
"link = {" << endl <<
" " 2120 << nodePrefix <<
"link-id = '" << urlPtr <<
"';" <<
endl;
2124 t <<
" " << nodePrefix <<
"link-external = '" 2125 << refPtr <<
"';" <<
endl;
2136 for (;(childNode=nli.
current());++nli,++eli)
2139 t <<
" node-child = {" <<
endl;
2140 t <<
" child-id = '" << childNode->
m_number <<
"';" <<
endl;
2141 t <<
" relation = ";
2157 t <<
" edgelabel = <<_EnD_oF_dEf_TeXt_" << endl
2159 <<
"_EnD_oF_dEf_TeXt_;" <<
endl;
2161 t <<
" }; /* node-child */" <<
endl;
2164 t <<
" }; /* node */" <<
endl;
2272 const char *path,
const char *
fileName,
int id)
const 2278 baseName.
sprintf(
"inherit_graph_%d",
id);
2279 QCString imgName = baseName+
"."+ imgExt;
2280 QCString mapName = baseName+
".map";
2291 md5stream <<
" rankdir=\"LR\";" <<
endl;
2292 for (dnli2.toFirst();(node=dnli2.current());++dnli2)
2299 for (dnli2.toFirst();(node=dnli2.current());++dnli2)
2312 bool regenerate=
FALSE;
2318 QCString dotName=absBaseName+
".dot";
2327 dotRun->
addJob(imgFmt,absImgName);
2349 out <<
"<!-- SVG " << mapId <<
" -->" <<
endl;
2354 out <<
"<img src=\"" << imgName <<
"\" border=\"0\" alt=\"\" usemap=\"#" 2355 << mapLabel <<
"\"/>" <<
endl;
2361 out <<
"<!-- MAP " << mapId <<
" -->" <<
endl;
2367 const char *path,
const char *
fileName)
const 2372 if (m_rootSubgraphs->count()==0)
return;
2378 err(
"Output dir %s does not exist!\n",path); exit(1);
2382 out <<
"<table border=\"0\" cellspacing=\"10\" cellpadding=\"0\">" <<
endl;
2390 createGraph(n,out,path,fileName,count++);
2391 out <<
"</td></tr>" <<
endl;
2393 out <<
"</table>" <<
endl;
2403 for ( ; (bcd=bcli.current()) ; ++bcli )
2412 if ((bn=m_usedNodes->find(bClass->
name())))
2438 tmp_url+=
"#"+bClass->
anchor();
2442 bn =
new DotNode(m_curNodeNumber++,
2456 m_usedNodes->insert(bClass->
name(),bn);
2460 bool wasVisited=bClass->
visited;
2462 addHierarchy(bn,bClass,wasVisited);
2474 for (cli.toLast();(cd=cli.current());--
cli)
2493 tmp_url+=
"#"+cd->
anchor();
2504 m_usedNodes->insert(cd->
name(),
n);
2505 m_rootNodes->insert(0,n);
2508 addHierarchy(n,cd,cd->
visited);
2519 m_usedNodes =
new QDict<DotNode>(1009);
2551 m_rootSubgraphs->inSort(dn);
2553 m_rootSubgraphs->inSort(n);
2583 delete m_rootSubgraphs;
2591 const char *
label,
const char *usedName,
const char *templSpec,
bool base,
int distance)
2599 className=
"anonymous:";
2616 DotNode *bn = m_usedNodes->find(className);
2621 n->
addChild(bn,prot,edgeStyle,label);
2626 bn->
addChild(n,prot,edgeStyle,label);
2642 tmp_url+=
"#"+cd->
anchor();
2646 bn =
new DotNode(m_curNodeNumber++,
2655 n->
addChild(bn,prot,edgeStyle,label);
2660 bn->
addChild(n,prot,edgeStyle,label);
2664 m_usedNodes->insert(className,bn);
2668 buildGraph(cd,bn,base,distance+1);
2674 while (queue.
count()>0)
2679 bool truncated =
FALSE;
2710 int maxNodes,
bool includeParents)
2716 childQueue.
append(rootNode);
2717 if (includeParents) parentQueue.
append(rootNode);
2718 bool firstNode=
TRUE;
2720 while ((childQueue.
count()>0 || parentQueue.
count()>0) && maxNodes>0)
2722 static int maxDistance =
Config_getInt(
"MAX_DOT_GRAPH_DEPTH");
2723 if (childQueue.
count()>0)
2727 if (!n->
isVisible() && distance<=maxDistance)
2731 int oldSize=(
int)childTreeWidth.
size();
2732 if (distance>oldSize)
2735 int i;
for (i=oldSize;i<
distance;i++) childTreeWidth[i]=0;
2753 if (includeParents && parentQueue.
count()>0)
2762 int oldSize = (
int)parentTreeWidth.
size();
2763 if (distance>oldSize)
2766 int i;
for (i=oldSize;i<
distance;i++) parentTreeWidth[i]=0;
2787 int maxHeight=(
int)
QMAX(childTreeWidth.
size(),parentTreeWidth.
size());
2789 for (i=0;i<childTreeWidth.
size();i++)
2791 if (childTreeWidth.
at(i)>maxWidth) maxWidth=childTreeWidth.
at(i);
2793 for (i=0;i<parentTreeWidth.
size();i++)
2795 if (parentTreeWidth.
at(i)>maxWidth) maxWidth=parentTreeWidth.
at(i);
2798 return maxWidth>80 && maxHeight<12;
2806 static bool templateRelations =
Config_getBool(
"TEMPLATE_RELATIONS");
2818 for ( ; (bcd=bcli.
current()) ; ++bcli )
2839 for (;(ucd=ucdi.current());++ucdi)
2842 QDictIterator<void> dvi(*ucd->
accessors);
2847 for (;(s=dvi.currentKey()) && count<maxLabels;++dvi,++
count)
2859 if (count==maxLabels) label+=
"\n...";
2866 if (templateRelations && base)
2873 for (;(ccd=ccdi.current());++ccdi)
2876 QDictIterator<void> dvi(*ccd->
accessors);
2881 for (;(s=dvi.currentKey()) && count<maxLabels;++dvi,++
count)
2893 if (count==maxLabels) label+=
"\n...";
2903 if (templateRelations)
2912 for (;(templInstance=
cli.current());++
cli)
2914 if (templInstance==cd)
2927 QDictIterator<ClassDef>
cli(*templInstances);
2929 for (;(templInstance=cli.current());++
cli)
2949 tmp_url+=
"#"+cd->
anchor();
2954 m_startNode =
new DotNode(m_curNodeNumber++,
2961 m_startNode->setDistance(0);
2962 m_usedNodes =
new QDict<DotNode>(1009);
2963 m_usedNodes->insert(className,m_startNode);
2968 buildGraph(cd,m_startNode,
TRUE,1);
2982 openNodeQueue.
append(m_startNode);
2992 return m_startNode->m_children==0 && m_startNode->m_parents==0;
2994 return !umlLook && m_startNode->m_children==0;
3001 numNodes+= m_startNode->m_children ? m_startNode->m_children->count() : 0;
3004 numNodes+= m_startNode->m_parents ? m_startNode->m_parents->count() : 0;
3006 return numNodes>=maxNodes;
3036 md5stream <<
" rankdir=\"LR\";" <<
endl;
3039 root->
write(md5stream,
3064 pn->
write(md5stream,
3083 graphStr=buf.
data();
3101 root,gt,format,lrRank,renderParents,
3102 backArrows,
title,theGraph);
3103 QFile f(baseName+
".dot");
3115 switch (m_graphType)
3118 result+=
"_coll_graph";
3124 result+=
"_inherit_graph";
3138 const char *relPath,
3140 bool generateImageMap,
3147 err(
"Output dir %s does not exist!\n",path); exit(1);
3153 switch (m_graphType)
3162 mapName=
"inherit_map";
3174 QCString absDotName = absBaseName+
".dot";
3175 QCString absMapName = absBaseName+
".map";
3176 QCString absPdfName = absBaseName+
".pdf";
3177 QCString absEpsName = absBaseName+
".eps";
3178 QCString absImgName = absBaseName+
"."+imgExt;
3180 bool regenerate =
FALSE;
3188 m_startNode->label()
3191 usePDFLatex ? absPdfName : absEpsName,
3200 dotRun->
addJob(imgFmt,absImgName);
3205 else if (graphFormat==
GOF_EPS)
3210 dotRun->
addJob(
"pdf",absPdfName);
3214 dotRun->
addJob(
"ps",absEpsName);
3223 out <<
"<para>" <<
endl;
3224 out <<
" <figure>" <<
endl;
3226 switch (m_graphType)
3229 out <<
"Collaboration graph";
3232 out <<
"Inheritance graph";
3238 out <<
"</title>" <<
endl;
3239 out <<
" <mediaobject>" <<
endl;
3240 out <<
" <imageobject>" <<
endl;
3241 out <<
" <imagedata";
3242 out <<
" width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName <<
"." << imgExt <<
"\">";
3243 out <<
"</imagedata>" <<
endl;
3244 out <<
" </imageobject>" <<
endl;
3245 out <<
" </mediaobject>" <<
endl;
3246 out <<
" </figure>" <<
endl;
3247 out <<
"</para>" <<
endl;
3249 else if (graphFormat==
GOF_BITMAP && generateImageMap)
3255 out <<
"<div class=\"center\">";
3263 out <<
"<!-- SVG " << mapId <<
" -->" <<
endl;
3265 out <<
"</div>" <<
endl;
3269 out <<
"<div class=\"center\">";
3270 out <<
"<img src=\"" << relPath << baseName <<
"." 3271 << imgExt <<
"\" border=\"0\" usemap=\"#" 3272 << mapLabel <<
"\" alt=\"";
3273 switch (m_graphType)
3276 out <<
"Collaboration graph";
3279 out <<
"Inheritance graph";
3286 out <<
"</div>" <<
endl;
3287 if (regenerate || !
insertMapFile(out,absMapName,relPath,mapLabel))
3291 out <<
"<!-- MAP " << mapId <<
" -->" <<
endl;
3295 else if (graphFormat==
GOF_EPS)
3300 out <<
endl <<
"% FIG " << figId <<
endl;
3312 QDictIterator<DotNode> dni(*m_usedNodes);
3314 for (;(node=dni.current());++dni)
3322 QDictIterator<DotNode> dni(*m_usedNodes);
3324 for (;(node=dni.current());++dni)
3332 QDictIterator<DotNode> dni(*m_usedNodes);
3334 for (;(node=dni.current());++dni)
3352 for (;(ii=ili.
current());++ili)
3372 DotNode *bn = m_usedNodes->find(in);
3398 m_usedNodes->insert(in,bn);
3401 if (bfd) buildGraph(bn,bfd,distance+1);
3410 while (queue.
count()>0 && maxNodes>0)
3412 static int maxDistance =
Config_getInt(
"MAX_DOT_GRAPH_DEPTH");
3434 while (queue.
count()>0)
3439 bool truncated =
FALSE;
3460 m_inverse = inverse;
3464 m_startNode =
new DotNode(m_curNodeNumber++,
3470 m_startNode->setDistance(0);
3471 m_usedNodes =
new QDict<DotNode>(1009);
3472 m_usedNodes->insert(fd->
absFilePath(),m_startNode);
3473 buildGraph(m_startNode,fd,1);
3476 int maxNodes =
nodes;
3482 openNodeQueue.
append(m_startNode);
3483 determineVisibleNodes(openNodeQueue,maxNodes);
3484 openNodeQueue.
clear();
3485 openNodeQueue.
append(m_startNode);
3486 determineTruncatedNodes(openNodeQueue);
3498 if (m_inverse) result+=
"_dep";
3508 const char *relPath,
3509 bool generateImageMap,
3517 err(
"Output dir %s does not exist!\n",path); exit(1);
3522 if (m_inverse) baseName+=
"_dep";
3526 if (m_inverse) mapName+=
"dep";
3531 QCString absDotName = absBaseName+
".dot";
3532 QCString absMapName = absBaseName+
".map";
3533 QCString absPdfName = absBaseName+
".pdf";
3534 QCString absEpsName = absBaseName+
".eps";
3535 QCString absImgName = absBaseName+
"."+imgExt;
3537 bool regenerate =
FALSE;
3545 m_startNode->label()
3548 usePDFLatex ? absPdfName : absEpsName,
3557 dotRun->
addJob(imgFmt,absImgName);
3561 else if (graphFormat==
GOF_EPS)
3566 dotRun->
addJob(
"pdf",absPdfName);
3570 dotRun->
addJob(
"ps",absEpsName);
3579 out <<
"<para>" <<
endl;
3580 out <<
" <figure>" <<
endl;
3581 out <<
" <title>Dependency diagram";
3582 out <<
"</title>" <<
endl;
3583 out <<
" <mediaobject>" <<
endl;
3584 out <<
" <imageobject>" <<
endl;
3585 out <<
" <imagedata";
3586 out <<
" width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName <<
"." << imgExt <<
"\">";
3587 out <<
"</imagedata>" <<
endl;
3588 out <<
" </imageobject>" <<
endl;
3589 out <<
" </mediaobject>" <<
endl;
3590 out <<
" </figure>" <<
endl;
3591 out <<
"</para>" <<
endl;
3593 else if (graphFormat==
GOF_BITMAP && generateImageMap)
3597 out <<
"<div class=\"center\">";
3605 out <<
"<!-- SVG " << mapId <<
" -->" <<
endl;
3607 out <<
"</div>" <<
endl;
3611 out <<
"<div class=\"center\"><img src=\"" << relPath << baseName <<
"." << imgExt <<
"\" border=\"0\" usemap=\"#" << mapName <<
"\" alt=\"\"/>";
3612 out <<
"</div>" <<
endl;
3614 QCString absMapName = absBaseName+
".map";
3615 if (regenerate || !
insertMapFile(out,absMapName,relPath,mapName))
3619 out <<
"<!-- MAP " << mapId <<
" -->" <<
endl;
3623 else if (graphFormat==
GOF_EPS)
3628 out <<
endl <<
"% FIG " << figId <<
endl;
3638 return m_startNode->m_children==0;
3644 int numNodes = m_startNode->m_children ? m_startNode->m_children->count() : 0;
3645 return numNodes>=maxNodes;
3650 QDictIterator<DotNode> dni(*m_usedNodes);
3652 for (;(node=dni.current());++dni)
3660 QDictIterator<DotNode> dni(*m_usedNodes);
3662 for (;(node=dni.current());++dni)
3679 for (;(rmd=mri.current());++mri)
3686 DotNode *bn = m_usedNodes->find(uniqueId);
3716 m_usedNodes->insert(uniqueId,bn);
3718 buildGraph(bn,rmd,distance+1);
3727 while (queue.
count()>0 && maxNodes>0)
3729 static int maxDistance =
Config_getInt(
"MAX_DOT_GRAPH_DEPTH");
3751 while (queue.
count()>0)
3756 bool truncated =
FALSE;
3778 m_inverse = inverse;
3793 m_startNode =
new DotNode(m_curNodeNumber++,
3799 m_startNode->setDistance(0);
3800 m_usedNodes =
new QDict<DotNode>(1009);
3801 m_usedNodes->insert(uniqueId,m_startNode);
3802 buildGraph(m_startNode,md,1);
3805 int maxNodes =
nodes;
3811 openNodeQueue.
append(m_startNode);
3812 determineVisibleNodes(openNodeQueue,maxNodes);
3813 openNodeQueue.
clear();
3814 openNodeQueue.
append(m_startNode);
3815 determineTruncatedNodes(openNodeQueue);
3826 const char *path,
const char *
fileName,
3827 const char *relPath,
bool generateImageMap,
int 3834 err(
"Output dir %s does not exist!\n",path); exit(1);
3838 QCString baseName = m_diskName + (m_inverse ?
"_icgraph" :
"_cgraph");
3844 QCString absDotName = absBaseName+
".dot";
3845 QCString absMapName = absBaseName+
".map";
3846 QCString absPdfName = absBaseName+
".pdf";
3847 QCString absEpsName = absBaseName+
".eps";
3848 QCString absImgName = absBaseName+
"."+imgExt;
3850 bool regenerate =
FALSE;
3858 m_startNode->label()
3861 usePDFLatex ? absPdfName : absEpsName,
3870 dotRun->
addJob(imgFmt,absImgName);
3875 else if (graphFormat==
GOF_EPS)
3881 dotRun->
addJob(
"pdf",absPdfName);
3885 dotRun->
addJob(
"ps",absEpsName);
3895 out <<
"<para>" <<
endl;
3896 out <<
" <figure>" <<
endl;
3897 out <<
" <title>Call diagram";
3898 out <<
"</title>" <<
endl;
3899 out <<
" <mediaobject>" <<
endl;
3900 out <<
" <imageobject>" <<
endl;
3901 out <<
" <imagedata";
3902 out <<
" width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName <<
"." << imgExt <<
"\">";
3903 out <<
"</imagedata>" <<
endl;
3904 out <<
" </imageobject>" <<
endl;
3905 out <<
" </mediaobject>" <<
endl;
3906 out <<
" </figure>" <<
endl;
3907 out <<
"</para>" <<
endl;
3909 else if (graphFormat==
GOF_BITMAP && generateImageMap)
3913 out <<
"<div class=\"center\">";
3921 out <<
"<!-- SVG " << mapId <<
" -->" <<
endl;
3923 out <<
"</div>" <<
endl;
3927 out <<
"<div class=\"center\"><img src=\"" << relPath << baseName <<
"." 3928 << imgExt <<
"\" border=\"0\" usemap=\"#" 3929 << mapName <<
"\" alt=\"";
3931 out <<
"</div>" <<
endl;
3933 if (regenerate || !
insertMapFile(out,absMapName,relPath,mapName))
3937 out <<
"<!-- MAP " << mapId <<
" -->" <<
endl;
3941 else if (graphFormat==
GOF_EPS)
3946 out <<
endl <<
"% FIG " << figId <<
endl;
3956 return m_startNode->m_children==0;
3962 int numNodes = m_startNode->m_children ? m_startNode->m_children->count() : 0;
3963 return numNodes>=maxNodes;
3982 const char *relPath,
3983 bool generateImageMap,
3985 bool linkRelations)
const 3991 err(
"Output dir %s does not exist!\n",path); exit(1);
4001 QCString absDotName = absBaseName+
".dot";
4002 QCString absMapName = absBaseName+
".map";
4003 QCString absPdfName = absBaseName+
".pdf";
4004 QCString absEpsName = absBaseName+
".eps";
4005 QCString absImgName = absBaseName+
"."+imgExt;
4016 bool regenerate=
FALSE;
4019 usePDFLatex ? absPdfName : absEpsName,
4028 err(
"Cannot create file %s.dot for writing!\n",baseName.
data());
4031 t << theGraph.
data();
4038 dotRun->
addJob(imgFmt,absImgName);
4042 else if (graphFormat==
GOF_EPS)
4047 dotRun->
addJob(
"pdf",absPdfName);
4051 dotRun->
addJob(
"ps",absEpsName);
4060 out <<
"<para>" <<
endl;
4061 out <<
" <figure>" <<
endl;
4062 out <<
" <title>Directory Dependency diagram";
4063 out <<
"</title>" <<
endl;
4064 out <<
" <mediaobject>" <<
endl;
4065 out <<
" <imageobject>" <<
endl;
4066 out <<
" <imagedata";
4067 out <<
" width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName <<
"." << imgExt <<
"\">";
4068 out <<
"</imagedata>" <<
endl;
4069 out <<
" </imageobject>" <<
endl;
4070 out <<
" </mediaobject>" <<
endl;
4071 out <<
" </figure>" <<
endl;
4072 out <<
"</para>" <<
endl;
4074 else if (graphFormat==
GOF_BITMAP && generateImageMap)
4078 out <<
"<div class=\"center\">";
4086 out <<
"<!-- SVG " << mapId <<
" -->" <<
endl;
4088 out <<
"</div>" <<
endl;
4092 out <<
"<div class=\"center\"><img src=\"" << relPath << baseName <<
"." 4093 << imgExt <<
"\" border=\"0\" usemap=\"#" 4094 << mapName <<
"\" alt=\"";
4097 out <<
"</div>" <<
endl;
4099 if (regenerate || !
insertMapFile(out,absMapName,relPath,mapName))
4103 out <<
"<!-- MAP " << mapId <<
" -->" <<
endl;
4107 else if (graphFormat==
GOF_EPS)
4112 out <<
endl <<
"% FIG " << figId <<
endl;
4133 err(
"Output dir %s does not exist!\n",path); exit(1);
4139 md5stream <<
" Node9 [shape=\"box\",label=\"Inherited\",fontsize=\"" <<
FONTSIZE <<
"\",height=0.2,width=0.4,fontname=\"" <<
FONTNAME <<
"\",fillcolor=\"grey75\",style=\"filled\" fontcolor=\"black\"];\n";
4140 md5stream <<
" Node10 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" <<
FONTSIZE <<
"\",style=\"solid\",fontname=\"" << FONTNAME <<
"\"];\n";
4141 md5stream <<
" Node10 [shape=\"box\",label=\"PublicBase\",fontsize=\"" <<
FONTSIZE <<
"\",height=0.2,width=0.4,fontname=\"" << FONTNAME <<
"\",color=\"black\",URL=\"$classPublicBase" <<
Doxygen::htmlFileExtension <<
"\"];\n";
4142 md5stream <<
" Node11 -> Node10 [dir=\"back\",color=\"midnightblue\",fontsize=\"" <<
FONTSIZE <<
"\",style=\"solid\",fontname=\"" << FONTNAME <<
"\"];\n";
4143 md5stream <<
" Node11 [shape=\"box\",label=\"Truncated\",fontsize=\"" <<
FONTSIZE <<
"\",height=0.2,width=0.4,fontname=\"" << FONTNAME <<
"\",color=\"red\",URL=\"$classTruncated" << Doxygen::htmlFileExtension <<
"\"];\n";
4144 md5stream <<
" Node13 -> Node9 [dir=\"back\",color=\"darkgreen\",fontsize=\"" <<
FONTSIZE <<
"\",style=\"solid\",fontname=\"" << FONTNAME <<
"\"];\n";
4145 md5stream <<
" Node13 [shape=\"box\",label=\"ProtectedBase\",fontsize=\"" <<
FONTSIZE <<
"\",height=0.2,width=0.4,fontname=\"" << FONTNAME <<
"\",color=\"black\",URL=\"$classProtectedBase" << Doxygen::htmlFileExtension <<
"\"];\n";
4146 md5stream <<
" Node14 -> Node9 [dir=\"back\",color=\"firebrick4\",fontsize=\"" <<
FONTSIZE <<
"\",style=\"solid\",fontname=\"" << FONTNAME <<
"\"];\n";
4147 md5stream <<
" Node14 [shape=\"box\",label=\"PrivateBase\",fontsize=\"" <<
FONTSIZE <<
"\",height=0.2,width=0.4,fontname=\"" << FONTNAME <<
"\",color=\"black\",URL=\"$classPrivateBase" << Doxygen::htmlFileExtension <<
"\"];\n";
4148 md5stream <<
" Node15 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" <<
FONTSIZE <<
"\",style=\"solid\",fontname=\"" << FONTNAME <<
"\"];\n";
4149 md5stream <<
" Node15 [shape=\"box\",label=\"Undocumented\",fontsize=\"" <<
FONTSIZE <<
"\",height=0.2,width=0.4,fontname=\"" << FONTNAME <<
"\",color=\"grey75\"];\n";
4150 md5stream <<
" Node16 -> Node9 [dir=\"back\",color=\"midnightblue\",fontsize=\"" <<
FONTSIZE <<
"\",style=\"solid\",fontname=\"" << FONTNAME <<
"\"];\n";
4151 md5stream <<
" Node16 [shape=\"box\",label=\"Templ< int >\",fontsize=\"" <<
FONTSIZE <<
"\",height=0.2,width=0.4,fontname=\"" << FONTNAME <<
"\",color=\"black\",URL=\"$classTempl" << Doxygen::htmlFileExtension <<
"\"];\n";
4152 md5stream <<
" Node17 -> Node16 [dir=\"back\",color=\"orange\",fontsize=\"" <<
FONTSIZE <<
"\",style=\"dashed\",label=\"< int >\",fontname=\"" << FONTNAME <<
"\"];\n";
4153 md5stream <<
" Node17 [shape=\"box\",label=\"Templ< T >\",fontsize=\"" <<
FONTSIZE <<
"\",height=0.2,width=0.4,fontname=\"" << FONTNAME <<
"\",color=\"black\",URL=\"$classTempl" << Doxygen::htmlFileExtension <<
"\"];\n";
4154 md5stream <<
" Node18 -> Node9 [dir=\"back\",color=\"darkorchid3\",fontsize=\"" <<
FONTSIZE <<
"\",style=\"dashed\",label=\"m_usedClass\",fontname=\"" << FONTNAME <<
"\"];\n";
4155 md5stream <<
" Node18 [shape=\"box\",label=\"Used\",fontsize=\"" <<
FONTSIZE <<
"\",height=0.2,width=0.4,fontname=\"" << FONTNAME <<
"\",color=\"black\",URL=\"$classUsed" << Doxygen::htmlFileExtension <<
"\"];\n";
4162 QCString absDotName = absBaseName+
".dot";
4165 QCString imgName =
"graph_legend."+imgExt;
4166 QCString absImgName = absBaseName+
"."+imgExt;
4170 QFile dotFile(absDotName);
4173 err(
"Could not open file %s for writing\n",dotFile.
name().
data());
4178 dotText << theGraph;
4184 dotRun->
addJob(imgFmt,absImgName);
4209 err(
"Output dir %s does not exist!\n",outDir); exit(1);
4220 dotRun.
addJob(imgFmt,absImgName);
4225 dotRun.addJob(
"pdf",absOutFile+
".pdf");
4229 dotRun.addJob(
"ps",absOutFile+
".eps");
4233 dotRun.preventCleanUp();
4258 const QCString &context,
int graphId)
4264 err(
"Output dir %s does not exist!\n",outDir.
data()); exit(1);
4267 QCString mapName = baseName+
".map";
4270 QCString imgName = baseName+
"."+imgExt;
4275 dotRun.preventCleanUp();
4285 QCString svgName=outDir+
"/"+baseName+
".svg";
4293 t <<
"<img src=\"" << relPath << imgName <<
"\" alt=\"" 4294 << imgName <<
"\" border=\"0\" usemap=\"#" << mapName <<
"\"/>" <<
endl 4295 <<
"<map name=\"" << mapName <<
"\" id=\"" << mapName <<
"\">";
4299 t <<
"</map>" <<
endl;
4310 m_usedNodes =
new QDict<DotNode>(1009);
4313 m_usedNodes->insert(gd->
name(), m_rootNode );
4314 m_edges.setAutoDelete(
TRUE);
4347 m_usedNodes->insert(d->
name(), nnode );
4359 for (;(def=defli.
current());++defli)
4361 DotNode* nnode = m_usedNodes->find(def->name());
4364 tmp_url = def->getReference()+
"$"+def->getOutputFileBase();
4365 QCString tooltip = def->briefDescriptionAsTooltip();
4366 nnode =
new DotNode(m_curNodeId++, def->groupTitle(), tooltip, tmp_url );
4368 m_usedNodes->insert(def->name(), nnode );
4386 for (;(def=defli.current());++defli)
4389 if (!def->anchor().isEmpty())
4391 tmp_url+=
"#"+def->anchor();
4402 for (;(def=defli.current());++defli)
4414 for (;(def=defli.
current());++defli)
4426 for (;(def=defli.current());++defli)
4438 for (;(def=defli.
current());++defli)
4448 if ( !( ml && ml->
count()) )
return;
4451 for (;(def=defli.
current());++defli)
4468 if ( newEdge->
pNStart==_pNStart &&
4469 newEdge->
pNEnd==_pNEnd &&
4470 newEdge->
eType==_eType
4478 newEdge =
new Edge(_pNStart,_pNEnd,_eType);
4479 m_edges.append( newEdge );
4484 newEdge->
links.append(
new Link(_label,_url));
4499 for (;(d=gli.current());++gli)
4501 DotNode* nnode = m_usedNodes->find(d->name());
4502 if ( nnode != m_rootNode )
4506 tmp_str = d->getReference()+
"$"+d->getOutputFileBase();
4507 QCString tooltip = d->briefDescriptionAsTooltip();
4508 nnode =
new DotNode(m_curNodeId++, d->groupTitle(), tooltip, tmp_str );
4510 m_usedNodes->insert(d->name(), nnode );
4513 addEdge( m_rootNode, nnode, eType, tmp_str, url );
4521 const char *path,
const char *
fileName,
const char *relPath,
4522 bool writeImageMap,
int graphId)
const 4528 err(
"Output dir %s does not exist!\n",path); exit(1);
4537 QDictIterator<DotNode> dni(*m_usedNodes);
4539 for (dni.toFirst();(pn=dni.current());++dni)
4545 for (dni.toFirst();(pn=dni.current());++dni)
4555 edge->
write( md5stream );
4567 QCString imgName = baseName+
"."+imgExt;
4570 QCString absDotName = absBaseName+
".dot";
4571 QCString absImgName = absBaseName+
"."+imgExt;
4572 QCString absMapName = absBaseName+
".map";
4573 QCString absPdfName = absBaseName+
".pdf";
4574 QCString absEpsName = absBaseName+
".eps";
4575 bool regenerate=
FALSE;
4578 usePDFLatex ? absPdfName : absEpsName,
4584 QFile dotfile(absDotName);
4595 dotRun->
addJob(imgFmt,absImgName);
4600 else if (graphFormat==
GOF_EPS)
4605 dotRun->
addJob(
"pdf",absPdfName);
4609 dotRun->
addJob(
"ps",absEpsName);
4617 t <<
"<para>" <<
endl;
4618 t <<
" <figure>" <<
endl;
4619 t <<
" <title>Group Collaboration diagram";
4620 t <<
"</title>" <<
endl;
4621 t <<
" <mediaobject>" <<
endl;
4622 t <<
" <imageobject>" <<
endl;
4624 t <<
" width=\"50%\" align=\"center\" valign=\"middle\" scalefit=\"1\" fileref=\"" << relPath << baseName <<
"." << imgExt <<
"\">";
4625 t <<
"</imagedata>" <<
endl;
4626 t <<
" </imageobject>" <<
endl;
4627 t <<
" </mediaobject>" <<
endl;
4628 t <<
" </figure>" <<
endl;
4629 t <<
"</para>" <<
endl;
4631 else if (graphFormat==
GOF_BITMAP && writeImageMap)
4634 t <<
"<center><table><tr><td>";
4638 t <<
"<div class=\"center\">";
4646 t <<
"<!-- SVG " << mapId <<
" -->" <<
endl;
4648 t <<
"</div>" <<
endl;
4652 t <<
"<img src=\"" << relPath << imgName
4653 <<
"\" border=\"0\" alt=\"\" usemap=\"#" 4654 << mapLabel <<
"\"/>" <<
endl;
4655 if (regenerate || !
insertMapFile(t,absMapName,relPath,mapLabel))
4659 t <<
"<!-- MAP " << mapId <<
" -->" <<
endl;
4662 t <<
"</td></tr></table></center>" <<
endl;
4664 else if (graphFormat==
GOF_EPS)
4669 t <<
endl <<
"% FIG " << figId <<
endl;
4679 const char* linkTypeColor[] = {
4688 QCString arrowStyle =
"dir=\"none\", style=\"dashed\"";
4689 t <<
" Node" << pNStart->number();
4691 t <<
"Node" << pNEnd->number();
4693 t <<
" [shape=plaintext";
4694 if (links.count()>0)
4717 const int maxLabels = 10;
4720 if (first) first=
FALSE;
else t <<
"\\n";
4723 if (count==maxLabels) t <<
"\\n...";
4730 arrowStyle =
"dir=\"back\", style=\"solid\"";
4733 t <<
", color=\"" << linkTypeColor[(
int)eType] <<
"\"";
4736 t <<
", " << arrowStyle;
4742 return m_usedNodes->count() <= 1;
4751 t <<
"\"Dot Graph\"";
4761 t <<
" bgcolor=\"transparent\";" <<
endl;
4763 t <<
" edge [fontname=\"" <<
FONTNAME <<
"\",fontsize=\"" <<
FONTSIZE <<
"\"," 4764 "labelfontname=\"" <<
FONTNAME <<
"\",labelfontsize=\"" <<
FONTSIZE <<
"\"];\n";
4765 t <<
" node [fontname=\"" <<
FONTNAME <<
"\",fontsize=\"" << FONTSIZE <<
"\",shape=record];\n";
4766 t <<
" rankdir=LR;\n";
4771 t <<
"digraph \"" << dd->
displayName() <<
"\" {\n";
4774 t <<
" bgcolor=transparent;\n";
4776 t <<
" compound=true\n";
4777 t <<
" node [ fontsize=\"" <<
FONTSIZE <<
"\", fontname=\"" <<
FONTNAME <<
"\"];\n";
4778 t <<
" edge [ labelfontsize=\"" <<
FONTSIZE <<
"\", labelfontname=\"" << FONTNAME <<
"\"];\n";
4780 QDict<DirDef> dirsInGraph(257);
4786 t <<
" graph [ bgcolor=\"#ddddee\", pencolor=\"black\", label=\"" 4788 <<
"\" fontname=\"" << FONTNAME <<
"\", fontsize=\"" <<
FONTSIZE <<
"\", URL=\"";
4795 t <<
" graph [ bgcolor=\"#eeeeff\", pencolor=\"black\", label=\"\"" 4804 for (sdi.toFirst();(sdir=sdi.
current());++sdi)
4806 t <<
" " << sdir->getOutputFileBase() <<
" [shape=box label=\"" 4807 << sdir->shortName() <<
"\"";
4808 if (sdir->isCluster())
4810 t <<
" color=\"red\"";
4814 t <<
" color=\"black\"";
4816 t <<
" fillcolor=\"white\" style=\"filled\"";
4817 t <<
" URL=\"" << sdir->getOutputFileBase()
4820 dirsInGraph.insert(sdir->getOutputFileBase(),sdir);
4827 << dd->
shortName() <<
"\", style=\"filled\", fillcolor=\"#eeeeff\"," 4837 QDictIterator<UsedDir> udi(*dd->
usedDirs());
4840 for (udi.toFirst();(udir=udi.current());++udi)
4843 const DirDef *usedDir=udir->dir();
4854 if (dir!=usedDir && dir->
parent()==usedDir->
parent() &&
4864 t <<
" fillcolor=\"white\" style=\"filled\"";
4866 t <<
" color=\"red\"";
4879 QDictIterator<DirDef> di(dirsInGraph);
4880 for (di.toFirst();(dir=di.current());++di)
4882 QDictIterator<UsedDir> udi(*dir->
usedDirs());
4884 for (udi.toFirst();(udir=udi.current());++udi)
4886 const DirDef *usedDir=udir->dir();
4887 if ((dir!=dd || !udir->inherited()) &&
4888 (usedDir!=dd || !udir->inherited()) &&
4900 int nrefs = udir->filePairs().count();
4903 t <<
" [headlabel=\"" << nrefs <<
"\", labeldistance=1.5";
void portable_sleep(int ms)
TruncState m_truncated
does the node have non-visible children/parents
Traverses directory structures and contents in a platform-independent way.
QCString convertToXML(const char *s)
bool isParentOf(DirDef *dir) const
QList< EdgeInfo > * m_edgeInfo
edge info for each child
Q_EXPORT int qstrncmp(const char *str1, const char *str2, uint len)
static SDict< DirRelation > dirRelations
void portable_sysTimerStop()
QCString m_tooltip
node's tooltip
static void resetReNumbering()
MemberGroupList * getMemberGroupList() const
int addSVGConversion(const QCString &file, const QCString &relPath, bool urlOnly, const QCString &context, bool zoomable, int graphId)
bool determineVisibleNodes(DotNode *rootNode, int maxNodes, bool includeParents)
void writeBox(FTextStream &t, GraphType gt, GraphOutputFormat f, bool hasNonReachableChildren, bool reNumber=FALSE)
void addParent(DotNode *n)
BaseClassList * subClasses() const
virtual QCString getReference() const
void addClass(ClassDef *cd, DotNode *n, int prot, const char *label, const char *usedName, const char *templSpec, bool base, int distance)
static int getDotFontSize()
const CleanupItem & cleanup() const
const QCString & shortName() const
virtual bool remove(const QString &fileName, bool acceptAbsPath=TRUE)
QCString getReference() const
QCString escapeCharsInString(const char *name, bool allowDots, bool allowUnderscore)
static void writeBoxMemberList(FTextStream &t, char prot, MemberList *ml, ClassDef *scope, bool isStatic=FALSE, const QDict< void > *skipNames=0)
DotClassGraph(ClassDef *cd, DotNode::GraphType t)
DotConstString m_postArgs
static bool insertMapFile(FTextStream &out, const QCString &mapFile, const QCString &relPath, const QCString &mapLabel)
void msg(const char *fmt,...)
static bool checkAndUpdateMd5Signature(const QCString &baseName, const QCString &md5)
QDict< void > * accessors
void write(FTextStream &t, GraphType gt, GraphOutputFormat f, bool topDown, bool toChildren, bool backArrows, bool reNumber)
static bool checkDeliverables(const QCString &file1, const QCString &file2=QCString())
static ClassSDict * hiddenClasses
int contains(char c, bool cs=TRUE) const
void append(const type *d)
void determineVisibleNodes(QList< DotNode > &queue, int &maxNodes)
const char * portable_getenv(const char *variable)
bool generateSourceFile() const
void determineTruncatedNodes(QList< DotNode > &queue)
const char *const * arrowStyleMap
static QCString htmlFileExtension
MemberList * members() const
void writeDotImageMapFromFile(FTextStream &t, const QCString &inFile, const QCString &outDir, const QCString &relPath, const QCString &baseName, const QCString &context, int graphId)
int findRef(const type *d) const
static QCString convertLabel(const QCString &l)
void addCollaborationMember(Definition *def, QCString &url, EdgeType eType)
bool m_isRoot
indicates if this is a root node
virtual QCString trLegendTitle()=0
void enqueue(DotRunner *runner)
TruncState isTruncated() const
static bool format(QChar::Decomposition tag, QString &str, int index, int len)
static void writeSVGNotSupported(FTextStream &out)
static DotManager * instance()
const DotNode * findDocNode() const
void buildGraph(DotNode *n, FileDef *fd, int distance)
QCString writeGraph(FTextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const char *path, const char *fileName, const char *relPath, bool writeImageMap=TRUE, int graphId=-1) const
static QCString replaceRef(const QCString &buf, const QCString relPath, bool urlOnly, const QCString &context, const QCString &target=QCString())
void writeDEF(FTextStream &t)
static QCString stripPath(const QCString &s)
int readLine(char *data, uint maxlen)
static QCString className
int readBlock(char *data, uint len)
QCString left(uint len) const
void portable_unsetenv(const char *variable)
The QString class provides an abstraction of Unicode text and the classic C null-terminated char arra...
boost::graph_traits< ModuleGraph >::edge_descriptor Edge
static const char * normalEdgeStyleMap[]
void write(FTextStream &t) const
Simplified and optimized version of QTextStream.
void writeDocbook(FTextStream &t, bool isClassGraph)
QCString displayName(bool includeScope=TRUE) const
int find(char c, int index=0, bool cs=TRUE) const
void addChild(DotNode *n, int edgeColor=EdgeInfo::Purple, int edgeStyle=EdgeInfo::Solid, const char *edgeLab=0, const char *edgeURL=0, int edgeLabCol=-1)
QCString diskName() const
DotInclDepGraph(FileDef *fd, bool inverse)
QCString getFileBase() const
const char * groupTitle() const
GroupList * partOfGroups() const
void append(const char *key, const T *d)
static constexpr double mg
virtual QString absPath() const
QCString getReference() const
int findRev(char c, int index=-1, bool cs=TRUE) const
ClassSDict * getClasses() const
static int m_curNodeNumber
int addMap(const QCString &file, const QCString &mapFile, const QCString &relPath, bool urlOnly, const QCString &context, const QCString &label)
GroupList * getSubGroups() const
Protection protection() const
MemberSDict * getReferencesMembers() const
static const char svgZoomHeader[]
void portable_sysTimerStart()
virtual QCString trAndMore(const QCString &number)=0
QCString displayName(bool=TRUE) const
static QCString escapeTooltip(const QCString &tooltip)
int addFigure(const QCString &baseName, const QCString &figureName, bool heightCheck)
void removeParent(DotNode *n)
static void writeGraphHeader(FTextStream &t, const QCString &title=QCString())
void setAutoDelete(bool val)
static EdgeProperties normalEdgeProps
#define Config_getEnum(val)
static void removeDotGraph(const QCString &dotName)
static void deleteNodes(DotNode *node, SDict< DotNode > *skipNodes=0)
virtual QCString trGraphicalHierarchy()=0
#define Config_getInt(val)
void buildGraph(ClassDef *cd, DotNode *n, bool base, int distance)
void writeDEF(FTextStream &t)
int reNumberNode(int number, bool doReNumbering)
QCString writeGraph(FTextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const char *path, const char *fileName, const char *relPath, bool TBRank=TRUE, bool imageMap=TRUE, int graphId=-1) const
ClassDef * templateMaster() const
static const char * umlArrowStyleMap[]
static EdgeProperties umlEdgeProps
QCString m_url
url of the node (format: remote$local)
int writeBlock(const char *data, uint len)
MemberSDict * getReferencedByMembers() const
static QArray< int > s_newNumber
const char * data() const
QList< DotRunner > m_dotRuns
friend QCString computeMd5Signature(DotNode *root, GraphType gt, GraphOutputFormat f, bool lrRank, bool renderParents, bool backArrows, const QCString &title, QCString &graphStr)
const QCString & name() const
static void writeDotDirDepGraph(FTextStream &t, DirDef *dd, bool linkRelations)
QCString getFileBase() const
void determineTruncatedNodes(QList< DotNode > &queue)
PageSDict * getPages() const
int qstricmp(const char *str1, const char *str2)
static QCString stripProtectionPrefix(const QCString &s)
static bool updateDotGraph(DotNode *root, DotNode::GraphType gt, const QCString &baseName, GraphOutputFormat format, bool lrRank, bool renderParents, bool backArrows, const QCString &title=QCString())
DotConstString m_imageName
QCString linkToText(SrcLangExt lang, const char *link, bool isFileName)
static void unsetDotFontPath()
void MD5Buffer(const unsigned char *buf, unsigned int len, unsigned char sig[16])
virtual bool rename(const QString &name, const QString &newName, bool acceptAbsPaths=TRUE)
static const char * normalEdgeColorMap[]
QCString getSourceFileBase() const
QCString right(uint len) const
QList< IncludeInfo > * includeFileList() const
void setDistance(int distance)
SrcLangExt getLanguage() const
void set(const QCString &s)
void addHierarchy(DotNode *n, ClassDef *cd, bool hide)
QList< DotNode > * m_children
list of child nodes (outgoing arrows)
int addSVGObject(const QCString &baseName, const QCString &figureName, const QCString &relPath)
void markAsTruncated(bool b=TRUE)
static bool readSVGSize(const QCString &fileName, int *width, int *height)
bool m_written
used to mark a node as written
static bool writeVecGfxFigure(FTextStream &out, const QCString &baseName, const QCString &figureName)
void writeXML(FTextStream &t, bool isClassGraph)
const DirList & subDirs() const
NamespaceSDict * getNamespaces() const
int addSVGConversion(const QCString &relPath, bool urlOnly, const QCString &context, bool zoomable, int graphId)
const QDict< UsedDir > * usedDirs() const
void determineTruncatedNodes(QList< DotNode > &queue, bool includeParents)
SDict< DotFilePatcher > m_dotMaps
QCString & prepend(const char *s)
void writeDotGraphFromFile(const char *inFile, const char *outDir, const char *outFile, GraphOutputFormat format)
A bunch of utility functions.
ConstraintClassDict * templateTypeConstraints() const
int addFigure(const QCString &file, const QCString &baseName, const QCString &figureName, bool heightCheck)
const char * data() const
char portable_pathListSeparator()
void addImageFile(const char *name)
void writeArrow(FTextStream &t, GraphType gt, GraphOutputFormat f, DotNode *cn, EdgeInfo *ei, bool topDown, bool pointBack=TRUE, bool reNumber=FALSE)
#define Config_getString(val)
DotGroupCollaboration(GroupDef *gd)
QList< DotNode > * m_parents
list of parent nodes (incoming arrows)
#define Config_getBool(val)
const char *const * edgeColorMap
ClassDef * getClassDef() const
QCString getDotImageExtension(void)
bool isObjCMethod() const
bool depGraphIsTrivial() const
virtual QCString qualifiedName() const
QCString diskName() const
void writeXML(FTextStream &t)
void addClassList(ClassSDict *cl)
static void checkDotResult(const char *imgExt, const char *imgName)
QCString & insert(uint index, const char *s)
static const char * umlEdgeStyleMap[]
void initClassHierarchy(ClassSDict *cl)
int findParent(DotNode *n)
void err(const char *fmt,...)
static QCString getDotFontName()
int compareValues(const DotNode *n1, const DotNode *n2) const
QCString absFilePath() const
void addPostProcessing(const char *cmd, const char *args)
static DotManager * m_theInstance
QCString mid(uint index, uint len=0xffffffff) const
QCString getOutputFileBase() const
The QFile class is an I/O device that operates on files.
static bool readBoundingBox(const char *fileName, int *width, int *height, bool isEps)
int addSVGObject(const QCString &file, const QCString &baseName, const QCString &figureNAme, const QCString &relPath)
QCString & sprintf(const char *format,...)
void buildGraph(GroupDef *gd)
static void writeGraphFooter(FTextStream &t)
QCString getOutputFileBase() const
MemberGroupSDict * getMemberGroupSDict() const
static const char * normalArrowStyleMap[]
void portable_setenv(const char *name, const char *value)
virtual Definition * getOuterScope() const
QCString getOutputFileBase() const
QCString writeGraph(FTextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const char *path, const char *fileName, const char *relPath, bool writeImageMap=TRUE, int graphId=-1) const
static QString fromUtf8(const char *, int len=-1)
UsesClassDict * usedByImplementationClasses() const
MemberList * getMemberList(MemberListType lt) const
void addJob(const char *format, const char *output)
bool showInCallGraph() const
void writeGraph(FTextStream &t, const char *path, const char *fileName) const
QCString qualifiedName() const
bool isVisibleInHierarchy()
QList< DotConstString > m_jobs
void MD5SigToString(unsigned char signature[16], char *str, int len)
QList< IncludeInfo > * includedByFileList() const
QDict< ClassDef > * getTemplateInstances() const
static bool writeSVGFigureLink(FTextStream &out, const QCString &relPath, const QCString &baseName, const QCString &absImgName)
DotFilePatcher(const char *patchFile)
static const char * umlEdgeColorMap[]
QCString stripScope(const char *name)
DotNode(int n, const char *lab, const char *tip, const char *url, bool rootNode=FALSE, ClassDef *cd=0)
void writeGraphHeader(FTextStream &t, const QCString &title) const
ClassDef * m_classDef
class representing this node (can be 0)
int addMap(const QCString &mapFile, const QCString &relPath, bool urlOnly, const QCString &context, const QCString &label)
CleanupItem m_cleanupItem
A model of a page symbol.
Edge * addEdge(DotNode *_pNStart, DotNode *_pNEnd, EdgeType _eType, const QCString &_label, const QCString &_url)
static int m_curNodeNumber
static void setDotFontPath(const char *path)
static int m_curNodeNumber
void writeDocbook(FTextStream &t)
void line(double t, double *p, double &x, double &y, double &z)
QCString convertNameToFile(const char *name, bool allowDots, bool allowUnderscore)
static int m_curNodeNumber
void writeXML(FTextStream &t)
QCString getOutputFileBase() const
QCString insertTemplateSpecifierInScope(const QCString &scope, const QCString &templ)
FileList * getFiles() const
bool m_hasDoc
used to mark a node as documented
bool hasVisibleRoot(BaseClassList *bcl)
static QCString g_dotFontPath
bool m_deleted
used to mark a node as deleted
QCString m_label
label text
Translator * theTranslator
QCString writeGraph(FTextStream &out, GraphOutputFormat gf, EmbeddedOutputFormat ef, const char *path, const char *fileName, const char *relPath, bool writeImageMap=TRUE, int graphId=-1, bool linkRelations=TRUE) const
bool m_visible
is the node visible in the output
void colorConnectedNodes(int curColor)
QCString briefDescriptionAsTooltip() const
UsesClassDict * usedImplementationClasses() const
int m_distance
shortest path to the root node
static const char svgZoomFooter[]
QCString writeGraph(FTextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const char *path, const char *fileName, const char *relPath, bool writeImageMap=TRUE, int graphId=-1) const
void markAsVisible(bool b=TRUE)
QList< DotWorkerThread > m_workers
The QFileInfo class provides system-independent file information.
QCString getOutputFileBase() const
const char *const * edgeStyleMap
Q_EXPORT int qstrcmp(const char *str1, const char *str2)
void determineVisibleNodes(QList< DotNode > &queue, int &maxNodes)
T * find(const char *key)
DotWorkerThread(DotRunnerQueue *queue)
static bool convertMapFile(FTextStream &t, const char *mapName, const QCString relPath, bool urlOnly=FALSE, const QCString &context=QCString())
DotRunner(const QCString &file, const QCString &fontPath, bool checkResult, const QCString &imageName=QCString())
void deleteNode(DotNodeList &deletedList, SDict< DotNode > *skipNodes=0)
void setAutoDelete(bool enable)
static ClassSDict * classSDict
QCString externalLinkTarget()
FILE * portable_fopen(const char *fileName, const char *mode)
void addRun(DotRunner *run)
std::string nl(std::size_t i=1)
const QCString & docName() const
DirList * getDirs() const
MemberList * getMemberList(MemberListType lt)
virtual bool exists() const
static IndexList * indexList
void createGraph(DotNode *rootNode, FTextStream &t, const char *path, const char *fileName, int id) const
Portable versions of functions that are platform dependent.
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
DotCallGraph(MemberDef *md, bool inverse)
QTextStream & endl(QTextStream &s)
void buildGraph(DotNode *n, MemberDef *md, int distance)
BaseClassList * baseClasses() const
void addMemberList(class MemberList *ml)
const char * data() const
void removeChild(DotNode *n)
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
QList< DotRunner::CleanupItem > m_cleanupItems
int portable_system(const char *command, const char *args, bool commandHasConsole)
QDict< void > * accessors
void generateGraphLegend(const char *path)
static int s_max_newNumber
static int idealThreadCount()
void writeDocbook(FTextStream &t)