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