Qucs-GUI  0.0.19
/home/travis/build/Qucs/qucs/qucs/qucs/diagrams/truthdiagram.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                               truthdiagram.cpp
00003                              ------------------
00004     begin                : Sat Nov 12 2005
00005     copyright            : (C) 2005 by Michael Margraf
00006     email                : michael.margraf@alumni.tu-berlin.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00023 #include <cmath>
00024 
00025 #include <QFontMetrics>
00026 
00027 #include "truthdiagram.h"
00028 #include "main.h"
00029 
00030 
00031 TruthDiagram::TruthDiagram(int _cx, int _cy) : TabDiagram(_cx, _cy)
00032 {
00033   x1 = 0;    // no extension to select area
00034   y1 = 0;
00035   x2 = x3 = 150;  // initial size of diagram
00036   y2 = 200;
00037   Name = "Truth";
00038   xAxis.limit_min = 0.0;  // scroll bar position (needs to be saved in file)
00039 
00040   calcDiagram();
00041 }
00042 
00043 TruthDiagram::~TruthDiagram()
00044 {
00045 }
00046 
00047 // ------------------------------------------------------------
00048 // calculates the text in the tabular
00049 int TruthDiagram::calcDiagram()
00050 {
00051   Lines.clear();
00052   Texts.clear();
00053   Arcs.clear();
00054 
00055   x1 = 0;  // no scroll bar
00056   x3 = x2;
00057   // get size of text using the screen-compatible metric
00058   QFontMetrics metrics(QucsSettings.font, 0);
00059   int tHeight = metrics.lineSpacing();
00060   QString Str;
00061   int colWidth=0, x=6, y;
00062 
00063   if(y2 < (41 + MIN_SCROLLBAR_SIZE))
00064     y2 = 41 + MIN_SCROLLBAR_SIZE;
00065 
00066   if(y2 < (tHeight + 8))
00067     y2 = tHeight + 8;
00068   y = y2 - tHeight - 6;
00069 
00070   // outer frame
00071   Lines.append(new Line(0, y2, x2, y2, QPen(Qt::black,0)));
00072   Lines.append(new Line(0, y2, 0, 0, QPen(Qt::black,0)));
00073   Lines.append(new Line(x2, y2, x2, 0, QPen(Qt::black,0)));
00074   Lines.append(new Line(0, 0, x2, 0, QPen(Qt::black,0)));
00075   Lines.append(new Line(0, y+2, x2, y+2, QPen(Qt::black,2)));
00076 
00077   if(xAxis.limit_min < 0.0)
00078     xAxis.limit_min = 0.0;
00079 
00080   Graph *firstGraph;
00081 
00082   QListIterator<Graph *> ig(Graphs);
00083   Graph *g = 0;
00084   if (ig.hasNext())
00085      g= ig.next();
00086 
00087   if(g == 0) {  // no variables specified in diagram ?
00088     Str = QObject::tr("no variables");
00089     colWidth = checkColumnWidth(Str, metrics, colWidth, x, y2);
00090     if(colWidth >= 0)
00091       Texts.append(new Text(x-4, y2-2, Str)); // independent variable
00092     return 0;
00093   }
00094 
00095   int NumAll=0;   // how many numbers per column
00096   int NumLeft=0;  // how many numbers could not be written
00097 
00098   char *py;
00099   int counting, invisibleCount=0;
00100   int startWriting, z;
00101 
00102   // any graph with data ?
00103   while(g->isEmpty()) {
00104     if (!ig.hasNext()) break; // no more graphs, exit loop
00105     g = ig.next(); // point to next graph
00106   }
00107 
00108   if(!g->isEmpty()) { // did we find a graph with data ?
00109     // ................................................
00110     NumAll = g->axis(0)->count * g->countY;  // number of values
00111     
00112     invisibleCount = NumAll - y/tHeight;
00113     if(invisibleCount <= 0)  xAxis.limit_min = 0.0;// height bigger than needed
00114     else {
00115       if(invisibleCount < int(xAxis.limit_min + 0.5))
00116   xAxis.limit_min = double(invisibleCount); // adjust limit of scroll bar
00117       NumLeft = invisibleCount - int(xAxis.limit_min + 0.5);
00118     }
00119 
00120     colWidth = 0;
00121     Texts.append(new Text(x-4, y2-2, Str)); // independent variable
00122     if(NumAll != 0) {
00123       z = metrics.width("1");
00124       colWidth = metrics.width("0");
00125       if(z > colWidth)  colWidth = z;
00126       colWidth += 2;
00127       counting = int(log(double(NumAll)) / log(2.0) + 0.9999); // number of bits
00128       
00129       if((x+colWidth*counting) >= x2) {    // enough space for text ?
00130   checkColumnWidth("0", metrics, 0, x2, y);
00131   goto funcEnd;
00132       }
00133       
00134       y = y2-tHeight-5;
00135       startWriting = x;
00136       for(z=int(xAxis.limit_min + 0.5); z<NumAll; z++) {
00137   if(y < tHeight) break;  // no room for more rows ?
00138   startWriting = x;
00139   for(int zi=counting-1; zi>=0; zi--) {
00140     if(z & (1 << zi))  Str = "1";
00141     else  Str = "0";
00142     Texts.append(new Text( startWriting, y, Str));
00143     startWriting += colWidth;
00144   }
00145   y -= tHeight;
00146       }
00147       x = startWriting + 15;
00148     }
00149     Lines.append(new Line(x-8, y2, x-8, 0, QPen(Qt::black,2)));  
00150   }  // of "if no data in graphs"
00151   
00152 
00153   int zi, digitWidth;
00154   firstGraph = g;
00155   // ................................................
00156   // all dependent variables
00157   foreach(Graph *g ,Graphs) {
00158     y = y2-tHeight-5;
00159 
00160     Str = g->Var;
00161     colWidth = checkColumnWidth(Str, metrics, 0, x, y2);
00162     if(colWidth < 0)  goto funcEnd;
00163     Texts.append(new Text(x, y2-2, Str));  // dependent variable
00164 
00165 
00166     startWriting = int(xAxis.limit_min + 0.5);  // when to reach visible area
00167     if(g->axis(0)) {
00168 
00169       if(sameDependencies(g, firstGraph)) {
00170 
00171         if(g->Var.right(2) != ".X") {  // not a digital variable ?
00172           double *pdy = g->cPointsY - 2;
00173           for(z = NumAll; z>0; z--) {
00174             pdy += 2;
00175             if(startWriting-- > 0) continue; // reached visible area ?
00176             if(y < tHeight) break;           // no room for more rows ?
00177             Str = QString::number(sqrt((*pdy)*(*pdy) + (*(pdy+1))*(*(pdy+1))));
00178 
00179             colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
00180             if(colWidth < 0)  goto funcEnd;
00181 
00182             Texts.append(new Text(x, y, Str));
00183             y -= tHeight;
00184           }
00185         }
00186 
00187         else {  // digital variable !!!
00188           py = (char*)g->cPointsY;
00189           counting = strlen((char*)py);    // count number of "bits"
00190 
00191           digitWidth = metrics.width("X") + 2;
00192           if((x+digitWidth*counting) >= x2) {    // enough space for "bit vector" ?
00193             checkColumnWidth("0", metrics, 0, x2, y);
00194             goto funcEnd;
00195           }
00196 
00197           for(z = NumAll; z>0; z--) {
00198             if(startWriting-- > 0) {   // reached visible area ?
00199               py += counting + 1;
00200               continue;
00201             }
00202             if(y < tHeight) break;    // no room for more rows ?
00203 
00204             zi = 0;
00205             while(*py) {
00206               Str = *(py++);
00207               Texts.append(new Text(x + zi, y, Str));
00208               zi += digitWidth;
00209             }
00210             py++;
00211             y -= tHeight;
00212           }
00213 
00214           digitWidth *= counting;
00215           if(colWidth < digitWidth)
00216             colWidth = digitWidth;
00217         }
00218 
00219       }  // of "if(sameDeps)"
00220       else {
00221         Str = QObject::tr("wrong dependency");
00222         colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
00223         if(colWidth < 0)  goto funcEnd;
00224         Texts.append(new Text(x, y, Str));
00225       }
00226     }
00227     else {   // no data in graph
00228       Str = QObject::tr("no data");
00229       colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
00230       if(colWidth < 0)  goto funcEnd;
00231       Texts.append(new Text(x, y, Str));
00232     }
00233     x += colWidth+15;
00234     if(g != Graphs.last())   // do not paint last line
00235       Lines.append(new Line(x-8, y2, x-8, 0, QPen(Qt::black,0)));
00236   }
00237 
00238 funcEnd:
00239   if(invisibleCount > 0) {  // could all numbers be written ?
00240     x1 = 18;   // extend the select area to the left
00241 
00242     zAxis.limit_max = double(NumAll);  // number of data (rows) 
00243 
00244     // calculate data for painting scroll bar
00245     y = int(xAxis.limit_min + 0.5);
00246     NumLeft = NumAll - NumLeft - y;
00247 
00248     // position of scroll bar in pixel
00249     yAxis.numGraphs = (y2 - 39) * y / NumAll;
00250 
00251     // height of scroll bar
00252     zAxis.numGraphs = (y2 - 39) * NumLeft / NumAll;
00253     if(zAxis.numGraphs < MIN_SCROLLBAR_SIZE) {
00254       yAxis.numGraphs -= (MIN_SCROLLBAR_SIZE - zAxis.numGraphs + 1)
00255                          * y / NumAll;
00256       zAxis.numGraphs = MIN_SCROLLBAR_SIZE;
00257     }
00258 
00259     xAxis.numGraphs = NumLeft;  // number of lines in the diagram
00260   }
00261 
00262   return 1;
00263 }
00264 
00265 // ------------------------------------------------------------
00266 Diagram* TruthDiagram::newOne()
00267 {
00268   return new TruthDiagram();
00269 }
00270 
00271 // ------------------------------------------------------------
00272 Element* TruthDiagram::info(QString& Name, char* &BitmapFile, bool getNewOne)
00273 {
00274   Name = QObject::tr("Truth Table");
00275   BitmapFile = (char *) "truth";
00276 
00277   if(getNewOne)  return new TruthDiagram();
00278   return 0;
00279 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines