Qucs-GUI
0.0.19
|
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 }