diagram.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  *
4  *
5  *
6  * Copyright (C) 1997-2015 by Dimitri van Heesch.
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation under the terms of the GNU General Public License is hereby
10  * granted. No representations are made about the suitability of this software
11  * for any purpose. It is provided "as is" without express or implied warranty.
12  * See the GNU General Public License for more details.
13  *
14  * Documents produced by Doxygen are derivative works derived from the
15  * input used in their production; they are not affected by this license.
16  *
17  */
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <qlist.h>
22 #include <qarray.h>
23 #include "ftextstream.h"
24 #include <qfile.h>
25 
26 #include "diagram.h"
27 #include "image.h"
28 #include "classdef.h"
29 #include "config.h"
30 #include "message.h"
31 #include "util.h"
32 #include "doxygen.h"
33 #include "portable.h"
34 #include "index.h"
35 #include "classlist.h"
36 
37 //-----------------------------------------------------------------------------
38 
39 class DiagramItemList;
40 
41 /** Class representing a single node in the built-in class diagram */
43 {
44  public:
46  Protection prot,Specifier virt,const char *ts);
47  ~DiagramItem();
48  QCString label() const;
49  QCString fileName() const;
50  DiagramItem *parentItem() { return parent; }
52  void move(int dx,int dy) { x+=dx; y+=dy; }
53  int xPos() const { return x; }
54  int yPos() const { return y; }
55  int avgChildPos() const;
56  int numChildren() const;
57  void addChild(DiagramItem *di);
58  int number() const { return num; }
59  Protection protection() const { return prot; }
60  Specifier virtualness() const { return virt; }
61  void putInList() { inList=TRUE; }
62  bool isInList() const { return inList; }
63  ClassDef *getClassDef() const { return classDef; }
64  private:
67  int x,y;
68  int num;
72  bool inList;
74 };
75 
76 /** Class representing a list of DiagramItem object. */
77 class DiagramItemList : public QList<DiagramItem>
78 {
79  public:
82 };
83 
84 /** Class representing a row in the built-in class diagram */
85 class DiagramRow : public QList<DiagramItem>
86 {
87  public:
89  {
90  diagram=d;
91  level=l;
92  setAutoDelete(TRUE);
93  }
94  void insertClass(DiagramItem *parent,ClassDef *cd,bool doBases,
95  Protection prot,Specifier virt,const char *ts);
96  uint number() { return level; }
97  private:
100 };
101 
102 /** Class representing iterator for the rows in the built-in class diagram. */
103 class DiagramRowIterator : public QListIterator<DiagramRow>
104 {
105  public:
107  : QListIterator<DiagramRow>(d) {}
108 };
109 
110 /** Class represeting the tree layout for the built-in class diagram. */
111 class TreeDiagram : public QList<DiagramRow>
112 {
113  public:
114  TreeDiagram(ClassDef *root,bool doBases);
115  ~TreeDiagram();
116  void computeLayout();
117  uint computeRows();
118  //uint computeCols();
119  void moveChildren(DiagramItem *root,int dx);
120  void computeExtremes(uint *labelWidth,uint *xpos);
121  void drawBoxes(FTextStream &t,Image *image,
122  bool doBase,bool bitmap,
123  uint baseRows,uint superRows,
124  uint cellWidth,uint cellHeight,
125  QCString relPath="",
126  bool generateMap=TRUE);
127  void drawConnectors(FTextStream &t,Image *image,
128  bool doBase,bool bitmap,
129  uint baseRows,uint superRows,
130  uint cellWidth,uint cellheight);
131  private:
132  bool layoutTree(DiagramItem *root,int row);
133  TreeDiagram &operator=(const TreeDiagram &);
134  TreeDiagram(const TreeDiagram &);
135 };
136 
137 
138 
139 //-----------------------------------------------------------------------------
140 
141 const uint maxTreeWidth = 8;
142 const int gridWidth = 100;
143 const int gridHeight = 100;
144 
145 const uint labelHorSpacing = 10; // horizontal distance between labels
146 const uint labelVertSpacing = 32; // vertical distance between labels
147 const uint labelHorMargin = 6; // horiz. spacing between label and box
148 const uint fontHeight = 12; // height of a character
149 
150 //static QCString escapeLatex(const char *s)
151 //{
152 // QCString result;
153 // char c;
154 // while ((c=*s++))
155 // {
156 // if (c=='_') result+="\\_";
157 // else result+=c;
158 // }
159 // return result;
160 //}
161 
163 {
164  switch(p)
165  {
166  case Public: return 0xffffffff;
167  case Package: // package is not possible!
168  case Protected: return 0xcccccccc;
169  case Private: return 0xaaaaaaaa;
170  }
171  return 0;
172 }
173 
175 {
176  switch(p)
177  {
178  case Public: return 6;
179  case Package: // package is not possible!
180  case Protected: return 5;
181  case Private: return 4;
182  }
183  return 0;
184 }
185 
187 {
188  switch(p)
189  {
190  case Public: return "solid";
191  case Package: // package is not possible!
192  case Protected: return "dashed";
193  case Private: return "dotted";
194  }
195  return 0;
196 }
197 
199 {
200  switch(p)
201  {
202  case Normal: return 0xffffffff;
203  case Virtual: return 0xf0f0f0f0;
204  default: return 0;
205  }
206  return 0;
207 }
208 
209 // pre: dil is not empty
211 {
213  DiagramItem *di=it.current();
215  for (++it;(di=it.current());++it)
216  {
217  Protection p=di->protection();
218  if (p!=result)
219  {
220  if (result==Protected && p==Public) result=p;
221  else if (result==Private) result=p;
222  }
223  }
224  return result;
225 }
226 
227 static void writeBitmapBox(DiagramItem *di,Image *image,
228  int x,int y,int w,int h,bool firstRow,
229  bool hasDocs,bool children=FALSE)
230 {
231  int colFill = hasDocs ? (firstRow ? 0 : 2) : 7;
232  int colBorder = (firstRow || !hasDocs) ? 1 : 3;
233  int l = Image::stringLength(di->label());
235  image->fillRect(x+1,y+1,w-2,h-2,colFill,mask);
236  image->drawRect(x,y,w,h,colBorder,mask);
237  image->writeString(x+(w-l)/2, y+(h-fontHeight)/2, di->label(),1);
238  if (children)
239  {
240  int i;
241  for (i=0;i<5;i++)
242  image->drawHorzLine(y+h+i-6,x+w-2-i,x+w-2,firstRow?1:3,0xffffffff);
243  }
244 }
245 
247  float x,float y,bool children=FALSE)
248 {
249  if (di->virtualness()==Virtual) t << "dashed\n";
250  t << " (" << di->label() << ") " << x << " " << y << " box\n";
251  if (children) t << x << " " << y << " mark\n";
252  if (di->virtualness()==Virtual) t << "solid\n";
253 }
254 
255 static void writeMapArea(FTextStream &t,ClassDef *cd,QCString relPath,
256  int x,int y,int w,int h)
257 {
258  if (cd->isLinkable())
259  {
260  QCString ref=cd->getReference();
261  t << "<area ";
262  if (!ref.isEmpty())
263  {
264  t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
265  }
266  t << "href=\"";
267  t << externalRef(relPath,ref,TRUE);
269  if (!cd->anchor().isEmpty())
270  {
271  t << "#" << cd->anchor();
272  }
273  t << "\" ";
274  QCString tooltip = cd->briefDescriptionAsTooltip();
275  if (!tooltip.isEmpty())
276  {
277  t << "title=\"" << convertToHtml(tooltip) << "\" ";
278  }
279  t << "alt=\"" << convertToXML(cd->displayName());
280  t << "\" shape=\"rect\" coords=\"" << x << "," << y << ",";
281  t << (x+w) << "," << (y+h) << "\"/>" << endl;
282  }
283 }
284 //-----------------------------------------------------------------------------
285 
287  Protection pr,Specifier vi,const char *ts)
288 {
289  parent=p;
290  x=y=0;
291  //name=n;
292  num=number;
294  prot=pr;
295  virt=vi;
296  inList=FALSE;
297  classDef=cd;
298  templSpec=ts;
299 }
300 
302 {
303  delete children;
304 }
305 
307 {
309  if (!templSpec.isEmpty())
310  {
311  // we use classDef->name() here and not diplayName() in order
312  // to get the name used in the inheritance relation.
313  QCString n = classDef->name();
314  if (/*n.right(2)=="-g" ||*/ n.right(2)=="-p")
315  {
316  n = n.left(n.length()-2);
317  }
319  }
320  else
321  {
322  result=classDef->displayName();
323  }
324  if (Config_getBool("HIDE_SCOPE_NAMES")) result=stripScope(result);
325  return result;
326 }
327 
329 {
330  return classDef->getOutputFileBase();
331 }
332 
334 {
335  DiagramItem *di;
336  int c=children->count();
337  if (c==0) // no children -> don't move
338  return xPos();
339  if ((di=children->getFirst())->isInList()) // children should be in a list
340  return di->xPos();
341  if (c&1) // odd number of children -> get pos of middle child
342  return children->at(c/2)->xPos();
343  else // even number of children -> get middle of most middle children
344  return (children->at(c/2-1)->xPos()+children->at(c/2)->xPos())/2;
345 }
346 
348 {
349  return children->count();
350 }
351 
353 {
354  children->append(di);
355 }
356 
358  Protection prot,Specifier virt,const char *ts)
359 {
360  //if (cd->visited) return; // the visit check does not work in case of
361  // multiple inheritance of the same class!
362  DiagramItem *di=new DiagramItem(parent, diagram->at(level)->count(),
363  cd,prot,virt,ts);
364  //cd->visited=TRUE;
365  if (parent) parent->addChild(di);
367  append(di);
368  BaseClassList *bcl=doBases ? cd->baseClasses() : cd->subClasses();
369  int count=0;
370  if (bcl)
371  {
372  /* there are base/sub classes */
373  BaseClassListIterator it(*bcl);
374  BaseClassDef *bcd;
375  for (;(bcd=it.current());++it)
376  {
377  ClassDef *ccd=bcd->classDef;
378  if (ccd && ccd->isVisibleInHierarchy() /*&& !ccd->visited*/) count++;
379  }
380  }
381  if (count>0 && (prot!=Private || !doBases))
382  {
383  DiagramRow *row=0;
384  if (diagram->count()<=level+1) /* add new row */
385  {
386  row = new DiagramRow(diagram,level+1);
387  diagram->append(row);
388  }
389  else /* get next row */
390  {
391  row=diagram->at(level+1);
392  }
393  /* insert base classes in the next row */
394  BaseClassListIterator it(*bcl);
395  BaseClassDef *bcd;
396  for (;(bcd=it.current());++it)
397  {
398  ClassDef *ccd=bcd->classDef;
399  if (ccd && ccd->isVisibleInHierarchy() /*&& !ccd->visited*/)
400  {
401  row->insertClass(di,ccd,doBases,bcd->prot,
402  doBases?bcd->virt:Normal,
403  doBases?bcd->templSpecifiers.data():"");
404  }
405  }
406  }
407 }
408 
410 {
411  setAutoDelete(TRUE);
412  DiagramRow *row=new DiagramRow(this,0);
413  append(row);
414  row->insertClass(0,root,doBases,Public,Normal,0);
415 }
416 
418 {
419 }
420 
421 
423 {
424  DiagramItemList *dil=root->getChildren();
426  DiagramItem *di;
427  for (;(di=it.current());++it)
428  {
429  di->move(dx,0);
430  moveChildren(di,dx);
431  }
432 }
433 
435 {
436  bool moved=FALSE;
437  //printf("layoutTree(%s,%d)\n",root->label().data(),r);
438 
439  DiagramItemList *dil=root->getChildren();
440  if (dil->count()>0)
441  {
442  uint k;
443  int pPos=root->xPos();
444  int cPos=root->avgChildPos();
445  if (pPos>cPos) // move children
446  {
447  DiagramRow *row=at(r+1);
448  //printf("Moving children %d-%d in row %d\n",
449  // dil->getFirst()->number(),row->count()-1,r+1);
450  for (k=dil->getFirst()->number();k<row->count();k++)
451  row->at(k)->move(pPos-cPos,0);
452  moved=TRUE;
453  }
454  else if (pPos<cPos) // move parent
455  {
456  DiagramRow *row=at(r);
457  //printf("Moving parents %d-%d in row %d\n",
458  // root->number(),row->count()-1,r);
459  for (k=root->number();k<row->count();k++)
460  row->at(k)->move(cPos-pPos,0);
461  moved=TRUE;
462  }
463 
464  // recurse to children
466  DiagramItem *di;
467  for (;(di=it.current()) && !moved && !di->isInList();++it)
468  {
469  moved = layoutTree(di,r+1);
470  }
471  }
472  return moved;
473 }
474 
476 {
477  QListIterator<DiagramRow> it(*this);
478  DiagramRow *row;
479  for (;(row=it.current()) && row->count()<maxTreeWidth;++it) {}
480  if (row)
481  {
482  //printf("computeLayout() list row at %d\n",row->number());
483  QListIterator<DiagramItem> rit(*row);
484  DiagramItem *di;
485  DiagramItem *opi=0;
486  int delta=0;
487  bool first=TRUE;
488  for (;(di=rit.current());++rit)
489  {
490  DiagramItem *pi=di->parentItem();
491  if (pi==opi && !first) { delta-=gridWidth; }
492  first = pi!=opi;
493  opi=pi;
494  di->move(delta,0); // collapse all items in the same
495  // list (except the first)
496  di->putInList();
497  }
498  }
499 
500  // re-organize the diagram items
501  DiagramItem *root=getFirst()->getFirst();
502  while (layoutTree(root,0)) { }
503 
504  // move first items of the lists
505  if (row)
506  {
507  QListIterator<DiagramItem> rit(*row);
508  DiagramItem *di;
509  while ((di=rit.current()))
510  {
511  DiagramItem *pi=di->parentItem();
512  if (pi->getChildren()->count()>1)
513  {
514  di->move(gridWidth,0);
515  while (di && di->parentItem()==pi) { ++rit; di=rit.current(); }
516  }
517  else
518  {
519  ++rit;
520  }
521  }
522  }
523 }
524 
526 {
527  //printf("TreeDiagram::computeRows()=%d\n",count());
528  int count=0;
529  QListIterator<DiagramRow> it(*this);
530  DiagramRow *row;
531  for (;(row=it.current()) && !row->getFirst()->isInList();++it)
532  {
533  count++;
534  }
535  //printf("count=%d row=%p\n",count,row);
536  if (row)
537  {
538  int maxListLen=0;
539  int curListLen=0;
540  DiagramItem *opi=0;
541  QListIterator<DiagramItem> rit(*row);
542  DiagramItem *di;
543  for (;(di=rit.current());++rit)
544  {
545  if (di->parentItem()!=opi) curListLen=1; else curListLen++;
546  if (curListLen>maxListLen) maxListLen=curListLen;
547  opi=di->parentItem();
548  }
549  //printf("maxListLen=%d\n",maxListLen);
550  count+=maxListLen;
551  }
552  return count;
553 }
554 
555 void TreeDiagram::computeExtremes(uint *maxLabelLen,uint *maxXPos)
556 {
557  uint ml=0,mx=0;
558  QListIterator<DiagramRow> it(*this);
559  DiagramRow *dr;
560  bool done=FALSE;
561  for (;(dr=it.current()) && !done;++it)
562  {
564  DiagramItem *di;
565  for (;(di=rit.current());++rit)
566  {
567  if (di->isInList()) done=TRUE;
568  if (maxXPos) mx=QMAX(mx,(uint)di->xPos());
569  if (maxLabelLen) ml=QMAX(ml,Image::stringLength(di->label()));
570  }
571  }
572  if (maxLabelLen) *maxLabelLen=ml;
573  if (maxXPos) *maxXPos=mx;
574 }
575 
577  bool doBase,bool bitmap,
578  uint baseRows,uint superRows,
579  uint cellWidth,uint cellHeight,
580  QCString relPath,
581  bool generateMap)
582 {
583  QListIterator<DiagramRow> it(*this);
584  DiagramRow *dr;
585  if (!doBase) ++it;
586  bool done=FALSE;
587  bool firstRow = doBase;
588  for (;(dr=it.current()) && !done;++it)
589  {
590  int x=0,y=0;
591  float xf=0.0f,yf=0.0f;
593  DiagramItem *di = rit.current();
594  if (di->isInList()) // put boxes in a list
595  {
596  DiagramItem *opi=0;
597  if (doBase) rit.toLast(); else rit.toFirst();
598  while ((di=rit.current()))
599  {
600  if (di->parentItem()==opi)
601  {
602  if (bitmap)
603  {
604  if (doBase) y -= cellHeight+labelVertSpacing;
605  else y += cellHeight+labelVertSpacing;
606  }
607  else
608  {
609  if (doBase) yf += 1.0f;
610  else yf -= 1.0f;
611  }
612  }
613  else
614  {
615  if (bitmap)
616  {
617  x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth;
618  if (doBase)
619  {
620  y = image->getHeight()-
621  superRows*cellHeight-
622  (superRows-1)*labelVertSpacing-
623  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
624  }
625  else
626  {
627  y = (baseRows-1)*(cellHeight+labelVertSpacing)+
628  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
629  }
630  }
631  else
632  {
633  xf = di->xPos()/(float)gridWidth;
634  if (doBase)
635  {
636  yf = di->yPos()/(float)gridHeight+superRows-1;
637  }
638  else
639  {
640  yf = superRows-1-di->yPos()/(float)gridHeight;
641  }
642  }
643  }
644  opi=di->parentItem();
645 
646  if (bitmap)
647  {
648  bool hasDocs=di->getClassDef()->isLinkable();
649  writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,
650  hasDocs,di->getChildren()->count()>0);
651  if (!firstRow && generateMap)
652  writeMapArea(t,di->getClassDef(),relPath,x,y,cellWidth,cellHeight);
653  }
654  else
655  {
656  writeVectorBox(t,di,xf,yf,di->getChildren()->count()>0);
657  }
658 
659  if (doBase) --rit; else ++rit;
660  }
661  done=TRUE;
662  }
663  else // draw a tree of boxes
664  {
665  for (rit.toFirst();(di=rit.current());++rit)
666  {
667  if (bitmap)
668  {
669  x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth;
670  if (doBase)
671  {
672  y = image->getHeight()-
673  superRows*cellHeight-
674  (superRows-1)*labelVertSpacing-
675  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
676  }
677  else
678  {
679  y = (baseRows-1)*(cellHeight+labelVertSpacing)+
680  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
681  }
682  bool hasDocs=di->getClassDef()->isLinkable();
683  writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,hasDocs);
684  if (!firstRow && generateMap)
685  writeMapArea(t,di->getClassDef(),relPath,x,y,cellWidth,cellHeight);
686  }
687  else
688  {
689  xf=di->xPos()/(float)gridWidth;
690  if (doBase)
691  {
692  yf = di->yPos()/(float)gridHeight+superRows-1;
693  }
694  else
695  {
696  yf = superRows-1-di->yPos()/(float)gridHeight;
697  }
698  writeVectorBox(t,di,xf,yf);
699  }
700  }
701  }
702  firstRow=FALSE;
703  }
704 }
705 
707  bool doBase,bool bitmap,
708  uint baseRows,uint superRows,
709  uint cellWidth,uint cellHeight)
710 {
711  QListIterator<DiagramRow> it(*this);
712  DiagramRow *dr;
713  bool done=FALSE;
714  for (;(dr=it.current()) && !done;++it) // for each row
715  {
717  DiagramItem *di = rit.current();
718  if (di->isInList()) // row consists of list connectors
719  {
720  int x=0,y=0,ys=0;
721  float xf=0.0f,yf=0.0f,ysf=0.0f;
722  for (;(di=rit.current());++rit)
723  {
724  DiagramItem *pi=di->parentItem();
725  DiagramItemList *dil=pi->getChildren();
726  DiagramItem *last=dil->getLast();
727  if (di==last) // single child
728  {
729  if (bitmap) // draw pixels
730  {
731  x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
732  if (doBase) // base classes
733  {
734  y = image->getHeight()-
735  (superRows-1)*(cellHeight+labelVertSpacing)-
736  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
737  image->drawVertArrow(x,y,y+labelVertSpacing/2,
738  protToColor(di->protection()),
739  protToMask(di->protection()));
740  }
741  else // super classes
742  {
743  y = (baseRows-1)*(cellHeight+labelVertSpacing)-
745  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
746  image->drawVertLine(x,y,y+labelVertSpacing/2,
747  protToColor(di->protection()),
748  protToMask(di->protection()));
749  }
750  }
751  else // draw vectors
752  {
753  t << protToString(di->protection()) << endl;
754  if (doBase)
755  {
756  t << "1 " << (di->xPos()/(float)gridWidth) << " "
757  << (di->yPos()/(float)gridHeight+superRows-1) << " in\n";
758  }
759  else
760  {
761  t << "0 " << (di->xPos()/(float)gridWidth) << " "
762  << ((float)superRows-0.25-di->yPos()/(float)gridHeight)
763  << " in\n";
764  }
765  }
766  }
767  else // multiple children, put them in a vertical list
768  {
769  if (bitmap)
770  {
771  x = di->parentItem()->xPos()*
772  (cellWidth+labelHorSpacing)/gridWidth+cellWidth/2;
773  if (doBase) // base classes
774  {
775  ys = image->getHeight()-
776  (superRows-1)*(cellHeight+labelVertSpacing)-
777  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
778  y = ys - cellHeight/2;
779  }
780  else // super classes
781  {
782  ys = (baseRows-1)*(cellHeight+labelVertSpacing)+
783  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
784  y = ys + cellHeight/2;
785  }
786  }
787  else
788  {
789  xf = di->parentItem()->xPos()/(float)gridWidth;
790  if (doBase)
791  {
792  ysf = di->yPos()/(float)gridHeight+superRows-1;
793  yf = ysf + 0.5f;
794  }
795  else
796  {
797  ysf = (float)superRows-0.25f-di->yPos()/(float)gridHeight;
798  yf = ysf - 0.25f;
799  }
800  }
801  while (di!=last) // more children to add
802  {
803  if (bitmap)
804  {
805  if (doBase) // base classes
806  {
807  image->drawHorzArrow(y,x,x+cellWidth/2+labelHorSpacing,
808  protToColor(di->protection()),
809  protToMask(di->protection()));
810  y -= cellHeight+labelVertSpacing;
811  }
812  else // super classes
813  {
814  image->drawHorzLine(y,x,x+cellWidth/2+labelHorSpacing,
815  protToColor(di->protection()),
816  protToMask(di->protection()));
817  y += cellHeight+labelVertSpacing;
818  }
819  }
820  else
821  {
822  t << protToString(di->protection()) << endl;
823  if (doBase)
824  {
825  t << "1 " << xf << " " << yf << " hedge\n";
826  yf += 1.0f;
827  }
828  else
829  {
830  t << "0 " << xf << " " << yf << " hedge\n";
831  yf -= 1.0f;
832  }
833  }
834  ++rit; di=rit.current();
835  }
836  // add last horizonal line and a vertical connection line
837  if (bitmap)
838  {
839  if (doBase) // base classes
840  {
841  image->drawHorzArrow(y,x,x+cellWidth/2+labelHorSpacing,
842  protToColor(di->protection()),
843  protToMask(di->protection()));
844  image->drawVertLine(x,y,ys+labelVertSpacing/2,
847  }
848  else // super classes
849  {
850  image->drawHorzLine(y,x,x+cellWidth/2+labelHorSpacing,
851  protToColor(di->protection()),
852  protToMask(di->protection()));
853  image->drawVertLine(x,ys-labelVertSpacing/2,y,
856  }
857  }
858  else
859  {
860  t << protToString(di->protection()) << endl;
861  if (doBase)
862  {
863  t << "1 " << xf << " " << yf << " hedge\n";
864  }
865  else
866  {
867  t << "0 " << xf << " " << yf << " hedge\n";
868  }
870  if (doBase)
871  {
872  t << xf << " " << ysf << " " << yf << " vedge\n";
873  }
874  else
875  {
876  t << xf << " " << (ysf + 0.25) << " " << yf << " vedge\n";
877  }
878  }
879  }
880  }
881  done=TRUE; // the tree is drawn now
882  }
883  else // normal tree connector
884  {
885  for (;(di=rit.current());++rit)
886  {
887  int x=0,y=0;
888  DiagramItemList *dil = di->getChildren();
889  DiagramItem *parent = di->parentItem();
890  if (parent) // item has a parent -> connect to it
891  {
892  if (bitmap) // draw pixels
893  {
894  x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
895  if (doBase) // base classes
896  {
897  y = image->getHeight()-
898  (superRows-1)*(cellHeight+labelVertSpacing)-
899  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
900  /* write input line */
901  image->drawVertArrow(x,y,y+labelVertSpacing/2,
902  protToColor(di->protection()),
903  protToMask(di->protection()));
904  }
905  else // super classes
906  {
907  y = (baseRows-1)*(cellHeight+labelVertSpacing)-
909  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
910  /* write output line */
911  image->drawVertLine(x,y,y+labelVertSpacing/2,
912  protToColor(di->protection()),
913  protToMask(di->protection()));
914  }
915  }
916  else // draw pixels
917  {
918  t << protToString(di->protection()) << endl;
919  if (doBase)
920  {
921  t << "1 " << di->xPos()/(float)gridWidth << " "
922  << (di->yPos()/(float)gridHeight+superRows-1) << " in\n";
923  }
924  else
925  {
926  t << "0 " << di->xPos()/(float)gridWidth << " "
927  << ((float)superRows-0.25-di->yPos()/(float)gridHeight)
928  << " in\n";
929  }
930  }
931  }
932  if (dil->count()>0)
933  {
935  uint mask=protToMask(p);
936  uint col=protToColor(p);
937  if (bitmap)
938  {
939  x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
940  if (doBase) // base classes
941  {
942  y = image->getHeight()-
943  (superRows-1)*(cellHeight+labelVertSpacing)-
944  cellHeight-labelVertSpacing/2-
945  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
946  image->drawVertLine(x,y,y+labelVertSpacing/2-1,col,mask);
947  }
948  else // super classes
949  {
950  y = (baseRows-1)*(cellHeight+labelVertSpacing)+
951  cellHeight+
952  di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
953  image->drawVertArrow(x,y,y+labelVertSpacing/2-1,col,mask);
954  }
955  }
956  else
957  {
958  t << protToString(p) << endl;
959  if (doBase)
960  {
961  t << "0 " << di->xPos()/(float)gridWidth << " "
962  << (di->yPos()/(float)gridHeight+superRows-1) << " out\n";
963  }
964  else
965  {
966  t << "1 " << di->xPos()/(float)gridWidth << " "
967  << ((float)superRows-1.75-di->yPos()/(float)gridHeight)
968  << " out\n";
969  }
970  }
971  /* write input line */
972  DiagramItem *first = dil->getFirst();
973  DiagramItem *last = dil->getLast();
974  if (first!=last && !first->isInList()) /* connect with all base classes */
975  {
976  if (bitmap)
977  {
978  int xs = first->xPos()*(cellWidth+labelHorSpacing)/gridWidth
979  + cellWidth/2;
980  int xe = last->xPos()*(cellWidth+labelHorSpacing)/gridWidth
981  + cellWidth/2;
982  if (doBase) // base classes
983  {
984  image->drawHorzLine(y,xs,xe,col,mask);
985  }
986  else // super classes
987  {
988  image->drawHorzLine(y+labelVertSpacing/2,xs,xe,col,mask);
989  }
990  }
991  else
992  {
993  t << protToString(p) << endl;
994  if (doBase)
995  {
996  t << first->xPos()/(float)gridWidth << " "
997  << last->xPos()/(float)gridWidth << " "
998  << (first->yPos()/(float)gridHeight+superRows-1)
999  << " conn\n";
1000  }
1001  else
1002  {
1003  t << first->xPos()/(float)gridWidth << " "
1004  << last->xPos()/(float)gridWidth << " "
1005  << ((float)superRows-first->yPos()/(float)gridHeight)
1006  << " conn\n";
1007  }
1008  }
1009  }
1010  }
1011  }
1012  }
1013  }
1014 }
1015 
1016 
1018 {
1020  ClassDef *cd;
1021  for (;(cd=cli.current());++cli)
1022  {
1023  cd->visited=FALSE;
1024  }
1025 }
1026 
1028 {
1029  clearVisitFlags();
1030  base = new TreeDiagram(root,TRUE);
1031  base->computeLayout();
1032  clearVisitFlags();
1033  super = new TreeDiagram(root,FALSE);
1034  super->computeLayout();
1035  DiagramItem *baseItem = base->getFirst()->getFirst();
1036  DiagramItem *superItem = super->getFirst()->getFirst();
1037  int xbase = baseItem->xPos();
1038  int xsuper = superItem->xPos();
1039  if (xbase>xsuper)
1040  {
1041  superItem->move(xbase-xsuper,0);
1042  super->moveChildren(superItem,xbase-xsuper);
1043  }
1044  else if (xbase<xsuper)
1045  {
1046  baseItem->move(xsuper-xbase,0);
1047  base->moveChildren(baseItem,xsuper-xbase);
1048  }
1049 }
1050 
1052 {
1053  delete base;
1054  delete super;
1055 }
1056 
1058  const char *fileName) const
1059 {
1060  uint baseRows=base->computeRows();
1061  uint superRows=super->computeRows();
1062  uint baseMaxX, baseMaxLabelWidth, superMaxX, superMaxLabelWidth;
1063  base->computeExtremes(&baseMaxLabelWidth,&baseMaxX);
1064  super->computeExtremes(&superMaxLabelWidth,&superMaxX);
1065 
1066  uint rows=baseRows+superRows-1;
1067  uint cols=(QMAX(baseMaxX,superMaxX)+gridWidth*2-1)/gridWidth;
1068 
1069  // Estimate the image aspect width and height in pixels.
1070  uint estHeight = rows*40;
1071  uint estWidth = cols*(20+QMAX(baseMaxLabelWidth,superMaxLabelWidth));
1072  //printf("Estimated size %d x %d\n",estWidth,estHeight);
1073 
1074  const float pageWidth = 14.0f; // estimated page width in cm.
1075  // Somewhat lower to deal with estimation
1076  // errors.
1077 
1078  // compute the image height in centimeters based on the estimates
1079  float realHeight = QMIN(rows,12); // real height in cm
1080  float realWidth = realHeight * estWidth/(float)estHeight;
1081  if (realWidth>pageWidth) // assume that the page width is about 15 cm
1082  {
1083  realHeight*=pageWidth/realWidth;
1084  realWidth=pageWidth;
1085  }
1086 
1087  //output << "}\n";
1088  output << "\\begin{figure}[H]\n"
1089  "\\begin{center}\n"
1090  "\\leavevmode\n";
1091  output << "\\includegraphics[height=" << realHeight << "cm]{"
1092  << fileName << "}" << endl;
1093  output << "\\end{center}\n"
1094  "\\end{figure}\n";
1095 
1096  //printf("writeFigure rows=%d cols=%d\n",rows,cols);
1097 
1098  QCString epsBaseName=(QCString)path+"/"+fileName;
1099  QCString epsName=epsBaseName+".eps";
1100  QFile f1;
1101  f1.setName(epsName.data());
1102  if (!f1.open(IO_WriteOnly))
1103  {
1104  err("Could not open file %s for writing\n",f1.name().data());
1105  exit(1);
1106  }
1107  FTextStream t(&f1);
1108 
1109  //printf("writeEPS() rows=%d cols=%d\n",rows,cols);
1110 
1111  // generate EPS header and postscript variables and procedures
1112 
1113  t << "%!PS-Adobe-2.0 EPSF-2.0\n";
1114  t << "%%Title: ClassName\n";
1115  t << "%%Creator: Doxygen\n";
1116  t << "%%CreationDate: Time\n";
1117  t << "%%For: \n";
1118  t << "%Magnification: 1.00\n";
1119  t << "%%Orientation: Portrait\n";
1120  t << "%%BoundingBox: 0 0 500 " << estHeight*500.0/(float)estWidth << "\n";
1121  t << "%%Pages: 0\n";
1122  t << "%%BeginSetup\n";
1123  t << "%%EndSetup\n";
1124  t << "%%EndComments\n";
1125  t << "\n";
1126  t << "% ----- variables -----\n";
1127  t << "\n";
1128  t << "/boxwidth 0 def\n";
1129  t << "/boxheight 40 def\n";
1130  t << "/fontheight 24 def\n";
1131  t << "/marginwidth 10 def\n";
1132  t << "/distx 20 def\n";
1133  t << "/disty 40 def\n";
1134  t << "/boundaspect " << estWidth/(float)estHeight << " def % aspect ratio of the BoundingBox (width/height)\n";
1135  t << "/boundx 500 def\n";
1136  t << "/boundy boundx boundaspect div def\n";
1137  t << "/xspacing 0 def\n";
1138  t << "/yspacing 0 def\n";
1139  t << "/rows " << rows << " def\n";
1140  t << "/cols " << cols << " def\n";
1141  t << "/scalefactor 0 def\n";
1142  t << "/boxfont /Times-Roman findfont fontheight scalefont def\n";
1143  t << "\n";
1144  t << "% ----- procedures -----\n";
1145  t << "\n";
1146  t << "/dotted { [1 4] 0 setdash } def\n";
1147  t << "/dashed { [5] 0 setdash } def\n";
1148  t << "/solid { [] 0 setdash } def\n";
1149  t << "\n";
1150  t << "/max % result = MAX(arg1,arg2)\n";
1151  t << "{\n";
1152  t << " /a exch def\n";
1153  t << " /b exch def\n";
1154  t << " a b gt {a} {b} ifelse\n";
1155  t << "} def\n";
1156  t << "\n";
1157  t << "/xoffset % result = MAX(0,(scalefactor-(boxwidth*cols+distx*(cols-1)))/2)\n";
1158  t << "{\n";
1159  t << " 0 scalefactor boxwidth cols mul distx cols 1 sub mul add sub 2 div max\n";
1160  t << "} def\n";
1161  t << "\n";
1162  t << "/cw % boxwidth = MAX(boxwidth, stringwidth(arg1))\n";
1163  t << "{\n";
1164  t << " /str exch def\n";
1165  t << " /boxwidth boxwidth str stringwidth pop max def\n";
1166  t << "} def\n";
1167  t << "\n";
1168  t << "/box % draws a box with text `arg1' at grid pos (arg2,arg3)\n";
1169  t << "{ gsave\n";
1170  t << " 2 setlinewidth\n";
1171  t << " newpath\n";
1172  t << " exch xspacing mul xoffset add\n";
1173  t << " exch yspacing mul\n";
1174  t << " moveto\n";
1175  t << " boxwidth 0 rlineto \n";
1176  t << " 0 boxheight rlineto \n";
1177  t << " boxwidth neg 0 rlineto \n";
1178  t << " 0 boxheight neg rlineto \n";
1179  t << " closepath\n";
1180  t << " dup stringwidth pop neg boxwidth add 2 div\n";
1181  t << " boxheight fontheight 2 div sub 2 div\n";
1182  t << " rmoveto show stroke\n";
1183  t << " grestore\n";
1184  t << "} def \n";
1185  t << "\n";
1186  t << "/mark\n";
1187  t << "{ newpath\n";
1188  t << " exch xspacing mul xoffset add boxwidth add\n";
1189  t << " exch yspacing mul\n";
1190  t << " moveto\n";
1191  t << " 0 boxheight 4 div rlineto\n";
1192  t << " boxheight neg 4 div boxheight neg 4 div rlineto\n";
1193  t << " closepath\n";
1194  t << " eofill\n";
1195  t << " stroke\n";
1196  t << "} def\n";
1197  t << "\n";
1198  t << "/arrow\n";
1199  t << "{ newpath\n";
1200  t << " moveto\n";
1201  t << " 3 -8 rlineto\n";
1202  t << " -6 0 rlineto\n";
1203  t << " 3 8 rlineto\n";
1204  t << " closepath\n";
1205  t << " eofill\n";
1206  t << " stroke\n";
1207  t << "} def\n";
1208  t << "\n";
1209  t << "/out % draws an output connector for the block at (arg1,arg2)\n";
1210  t << "{\n";
1211  t << " newpath\n";
1212  t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
1213  t << " exch yspacing mul boxheight add\n";
1214  t << " /y exch def\n";
1215  t << " /x exch def\n";
1216  t << " x y moveto\n";
1217  t << " 0 disty 2 div rlineto \n";
1218  t << " stroke\n";
1219  t << " 1 eq { x y disty 2 div add arrow } if\n";
1220  t << "} def\n";
1221  t << "\n";
1222  t << "/in % draws an input connector for the block at (arg1,arg2)\n";
1223  t << "{\n";
1224  t << " newpath\n";
1225  t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
1226  t << " exch yspacing mul disty 2 div sub\n";
1227  t << " /y exch def\n";
1228  t << " /x exch def\n";
1229  t << " x y moveto\n";
1230  t << " 0 disty 2 div rlineto\n";
1231  t << " stroke\n";
1232  t << " 1 eq { x y disty 2 div add arrow } if\n";
1233  t << "} def\n";
1234  t << "\n";
1235  t << "/hedge\n";
1236  t << "{\n";
1237  t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
1238  t << " exch yspacing mul boxheight 2 div sub\n";
1239  t << " /y exch def\n";
1240  t << " /x exch def\n";
1241  t << " newpath\n";
1242  t << " x y moveto\n";
1243  t << " boxwidth 2 div distx add 0 rlineto\n";
1244  t << " stroke\n";
1245  t << " 1 eq\n";
1246  t << " { newpath x boxwidth 2 div distx add add y moveto\n";
1247  t << " -8 3 rlineto\n";
1248  t << " 0 -6 rlineto\n";
1249  t << " 8 3 rlineto\n";
1250  t << " closepath\n";
1251  t << " eofill\n";
1252  t << " stroke\n";
1253  t << " } if\n";
1254  t << "} def\n";
1255  t << "\n";
1256  t << "/vedge\n";
1257  t << "{\n";
1258  t << " /ye exch def\n";
1259  t << " /ys exch def\n";
1260  t << " /xs exch def\n";
1261  t << " newpath\n";
1262  t << " xs xspacing mul xoffset add boxwidth 2 div add dup\n";
1263  t << " ys yspacing mul boxheight 2 div sub\n";
1264  t << " moveto\n";
1265  t << " ye yspacing mul boxheight 2 div sub\n";
1266  t << " lineto\n";
1267  t << " stroke\n";
1268  t << "} def\n";
1269  t << "\n";
1270  t << "/conn % connections the blocks from col `arg1' to `arg2' of row `arg3'\n";
1271  t << "{\n";
1272  t << " /ys exch def\n";
1273  t << " /xe exch def\n";
1274  t << " /xs exch def\n";
1275  t << " newpath\n";
1276  t << " xs xspacing mul xoffset add boxwidth 2 div add\n";
1277  t << " ys yspacing mul disty 2 div sub\n";
1278  t << " moveto\n";
1279  t << " xspacing xe xs sub mul 0\n";
1280  t << " rlineto\n";
1281  t << " stroke\n";
1282  t << "} def\n";
1283  t << "\n";
1284  t << "% ----- main ------\n";
1285  t << "\n";
1286  t << "boxfont setfont\n";
1287  t << "1 boundaspect scale\n";
1288 
1289 
1290  bool done=FALSE;
1292  DiagramRow *dr;
1293  for (;(dr=bit.current()) && !done;++bit)
1294  {
1295  QListIterator<DiagramItem> rit(*dr);
1296  DiagramItem *di;
1297  for (;(di=rit.current());++rit)
1298  {
1299  done=di->isInList();
1300  t << "(" << di->label() << ") cw\n";
1301  }
1302  }
1303  QListIterator<DiagramRow> sit(*super);
1304  ++sit;
1305  done=FALSE;
1306  for (;(dr=sit.current()) && !done;++sit)
1307  {
1308  QListIterator<DiagramItem> rit(*dr);
1309  DiagramItem *di;
1310  for (;(di=rit.current());++rit)
1311  {
1312  done=di->isInList();
1313  t << "(" << di->label() << ") cw\n";
1314  }
1315  }
1316 
1317  t << "/boxwidth boxwidth marginwidth 2 mul add def\n"
1318  << "/xspacing boxwidth distx add def\n"
1319  << "/yspacing boxheight disty add def\n"
1320  << "/scalefactor \n"
1321  << " boxwidth cols mul distx cols 1 sub mul add\n"
1322  << " boxheight rows mul disty rows 1 sub mul add boundaspect mul \n"
1323  << " max def\n"
1324  << "boundx scalefactor div boundy scalefactor div scale\n";
1325 
1326  t << "\n% ----- classes -----\n\n";
1327  base->drawBoxes(t,0,TRUE,FALSE,baseRows,superRows,0,0);
1328  super->drawBoxes(t,0,FALSE,FALSE,baseRows,superRows,0,0);
1329 
1330  t << "\n% ----- relations -----\n\n";
1331  base->drawConnectors(t,0,TRUE,FALSE,baseRows,superRows,0,0);
1332  super->drawConnectors(t,0,FALSE,FALSE,baseRows,superRows,0,0);
1333 
1334  f1.close();
1335  if (Config_getBool("USE_PDFLATEX"))
1336  {
1337  QCString epstopdfArgs(4096);
1338  epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"",
1339  epsBaseName.data(),epsBaseName.data());
1340  //printf("Converting eps using `%s'\n",epstopdfArgs.data());
1342  if (portable_system("epstopdf",epstopdfArgs)!=0)
1343  {
1344  err("Problems running epstopdf. Check your TeX installation!\n");
1346  return;
1347  }
1349  }
1350 }
1351 
1352 
1353 void ClassDiagram::writeImage(FTextStream &t,const char *path,
1354  const char *relPath,const char *fileName,
1355  bool generateMap) const
1356 {
1357  uint baseRows=base->computeRows();
1358  uint superRows=super->computeRows();
1359  uint rows=baseRows+superRows-1;
1360 
1361  uint lb,ls,xb,xs;
1362  base->computeExtremes(&lb,&xb);
1363  super->computeExtremes(&ls,&xs);
1364 
1365  uint cellWidth = QMAX(lb,ls)+labelHorMargin*2;
1366  uint maxXPos = QMAX(xb,xs);
1367  uint labelVertMargin = 6; //QMAX(6,(cellWidth-fontHeight)/6); // aspect at least 1:3
1368  uint cellHeight = labelVertMargin*2+fontHeight;
1369  uint imageWidth = (maxXPos+gridWidth)*cellWidth/gridWidth+
1370  (maxXPos*labelHorSpacing)/gridWidth;
1371  uint imageHeight = rows*cellHeight+(rows-1)*labelVertSpacing;
1372 
1373  Image image(imageWidth,imageHeight);
1374 
1375  base->drawBoxes(t,&image,TRUE,TRUE,baseRows,superRows,cellWidth,cellHeight,relPath,generateMap);
1376  super->drawBoxes(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight,relPath,generateMap);
1377  base->drawConnectors(t,&image,TRUE,TRUE,baseRows,superRows,cellWidth,cellHeight);
1378  super->drawConnectors(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight);
1379 
1380 #define IMAGE_EXT ".png"
1381  image.save((QCString)path+"/"+fileName+IMAGE_EXT);
1383 
1384  if (generateMap) t << "</map>" << endl;
1385 }
1386 
void computeExtremes(uint *labelWidth, uint *xpos)
Definition: diagram.cpp:555
QCString convertToXML(const char *s)
Definition: util.cpp:5717
void move(int dx, int dy)
Definition: diagram.cpp:52
ClassDef * classDef
Definition: classdef.h:520
uint getHeight() const
Definition: image.h:43
DiagramRowIterator(const QList< DiagramRow > &d)
Definition: diagram.cpp:106
void portable_sysTimerStop()
Definition: portable.cpp:415
static uint protToColor(Protection p)
Definition: diagram.cpp:174
ClassDiagram(ClassDef *root)
Definition: diagram.cpp:1027
void fillRect(int x, int y, int width, int height, uchar colIndex, uint mask)
Definition: image.cpp:374
DiagramItem(DiagramItem *p, int number, ClassDef *cd, Protection prot, Specifier virt, const char *ts)
Definition: diagram.cpp:286
BaseClassList * subClasses() const
Definition: classdef.cpp:4404
void putInList()
Definition: diagram.cpp:61
Definition: types.h:29
void writeFigure(FTextStream &t, const char *path, const char *file) const
Definition: diagram.cpp:1057
static QCString result
bool isEmpty() const
Definition: qcstring.h:189
QString name() const
Definition: qfile.h:121
uint length() const
Definition: qcstring.h:195
TH3F * xpos
Definition: doAna.cpp:29
const uint maxTreeWidth
Definition: diagram.cpp:141
int yPos() const
Definition: diagram.cpp:54
int xPos() const
Definition: diagram.cpp:53
void append(const type *d)
Definition: qlist.h:73
TreeDiagram * diagram
Definition: diagram.cpp:98
#define IO_WriteOnly
Definition: qiodevice.h:62
Definition: types.h:26
static QCString htmlFileExtension
Definition: doxygen.h:130
void drawHorzArrow(int y, int xs, int xe, uchar colIndex, uint mask)
Definition: image.cpp:335
static Protection getMinProtectionLevel(DiagramItemList *dil)
Definition: diagram.cpp:210
void drawHorzLine(int y, int xs, int xe, uchar colIndex, uint mask)
Definition: image.cpp:325
ClassDef * getClassDef() const
Definition: diagram.cpp:63
friend uint stringLength(const char *s)
Definition: image.cpp:314
ClassDef * classDef
Definition: diagram.cpp:73
Protection protection() const
Definition: diagram.cpp:59
bool isInList() const
Definition: diagram.cpp:62
const bool FALSE
Definition: qglobal.h:370
Definition: types.h:26
int number() const
Definition: diagram.cpp:58
uint number()
Definition: diagram.cpp:96
const int gridHeight
Definition: diagram.cpp:143
DiagramRow(TreeDiagram *d, int l)
Definition: diagram.cpp:88
type * at(uint i) const
Definition: qlist.h:94
Protection prot
Definition: classdef.h:530
QCString fileName() const
Definition: diagram.cpp:328
QCString left(uint len) const
Definition: qcstring.cpp:213
Simplified and optimized version of QTextStream.
Definition: ftextstream.h:11
QCString displayName(bool includeScope=TRUE) const
Definition: classdef.cpp:312
void setName(const QString &name)
Definition: qfile.cpp:167
static QStrList * l
Definition: config.cpp:1044
Definition: types.h:26
QCString getReference() const
Definition: classdef.cpp:3814
Definition: types.h:29
void insertClass(DiagramItem *parent, ClassDef *cd, bool doBases, Protection prot, Specifier virt, const char *ts)
Definition: diagram.cpp:357
int avgChildPos() const
Definition: diagram.cpp:333
void writeString(int x, int y, const char *s, uchar fg)
Definition: image.cpp:301
void portable_sysTimerStart()
Definition: portable.cpp:410
DiagramItem * parentItem()
Definition: diagram.cpp:50
#define QMIN(a, b)
Definition: qglobal.h:391
Specifier virt
Definition: diagram.cpp:70
const uint labelHorMargin
Definition: diagram.cpp:147
#define IMAGE_EXT
static void writeBitmapBox(DiagramItem *di, Image *image, int x, int y, int w, int h, bool firstRow, bool hasDocs, bool children=FALSE)
Definition: diagram.cpp:227
def cli(ctx)
Definition: main.py:7
uint count() const
Definition: qlist.h:66
static QCString protToString(Protection p)
Definition: diagram.cpp:186
const char * data() const
Definition: qstring.h:542
type * getLast() const
Definition: qlist.h:96
void drawConnectors(FTextStream &t, Image *image, bool doBase, bool bitmap, uint baseRows, uint superRows, uint cellWidth, uint cellheight)
Definition: diagram.cpp:706
uint level
Definition: diagram.cpp:99
#define QMAX(a, b)
Definition: qglobal.h:390
DiagramItem * parent
Definition: diagram.cpp:66
const QCString & name() const
Definition: definition.h:114
QCString templSpec
Definition: diagram.cpp:71
void writeImage(FTextStream &t, const char *path, const char *relPath, const char *file, bool generateMap=TRUE) const
Definition: diagram.cpp:1353
QCString convertToHtml(const char *s, bool keepEntities)
Definition: util.cpp:5746
QCString right(uint len) const
Definition: qcstring.cpp:231
std::void_t< T > n
bool open(int)
Definition: qfile_unix.cpp:134
void drawRect(int x, int y, int width, int height, uchar colIndex, uint mask)
Definition: image.cpp:366
QCString anchor() const
Definition: classdef.cpp:4606
Specifier
Definition: types.h:29
const uint labelHorSpacing
Definition: diagram.cpp:145
p
Definition: test.py:223
A bunch of utility functions.
const char * data() const
Definition: qcstring.h:207
bool isLinkable() const
Definition: classdef.cpp:2729
void addImageFile(const char *name)
Definition: index.h:147
type * current() const
Definition: qlist.h:146
Specifier virtualness() const
Definition: diagram.cpp:60
#define Config_getBool(val)
Definition: config.cpp:664
type * getFirst() const
Definition: qlist.h:95
bool inList
Definition: diagram.cpp:72
void err(const char *fmt,...)
Definition: message.cpp:226
bool visited
Definition: classdef.h:402
DiagramItemList * getChildren()
Definition: diagram.cpp:51
static void writeMapArea(FTextStream &t, ClassDef *cd, QCString relPath, int x, int y, int w, int h)
Definition: diagram.cpp:255
The QFile class is an I/O device that operates on files.
Definition: qfile.h:50
QCString & sprintf(const char *format,...)
Definition: qcstring.cpp:27
const uint fontHeight
Definition: diagram.cpp:148
QCString getOutputFileBase() const
Definition: classdef.cpp:3533
Specifier virt
Definition: classdef.h:535
static uint virtToMask(Specifier p)
Definition: diagram.cpp:198
QCString templSpecifiers
Definition: classdef.h:538
uint computeRows()
Definition: diagram.cpp:525
bool isVisibleInHierarchy()
Definition: classdef.cpp:2743
void drawBoxes(FTextStream &t, Image *image, bool doBase, bool bitmap, uint baseRows, uint superRows, uint cellWidth, uint cellHeight, QCString relPath="", bool generateMap=TRUE)
Definition: diagram.cpp:576
Protection prot
Definition: diagram.cpp:69
QCString stripScope(const char *name)
Definition: util.cpp:5605
void drawVertArrow(int x, int ys, int ye, uchar colIndex, uint mask)
Definition: image.cpp:355
Definition: image.h:24
QCString insertTemplateSpecifierInScope(const QCString &scope, const QCString &templ)
Definition: util.cpp:5527
QCString label() const
Definition: diagram.cpp:306
void drawVertLine(int x, int ys, int ye, uchar colIndex, uint mask)
Definition: image.cpp:346
Protection
Definition: types.h:26
static uint protToMask(Protection p)
Definition: diagram.cpp:162
TreeDiagram(ClassDef *root, bool doBases)
Definition: diagram.cpp:409
friend class Iterator
Definition: sortdict.h:289
float pi
Definition: units.py:11
QCString briefDescriptionAsTooltip() const
static void writeVectorBox(FTextStream &t, DiagramItem *di, float x, float y, bool children=FALSE)
Definition: diagram.cpp:246
void computeLayout()
Definition: diagram.cpp:475
void addChild(DiagramItem *di)
Definition: diagram.cpp:352
static constexpr double ys
Definition: Units.h:103
void close()
Definition: qfile_unix.cpp:614
bool layoutTree(DiagramItem *root, int row)
Definition: diagram.cpp:434
const int gridWidth
Definition: diagram.cpp:142
DiagramItemList * children
Definition: diagram.cpp:65
unsigned uint
Definition: qglobal.h:351
static ClassSDict * classSDict
Definition: doxygen.h:99
QCString externalLinkTarget()
Definition: util.cpp:7850
void moveChildren(DiagramItem *root, int dx)
Definition: diagram.cpp:422
type * toLast()
Definition: qlist.h:136
const bool TRUE
Definition: qglobal.h:371
static IndexList * indexList
Definition: doxygen.h:149
Portable versions of functions that are platform dependent.
const uint labelVertSpacing
Definition: diagram.cpp:146
QTextStream & endl(QTextStream &s)
int numChildren() const
Definition: diagram.cpp:347
BaseClassList * baseClasses() const
Definition: classdef.cpp:4399
Definition: qlist.h:54
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition: util.cpp:7856
int portable_system(const char *command, const char *args, bool commandHasConsole)
Definition: portable.cpp:33
type * toFirst()
Definition: qlist.h:135
void clearVisitFlags()
Definition: diagram.cpp:1017