My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
truthdiagram.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  truthdiagram.cpp
3  ------------------
4  begin : Sat Nov 12 2005
5  copyright : (C) 2005 by Michael Margraf
6  email : michael.margraf@alumni.tu-berlin.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "truthdiagram.h"
19 #include "main.h"
20 
21 #include <math.h>
22 
23 
24 TruthDiagram::TruthDiagram(int _cx, int _cy) : TabDiagram(_cx, _cy)
25 {
26  x1 = 0; // no extension to select area
27  y1 = 0;
28  x2 = x3 = 150; // initial size of diagram
29  y2 = 200;
30  Name = "Truth";
31  xAxis.limit_min = 0.0; // scroll bar position (needs to be saved in file)
32 
33  calcDiagram();
34 }
35 
37 {
38 }
39 
40 // ------------------------------------------------------------
41 // calculates the text in the tabular
43 {
44  Lines.clear();
45  Texts.clear();
46  Arcs.clear();
47 
48  x1 = 0; // no scroll bar
49  x3 = x2;
50  QFontMetrics metrics(QucsSettings.font);
51  int tHeight = metrics.lineSpacing();
52  QString Str;
53  int colWidth=0, x=6, y;
54 
55  if(y2 < (41 + MIN_SCROLLBAR_SIZE))
56  y2 = 41 + MIN_SCROLLBAR_SIZE;
57 
58  if(y2 < (tHeight + 8))
59  y2 = tHeight + 8;
60  y = y2 - tHeight - 6;
61 
62  // outer frame
63  Lines.append(new Line(0, y2, x2, y2, QPen(QPen::black,0)));
64  Lines.append(new Line(0, y2, 0, 0, QPen(QPen::black,0)));
65  Lines.append(new Line(x2, y2, x2, 0, QPen(QPen::black,0)));
66  Lines.append(new Line(0, 0, x2, 0, QPen(QPen::black,0)));
67  Lines.append(new Line(0, y+2, x2, y+2, QPen(QPen::black,2)));
68 
69  if(xAxis.limit_min < 0.0)
70  xAxis.limit_min = 0.0;
71 
72  Graph *firstGraph;
73  Graph *g = Graphs.first();
74  if(g == 0) { // no variables specified in diagram ?
75  Str = QObject::tr("no variables");
76  colWidth = checkColumnWidth(Str, metrics, colWidth, x, y2);
77  if(colWidth >= 0)
78  Texts.append(new Text(x-4, y2-2, Str)); // independent variable
79  return 0;
80  }
81 
82 
83  int NumAll=0; // how many numbers per column
84  int NumLeft=0; // how many numbers could not be written
85 
86  char *py;
87  int counting, invisibleCount=0;
88  int startWriting, z;
89 
90  while(g->cPointsX.isEmpty()) { // any graph with data ?
91  g = Graphs.next();
92  if(g == 0) break;
93  }
94 if(g) if(!g->cPointsX.isEmpty()) {
95  // ................................................
96  NumAll = g->cPointsX.getFirst()->count * g->countY; // number of values
97 
98  invisibleCount = NumAll - y/tHeight;
99  if(invisibleCount <= 0) xAxis.limit_min = 0.0;// height bigger than needed
100  else {
101  if(invisibleCount < int(xAxis.limit_min + 0.5))
102  xAxis.limit_min = double(invisibleCount); // adjust limit of scroll bar
103  NumLeft = invisibleCount - int(xAxis.limit_min + 0.5);
104  }
105 
106 
107  colWidth = 0;
108  Texts.append(new Text(x-4, y2-2, Str)); // independent variable
109  if(NumAll != 0) {
110  z = metrics.width("1");
111  colWidth = metrics.width("0");
112  if(z > colWidth) colWidth = z;
113  colWidth += 2;
114  counting = int(log(double(NumAll)) / log(2.0) + 0.9999); // number of bits
115 
116  if((x+colWidth*counting) >= x2) { // enough space for text ?
117  checkColumnWidth("0", metrics, 0, x2, y);
118  goto funcEnd;
119  }
120 
121  y = y2-tHeight-5;
122  startWriting = x;
123  for(z=int(xAxis.limit_min + 0.5); z<NumAll; z++) {
124  if(y < tHeight) break; // no room for more rows ?
125  startWriting = x;
126  for(int zi=counting-1; zi>=0; zi--) {
127  if(z & (1 << zi)) Str = "1";
128  else Str = "0";
129  Texts.append(new Text( startWriting, y, Str));
130  startWriting += colWidth;
131  }
132  y -= tHeight;
133  }
134  x = startWriting + 15;
135  }
136  Lines.append(new Line(x-8, y2, x-8, 0, QPen(QPen::black,2)));
137 
138 } // of "if no data in graphs"
139 
140 
141  int zi, digitWidth;
142  firstGraph = g;
143  // ................................................
144  // all dependent variables
145  for(g = Graphs.first(); g!=0; g = Graphs.next()) {
146  y = y2-tHeight-5;
147 
148  Str = g->Var;
149  colWidth = checkColumnWidth(Str, metrics, 0, x, y2);
150  if(colWidth < 0) goto funcEnd;
151  Texts.append(new Text(x, y2-2, Str)); // dependent variable
152 
153 
154  startWriting = int(xAxis.limit_min + 0.5); // when to reach visible area
155  if(g->cPointsX.getFirst()) {
156 
157  if(sameDependencies(g, firstGraph)) {
158 
159  if(g->Var.right(2) != ".X") { // not a digital variable ?
160  double *pdy = g->cPointsY - 2;
161  for(z = NumAll; z>0; z--) {
162  pdy += 2;
163  if(startWriting-- > 0) continue; // reached visible area ?
164  if(y < tHeight) break; // no room for more rows ?
165  Str = QString::number(sqrt((*pdy)*(*pdy) + (*(pdy+1))*(*(pdy+1))));
166 
167  colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
168  if(colWidth < 0) goto funcEnd;
169 
170  Texts.append(new Text(x, y, Str));
171  y -= tHeight;
172  }
173  }
174 
175  else { // digital variable !!!
176  py = (char*)g->cPointsY;
177  counting = strlen((char*)py); // count number of "bits"
178 
179  digitWidth = metrics.width("X") + 2;
180  if((x+digitWidth*counting) >= x2) { // enough space for "bit vector" ?
181  checkColumnWidth("0", metrics, 0, x2, y);
182  goto funcEnd;
183  }
184 
185  for(z = NumAll; z>0; z--) {
186  if(startWriting-- > 0) { // reached visible area ?
187  py += counting + 1;
188  continue;
189  }
190  if(y < tHeight) break; // no room for more rows ?
191 
192  zi = 0;
193  while(*py) {
194  Str = *(py++);
195  Texts.append(new Text(x + zi, y, Str));
196  zi += digitWidth;
197  }
198  py++;
199  y -= tHeight;
200  }
201 
202  digitWidth *= counting;
203  if(colWidth < digitWidth)
204  colWidth = digitWidth;
205  }
206 
207  } // of "if(sameDeps)"
208  else {
209  Str = QObject::tr("wrong dependency");
210  colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
211  if(colWidth < 0) goto funcEnd;
212  Texts.append(new Text(x, y, Str));
213  }
214  }
215  else { // no data in graph
216  Str = QObject::tr("no data");
217  colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
218  if(colWidth < 0) goto funcEnd;
219  Texts.append(new Text(x, y, Str));
220  }
221  x += colWidth+15;
222  if(g != Graphs.getLast()) // do not paint last line
223  Lines.append(new Line(x-8, y2, x-8, 0, QPen(QPen::black,0)));
224  }
225 
226 funcEnd:
227  if(invisibleCount > 0) { // could all numbers be written ?
228  x1 = 18; // extend the select area to the left
229 
230  zAxis.limit_max = double(NumAll); // number of data (rows)
231 
232  // calculate data for painting scroll bar
233  y = int(xAxis.limit_min + 0.5);
234  NumLeft = NumAll - NumLeft - y;
235 
236  // position of scroll bar in pixel
237  yAxis.numGraphs = (y2 - 39) * y / NumAll;
238 
239  // height of scroll bar
240  zAxis.numGraphs = (y2 - 39) * NumLeft / NumAll;
243  * y / NumAll;
245  }
246 
247  xAxis.numGraphs = NumLeft; // number of lines in the diagram
248  }
249 
250  return 1;
251 }
252 
253 // ------------------------------------------------------------
255 {
256  return new TruthDiagram();
257 }
258 
259 // ------------------------------------------------------------
260 Element* TruthDiagram::info(QString& Name, char* &BitmapFile, bool getNewOne)
261 {
262  Name = QObject::tr("Truth Table");
263  BitmapFile = (char *) "truth";
264 
265  if(getNewOne) return new TruthDiagram();
266  return 0;
267 }