|
Packit |
1c1d7e |
/******************************************************************************
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* Copyright (C) 1997-2015 by Dimitri van Heesch.
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* Permission to use, copy, modify, and distribute this software and its
|
|
Packit |
1c1d7e |
* documentation under the terms of the GNU General Public License is hereby
|
|
Packit |
1c1d7e |
* granted. No representations are made about the suitability of this software
|
|
Packit |
1c1d7e |
* for any purpose. It is provided "as is" without express or implied warranty.
|
|
Packit |
1c1d7e |
* See the GNU General Public License for more details.
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* Documents produced by Doxygen are derivative works derived from the
|
|
Packit |
1c1d7e |
* input used in their production; they are not affected by this license.
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#include <stdio.h>
|
|
Packit |
1c1d7e |
#include <stdlib.h>
|
|
Packit |
1c1d7e |
#include <qlist.h>
|
|
Packit |
1c1d7e |
#include <qarray.h>
|
|
Packit |
1c1d7e |
#include "ftextstream.h"
|
|
Packit |
1c1d7e |
#include <qfile.h>
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#include "diagram.h"
|
|
Packit |
1c1d7e |
#include "image.h"
|
|
Packit |
1c1d7e |
#include "classdef.h"
|
|
Packit |
1c1d7e |
#include "config.h"
|
|
Packit |
1c1d7e |
#include "message.h"
|
|
Packit |
1c1d7e |
#include "util.h"
|
|
Packit |
1c1d7e |
#include "doxygen.h"
|
|
Packit |
1c1d7e |
#include "portable.h"
|
|
Packit |
1c1d7e |
#include "index.h"
|
|
Packit |
1c1d7e |
#include "classlist.h"
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//-----------------------------------------------------------------------------
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
class DiagramItemList;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/** Class representing a single node in the built-in class diagram */
|
|
Packit |
1c1d7e |
class DiagramItem
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
public:
|
|
Packit |
1c1d7e |
DiagramItem(DiagramItem *p,int number,ClassDef *cd,
|
|
Packit |
1c1d7e |
Protection prot,Specifier virt,const char *ts);
|
|
Packit |
1c1d7e |
~DiagramItem();
|
|
Packit |
1c1d7e |
QCString label() const;
|
|
Packit |
1c1d7e |
QCString fileName() const;
|
|
Packit |
1c1d7e |
DiagramItem *parentItem() { return parent; }
|
|
Packit |
1c1d7e |
DiagramItemList *getChildren() { return children; }
|
|
Packit |
1c1d7e |
void move(int dx,int dy) { x+=dx; y+=dy; }
|
|
Packit |
1c1d7e |
int xPos() const { return x; }
|
|
Packit |
1c1d7e |
int yPos() const { return y; }
|
|
Packit |
1c1d7e |
int avgChildPos() const;
|
|
Packit |
1c1d7e |
int numChildren() const;
|
|
Packit |
1c1d7e |
void addChild(DiagramItem *di);
|
|
Packit |
1c1d7e |
int number() const { return num; }
|
|
Packit |
1c1d7e |
Protection protection() const { return prot; }
|
|
Packit |
1c1d7e |
Specifier virtualness() const { return virt; }
|
|
Packit |
1c1d7e |
void putInList() { inList=TRUE; }
|
|
Packit |
1c1d7e |
bool isInList() const { return inList; }
|
|
Packit |
1c1d7e |
ClassDef *getClassDef() const { return classDef; }
|
|
Packit |
1c1d7e |
private:
|
|
Packit |
1c1d7e |
DiagramItemList *children;
|
|
Packit |
1c1d7e |
DiagramItem *parent;
|
|
Packit |
1c1d7e |
int x,y;
|
|
Packit |
1c1d7e |
int num;
|
|
Packit |
1c1d7e |
Protection prot;
|
|
Packit |
1c1d7e |
Specifier virt;
|
|
Packit |
1c1d7e |
QCString templSpec;
|
|
Packit |
1c1d7e |
bool inList;
|
|
Packit |
1c1d7e |
ClassDef *classDef;
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/** Class representing a list of DiagramItem object. */
|
|
Packit |
1c1d7e |
class DiagramItemList : public QList<DiagramItem>
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
public:
|
|
Packit |
1c1d7e |
DiagramItemList() : QList<DiagramItem>() {}
|
|
Packit |
1c1d7e |
~DiagramItemList() {}
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/** Class representing a row in the built-in class diagram */
|
|
Packit |
1c1d7e |
class DiagramRow : public QList<DiagramItem>
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
public:
|
|
Packit |
1c1d7e |
DiagramRow(TreeDiagram *d,int l) : QList<DiagramItem>()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
diagram=d;
|
|
Packit |
1c1d7e |
level=l;
|
|
Packit |
1c1d7e |
setAutoDelete(TRUE);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
void insertClass(DiagramItem *parent,ClassDef *cd,bool doBases,
|
|
Packit |
1c1d7e |
Protection prot,Specifier virt,const char *ts);
|
|
Packit |
1c1d7e |
uint number() { return level; }
|
|
Packit |
1c1d7e |
private:
|
|
Packit |
1c1d7e |
TreeDiagram *diagram;
|
|
Packit |
1c1d7e |
uint level;
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/** Class representing iterator for the rows in the built-in class diagram. */
|
|
Packit |
1c1d7e |
class DiagramRowIterator : public QListIterator<DiagramRow>
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
public:
|
|
Packit |
1c1d7e |
DiagramRowIterator(const QList<DiagramRow> &d)
|
|
Packit |
1c1d7e |
: QListIterator<DiagramRow>(d) {}
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/** Class represeting the tree layout for the built-in class diagram. */
|
|
Packit |
1c1d7e |
class TreeDiagram : public QList<DiagramRow>
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
public:
|
|
Packit |
1c1d7e |
TreeDiagram(ClassDef *root,bool doBases);
|
|
Packit |
1c1d7e |
~TreeDiagram();
|
|
Packit |
1c1d7e |
void computeLayout();
|
|
Packit |
1c1d7e |
uint computeRows();
|
|
Packit |
1c1d7e |
//uint computeCols();
|
|
Packit |
1c1d7e |
void moveChildren(DiagramItem *root,int dx);
|
|
Packit |
1c1d7e |
void computeExtremes(uint *labelWidth,uint *xpos);
|
|
Packit |
1c1d7e |
void drawBoxes(FTextStream &t,Image *image,
|
|
Packit |
1c1d7e |
bool doBase,bool bitmap,
|
|
Packit |
1c1d7e |
uint baseRows,uint superRows,
|
|
Packit |
1c1d7e |
uint cellWidth,uint cellHeight,
|
|
Packit |
1c1d7e |
QCString relPath="",
|
|
Packit |
1c1d7e |
bool generateMap=TRUE);
|
|
Packit |
1c1d7e |
void drawConnectors(FTextStream &t,Image *image,
|
|
Packit |
1c1d7e |
bool doBase,bool bitmap,
|
|
Packit |
1c1d7e |
uint baseRows,uint superRows,
|
|
Packit |
1c1d7e |
uint cellWidth,uint cellheight);
|
|
Packit |
1c1d7e |
private:
|
|
Packit |
1c1d7e |
bool layoutTree(DiagramItem *root,int row);
|
|
Packit |
1c1d7e |
TreeDiagram &operator=(const TreeDiagram &);
|
|
Packit |
1c1d7e |
TreeDiagram(const TreeDiagram &);
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//-----------------------------------------------------------------------------
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
const uint maxTreeWidth = 8;
|
|
Packit |
1c1d7e |
const int gridWidth = 100;
|
|
Packit |
1c1d7e |
const int gridHeight = 100;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
const uint labelHorSpacing = 10; // horizontal distance between labels
|
|
Packit |
1c1d7e |
const uint labelVertSpacing = 32; // vertical distance between labels
|
|
Packit |
1c1d7e |
const uint labelHorMargin = 6; // horiz. spacing between label and box
|
|
Packit |
1c1d7e |
const uint fontHeight = 12; // height of a character
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//static QCString escapeLatex(const char *s)
|
|
Packit |
1c1d7e |
//{
|
|
Packit |
1c1d7e |
// QCString result;
|
|
Packit |
1c1d7e |
// char c;
|
|
Packit |
1c1d7e |
// while ((c=*s++))
|
|
Packit |
1c1d7e |
// {
|
|
Packit |
1c1d7e |
// if (c=='_') result+="\\_";
|
|
Packit |
1c1d7e |
// else result+=c;
|
|
Packit |
1c1d7e |
// }
|
|
Packit |
1c1d7e |
// return result;
|
|
Packit |
1c1d7e |
//}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static uint protToMask(Protection p)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
switch(p)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
case Public: return 0xffffffff;
|
|
Packit |
1c1d7e |
case Package: // package is not possible!
|
|
Packit |
1c1d7e |
case Protected: return 0xcccccccc;
|
|
Packit |
1c1d7e |
case Private: return 0xaaaaaaaa;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return 0;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static uint protToColor(Protection p)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
switch(p)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
case Public: return 6;
|
|
Packit |
1c1d7e |
case Package: // package is not possible!
|
|
Packit |
1c1d7e |
case Protected: return 5;
|
|
Packit |
1c1d7e |
case Private: return 4;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return 0;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static QCString protToString(Protection p)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
switch(p)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
case Public: return "solid";
|
|
Packit |
1c1d7e |
case Package: // package is not possible!
|
|
Packit |
1c1d7e |
case Protected: return "dashed";
|
|
Packit |
1c1d7e |
case Private: return "dotted";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return 0;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static uint virtToMask(Specifier p)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
switch(p)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
case Normal: return 0xffffffff;
|
|
Packit |
1c1d7e |
case Virtual: return 0xf0f0f0f0;
|
|
Packit |
1c1d7e |
default: return 0;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return 0;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// pre: dil is not empty
|
|
Packit |
1c1d7e |
static Protection getMinProtectionLevel(DiagramItemList *dil)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QListIterator<DiagramItem> it(*dil);
|
|
Packit |
1c1d7e |
DiagramItem *di=it.current();
|
|
Packit |
1c1d7e |
Protection result=di->protection();
|
|
Packit |
1c1d7e |
for (++it;(di=it.current());++it)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
Protection p=di->protection();
|
|
Packit |
1c1d7e |
if (p!=result)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (result==Protected && p==Public) result=p;
|
|
Packit |
1c1d7e |
else if (result==Private) result=p;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return result;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void writeBitmapBox(DiagramItem *di,Image *image,
|
|
Packit |
1c1d7e |
int x,int y,int w,int h,bool firstRow,
|
|
Packit |
1c1d7e |
bool hasDocs,bool children=FALSE)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
int colFill = hasDocs ? (firstRow ? 0 : 2) : 7;
|
|
Packit |
1c1d7e |
int colBorder = (firstRow || !hasDocs) ? 1 : 3;
|
|
Packit |
1c1d7e |
int l = Image::stringLength(di->label());
|
|
Packit |
1c1d7e |
uint mask=virtToMask(di->virtualness());
|
|
Packit |
1c1d7e |
image->fillRect(x+1,y+1,w-2,h-2,colFill,mask);
|
|
Packit |
1c1d7e |
image->drawRect(x,y,w,h,colBorder,mask);
|
|
Packit |
1c1d7e |
image->writeString(x+(w-l)/2, y+(h-fontHeight)/2, di->label(),1);
|
|
Packit |
1c1d7e |
if (children)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
int i;
|
|
Packit |
1c1d7e |
for (i=0;i<5;i++)
|
|
Packit |
1c1d7e |
image->drawHorzLine(y+h+i-6,x+w-2-i,x+w-2,firstRow?1:3,0xffffffff);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void writeVectorBox(FTextStream &t,DiagramItem *di,
|
|
Packit |
1c1d7e |
float x,float y,bool children=FALSE)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (di->virtualness()==Virtual) t << "dashed\n";
|
|
Packit |
1c1d7e |
t << " (" << di->label() << ") " << x << " " << y << " box\n";
|
|
Packit |
1c1d7e |
if (children) t << x << " " << y << " mark\n";
|
|
Packit |
1c1d7e |
if (di->virtualness()==Virtual) t << "solid\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void writeMapArea(FTextStream &t,ClassDef *cd,QCString relPath,
|
|
Packit |
1c1d7e |
int x,int y,int w,int h)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (cd->isLinkable())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QCString ref=cd->getReference();
|
|
Packit |
1c1d7e |
t << "
|
|
Packit |
1c1d7e |
if (!ref.isEmpty())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
t << "href=\"";
|
|
Packit |
1c1d7e |
t << externalRef(relPath,ref,TRUE);
|
|
Packit |
1c1d7e |
t << cd->getOutputFileBase() << Doxygen::htmlFileExtension;
|
|
Packit |
1c1d7e |
if (!cd->anchor().isEmpty())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << "#" << cd->anchor();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
t << "\" ";
|
|
Packit |
1c1d7e |
QCString tooltip = cd->briefDescriptionAsTooltip();
|
|
Packit |
1c1d7e |
if (!tooltip.isEmpty())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << "title=\"" << convertToHtml(tooltip) << "\" ";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
t << "alt=\"" << convertToXML(cd->displayName());
|
|
Packit |
1c1d7e |
t << "\" shape=\"rect\" coords=\"" << x << "," << y << ",";
|
|
Packit |
1c1d7e |
t << (x+w) << "," << (y+h) << "\"/>" << endl;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
//-----------------------------------------------------------------------------
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
DiagramItem::DiagramItem(DiagramItem *p,int number,ClassDef *cd,
|
|
Packit |
1c1d7e |
Protection pr,Specifier vi,const char *ts)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
parent=p;
|
|
Packit |
1c1d7e |
x=y=0;
|
|
Packit |
1c1d7e |
//name=n;
|
|
Packit |
1c1d7e |
num=number;
|
|
Packit |
1c1d7e |
children = new DiagramItemList;
|
|
Packit |
1c1d7e |
prot=pr;
|
|
Packit |
1c1d7e |
virt=vi;
|
|
Packit |
1c1d7e |
inList=FALSE;
|
|
Packit |
1c1d7e |
classDef=cd;
|
|
Packit |
1c1d7e |
templSpec=ts;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
DiagramItem::~DiagramItem()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
delete children;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
QCString DiagramItem::label() const
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QCString result;
|
|
Packit |
1c1d7e |
if (!templSpec.isEmpty())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
// we use classDef->name() here and not diplayName() in order
|
|
Packit |
1c1d7e |
// to get the name used in the inheritance relation.
|
|
Packit |
1c1d7e |
QCString n = classDef->name();
|
|
Packit |
1c1d7e |
if (/*n.right(2)=="-g" ||*/ n.right(2)=="-p")
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
n = n.left(n.length()-2);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
result=insertTemplateSpecifierInScope(n,templSpec);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
result=classDef->displayName();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
if (Config_getBool(HIDE_SCOPE_NAMES)) result=stripScope(result);
|
|
Packit |
1c1d7e |
return result;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
QCString DiagramItem::fileName() const
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
return classDef->getOutputFileBase();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
int DiagramItem::avgChildPos() const
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
DiagramItem *di;
|
|
Packit |
1c1d7e |
int c=children->count();
|
|
Packit |
1c1d7e |
if (c==0) // no children -> don't move
|
|
Packit |
1c1d7e |
return xPos();
|
|
Packit |
1c1d7e |
if ((di=children->getFirst())->isInList()) // children should be in a list
|
|
Packit |
1c1d7e |
return di->xPos();
|
|
Packit |
1c1d7e |
if (c&1) // odd number of children -> get pos of middle child
|
|
Packit |
1c1d7e |
return children->at(c/2)->xPos();
|
|
Packit |
1c1d7e |
else // even number of children -> get middle of most middle children
|
|
Packit |
1c1d7e |
return (children->at(c/2-1)->xPos()+children->at(c/2)->xPos())/2;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
int DiagramItem::numChildren() const
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
return children->count();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void DiagramItem::addChild(DiagramItem *di)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
children->append(di);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void DiagramRow::insertClass(DiagramItem *parent,ClassDef *cd,bool doBases,
|
|
Packit |
1c1d7e |
Protection prot,Specifier virt,const char *ts)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//if (cd->visited) return; // the visit check does not work in case of
|
|
Packit |
1c1d7e |
// multiple inheritance of the same class!
|
|
Packit |
1c1d7e |
DiagramItem *di=new DiagramItem(parent, diagram->at(level)->count(),
|
|
Packit |
1c1d7e |
cd,prot,virt,ts);
|
|
Packit |
1c1d7e |
//cd->visited=TRUE;
|
|
Packit |
1c1d7e |
if (parent) parent->addChild(di);
|
|
Packit |
1c1d7e |
di->move(count()*gridWidth,level*gridHeight);
|
|
Packit |
1c1d7e |
append(di);
|
|
Packit |
1c1d7e |
BaseClassList *bcl=doBases ? cd->baseClasses() : cd->subClasses();
|
|
Packit |
1c1d7e |
int count=0;
|
|
Packit |
1c1d7e |
if (bcl)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
/* there are base/sub classes */
|
|
Packit |
1c1d7e |
BaseClassListIterator it(*bcl);
|
|
Packit |
1c1d7e |
BaseClassDef *bcd;
|
|
Packit |
1c1d7e |
for (;(bcd=it.current());++it)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
ClassDef *ccd=bcd->classDef;
|
|
Packit |
1c1d7e |
if (ccd && ccd->isVisibleInHierarchy() /*&& !ccd->visited*/) count++;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
if (count>0 && (prot!=Private || !doBases))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
DiagramRow *row=0;
|
|
Packit |
1c1d7e |
if (diagram->count()<=level+1) /* add new row */
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
row = new DiagramRow(diagram,level+1);
|
|
Packit |
1c1d7e |
diagram->append(row);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else /* get next row */
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
row=diagram->at(level+1);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
/* insert base classes in the next row */
|
|
Packit |
1c1d7e |
BaseClassListIterator it(*bcl);
|
|
Packit |
1c1d7e |
BaseClassDef *bcd;
|
|
Packit |
1c1d7e |
for (;(bcd=it.current());++it)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
ClassDef *ccd=bcd->classDef;
|
|
Packit |
1c1d7e |
if (ccd && ccd->isVisibleInHierarchy() /*&& !ccd->visited*/)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
row->insertClass(di,ccd,doBases,bcd->prot,
|
|
Packit |
1c1d7e |
doBases?bcd->virt:Normal,
|
|
Packit |
1c1d7e |
doBases?bcd->templSpecifiers.data():"");
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
TreeDiagram::TreeDiagram(ClassDef *root,bool doBases)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
setAutoDelete(TRUE);
|
|
Packit |
1c1d7e |
DiagramRow *row=new DiagramRow(this,0);
|
|
Packit |
1c1d7e |
append(row);
|
|
Packit |
1c1d7e |
row->insertClass(0,root,doBases,Public,Normal,0);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
TreeDiagram::~TreeDiagram()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void TreeDiagram::moveChildren(DiagramItem *root,int dx)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
DiagramItemList *dil=root->getChildren();
|
|
Packit |
1c1d7e |
QListIterator<DiagramItem> it(*dil);
|
|
Packit |
1c1d7e |
DiagramItem *di;
|
|
Packit |
1c1d7e |
for (;(di=it.current());++it)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
di->move(dx,0);
|
|
Packit |
1c1d7e |
moveChildren(di,dx);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
bool TreeDiagram::layoutTree(DiagramItem *root,int r)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
bool moved=FALSE;
|
|
Packit |
1c1d7e |
//printf("layoutTree(%s,%d)\n",root->label().data(),r);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
DiagramItemList *dil=root->getChildren();
|
|
Packit |
1c1d7e |
if (dil->count()>0)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
uint k;
|
|
Packit |
1c1d7e |
int pPos=root->xPos();
|
|
Packit |
1c1d7e |
int cPos=root->avgChildPos();
|
|
Packit |
1c1d7e |
if (pPos>cPos) // move children
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
DiagramRow *row=at(r+1);
|
|
Packit |
1c1d7e |
//printf("Moving children %d-%d in row %d\n",
|
|
Packit |
1c1d7e |
// dil->getFirst()->number(),row->count()-1,r+1);
|
|
Packit |
1c1d7e |
for (k=dil->getFirst()->number();k<row->count();k++)
|
|
Packit |
1c1d7e |
row->at(k)->move(pPos-cPos,0);
|
|
Packit |
1c1d7e |
moved=TRUE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else if (pPos
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
DiagramRow *row=at(r);
|
|
Packit |
1c1d7e |
//printf("Moving parents %d-%d in row %d\n",
|
|
Packit |
1c1d7e |
// root->number(),row->count()-1,r);
|
|
Packit |
1c1d7e |
for (k=root->number();k<row->count();k++)
|
|
Packit |
1c1d7e |
row->at(k)->move(cPos-pPos,0);
|
|
Packit |
1c1d7e |
moved=TRUE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// recurse to children
|
|
Packit |
1c1d7e |
QListIterator<DiagramItem> it(*dil);
|
|
Packit |
1c1d7e |
DiagramItem *di;
|
|
Packit |
1c1d7e |
for (;(di=it.current()) && !moved && !di->isInList();++it)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
moved = layoutTree(di,r+1);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return moved;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void TreeDiagram::computeLayout()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QListIterator<DiagramRow> it(*this);
|
|
Packit |
1c1d7e |
DiagramRow *row;
|
|
Packit |
1c1d7e |
for (;(row=it.current()) && row->count()
|
|
Packit |
1c1d7e |
if (row)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//printf("computeLayout() list row at %d\n",row->number());
|
|
Packit |
1c1d7e |
QListIterator<DiagramItem> rit(*row);
|
|
Packit |
1c1d7e |
DiagramItem *di;
|
|
Packit |
1c1d7e |
DiagramItem *opi=0;
|
|
Packit |
1c1d7e |
int delta=0;
|
|
Packit |
1c1d7e |
bool first=TRUE;
|
|
Packit |
1c1d7e |
for (;(di=rit.current());++rit)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
DiagramItem *pi=di->parentItem();
|
|
Packit |
1c1d7e |
if (pi==opi && !first) { delta-=gridWidth; }
|
|
Packit |
1c1d7e |
first = pi!=opi;
|
|
Packit |
1c1d7e |
opi=pi;
|
|
Packit |
1c1d7e |
di->move(delta,0); // collapse all items in the same
|
|
Packit |
1c1d7e |
// list (except the first)
|
|
Packit |
1c1d7e |
di->putInList();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// re-organize the diagram items
|
|
Packit |
1c1d7e |
DiagramItem *root=getFirst()->getFirst();
|
|
Packit |
1c1d7e |
while (layoutTree(root,0)) { }
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// move first items of the lists
|
|
Packit |
1c1d7e |
if (row)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QListIterator<DiagramItem> rit(*row);
|
|
Packit |
1c1d7e |
DiagramItem *di;
|
|
Packit |
1c1d7e |
while ((di=rit.current()))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
DiagramItem *pi=di->parentItem();
|
|
Packit |
1c1d7e |
if (pi->getChildren()->count()>1)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
di->move(gridWidth,0);
|
|
Packit |
1c1d7e |
while (di && di->parentItem()==pi) { ++rit; di=rit.current(); }
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
++rit;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
uint TreeDiagram::computeRows()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//printf("TreeDiagram::computeRows()=%d\n",count());
|
|
Packit |
1c1d7e |
int count=0;
|
|
Packit |
1c1d7e |
QListIterator<DiagramRow> it(*this);
|
|
Packit |
1c1d7e |
DiagramRow *row;
|
|
Packit |
1c1d7e |
for (;(row=it.current()) && !row->getFirst()->isInList();++it)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
count++;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
//printf("count=%d row=%p\n",count,row);
|
|
Packit |
1c1d7e |
if (row)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
int maxListLen=0;
|
|
Packit |
1c1d7e |
int curListLen=0;
|
|
Packit |
1c1d7e |
DiagramItem *opi=0;
|
|
Packit |
1c1d7e |
QListIterator<DiagramItem> rit(*row);
|
|
Packit |
1c1d7e |
DiagramItem *di;
|
|
Packit |
1c1d7e |
for (;(di=rit.current());++rit)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (di->parentItem()!=opi) curListLen=1; else curListLen++;
|
|
Packit |
1c1d7e |
if (curListLen>maxListLen) maxListLen=curListLen;
|
|
Packit |
1c1d7e |
opi=di->parentItem();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
//printf("maxListLen=%d\n",maxListLen);
|
|
Packit |
1c1d7e |
count+=maxListLen;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return count;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void TreeDiagram::computeExtremes(uint *maxLabelLen,uint *maxXPos)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
uint ml=0,mx=0;
|
|
Packit |
1c1d7e |
QListIterator<DiagramRow> it(*this);
|
|
Packit |
1c1d7e |
DiagramRow *dr;
|
|
Packit |
1c1d7e |
bool done=FALSE;
|
|
Packit |
1c1d7e |
for (;(dr=it.current()) && !done;++it)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QListIterator<DiagramItem> rit(*dr);
|
|
Packit |
1c1d7e |
DiagramItem *di;
|
|
Packit |
1c1d7e |
for (;(di=rit.current());++rit)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (di->isInList()) done=TRUE;
|
|
Packit |
1c1d7e |
if (maxXPos) mx=QMAX(mx,(uint)di->xPos());
|
|
Packit |
1c1d7e |
if (maxLabelLen) ml=QMAX(ml,Image::stringLength(di->label()));
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
if (maxLabelLen) *maxLabelLen=ml;
|
|
Packit |
1c1d7e |
if (maxXPos) *maxXPos=mx;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void TreeDiagram::drawBoxes(FTextStream &t,Image *image,
|
|
Packit |
1c1d7e |
bool doBase,bool bitmap,
|
|
Packit |
1c1d7e |
uint baseRows,uint superRows,
|
|
Packit |
1c1d7e |
uint cellWidth,uint cellHeight,
|
|
Packit |
1c1d7e |
QCString relPath,
|
|
Packit |
1c1d7e |
bool generateMap)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QListIterator<DiagramRow> it(*this);
|
|
Packit |
1c1d7e |
DiagramRow *dr;
|
|
Packit |
1c1d7e |
if (!doBase) ++it;
|
|
Packit |
1c1d7e |
bool done=FALSE;
|
|
Packit |
1c1d7e |
bool firstRow = doBase;
|
|
Packit |
1c1d7e |
for (;(dr=it.current()) && !done;++it)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
int x=0,y=0;
|
|
Packit |
1c1d7e |
float xf=0.0f,yf=0.0f;
|
|
Packit |
1c1d7e |
QListIterator<DiagramItem> rit(*dr);
|
|
Packit |
1c1d7e |
DiagramItem *di = rit.current();
|
|
Packit |
1c1d7e |
if (di->isInList()) // put boxes in a list
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
DiagramItem *opi=0;
|
|
Packit |
1c1d7e |
if (doBase) rit.toLast(); else rit.toFirst();
|
|
Packit |
1c1d7e |
while ((di=rit.current()))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (di->parentItem()==opi)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (bitmap)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (doBase) y -= cellHeight+labelVertSpacing;
|
|
Packit |
1c1d7e |
else y += cellHeight+labelVertSpacing;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (doBase) yf += 1.0f;
|
|
Packit |
1c1d7e |
else yf -= 1.0f;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (bitmap)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth;
|
|
Packit |
1c1d7e |
if (doBase)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
y = image->getHeight()-
|
|
Packit |
1c1d7e |
superRows*cellHeight-
|
|
Packit |
1c1d7e |
(superRows-1)*labelVertSpacing-
|
|
Packit |
1c1d7e |
di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
y = (baseRows-1)*(cellHeight+labelVertSpacing)+
|
|
Packit |
1c1d7e |
di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
xf = di->xPos()/(float)gridWidth;
|
|
Packit |
1c1d7e |
if (doBase)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
yf = di->yPos()/(float)gridHeight+superRows-1;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
yf = superRows-1-di->yPos()/(float)gridHeight;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
opi=di->parentItem();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
if (bitmap)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
bool hasDocs=di->getClassDef()->isLinkable();
|
|
Packit |
1c1d7e |
writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,
|
|
Packit |
1c1d7e |
hasDocs,di->getChildren()->count()>0);
|
|
Packit |
1c1d7e |
if (!firstRow && generateMap)
|
|
Packit |
1c1d7e |
writeMapArea(t,di->getClassDef(),relPath,x,y,cellWidth,cellHeight);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
writeVectorBox(t,di,xf,yf,di->getChildren()->count()>0);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
if (doBase) --rit; else ++rit;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
done=TRUE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // draw a tree of boxes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
for (rit.toFirst();(di=rit.current());++rit)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (bitmap)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth;
|
|
Packit |
1c1d7e |
if (doBase)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
y = image->getHeight()-
|
|
Packit |
1c1d7e |
superRows*cellHeight-
|
|
Packit |
1c1d7e |
(superRows-1)*labelVertSpacing-
|
|
Packit |
1c1d7e |
di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
y = (baseRows-1)*(cellHeight+labelVertSpacing)+
|
|
Packit |
1c1d7e |
di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
bool hasDocs=di->getClassDef()->isLinkable();
|
|
Packit |
1c1d7e |
writeBitmapBox(di,image,x,y,cellWidth,cellHeight,firstRow,hasDocs);
|
|
Packit |
1c1d7e |
if (!firstRow && generateMap)
|
|
Packit |
1c1d7e |
writeMapArea(t,di->getClassDef(),relPath,x,y,cellWidth,cellHeight);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
xf=di->xPos()/(float)gridWidth;
|
|
Packit |
1c1d7e |
if (doBase)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
yf = di->yPos()/(float)gridHeight+superRows-1;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
yf = superRows-1-di->yPos()/(float)gridHeight;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
writeVectorBox(t,di,xf,yf);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
firstRow=FALSE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void TreeDiagram::drawConnectors(FTextStream &t,Image *image,
|
|
Packit |
1c1d7e |
bool doBase,bool bitmap,
|
|
Packit |
1c1d7e |
uint baseRows,uint superRows,
|
|
Packit |
1c1d7e |
uint cellWidth,uint cellHeight)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QListIterator<DiagramRow> it(*this);
|
|
Packit |
1c1d7e |
DiagramRow *dr;
|
|
Packit |
1c1d7e |
bool done=FALSE;
|
|
Packit |
1c1d7e |
for (;(dr=it.current()) && !done;++it) // for each row
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QListIterator<DiagramItem> rit(*dr);
|
|
Packit |
1c1d7e |
DiagramItem *di = rit.current();
|
|
Packit |
1c1d7e |
if (di->isInList()) // row consists of list connectors
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
int x=0,y=0,ys=0;
|
|
Packit |
1c1d7e |
float xf=0.0f,yf=0.0f,ysf=0.0f;
|
|
Packit |
1c1d7e |
for (;(di=rit.current());++rit)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
DiagramItem *pi=di->parentItem();
|
|
Packit |
1c1d7e |
DiagramItemList *dil=pi->getChildren();
|
|
Packit |
1c1d7e |
DiagramItem *last=dil->getLast();
|
|
Packit |
1c1d7e |
if (di==last) // single child
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (bitmap) // draw pixels
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
|
|
Packit |
1c1d7e |
if (doBase) // base classes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
y = image->getHeight()-
|
|
Packit |
1c1d7e |
(superRows-1)*(cellHeight+labelVertSpacing)-
|
|
Packit |
1c1d7e |
di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
|
|
Packit |
1c1d7e |
image->drawVertArrow(x,y,y+labelVertSpacing/2,
|
|
Packit |
1c1d7e |
protToColor(di->protection()),
|
|
Packit |
1c1d7e |
protToMask(di->protection()));
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // super classes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
y = (baseRows-1)*(cellHeight+labelVertSpacing)-
|
|
Packit |
1c1d7e |
labelVertSpacing/2+
|
|
Packit |
1c1d7e |
di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
|
|
Packit |
1c1d7e |
image->drawVertLine(x,y,y+labelVertSpacing/2,
|
|
Packit |
1c1d7e |
protToColor(di->protection()),
|
|
Packit |
1c1d7e |
protToMask(di->protection()));
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // draw vectors
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << protToString(di->protection()) << endl;
|
|
Packit |
1c1d7e |
if (doBase)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << "1 " << (di->xPos()/(float)gridWidth) << " "
|
|
Packit |
1c1d7e |
<< (di->yPos()/(float)gridHeight+superRows-1) << " in\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << "0 " << (di->xPos()/(float)gridWidth) << " "
|
|
Packit |
1c1d7e |
<< ((float)superRows-0.25-di->yPos()/(float)gridHeight)
|
|
Packit |
1c1d7e |
<< " in\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // multiple children, put them in a vertical list
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (bitmap)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
x = di->parentItem()->xPos()*
|
|
Packit |
1c1d7e |
(cellWidth+labelHorSpacing)/gridWidth+cellWidth/2;
|
|
Packit |
1c1d7e |
if (doBase) // base classes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
ys = image->getHeight()-
|
|
Packit |
1c1d7e |
(superRows-1)*(cellHeight+labelVertSpacing)-
|
|
Packit |
1c1d7e |
di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
|
|
Packit |
1c1d7e |
y = ys - cellHeight/2;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // super classes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
ys = (baseRows-1)*(cellHeight+labelVertSpacing)+
|
|
Packit |
1c1d7e |
di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
|
|
Packit |
1c1d7e |
y = ys + cellHeight/2;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
xf = di->parentItem()->xPos()/(float)gridWidth;
|
|
Packit |
1c1d7e |
if (doBase)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
ysf = di->yPos()/(float)gridHeight+superRows-1;
|
|
Packit |
1c1d7e |
yf = ysf + 0.5f;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
ysf = (float)superRows-0.25f-di->yPos()/(float)gridHeight;
|
|
Packit |
1c1d7e |
yf = ysf - 0.25f;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
while (di!=last) // more children to add
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (bitmap)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (doBase) // base classes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
image->drawHorzArrow(y,x,x+cellWidth/2+labelHorSpacing,
|
|
Packit |
1c1d7e |
protToColor(di->protection()),
|
|
Packit |
1c1d7e |
protToMask(di->protection()));
|
|
Packit |
1c1d7e |
y -= cellHeight+labelVertSpacing;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // super classes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
image->drawHorzLine(y,x,x+cellWidth/2+labelHorSpacing,
|
|
Packit |
1c1d7e |
protToColor(di->protection()),
|
|
Packit |
1c1d7e |
protToMask(di->protection()));
|
|
Packit |
1c1d7e |
y += cellHeight+labelVertSpacing;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << protToString(di->protection()) << endl;
|
|
Packit |
1c1d7e |
if (doBase)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << "1 " << xf << " " << yf << " hedge\n";
|
|
Packit |
1c1d7e |
yf += 1.0f;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << "0 " << xf << " " << yf << " hedge\n";
|
|
Packit |
1c1d7e |
yf -= 1.0f;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
++rit; di=rit.current();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
// add last horizonal line and a vertical connection line
|
|
Packit |
1c1d7e |
if (bitmap)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (doBase) // base classes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
image->drawHorzArrow(y,x,x+cellWidth/2+labelHorSpacing,
|
|
Packit |
1c1d7e |
protToColor(di->protection()),
|
|
Packit |
1c1d7e |
protToMask(di->protection()));
|
|
Packit |
1c1d7e |
image->drawVertLine(x,y,ys+labelVertSpacing/2,
|
|
Packit |
1c1d7e |
protToColor(getMinProtectionLevel(dil)),
|
|
Packit |
1c1d7e |
protToMask(getMinProtectionLevel(dil)));
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // super classes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
image->drawHorzLine(y,x,x+cellWidth/2+labelHorSpacing,
|
|
Packit |
1c1d7e |
protToColor(di->protection()),
|
|
Packit |
1c1d7e |
protToMask(di->protection()));
|
|
Packit |
1c1d7e |
image->drawVertLine(x,ys-labelVertSpacing/2,y,
|
|
Packit |
1c1d7e |
protToColor(getMinProtectionLevel(dil)),
|
|
Packit |
1c1d7e |
protToMask(getMinProtectionLevel(dil)));
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << protToString(di->protection()) << endl;
|
|
Packit |
1c1d7e |
if (doBase)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << "1 " << xf << " " << yf << " hedge\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << "0 " << xf << " " << yf << " hedge\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
t << protToString(getMinProtectionLevel(dil)) << endl;
|
|
Packit |
1c1d7e |
if (doBase)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << xf << " " << ysf << " " << yf << " vedge\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << xf << " " << (ysf + 0.25) << " " << yf << " vedge\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
done=TRUE; // the tree is drawn now
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // normal tree connector
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
for (;(di=rit.current());++rit)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
int x=0,y=0;
|
|
Packit |
1c1d7e |
DiagramItemList *dil = di->getChildren();
|
|
Packit |
1c1d7e |
DiagramItem *parent = di->parentItem();
|
|
Packit |
1c1d7e |
if (parent) // item has a parent -> connect to it
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (bitmap) // draw pixels
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
|
|
Packit |
1c1d7e |
if (doBase) // base classes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
y = image->getHeight()-
|
|
Packit |
1c1d7e |
(superRows-1)*(cellHeight+labelVertSpacing)-
|
|
Packit |
1c1d7e |
di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
|
|
Packit |
1c1d7e |
/* write input line */
|
|
Packit |
1c1d7e |
image->drawVertArrow(x,y,y+labelVertSpacing/2,
|
|
Packit |
1c1d7e |
protToColor(di->protection()),
|
|
Packit |
1c1d7e |
protToMask(di->protection()));
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // super classes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
y = (baseRows-1)*(cellHeight+labelVertSpacing)-
|
|
Packit |
1c1d7e |
labelVertSpacing/2+
|
|
Packit |
1c1d7e |
di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
|
|
Packit |
1c1d7e |
/* write output line */
|
|
Packit |
1c1d7e |
image->drawVertLine(x,y,y+labelVertSpacing/2,
|
|
Packit |
1c1d7e |
protToColor(di->protection()),
|
|
Packit |
1c1d7e |
protToMask(di->protection()));
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // draw pixels
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << protToString(di->protection()) << endl;
|
|
Packit |
1c1d7e |
if (doBase)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << "1 " << di->xPos()/(float)gridWidth << " "
|
|
Packit |
1c1d7e |
<< (di->yPos()/(float)gridHeight+superRows-1) << " in\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << "0 " << di->xPos()/(float)gridWidth << " "
|
|
Packit |
1c1d7e |
<< ((float)superRows-0.25-di->yPos()/(float)gridHeight)
|
|
Packit |
1c1d7e |
<< " in\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
if (dil->count()>0)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
Protection p=getMinProtectionLevel(dil);
|
|
Packit |
1c1d7e |
uint mask=protToMask(p);
|
|
Packit |
1c1d7e |
uint col=protToColor(p);
|
|
Packit |
1c1d7e |
if (bitmap)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
|
|
Packit |
1c1d7e |
if (doBase) // base classes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
y = image->getHeight()-
|
|
Packit |
1c1d7e |
(superRows-1)*(cellHeight+labelVertSpacing)-
|
|
Packit |
1c1d7e |
cellHeight-labelVertSpacing/2-
|
|
Packit |
1c1d7e |
di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
|
|
Packit |
1c1d7e |
image->drawVertLine(x,y,y+labelVertSpacing/2-1,col,mask);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // super classes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
y = (baseRows-1)*(cellHeight+labelVertSpacing)+
|
|
Packit |
1c1d7e |
cellHeight+
|
|
Packit |
1c1d7e |
di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
|
|
Packit |
1c1d7e |
image->drawVertArrow(x,y,y+labelVertSpacing/2-1,col,mask);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << protToString(p) << endl;
|
|
Packit |
1c1d7e |
if (doBase)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << "0 " << di->xPos()/(float)gridWidth << " "
|
|
Packit |
1c1d7e |
<< (di->yPos()/(float)gridHeight+superRows-1) << " out\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << "1 " << di->xPos()/(float)gridWidth << " "
|
|
Packit |
1c1d7e |
<< ((float)superRows-1.75-di->yPos()/(float)gridHeight)
|
|
Packit |
1c1d7e |
<< " out\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
/* write input line */
|
|
Packit |
1c1d7e |
DiagramItem *first = dil->getFirst();
|
|
Packit |
1c1d7e |
DiagramItem *last = dil->getLast();
|
|
Packit |
1c1d7e |
if (first!=last && !first->isInList()) /* connect with all base classes */
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (bitmap)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
int xs = first->xPos()*(cellWidth+labelHorSpacing)/gridWidth
|
|
Packit |
1c1d7e |
+ cellWidth/2;
|
|
Packit |
1c1d7e |
int xe = last->xPos()*(cellWidth+labelHorSpacing)/gridWidth
|
|
Packit |
1c1d7e |
+ cellWidth/2;
|
|
Packit |
1c1d7e |
if (doBase) // base classes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
image->drawHorzLine(y,xs,xe,col,mask);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // super classes
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
image->drawHorzLine(y+labelVertSpacing/2,xs,xe,col,mask);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << protToString(p) << endl;
|
|
Packit |
1c1d7e |
if (doBase)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << first->xPos()/(float)gridWidth << " "
|
|
Packit |
1c1d7e |
<< last->xPos()/(float)gridWidth << " "
|
|
Packit |
1c1d7e |
<< (first->yPos()/(float)gridHeight+superRows-1)
|
|
Packit |
1c1d7e |
<< " conn\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
t << first->xPos()/(float)gridWidth << " "
|
|
Packit |
1c1d7e |
<< last->xPos()/(float)gridWidth << " "
|
|
Packit |
1c1d7e |
<< ((float)superRows-first->yPos()/(float)gridHeight)
|
|
Packit |
1c1d7e |
<< " conn\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void clearVisitFlags()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
ClassSDict::Iterator cli(*Doxygen::classSDict);
|
|
Packit |
1c1d7e |
ClassDef *cd;
|
|
Packit |
1c1d7e |
for (;(cd=cli.current());++cli)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
cd->visited=FALSE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
ClassDiagram::ClassDiagram(ClassDef *root)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
clearVisitFlags();
|
|
Packit |
1c1d7e |
base = new TreeDiagram(root,TRUE);
|
|
Packit |
1c1d7e |
base->computeLayout();
|
|
Packit |
1c1d7e |
clearVisitFlags();
|
|
Packit |
1c1d7e |
super = new TreeDiagram(root,FALSE);
|
|
Packit |
1c1d7e |
super->computeLayout();
|
|
Packit |
1c1d7e |
DiagramItem *baseItem = base->getFirst()->getFirst();
|
|
Packit |
1c1d7e |
DiagramItem *superItem = super->getFirst()->getFirst();
|
|
Packit |
1c1d7e |
int xbase = baseItem->xPos();
|
|
Packit |
1c1d7e |
int xsuper = superItem->xPos();
|
|
Packit |
1c1d7e |
if (xbase>xsuper)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
superItem->move(xbase-xsuper,0);
|
|
Packit |
1c1d7e |
super->moveChildren(superItem,xbase-xsuper);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else if (xbase
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
baseItem->move(xsuper-xbase,0);
|
|
Packit |
1c1d7e |
base->moveChildren(baseItem,xsuper-xbase);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
ClassDiagram::~ClassDiagram()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
delete base;
|
|
Packit |
1c1d7e |
delete super;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void ClassDiagram::writeFigure(FTextStream &output,const char *path,
|
|
Packit |
1c1d7e |
const char *fileName) const
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
uint baseRows=base->computeRows();
|
|
Packit |
1c1d7e |
uint superRows=super->computeRows();
|
|
Packit |
1c1d7e |
uint baseMaxX, baseMaxLabelWidth, superMaxX, superMaxLabelWidth;
|
|
Packit |
1c1d7e |
base->computeExtremes(&baseMaxLabelWidth,&baseMaxX);
|
|
Packit |
1c1d7e |
super->computeExtremes(&superMaxLabelWidth,&superMaxX);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
uint rows=baseRows+superRows-1;
|
|
Packit |
1c1d7e |
uint cols=(QMAX(baseMaxX,superMaxX)+gridWidth*2-1)/gridWidth;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// Estimate the image aspect width and height in pixels.
|
|
Packit |
1c1d7e |
uint estHeight = rows*40;
|
|
Packit |
1c1d7e |
uint estWidth = cols*(20+QMAX(baseMaxLabelWidth,superMaxLabelWidth));
|
|
Packit |
1c1d7e |
//printf("Estimated size %d x %d\n",estWidth,estHeight);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
const float pageWidth = 14.0f; // estimated page width in cm.
|
|
Packit |
1c1d7e |
// Somewhat lower to deal with estimation
|
|
Packit |
1c1d7e |
// errors.
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// compute the image height in centimeters based on the estimates
|
|
Packit |
1c1d7e |
float realHeight = QMIN(rows,12); // real height in cm
|
|
Packit |
1c1d7e |
float realWidth = realHeight * estWidth/(float)estHeight;
|
|
Packit |
1c1d7e |
if (realWidth>pageWidth) // assume that the page width is about 15 cm
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
realHeight*=pageWidth/realWidth;
|
|
Packit |
1c1d7e |
realWidth=pageWidth;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//output << "}\n";
|
|
Packit |
1c1d7e |
output << "\\begin{figure}[H]\n"
|
|
Packit |
1c1d7e |
"\\begin{center}\n"
|
|
Packit |
1c1d7e |
"\\leavevmode\n";
|
|
Packit |
1c1d7e |
output << "\\includegraphics[height=" << realHeight << "cm]{"
|
|
Packit |
1c1d7e |
<< fileName << "}" << endl;
|
|
Packit |
1c1d7e |
output << "\\end{center}\n"
|
|
Packit |
1c1d7e |
"\\end{figure}\n";
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//printf("writeFigure rows=%d cols=%d\n",rows,cols);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
QCString epsBaseName=(QCString)path+"/"+fileName;
|
|
Packit |
1c1d7e |
QCString epsName=epsBaseName+".eps";
|
|
Packit |
1c1d7e |
QFile f1;
|
|
Packit |
1c1d7e |
f1.setName(epsName.data());
|
|
Packit |
1c1d7e |
if (!f1.open(IO_WriteOnly))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
err("Could not open file %s for writing\n",f1.name().data());
|
|
Packit |
1c1d7e |
exit(1);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
FTextStream t(&f1;;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//printf("writeEPS() rows=%d cols=%d\n",rows,cols);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// generate EPS header and postscript variables and procedures
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
t << "%!PS-Adobe-2.0 EPSF-2.0\n";
|
|
Packit |
1c1d7e |
t << "%%Title: ClassName\n";
|
|
Packit |
1c1d7e |
t << "%%Creator: Doxygen\n";
|
|
Packit |
1c1d7e |
t << "%%CreationDate: Time\n";
|
|
Packit |
1c1d7e |
t << "%%For: \n";
|
|
Packit |
1c1d7e |
t << "%Magnification: 1.00\n";
|
|
Packit |
1c1d7e |
t << "%%Orientation: Portrait\n";
|
|
Packit |
1c1d7e |
t << "%%BoundingBox: 0 0 500 " << estHeight*500.0/(float)estWidth << "\n";
|
|
Packit |
1c1d7e |
t << "%%Pages: 0\n";
|
|
Packit |
1c1d7e |
t << "%%BeginSetup\n";
|
|
Packit |
1c1d7e |
t << "%%EndSetup\n";
|
|
Packit |
1c1d7e |
t << "%%EndComments\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "% ----- variables -----\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "/boxwidth 0 def\n";
|
|
Packit |
1c1d7e |
t << "/boxheight 40 def\n";
|
|
Packit |
1c1d7e |
t << "/fontheight 24 def\n";
|
|
Packit |
1c1d7e |
t << "/marginwidth 10 def\n";
|
|
Packit |
1c1d7e |
t << "/distx 20 def\n";
|
|
Packit |
1c1d7e |
t << "/disty 40 def\n";
|
|
Packit |
1c1d7e |
t << "/boundaspect " << estWidth/(float)estHeight << " def % aspect ratio of the BoundingBox (width/height)\n";
|
|
Packit |
1c1d7e |
t << "/boundx 500 def\n";
|
|
Packit |
1c1d7e |
t << "/boundy boundx boundaspect div def\n";
|
|
Packit |
1c1d7e |
t << "/xspacing 0 def\n";
|
|
Packit |
1c1d7e |
t << "/yspacing 0 def\n";
|
|
Packit |
1c1d7e |
t << "/rows " << rows << " def\n";
|
|
Packit |
1c1d7e |
t << "/cols " << cols << " def\n";
|
|
Packit |
1c1d7e |
t << "/scalefactor 0 def\n";
|
|
Packit |
1c1d7e |
t << "/boxfont /Times-Roman findfont fontheight scalefont def\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "% ----- procedures -----\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "/dotted { [1 4] 0 setdash } def\n";
|
|
Packit |
1c1d7e |
t << "/dashed { [5] 0 setdash } def\n";
|
|
Packit |
1c1d7e |
t << "/solid { [] 0 setdash } def\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "/max % result = MAX(arg1,arg2)\n";
|
|
Packit |
1c1d7e |
t << "{\n";
|
|
Packit |
1c1d7e |
t << " /a exch def\n";
|
|
Packit |
1c1d7e |
t << " /b exch def\n";
|
|
Packit |
1c1d7e |
t << " a b gt {a} {b} ifelse\n";
|
|
Packit |
1c1d7e |
t << "} def\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "/xoffset % result = MAX(0,(scalefactor-(boxwidth*cols+distx*(cols-1)))/2)\n";
|
|
Packit |
1c1d7e |
t << "{\n";
|
|
Packit |
1c1d7e |
t << " 0 scalefactor boxwidth cols mul distx cols 1 sub mul add sub 2 div max\n";
|
|
Packit |
1c1d7e |
t << "} def\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "/cw % boxwidth = MAX(boxwidth, stringwidth(arg1))\n";
|
|
Packit |
1c1d7e |
t << "{\n";
|
|
Packit |
1c1d7e |
t << " /str exch def\n";
|
|
Packit |
1c1d7e |
t << " /boxwidth boxwidth str stringwidth pop max def\n";
|
|
Packit |
1c1d7e |
t << "} def\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "/box % draws a box with text `arg1' at grid pos (arg2,arg3)\n";
|
|
Packit |
1c1d7e |
t << "{ gsave\n";
|
|
Packit |
1c1d7e |
t << " 2 setlinewidth\n";
|
|
Packit |
1c1d7e |
t << " newpath\n";
|
|
Packit |
1c1d7e |
t << " exch xspacing mul xoffset add\n";
|
|
Packit |
1c1d7e |
t << " exch yspacing mul\n";
|
|
Packit |
1c1d7e |
t << " moveto\n";
|
|
Packit |
1c1d7e |
t << " boxwidth 0 rlineto \n";
|
|
Packit |
1c1d7e |
t << " 0 boxheight rlineto \n";
|
|
Packit |
1c1d7e |
t << " boxwidth neg 0 rlineto \n";
|
|
Packit |
1c1d7e |
t << " 0 boxheight neg rlineto \n";
|
|
Packit |
1c1d7e |
t << " closepath\n";
|
|
Packit |
1c1d7e |
t << " dup stringwidth pop neg boxwidth add 2 div\n";
|
|
Packit |
1c1d7e |
t << " boxheight fontheight 2 div sub 2 div\n";
|
|
Packit |
1c1d7e |
t << " rmoveto show stroke\n";
|
|
Packit |
1c1d7e |
t << " grestore\n";
|
|
Packit |
1c1d7e |
t << "} def \n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "/mark\n";
|
|
Packit |
1c1d7e |
t << "{ newpath\n";
|
|
Packit |
1c1d7e |
t << " exch xspacing mul xoffset add boxwidth add\n";
|
|
Packit |
1c1d7e |
t << " exch yspacing mul\n";
|
|
Packit |
1c1d7e |
t << " moveto\n";
|
|
Packit |
1c1d7e |
t << " 0 boxheight 4 div rlineto\n";
|
|
Packit |
1c1d7e |
t << " boxheight neg 4 div boxheight neg 4 div rlineto\n";
|
|
Packit |
1c1d7e |
t << " closepath\n";
|
|
Packit |
1c1d7e |
t << " eofill\n";
|
|
Packit |
1c1d7e |
t << " stroke\n";
|
|
Packit |
1c1d7e |
t << "} def\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "/arrow\n";
|
|
Packit |
1c1d7e |
t << "{ newpath\n";
|
|
Packit |
1c1d7e |
t << " moveto\n";
|
|
Packit |
1c1d7e |
t << " 3 -8 rlineto\n";
|
|
Packit |
1c1d7e |
t << " -6 0 rlineto\n";
|
|
Packit |
1c1d7e |
t << " 3 8 rlineto\n";
|
|
Packit |
1c1d7e |
t << " closepath\n";
|
|
Packit |
1c1d7e |
t << " eofill\n";
|
|
Packit |
1c1d7e |
t << " stroke\n";
|
|
Packit |
1c1d7e |
t << "} def\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "/out % draws an output connector for the block at (arg1,arg2)\n";
|
|
Packit |
1c1d7e |
t << "{\n";
|
|
Packit |
1c1d7e |
t << " newpath\n";
|
|
Packit |
1c1d7e |
t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
|
|
Packit |
1c1d7e |
t << " exch yspacing mul boxheight add\n";
|
|
Packit |
1c1d7e |
t << " /y exch def\n";
|
|
Packit |
1c1d7e |
t << " /x exch def\n";
|
|
Packit |
1c1d7e |
t << " x y moveto\n";
|
|
Packit |
1c1d7e |
t << " 0 disty 2 div rlineto \n";
|
|
Packit |
1c1d7e |
t << " stroke\n";
|
|
Packit |
1c1d7e |
t << " 1 eq { x y disty 2 div add arrow } if\n";
|
|
Packit |
1c1d7e |
t << "} def\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "/in % draws an input connector for the block at (arg1,arg2)\n";
|
|
Packit |
1c1d7e |
t << "{\n";
|
|
Packit |
1c1d7e |
t << " newpath\n";
|
|
Packit |
1c1d7e |
t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
|
|
Packit |
1c1d7e |
t << " exch yspacing mul disty 2 div sub\n";
|
|
Packit |
1c1d7e |
t << " /y exch def\n";
|
|
Packit |
1c1d7e |
t << " /x exch def\n";
|
|
Packit |
1c1d7e |
t << " x y moveto\n";
|
|
Packit |
1c1d7e |
t << " 0 disty 2 div rlineto\n";
|
|
Packit |
1c1d7e |
t << " stroke\n";
|
|
Packit |
1c1d7e |
t << " 1 eq { x y disty 2 div add arrow } if\n";
|
|
Packit |
1c1d7e |
t << "} def\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "/hedge\n";
|
|
Packit |
1c1d7e |
t << "{\n";
|
|
Packit |
1c1d7e |
t << " exch xspacing mul xoffset add boxwidth 2 div add\n";
|
|
Packit |
1c1d7e |
t << " exch yspacing mul boxheight 2 div sub\n";
|
|
Packit |
1c1d7e |
t << " /y exch def\n";
|
|
Packit |
1c1d7e |
t << " /x exch def\n";
|
|
Packit |
1c1d7e |
t << " newpath\n";
|
|
Packit |
1c1d7e |
t << " x y moveto\n";
|
|
Packit |
1c1d7e |
t << " boxwidth 2 div distx add 0 rlineto\n";
|
|
Packit |
1c1d7e |
t << " stroke\n";
|
|
Packit |
1c1d7e |
t << " 1 eq\n";
|
|
Packit |
1c1d7e |
t << " { newpath x boxwidth 2 div distx add add y moveto\n";
|
|
Packit |
1c1d7e |
t << " -8 3 rlineto\n";
|
|
Packit |
1c1d7e |
t << " 0 -6 rlineto\n";
|
|
Packit |
1c1d7e |
t << " 8 3 rlineto\n";
|
|
Packit |
1c1d7e |
t << " closepath\n";
|
|
Packit |
1c1d7e |
t << " eofill\n";
|
|
Packit |
1c1d7e |
t << " stroke\n";
|
|
Packit |
1c1d7e |
t << " } if\n";
|
|
Packit |
1c1d7e |
t << "} def\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "/vedge\n";
|
|
Packit |
1c1d7e |
t << "{\n";
|
|
Packit |
1c1d7e |
t << " /ye exch def\n";
|
|
Packit |
1c1d7e |
t << " /ys exch def\n";
|
|
Packit |
1c1d7e |
t << " /xs exch def\n";
|
|
Packit |
1c1d7e |
t << " newpath\n";
|
|
Packit |
1c1d7e |
t << " xs xspacing mul xoffset add boxwidth 2 div add dup\n";
|
|
Packit |
1c1d7e |
t << " ys yspacing mul boxheight 2 div sub\n";
|
|
Packit |
1c1d7e |
t << " moveto\n";
|
|
Packit |
1c1d7e |
t << " ye yspacing mul boxheight 2 div sub\n";
|
|
Packit |
1c1d7e |
t << " lineto\n";
|
|
Packit |
1c1d7e |
t << " stroke\n";
|
|
Packit |
1c1d7e |
t << "} def\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "/conn % connections the blocks from col `arg1' to `arg2' of row `arg3'\n";
|
|
Packit |
1c1d7e |
t << "{\n";
|
|
Packit |
1c1d7e |
t << " /ys exch def\n";
|
|
Packit |
1c1d7e |
t << " /xe exch def\n";
|
|
Packit |
1c1d7e |
t << " /xs exch def\n";
|
|
Packit |
1c1d7e |
t << " newpath\n";
|
|
Packit |
1c1d7e |
t << " xs xspacing mul xoffset add boxwidth 2 div add\n";
|
|
Packit |
1c1d7e |
t << " ys yspacing mul disty 2 div sub\n";
|
|
Packit |
1c1d7e |
t << " moveto\n";
|
|
Packit |
1c1d7e |
t << " xspacing xe xs sub mul 0\n";
|
|
Packit |
1c1d7e |
t << " rlineto\n";
|
|
Packit |
1c1d7e |
t << " stroke\n";
|
|
Packit |
1c1d7e |
t << "} def\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "% ----- main ------\n";
|
|
Packit |
1c1d7e |
t << "\n";
|
|
Packit |
1c1d7e |
t << "boxfont setfont\n";
|
|
Packit |
1c1d7e |
t << "1 boundaspect scale\n";
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
bool done=FALSE;
|
|
Packit |
1c1d7e |
QListIterator<DiagramRow> bit(*base);
|
|
Packit |
1c1d7e |
DiagramRow *dr;
|
|
Packit |
1c1d7e |
for (;(dr=bit.current()) && !done;++bit)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QListIterator<DiagramItem> rit(*dr);
|
|
Packit |
1c1d7e |
DiagramItem *di;
|
|
Packit |
1c1d7e |
for (;(di=rit.current());++rit)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
done=di->isInList();
|
|
Packit |
1c1d7e |
t << "(" << di->label() << ") cw\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
QListIterator<DiagramRow> sit(*super);
|
|
Packit |
1c1d7e |
++sit;
|
|
Packit |
1c1d7e |
done=FALSE;
|
|
Packit |
1c1d7e |
for (;(dr=sit.current()) && !done;++sit)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QListIterator<DiagramItem> rit(*dr);
|
|
Packit |
1c1d7e |
DiagramItem *di;
|
|
Packit |
1c1d7e |
for (;(di=rit.current());++rit)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
done=di->isInList();
|
|
Packit |
1c1d7e |
t << "(" << di->label() << ") cw\n";
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
t << "/boxwidth boxwidth marginwidth 2 mul add def\n"
|
|
Packit |
1c1d7e |
<< "/xspacing boxwidth distx add def\n"
|
|
Packit |
1c1d7e |
<< "/yspacing boxheight disty add def\n"
|
|
Packit |
1c1d7e |
<< "/scalefactor \n"
|
|
Packit |
1c1d7e |
<< " boxwidth cols mul distx cols 1 sub mul add\n"
|
|
Packit |
1c1d7e |
<< " boxheight rows mul disty rows 1 sub mul add boundaspect mul \n"
|
|
Packit |
1c1d7e |
<< " max def\n"
|
|
Packit |
1c1d7e |
<< "boundx scalefactor div boundy scalefactor div scale\n";
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
t << "\n% ----- classes -----\n\n";
|
|
Packit |
1c1d7e |
base->drawBoxes(t,0,TRUE,FALSE,baseRows,superRows,0,0);
|
|
Packit |
1c1d7e |
super->drawBoxes(t,0,FALSE,FALSE,baseRows,superRows,0,0);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
t << "\n% ----- relations -----\n\n";
|
|
Packit |
1c1d7e |
base->drawConnectors(t,0,TRUE,FALSE,baseRows,superRows,0,0);
|
|
Packit |
1c1d7e |
super->drawConnectors(t,0,FALSE,FALSE,baseRows,superRows,0,0);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
f1.close();
|
|
Packit |
1c1d7e |
if (Config_getBool(USE_PDFLATEX))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QCString epstopdfArgs(4096);
|
|
Packit |
1c1d7e |
epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"",
|
|
Packit |
1c1d7e |
epsBaseName.data(),epsBaseName.data());
|
|
Packit |
1c1d7e |
//printf("Converting eps using `%s'\n",epstopdfArgs.data());
|
|
Packit |
1c1d7e |
portable_sysTimerStart();
|
|
Packit |
1c1d7e |
if (portable_system("epstopdf",epstopdfArgs)!=0)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
err("Problems running epstopdf. Check your TeX installation!\n");
|
|
Packit |
1c1d7e |
portable_sysTimerStop();
|
|
Packit |
1c1d7e |
return;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
portable_sysTimerStop();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void ClassDiagram::writeImage(FTextStream &t,const char *path,
|
|
Packit |
1c1d7e |
const char *relPath,const char *fileName,
|
|
Packit |
1c1d7e |
bool generateMap) const
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
uint baseRows=base->computeRows();
|
|
Packit |
1c1d7e |
uint superRows=super->computeRows();
|
|
Packit |
1c1d7e |
uint rows=baseRows+superRows-1;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
uint lb,ls,xb,xs;
|
|
Packit |
1c1d7e |
base->computeExtremes(&lb,&xb;;
|
|
Packit |
1c1d7e |
super->computeExtremes(&ls,&xs);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
uint cellWidth = QMAX(lb,ls)+labelHorMargin*2;
|
|
Packit |
1c1d7e |
uint maxXPos = QMAX(xb,xs);
|
|
Packit |
1c1d7e |
uint labelVertMargin = 6; //QMAX(6,(cellWidth-fontHeight)/6); // aspect at least 1:3
|
|
Packit |
1c1d7e |
uint cellHeight = labelVertMargin*2+fontHeight;
|
|
Packit |
1c1d7e |
uint imageWidth = (maxXPos+gridWidth)*cellWidth/gridWidth+
|
|
Packit |
1c1d7e |
(maxXPos*labelHorSpacing)/gridWidth;
|
|
Packit |
1c1d7e |
uint imageHeight = rows*cellHeight+(rows-1)*labelVertSpacing;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
Image image(imageWidth,imageHeight);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
base->drawBoxes(t,&image,TRUE,TRUE,baseRows,superRows,cellWidth,cellHeight,relPath,generateMap);
|
|
Packit |
1c1d7e |
super->drawBoxes(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight,relPath,generateMap);
|
|
Packit |
1c1d7e |
base->drawConnectors(t,&image,TRUE,TRUE,baseRows,superRows,cellWidth,cellHeight);
|
|
Packit |
1c1d7e |
super->drawConnectors(t,&image,FALSE,TRUE,baseRows,superRows,cellWidth,cellHeight);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#define IMAGE_EXT ".png"
|
|
Packit |
1c1d7e |
image.save((QCString)path+"/"+fileName+IMAGE_EXT);
|
|
Packit |
1c1d7e |
Doxygen::indexList->addImageFile(QCString(fileName)+IMAGE_EXT);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
if (generateMap) t << "</map>" << endl;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|