truthdiagram.cpp
------------------
begin : Sat Nov 12 2005
copyright : (C) 2005 by Michael Margraf
email : michael.margraf@alumni.tu-berlin.de
***************************************************************************/
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
\class TruthDiagram
\brief The TruthDiagram class implements the Truth Table diagram
*/
#include <cmath>
#include <QFontMetrics>
#include "truthdiagram.h"
#include "main.h"
TruthDiagram::TruthDiagram(int _cx, int _cy) : TabDiagram(_cx, _cy)
{
x1 = 0;
y1 = 0;
x2 = x3 = 150;
y2 = 200;
Name = "Truth";
xAxis.limit_min = 0.0;
calcDiagram();
}
TruthDiagram::~TruthDiagram()
{
}
int TruthDiagram::calcDiagram()
{
Lines.clear();
Texts.clear();
Arcs.clear();
x1 = 0;
x3 = x2;
QFontMetrics metrics(QucsSettings.font, 0);
int tHeight = metrics.lineSpacing();
QString Str;
int colWidth=0, x=6, y;
if(y2 < (41 + MIN_SCROLLBAR_SIZE))
y2 = 41 + MIN_SCROLLBAR_SIZE;
if(y2 < (tHeight + 8))
y2 = tHeight + 8;
y = y2 - tHeight - 6;
Lines.append(new qucs::Line(0, y2, x2, y2, QPen(Qt::black,0)));
Lines.append(new qucs::Line(0, y2, 0, 0, QPen(Qt::black,0)));
Lines.append(new qucs::Line(x2, y2, x2, 0, QPen(Qt::black,0)));
Lines.append(new qucs::Line(0, 0, x2, 0, QPen(Qt::black,0)));
Lines.append(new qucs::Line(0, y+2, x2, y+2, QPen(Qt::black,2)));
if(xAxis.limit_min < 0.0)
xAxis.limit_min = 0.0;
Graph *firstGraph;
QListIterator<Graph *> ig(Graphs);
Graph *g = 0;
if (ig.hasNext())
g= ig.next();
if(g == 0) {
Str = QObject::tr("no variables");
colWidth = checkColumnWidth(Str, metrics, colWidth, x, y2);
if(colWidth >= 0)
Texts.append(new Text(x-4, y2-2, Str));
return 0;
}
int NumAll=0;
int NumLeft=0;
char *py;
int counting, invisibleCount=0;
int startWriting, z;
while(g->isEmpty()) {
if (!ig.hasNext()) break;
g = ig.next();
}
if(!g->isEmpty()) {
NumAll = g->axis(0)->count * g->countY;
invisibleCount = NumAll - y/tHeight;
if(invisibleCount <= 0) xAxis.limit_min = 0.0;
else {
if(invisibleCount < int(xAxis.limit_min + 0.5))
xAxis.limit_min = double(invisibleCount);
NumLeft = invisibleCount - int(xAxis.limit_min + 0.5);
}
colWidth = 0;
Texts.append(new Text(x-4, y2-2, Str));
if(NumAll != 0) {
z = metrics.boundingRect("1").width();
colWidth = metrics.boundingRect("0").width();
if(z > colWidth) colWidth = z;
colWidth += 2;
counting = int(log(double(NumAll)) / log(2.0) + 0.9999);
if((x+colWidth*counting) >= x2) {
checkColumnWidth("0", metrics, 0, x2, y);
goto funcEnd;
}
y = y2-tHeight-5;
startWriting = x;
for(z=int(xAxis.limit_min + 0.5); z<NumAll; z++) {
if(y < tHeight) break;
startWriting = x;
for(int zi=counting-1; zi>=0; zi--) {
if(z & (1 << zi)) Str = "1";
else Str = "0";
Texts.append(new Text( startWriting, y, Str));
startWriting += colWidth;
}
y -= tHeight;
}
x = startWriting + 15;
}
Lines.append(new qucs::Line(x-8, y2, x-8, 0, QPen(Qt::black,2)));
}
int zi, digitWidth;
firstGraph = g;
for (Graph *g : Graphs) {
y = y2-tHeight-5;
Str = g->Var;
colWidth = checkColumnWidth(Str, metrics, 0, x, y2);
if(colWidth < 0) goto funcEnd;
Texts.append(new Text(x, y2-2, Str));
startWriting = int(xAxis.limit_min + 0.5);
if(g->axis(0)) {
if(sameDependencies(g, firstGraph)) {
if(g->Var.right(2) != ".X") {
double *pdy = g->cPointsY - 2;
for(z = NumAll; z>0; z--) {
pdy += 2;
if(startWriting-- > 0) continue;
if(y < tHeight) break;
Str = QString::number(sqrt((*pdy)*(*pdy) + (*(pdy+1))*(*(pdy+1))));
colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
if(colWidth < 0) goto funcEnd;
Texts.append(new Text(x, y, Str));
y -= tHeight;
}
}
else {
py = (char*)g->cPointsY;
counting = strlen((char*)py);
digitWidth = metrics.boundingRect("X").width() + 2;
if((x+digitWidth*counting) >= x2) {
checkColumnWidth("0", metrics, 0, x2, y);
goto funcEnd;
}
for(z = NumAll; z>0; z--) {
if(startWriting-- > 0) {
py += counting + 1;
continue;
}
if(y < tHeight) break;
zi = 0;
while(*py) {
Str = *(py++);
Texts.append(new Text(x + zi, y, Str));
zi += digitWidth;
}
py++;
y -= tHeight;
}
digitWidth *= counting;
if(colWidth < digitWidth)
colWidth = digitWidth;
}
}
else {
Str = QObject::tr("wrong dependency");
colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
if(colWidth < 0) goto funcEnd;
Texts.append(new Text(x, y, Str));
}
}
else {
Str = QObject::tr("no data");
colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
if(colWidth < 0) goto funcEnd;
Texts.append(new Text(x, y, Str));
}
x += colWidth+15;
if(g != Graphs.last())
Lines.append(new qucs::Line(x-8, y2, x-8, 0, QPen(Qt::black,0)));
}
funcEnd:
if(invisibleCount > 0) {
x1 = 18;
zAxis.limit_max = double(NumAll);
y = int(xAxis.limit_min + 0.5);
NumLeft = NumAll - NumLeft - y;
yAxis.numGraphs = (y2 - 39) * y / NumAll;
zAxis.numGraphs = (y2 - 39) * NumLeft / NumAll;
if(zAxis.numGraphs < MIN_SCROLLBAR_SIZE) {
yAxis.numGraphs -= (MIN_SCROLLBAR_SIZE - zAxis.numGraphs + 1)
* y / NumAll;
zAxis.numGraphs = MIN_SCROLLBAR_SIZE;
}
xAxis.numGraphs = NumLeft;
}
return 1;
}
Diagram* TruthDiagram::newOne()
{
return new TruthDiagram();
}
Element* TruthDiagram::info(QString& Name, char* &BitmapFile, bool getNewOne)
{
Name = QObject::tr("Truth Table");
BitmapFile = (char *) "truth";
if(getNewOne) return new TruthDiagram();
return 0;
}