My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tabdiagram.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tabdiagram.cpp
3  ----------------
4  begin : Fri Oct 24 2003
5  copyright : (C) 2003 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 "tabdiagram.h"
19 #include "main.h"
20 
21 #include <math.h>
22 
23 
24 TabDiagram::TabDiagram(int _cx, int _cy) : Diagram(_cx, _cy)
25 {
26  x1 = 0; // no extension to select area
27  y1 = 0;
28  x2 = x3 = 300; // initial size of diagram
29  y2 = 200;
30  Name = "Tab";
31  xAxis.limit_min = 0.0; // scroll bar position (needs to be saved in file)
32 
33  calcDiagram();
34 }
35 
37 {
38 }
39 
40 // ------------------------------------------------------------
42 {
43  // paint all lines
44  for(Line *pl = Lines.first(); pl != 0; pl = Lines.next()) {
45  p->Painter->setPen(pl->style);
46  p->drawLine(cx+pl->x1, cy-pl->y1, cx+pl->x2, cy-pl->y2);
47  }
48 
49  if(x1 > 0) { // paint scroll bar ?
50  int x, y, dx, dy;
51  QPointArray Points;
52  y = y2 - 20;
53  // draw scroll bar
54  int by = cy-y + yAxis.numGraphs;
55  p->fillRect(cx-14, by+1, 12, zAxis.numGraphs-1, QColor(192, 192, 192));
56 
57  // draw frame for scroll bar
58  p->Painter->setPen(QPen(QPen::black,0));
59  p->drawLine(cx-17, cy-y2, cx-17, cy);
60  p->drawLine(cx-17, cy-y2, cx, cy-y2);
61  p->drawLine(cx-17, cy, cx, cy);
62  y += 2;
63  p->drawLine(cx-17, cy-y, cx, cy-y);
64  y -= y2;
65  p->drawLine(cx-17, cy+y, cx, cy+y);
66 
67  // draw the arrows above and below the scroll bar
68  p->Painter->setBrush(QColor(192, 192, 192));
69  p->Painter->setPen(QColor(152, 152, 152));
70  p->drawLine(cx-2, by, cx-2, by + zAxis.numGraphs);
71  p->drawLine(cx-15, by + zAxis.numGraphs, cx-2, by + zAxis.numGraphs);
72 
73  p->map(cx-14, cy-y2+3, x, y);
74  p->map(cx-3, cy-y2+14, dx, dy);
75  Points.setPoints(3, x, dy, (x+dx)>>1, y, dx, dy);
76  p->Painter->drawConvexPolygon(Points);
77  p->Painter->setPen(QColor(224, 224, 224));
78  p->Painter->drawLine(x, dy, (x+dx)>>1, y);
79  p->drawLine(cx-15, by, cx-2, by);
80  p->drawLine(cx-15, by, cx-15, by + zAxis.numGraphs);
81 
82  p->Painter->setPen(QColor(152, 152, 152));
83  dy -= y;
84  p->map(cx-14, cy-3, x, y);
85  Points.setPoints(3, x, y-dy, (x+dx)>>1, y, dx, y-dy);
86  p->Painter->drawConvexPolygon(Points);
87  p->Painter->setPen(QColor(208, 208, 208));
88  p->Painter->drawLine(x, y-dy, (x+dx)>>1, y);
89  p->Painter->setPen(QColor(224, 224, 224));
90  p->Painter->drawLine(x, y-dy, dx, y-dy);
91 
92  p->Painter->setBrush(QBrush(Qt::NoBrush));
93  }
94 
95 
96  p->Painter->setPen(Qt::black);
97  // write whole text
98  for(Text *pt = Texts.first(); pt != 0; pt = Texts.next())
99  p->drawText(pt->s, cx+pt->x, cy-pt->y);
100 
101 
102  if(isSelected) {
103  p->Painter->setPen(QPen(QPen::darkGray,3));
104  p->drawRect(cx-5, cy-y2-5, x2+10, y2+10);
105  p->Painter->setPen(QPen(QPen::darkRed,2));
106  p->drawResizeRect(cx, cy-y2); // markers for changing the size
107  p->drawResizeRect(cx, cy);
108  p->drawResizeRect(cx+x2, cy-y2);
109  p->drawResizeRect(cx+x2, cy);
110  }
111 }
112 
113 // ------------------------------------------------------------
114 // calculates the text in the tabular
116 {
117  Lines.clear();
118  Texts.clear();
119  Arcs.clear();
120 
121  x1 = 0; // no scroll bar
122  x3 = x2;
123  QFontMetrics metrics(QucsSettings.font);
124  int tHeight = metrics.lineSpacing();
125  QString Str;
126  int colWidth=0, x=8, y;
127 
128  if(y2 < (41 + MIN_SCROLLBAR_SIZE))
129  y2 = 41 + MIN_SCROLLBAR_SIZE;
130 
131  if(y2 < (tHeight + 8))
132  y2 = tHeight + 8;
133  y = y2 - tHeight - 6;
134 
135  // outer frame
136  Lines.append(new Line(0, y2, x2, y2, QPen(QPen::black,0)));
137  Lines.append(new Line(0, y2, 0, 0, QPen(QPen::black,0)));
138  Lines.append(new Line(x2, y2, x2, 0, QPen(QPen::black,0)));
139  Lines.append(new Line(0, 0, x2, 0, QPen(QPen::black,0)));
140  Lines.append(new Line(0, y+2, x2, y+2, QPen(QPen::black,2)));
141 
142  if(xAxis.limit_min < 0.0)
143  xAxis.limit_min = 0.0;
144 
145  Graph *firstGraph;
146  Graph *g = Graphs.first();
147  if(g == 0) { // no variables specified in diagram ?
148  Str = QObject::tr("no variables");
149  colWidth = checkColumnWidth(Str, metrics, colWidth, x, y2);
150  if(colWidth >= 0)
151  Texts.append(new Text(x-4, y2-2, Str)); // independent variable
152  return 0;
153  }
154 
155 
156  int NumAll=0; // how many numbers per column
157  int NumLeft=0; // how many numbers could not be written
158 
159  double *py, *px;
160  int counting, invisibleCount=0;
161  int startWriting, lastCount = 1;
162 
163  while(g->cPointsX.isEmpty()) { // any graph with data ?
164  g = Graphs.next();
165  if(g == 0) break;
166  }
167 if(g) if(!g->cPointsX.isEmpty()) {
168  // ................................................
169  counting = g->cPointsX.getFirst()->count * g->countY; // number of values
170  NumAll = counting;
171 
172  invisibleCount = counting - y/tHeight;
173  if(invisibleCount <= 0) xAxis.limit_min = 0.0;// height bigger than needed
174  else {
175  NumLeft = invisibleCount - int(xAxis.limit_min + 0.5);
176  if(invisibleCount < int(xAxis.limit_min + 0.5))
177  xAxis.limit_min = double(invisibleCount); // adjust limit of scroll bar
178  }
179 
180  for(DataX *pD = g->cPointsX.last(); pD!=0; pD = g->cPointsX.prev()) {
181  colWidth = 0;
182  Str = pD->Var;
183  colWidth = checkColumnWidth(Str, metrics, colWidth, x, y2);
184  if(colWidth < 0) goto funcEnd;
185  startWriting = int(xAxis.limit_min + 0.5); // when to reach visible area
186 
187  Texts.append(new Text(x-4, y2-2, Str)); // independent variable
188  if(pD->count != 0) {
189  y = y2-tHeight-5;
190  counting /= pD->count; // how many rows to be skipped
191  for(int z1=0; z1<lastCount; z1++) {
192  px = pD->Points;
193  for(int z=pD->count; z>0; z--) {
194  if(startWriting <= 0) { // reached visible area ?
195  y += tHeight*startWriting;
196  startWriting = 0;
197  if(y < tHeight) break; // no room for more rows ?
198  Str = StringNum(*px, 'g', g->Precision);
199  colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
200  if(colWidth < 0) goto funcEnd;
201 
202  Texts.append(new Text( x, y, Str));
203  y -= tHeight*counting;
204  }
205  else startWriting -= counting;
206  px++;
207  }
208  if(pD == g->cPointsX.getFirst()) // only paint one time
209  if(y >= tHeight) if(y < y2-tHeight-5)
210  Lines.append(new Line(0, y+1, x2, y+1, QPen(QPen::black,0)));
211  }
212  lastCount *= pD->count;
213  }
214  x += colWidth+15;
215  Lines.append(new Line(x-8, y2, x-8, 0, QPen(QPen::black,0)));
216  }
217  Lines.current()->style = QPen(QPen::black,2);
218 
219 } // of "if no data in graphs"
220 
221 
222  firstGraph = g;
223  // ................................................
224  // all dependent variables
225  for(g = Graphs.first(); g!=0; g = Graphs.next()) {
226  y = y2-tHeight-5;
227  colWidth = 0;
228 
229  Str = g->Var;
230  colWidth = checkColumnWidth(Str, metrics, colWidth, x, y2);
231  if(colWidth < 0) goto funcEnd;
232  Texts.append(new Text(x, y2-2, Str)); // dependent variable
233 
234 
235  startWriting = int(xAxis.limit_min + 0.5); // when to reach visible area
236  py = g->cPointsY - 2;
237  if(g->cPointsX.getFirst()) {
238 
239  if (!g->cPointsY) { // no data points
240  Str = QObject::tr("invalid");
241  colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
242  if(colWidth < 0) goto funcEnd;
243  Texts.append(new Text(x, y, Str));
244  }
245  else if(sameDependencies(g, firstGraph)) {
246  int z=g->cPointsX.getFirst()->count * g->countY;
247  if(z > NumAll) NumAll = z;
248 
249  if(g->Var.right(2) != ".X")
250  for(; z>0; z--) {
251  py += 2;
252  if(startWriting-- > 0) continue; // reached visible area ?
253  if(y < tHeight) break; // no room for more rows ?
254  switch(g->numMode) {
255  case 0: Str = complexRect(*py, *(py+1), g->Precision); break;
256  case 1: Str = complexDeg (*py, *(py+1), g->Precision); break;
257  case 2: Str = complexRad (*py, *(py+1), g->Precision); break;
258  }
259 
260  colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
261  if(colWidth < 0) goto funcEnd;
262 
263  Texts.append(new Text(x, y, Str));
264  y -= tHeight;
265  }
266 
267  else { // digital data
268  char *pcy = (char*)g->cPointsY;
269  for(; z>0; z--) {
270  if(startWriting-- > 0) { // reached visible area ?
271  pcy += strlen(pcy) + 1;
272  continue;
273  }
274  if(y < tHeight) break; // no room for more rows ?
275  Str = QString(pcy);
276 
277  colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
278  if(colWidth < 0) goto funcEnd;
279 
280  Texts.append(new Text(x, y, Str));
281  pcy += strlen(pcy) + 1;
282  y -= tHeight;
283  }
284  }
285 
286  if(z > NumLeft) NumLeft = z;
287  } // of "if(sameDeps)"
288  else {
289  Str = QObject::tr("wrong dependency");
290  colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
291  if(colWidth < 0) goto funcEnd;
292  Texts.append(new Text(x, y, Str));
293  }
294  }
295  else { // no data in graph
296  Str = QObject::tr("no data");
297  colWidth = checkColumnWidth(Str, metrics, colWidth, x, y);
298  if(colWidth < 0) goto funcEnd;
299  Texts.append(new Text(x, y, Str));
300  }
301  x += colWidth+15;
302  if(g != Graphs.getLast()) // do not paint last line
303  Lines.append(new Line(x-8, y2, x-8, 0, QPen(QPen::black,0)));
304  }
305 
306 funcEnd:
307  if(invisibleCount > 0) { // could all numbers be written ?
308  x1 = 18; // extend the select area to the left
309 
310  zAxis.limit_max = double(NumAll); // number of data (rows)
311 
312  // calculate data for painting scroll bar
313  y = int(xAxis.limit_min + 0.5);
314  NumLeft = NumAll - NumLeft - y;
315 
316  // position of scroll bar in pixel
317  yAxis.numGraphs = (y2 - 39) * y / NumAll;
318 
319  // height of scroll bar
320  zAxis.numGraphs = (y2 - 39) * NumLeft / NumAll;
323  * y / NumAll;
325  }
326 
327  xAxis.numGraphs = NumLeft; // number of lines in the diagram
328  }
329 
330  return 1;
331 }
332 
333 // ------------------------------------------------------------
334 int TabDiagram::scroll(int clickPos)
335 {
336  if(x1 <= 0) return 0; // no scroll bar ?
337  int tmp = int(xAxis.limit_min + 0.5);
338 
339  int y = cy;
340  if(clickPos > (cy-20)) { // scroll one line down ?
341  xAxis.limit_min++;
342  }
343  else {
344  y -= y2 - 20;
345  if(clickPos < y) { // scroll bar one line up ?
346  if(xAxis.limit_min <= 0.0) return 0;
347  xAxis.limit_min--;
348  }
349  else {
350  y += yAxis.numGraphs;
351  if(clickPos < y) // scroll bar one page up ?
352  xAxis.limit_min -= double(xAxis.numGraphs);
353  else {
354  y += zAxis.numGraphs;
355  if(clickPos > y) // a page down?
356  xAxis.limit_min += double(xAxis.numGraphs);
357  else
358  return 2; // click on position bar
359  }
360  }
361  }
362 
363  calcDiagram();
364  if(tmp == int(xAxis.limit_min + 0.5))
365  return 0; // did anything change ?
366 
367  return 1;
368 }
369 
370 // ------------------------------------------------------------
371 bool TabDiagram::scrollTo(int initial, int, int dy)
372 {
373  int tmp = int(xAxis.limit_min + 0.5);
374  xAxis.limit_min = double(initial);
375  xAxis.limit_min += double(dy) / double(y2 - 39) * zAxis.limit_max;
377 
378  calcDiagram();
379  if(tmp == int(xAxis.limit_min + 0.5))
380  return false; // did anything change ?
381 
382  return true;
383 }
384 
385 // ------------------------------------------------------------
387 {
388  return new TabDiagram();
389 }
390 
391 // ------------------------------------------------------------
392 Element* TabDiagram::info(QString& Name, char* &BitmapFile, bool getNewOne)
393 {
394  Name = QObject::tr("Tabular");
395  BitmapFile = (char *) "tabular";
396 
397  if(getNewOne) return new TabDiagram();
398  return 0;
399 }