Bug Summary

File:OMPlot/OMPlot/OMPlotGUI/PlotWindow.cpp
Warning:line 732, column 35
Array access (from variable 'xVals') results in a null pointer dereference

Annotated Source Code

[?] Use j/k keys for keyboard navigation

1/*
2 * This file is part of OpenModelica.
3 *
4 * Copyright (c) 1998-CurrentYear, Linkoping University,
5 * Department of Computer and Information Science,
6 * SE-58183 Linkoping, Sweden.
7 *
8 * All rights reserved.
9 *
10 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3
11 * AND THIS OSMC PUBLIC LICENSE (OSMC-PL).
12 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S
13 * ACCEPTANCE OF THE OSMC PUBLIC LICENSE.
14 *
15 * The OpenModelica software and the Open Source Modelica
16 * Consortium (OSMC) Public License (OSMC-PL) are obtained
17 * from Linkoping University, either from the above address,
18 * from the URLs: http://www.ida.liu.se/projects/OpenModelica or
19 * http://www.openmodelica.org, and in the OpenModelica distribution.
20 * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
21 *
22 * This program is distributed WITHOUT ANY WARRANTY; without
23 * even the implied warranty of MERCHANTABILITY or FITNESS
24 * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
25 * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS
26 * OF OSMC-PL.
27 *
28 * See the full OSMC Public License conditions for more details.
29 *
30 * Main Authors 2010: Syed Adeel Asghar, Sonia Tariq
31 *
32 */
33
34#include <QtSvg/QSvgGenerator>
35#include "PlotWindow.h"
36#include "iostream"
37#include "qwt_plot_layout.h"
38#if QWT_VERSION0x060200 >= 0x060000
39#include "qwt_plot_renderer.h"
40#endif
41#include "qwt_scale_draw.h"
42#include "qwt_scale_widget.h"
43#include "qwt_text_label.h"
44
45using namespace OMPlot;
46
47PlotWindow::PlotWindow(QStringList arguments, QWidget *parent, bool isInteractiveSimulation)
48 : QMainWindow(parent), mIsInteractiveSimulation(isInteractiveSimulation)
49{
50 /* set the widget background white. so that the plot is more useable in books and publications. */
51 QPalette p(palette());
52 p.setColor(QPalette::Background, Qt::white);
53 setAutoFillBackground(true);
54 setPalette(p);
55 // setup the main window widget
56 setUpWidget();
57 // initialize plot by reading all parameters passed to it
58 if (arguments.size() > 1)
59 {
60 initializePlot(arguments);
61 mpPlot->getPlotZoomer()->setZoomBase(false);
62 }
63 // set qwtplot the central widget
64 setCentralWidget(getPlot());
65}
66
67PlotWindow::~PlotWindow()
68{
69
70}
71
72void PlotWindow::setUpWidget()
73{
74 // create an instance of qwt plot
75 mpPlot = new Plot(this);
76 // set up the toolbar
77 setupToolbar();
78 // set the default values
79 // set the plot title
80 setTitle(tr("Plot by OpenModelica"));
81 // set the plot grid
82 setDetailedGrid(true);
83}
84
85void PlotWindow::initializePlot(QStringList arguments)
86{
87 // open the file
88 initializeFile(QString(arguments[1]));
89 //Set up arguments
90 setTitle(QString(arguments[2]));
91 setGrid(QString(arguments[3]));
92 QString plotType = arguments[4];
93 if(QString(arguments[5]) == "true")
2
Assuming the condition is false
3
Taking false branch
94 setLogX(true);
95 else if(QString(arguments[5]) == "false")
4
Assuming the condition is true
5
Taking true branch
96 setLogX(false);
97 else
98 throw PlotException("Invalid input" + arguments[6]);
99 if(QString(arguments[6]) == "true")
6
Assuming the condition is false
7
Taking false branch
100 setLogY(true);
101 else if(QString(arguments[6]) == "false")
8
Assuming the condition is true
9
Taking true branch
102 setLogY(false);
103 else
104 throw PlotException("Invalid input" + arguments[7]);
105 setXLabel(QString(arguments[7]));
106 setYLabel(QString(arguments[8]));
107 setUnit("");
108 setDisplayUnit("");
109 setXRange(QString(arguments[9]).toDouble(), QString(arguments[10]).toDouble());
110 setYRange(QString(arguments[11]).toDouble(), QString(arguments[12]).toDouble());
111 setCurveWidth(QString(arguments[13]).toDouble());
112 setCurveStyle(QString(arguments[14]).toInt());
113 setLegendFont(QApplication::font());
114 setLegendPosition(QString(arguments[15]));
115 setFooter(QString(arguments[16]));
116 if (QString(arguments[17]) == "true") {
10
Assuming the condition is false
11
Taking false branch
117 setAutoScale(true);
118 } else if (QString(arguments[17]) == "false") {
12
Assuming the condition is true
13
Taking true branch
119 setAutoScale(false);
120 } else {
121 throw PlotException("Invalid input" + arguments[17]);
122 }
123 setTimeUnit("");
124 /* read variables */
125 QStringList variablesToRead;
126 for(int i = 18; i < arguments.length(); i++)
14
Assuming the condition is false
15
Loop condition is false. Execution continues on line 129
127 variablesToRead.append(QString(arguments[i]));
128
129 setVariablesList(variablesToRead);
130 //Plot
131 if(plotType.toLower().compare("plot") == 0)
16
Assuming the condition is false
17
Taking false branch
132 {
133 setPlotType(PlotWindow::PLOT);
134 plot();
135 }
136 else if(plotType.toLower().compare("plotall") == 0)
18
Assuming the condition is false
19
Taking false branch
137 {
138 setPlotType(PlotWindow::PLOTALL);
139 plot();
140 }
141 else if(plotType.toLower().compare("plotparametric") == 0)
20
Assuming the condition is true
21
Taking true branch
142 {
143 setPlotType(PlotWindow::PLOTPARAMETRIC);
144 plotParametric();
22
Calling 'PlotWindow::plotParametric'
145 }
146 else if (plotType.toLower().compare("plotinteractive") == 0)
147 {
148 setPlotType(PlotWindow::PLOTINTERACTIVE);
149 plotInteractive();
150 }
151}
152
153void PlotWindow::setVariablesList(QStringList variables)
154{
155 mVariablesList = variables;
156}
157
158void PlotWindow::setPlotType(PlotType type)
159{
160 mPlotType = type;
161}
162
163PlotWindow::PlotType PlotWindow::getPlotType()
164{
165 return mPlotType;
166}
167
168void PlotWindow::initializeFile(QString file)
169{
170 mFile.setFileName(file);
171 if (!mFile.exists()) {
172 throw NoFileException(QString("File not found : ").append(file).toStdString().c_str());
173 }
174}
175
176void PlotWindow::getStartStopTime(double &start, double &stop){
177 //PLOT PLT
178 if (mFile.fileName().endsWith("plt"))
179 {
180 QString currentLine;
181 // open the file
182 mFile.open(QIODevice::ReadOnly);
183 mpTextStream = new QTextStream(&mFile);
184 // read the interval size from the file
185 int intervalSize = 0;
186 while (!mpTextStream->atEnd())
187 {
188 currentLine = mpTextStream->readLine();
189 if (currentLine.startsWith("#IntervalSize"))
190 {
191 intervalSize = static_cast<QString>(currentLine.split("=").last()).toInt();
192 break;
193 }
194 }
195 // Read start and stop time
196 while (!mpTextStream->atEnd())
197 {
198 currentLine = mpTextStream->readLine();
199 QString currentVariable;
200 if (currentLine.contains("DataSet:"))
201 {
202 currentVariable = currentLine.remove("DataSet: ");
203 if (currentVariable == "time")
204 {
205 // read the variable values now
206 currentLine = mpTextStream->readLine();
207 QStringList values = currentLine.split(",");
208 start = QString(values[0]).toDouble();
209 for(int j = 0; j < intervalSize-1; j++)
210 {
211 currentLine = mpTextStream->readLine();
212 }
213 values = currentLine.split(",");
214 stop = QString(values[0]).toDouble();
215 break;
216 }
217 }
218 }
219 if(mpTextStream->atEnd()) throw NoVariableException("Variable doesnt exist: time");
220 // close the file
221 mFile.close();
222 }
223 //PLOT CSV
224 else if (mFile.fileName().endsWith("csv"))
225 {
226 /* open the file */
227 struct csv_data *csvReader;
228 csvReader = read_csv(mFile.fileName().toStdString().c_str());
229 if (csvReader == NULL__null) {
230 throw NoVariableException("Variable doesnt exist: time");
231 }
232 //Read in timevector
233 double *timeVals = read_csv_dataset(csvReader, "time");
234 if (timeVals == NULL__null) {
235 omc_free_csv_reader(csvReader);
236 throw NoVariableException("Variable doesnt exist: time");
237 }
238 start = timeVals[0];
239 stop = timeVals[csvReader->numsteps-1];
240
241 // close the file
242 omc_free_csv_reader(csvReader);
243 }
244 //PLOT MAT
245 else if(mFile.fileName().endsWith("mat"))
246 {
247 ModelicaMatReader reader;
248 const char *msg = "";
249 //Read in mat file
250 if(0 != (msg = omc_new_matlab4_reader(mFile.fileName().toStdString().c_str(), &reader))) {
251 throw PlotException(msg);
252 }
253
254 //Read in timevector
255 start = omc_matlab4_startTime(&reader);
256 stop = omc_matlab4_stopTime(&reader);
257
258 // close the file
259 omc_free_matlab4_reader(&reader);
260 } else {throw PlotException(tr("Failed to open simulation result file %1").arg(mFile.fileName()));}
261}
262
263void PlotWindow::setupToolbar()
264{
265 QToolBar *toolBar = new QToolBar(this);
266 setContextMenuPolicy(Qt::NoContextMenu);
267 // Interactive Simulation
268 if (mIsInteractiveSimulation) {
269 //start tool button
270 mpStartSimulationToolButton = new QToolButton;
271 mpStartSimulationToolButton->setText(tr("Start"));
272 mpStartSimulationToolButton->setIcon(QIcon(":/Resources/icons/play_animation.svg"));
273 mpStartSimulationToolButton->setToolTip(tr("Start"));
274 mpStartSimulationToolButton->setAutoRaise(true);
275 // pause tool button
276 mpPauseSimulationToolButton = new QToolButton;
277 mpPauseSimulationToolButton->setEnabled(false);
278 mpPauseSimulationToolButton->setText(tr("Pause"));
279 mpPauseSimulationToolButton->setIcon(QIcon(":/Resources/icons/pause.svg"));
280 mpPauseSimulationToolButton->setToolTip(tr("Pause"));
281 mpPauseSimulationToolButton->setAutoRaise(true);
282 // speed label and combo box
283 mpSimulationSpeedLabel = new QLabel(tr("Speed:"));
284 QDoubleValidator *pDoubleValidator = new QDoubleValidator(this);
285 pDoubleValidator->setBottom(0.01);
286 pDoubleValidator->setTop(100);
287 mpSimulationSpeedComboBox = new QComboBox;
288 mpSimulationSpeedComboBox->setEditable(true);
289 mpSimulationSpeedComboBox->addItems(QStringList() << "10" << "5" << "2" << "1" << "0.5" << "0.2" << "0.1");
290 mpSimulationSpeedComboBox->setCurrentIndex(3);
291 mpSimulationSpeedComboBox->setCompleter(0);
292 mpSimulationSpeedComboBox->setValidator(pDoubleValidator);
293 // add the interactive controls
294 toolBar->addWidget(mpStartSimulationToolButton);
295 toolBar->addSeparator();
296 toolBar->addWidget(mpPauseSimulationToolButton);
297 toolBar->addSeparator();
298 toolBar->addWidget(mpSimulationSpeedLabel);
299 toolBar->addWidget(mpSimulationSpeedComboBox);
300 toolBar->addSeparator();
301 }
302 // Auto scale
303 mpAutoScaleButton = new QToolButton(toolBar);
304 mpAutoScaleButton->setText(tr("Auto Scale"));
305 mpAutoScaleButton->setCheckable(true);
306 connect(mpAutoScaleButton, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(setAutoScale(bool))"1""setAutoScale(bool)");
307 toolBar->addWidget(mpAutoScaleButton);
308 toolBar->addSeparator();
309 //Fit in View
310 QToolButton *fitInViewButton = new QToolButton(toolBar);
311 fitInViewButton->setText(tr("Fit in View"));
312 connect(fitInViewButton, SIGNAL(clicked())"2""clicked()", SLOT(fitInView())"1""fitInView()");
313 toolBar->addWidget(fitInViewButton);
314 toolBar->addSeparator();
315 //EXPORT
316 QToolButton *btnExport = new QToolButton(toolBar);
317 btnExport->setText(tr("Save"));
318 //btnExport->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
319 connect(btnExport, SIGNAL(clicked())"2""clicked()", SLOT(exportDocument())"1""exportDocument()");
320 toolBar->addWidget(btnExport);
321 toolBar->addSeparator();
322 //PRINT
323 QToolButton *btnPrint = new QToolButton(toolBar);
324 btnPrint->setText(tr("Print"));
325 connect(btnPrint, SIGNAL(clicked())"2""clicked()", SLOT(printPlot())"1""printPlot()");
326 toolBar->addWidget(btnPrint);
327 toolBar->addSeparator();
328 //GRID
329 mpGridButton = new QToolButton(toolBar);
330 mpGridButton->setText(tr("Grid"));
331 mpGridButton->setCheckable(true);
332 connect(mpGridButton, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(setGrid(bool))"1""setGrid(bool)");
333 toolBar->addWidget(mpGridButton);
334 // Detailed grid
335 mpDetailedGridButton = new QToolButton(toolBar);
336 mpDetailedGridButton->setText(tr("Detailed Grid"));
337 mpDetailedGridButton->setCheckable(true);
338 connect(mpDetailedGridButton, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(setDetailedGrid(bool))"1""setDetailedGrid(bool)");
339 toolBar->addWidget(mpDetailedGridButton);
340 // No Grid Button
341 mpNoGridButton = new QToolButton(toolBar);
342 mpNoGridButton->setText(tr("No Grid"));
343 mpNoGridButton->setCheckable(true);
344 connect(mpNoGridButton, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(setNoGrid(bool))"1""setNoGrid(bool)");
345 toolBar->addWidget(mpNoGridButton);
346 // Add grid buttons to buttons group
347 QButtonGroup *pGridButtonGroup = new QButtonGroup;
348 pGridButtonGroup->setExclusive(true);
349 pGridButtonGroup->addButton(mpGridButton);
350 pGridButtonGroup->addButton(mpDetailedGridButton);
351 pGridButtonGroup->addButton(mpNoGridButton);
352 toolBar->addSeparator();
353 //LOG x LOG y
354 mpLogXCheckBox = new QCheckBox(tr("Log X"), this);
355 connect(mpLogXCheckBox, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(setLogX(bool))"1""setLogX(bool)");
356 toolBar->addWidget(mpLogXCheckBox);
357 toolBar->addSeparator();
358 mpLogYCheckBox = new QCheckBox(tr("Log Y"), this);
359 connect(mpLogYCheckBox, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(setLogY(bool))"1""setLogY(bool)");
360 toolBar->addWidget(mpLogYCheckBox);
361 toolBar->addSeparator();
362 // setup
363 mpSetupButton = new QToolButton(toolBar);
364 mpSetupButton->setText(tr("Setup"));
365 connect(mpSetupButton, SIGNAL(clicked())"2""clicked()", SLOT(showSetupDialog())"1""showSetupDialog()");
366 toolBar->addWidget(mpSetupButton);
367 // finally add the tool bar to the mainwindow
368 addToolBar(toolBar);
369}
370
371void PlotWindow::plot(PlotCurve *pPlotCurve)
372{
373 QString currentLine;
374 if (mVariablesList.isEmpty() and getPlotType() == PlotWindow::PLOT)
375 throw NoVariableException(QString("No variables specified!").toStdString().c_str());
376
377 bool editCase = pPlotCurve ? true : false;
378 //PLOT PLT
379 if (mFile.fileName().endsWith("plt"))
380 {
381 // open the file
382 mFile.open(QIODevice::ReadOnly);
383 mpTextStream = new QTextStream(&mFile);
384 // read the interval size from the file
385 int intervalSize = 0;
386 while (!mpTextStream->atEnd())
387 {
388 currentLine = mpTextStream->readLine();
389 if (currentLine.startsWith("#IntervalSize"))
390 {
391 intervalSize = static_cast<QString>(currentLine.split("=").last()).toInt();
392 break;
393 }
394 }
395
396 QStringList variablesPlotted;
397 // Read variable values and plot them
398 while (!mpTextStream->atEnd())
399 {
400 currentLine = mpTextStream->readLine();
401 QString currentVariable;
402 if (currentLine.contains("DataSet:"))
403 {
404 currentVariable = currentLine.remove("DataSet: ");
405 if (mVariablesList.contains(currentVariable) or getPlotType() == PlotWindow::PLOTALL)
406 {
407 variablesPlotted.append(currentVariable);
408 if (!editCase) {
409 pPlotCurve = new PlotCurve(QFileInfo(mFile).fileName(), currentVariable, "time", currentVariable, getUnit(), getDisplayUnit(), mpPlot);
410 mpPlot->addPlotCurve(pPlotCurve);
411 }
412 // clear previous curve data
413 pPlotCurve->clearXAxisVector();
414 pPlotCurve->clearYAxisVector();
415 // read the variable values now
416 currentLine = mpTextStream->readLine();
417 for(int j = 0; j < intervalSize; j++)
418 {
419 QStringList values = currentLine.split(",");
420 pPlotCurve->addXAxisValue(QString(values[0]).toDouble());
421 pPlotCurve->addYAxisValue(QString(values[1]).toDouble());
422 currentLine = mpTextStream->readLine();
423 }
424 pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize());
425 pPlotCurve->attach(mpPlot);
426 mpPlot->replot();
427 }
428 // if plottype is PLOT and we have read all the variable we need to plot then simply break the loop
429 if (getPlotType() == PlotWindow::PLOT)
430 if (mVariablesList.size() == variablesPlotted.size())
431 break;
432 }
433 }
434 // if plottype is PLOT then check which requested variables are not found in the file
435 if (getPlotType() == PlotWindow::PLOT)
436 checkForErrors(mVariablesList, variablesPlotted);
437 // close the file
438 mFile.close();
439 }
440 //PLOT CSV
441 else if (mFile.fileName().endsWith("csv"))
442 {
443 /* open the file */
444 QStringList variablesPlotted;
445 struct csv_data *csvReader;
446 csvReader = read_csv(mFile.fileName().toStdString().c_str());
447 if (csvReader == NULL__null)
448 throw PlotException(tr("Failed to open simulation result file %1").arg(mFile.fileName()));
449
450 //Read in timevector
451 double *timeVals = read_csv_dataset(csvReader, "time");
452 if (timeVals == NULL__null)
453 {
454 timeVals = read_csv_dataset(csvReader, "lambda");
455 if (timeVals == NULL__null)
456 {
457 omc_free_csv_reader(csvReader);
458 throw NoVariableException(tr("Variable doesnt exist: %1").arg("time or lambda").toStdString().c_str());
459 }
460 setXLabel("lambda");
461 }
462
463 // read in all values
464 for (int i = 0; i < csvReader->numvars; i++)
465 {
466 if (mVariablesList.contains(csvReader->variables[i]) or getPlotType() == PlotWindow::PLOTALL)
467 {
468 variablesPlotted.append(csvReader->variables[i]);
469 double *vals = read_csv_dataset(csvReader, csvReader->variables[i]);
470 if (vals == NULL__null)
471 {
472 omc_free_csv_reader(csvReader);
473 throw NoVariableException(tr("Variable doesnt exist: %1").arg(csvReader->variables[i]).toStdString().c_str());
474 }
475
476 if (!editCase) {
477 pPlotCurve = new PlotCurve(QFileInfo(mFile).fileName(), csvReader->variables[i], "time", csvReader->variables[i], getUnit(), getDisplayUnit(), mpPlot);
478 mpPlot->addPlotCurve(pPlotCurve);
479 }
480 // clear previous curve data
481 pPlotCurve->clearXAxisVector();
482 pPlotCurve->clearYAxisVector();
483 for (int i = 0 ; i < csvReader->numsteps ; i++)
484 {
485 pPlotCurve->addXAxisValue(timeVals[i]);
486 pPlotCurve->addYAxisValue(vals[i]);
487 }
488 pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize());
489 pPlotCurve->attach(mpPlot);
490 mpPlot->replot();
491 }
492 }
493 // if plottype is PLOT then check which requested variables are not found in the file
494 if (getPlotType() == PlotWindow::PLOT)
495 checkForErrors(mVariablesList, variablesPlotted);
496 // close the file
497 omc_free_csv_reader(csvReader);
498 }
499 //PLOT MAT
500 else if(mFile.fileName().endsWith("mat"))
501 {
502 ModelicaMatReader reader;
503 ModelicaMatVariable_t *var;
504 const char *msg = "";
505 QStringList variablesPlotted;
506
507 //Read in mat file
508 if(0 != (msg = omc_new_matlab4_reader(mFile.fileName().toStdString().c_str(), &reader))) {
509 throw PlotException(msg);
510 }
511 //Read in timevector
512 double startTime = omc_matlab4_startTime(&reader);
513 double stopTime = omc_matlab4_stopTime(&reader);
514 if (reader.nvar < 1) {
515 omc_free_matlab4_reader(&reader);
516 throw NoVariableException("Variable doesnt exist: time");
517 }
518 double *timeVals = omc_matlab4_read_vals(&reader,1);
519 if (!timeVals) {
520 omc_free_matlab4_reader(&reader);
521 throw NoVariableException(QString("Corrupt file. nvar %1").arg(reader.nvar).toStdString().c_str());
522 }
523 // read in all values
524 for (int i = 0; i < reader.nall; i++) {
525 if (mVariablesList.contains(reader.allInfo[i].name) or getPlotType() == PlotWindow::PLOTALL) {
526 variablesPlotted.append(reader.allInfo[i].name);
527 // create the plot curve for variable
528 if (!editCase) {
529 pPlotCurve = new PlotCurve(QFileInfo(mFile).fileName(), reader.allInfo[i].name, "time", reader.allInfo[i].name, getUnit(), getDisplayUnit(), mpPlot);
530 mpPlot->addPlotCurve(pPlotCurve);
531 }
532 // read the variable values
533 var = omc_matlab4_find_var(&reader, reader.allInfo[i].name);
534 if (!var) {
535 omc_free_matlab4_reader(&reader);
536 throw NoVariableException(QString("Variable doesn't exist : ").append(reader.allInfo[i].name).toStdString().c_str());
537 }
538 // clear previous curve data
539 pPlotCurve->clearXAxisVector();
540 pPlotCurve->clearYAxisVector();
541 // if variable is not a parameter then
542 if (!var->isParam) {
543 double *vals = omc_matlab4_read_vals(&reader,var->index);
544 if (!vals) {
545 omc_free_matlab4_reader(&reader);
546 throw NoVariableException(QString("Corrupt file. nvar %1").arg(reader.nvar).toStdString().c_str());
547 }
548 // set plot curve data and attach it to plot
549 for (int i = 0 ; i < reader.nrows ; i++) {
550 pPlotCurve->addXAxisValue(timeVals[i]);
551 pPlotCurve->addYAxisValue(vals[i]);
552 }
553 pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize());
554 pPlotCurve->attach(mpPlot);
555 mpPlot->replot();
556 } else { // if variable is a parameter then
557 double val;
558 if (omc_matlab4_val(&val,&reader,var,0.0)) {
559 omc_free_matlab4_reader(&reader);
560 throw NoVariableException(QString("Parameter doesn't have a value : ").append(reader.allInfo[i].name).toStdString().c_str());
561 }
562
563 pPlotCurve->addXAxisValue(startTime);
564 pPlotCurve->addYAxisValue(val);
565 pPlotCurve->addXAxisValue(stopTime);
566 pPlotCurve->addYAxisValue(val);
567 pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(),
568 pPlotCurve->getSize());
569 pPlotCurve->attach(mpPlot);
570 mpPlot->replot();
571 }
572 }
573 }
574 // if plottype is PLOT then check which requested variables are not found in the file
575 if (getPlotType() == PlotWindow::PLOT)
576 checkForErrors(mVariablesList, variablesPlotted);
577 // close the file
578 omc_free_matlab4_reader(&reader);
579 }
580}
581
582void PlotWindow::plotParametric(PlotCurve *pPlotCurve)
583{
584 QString xVariable, yVariable, xTitle, yTitle;
585 int pair = 0;
586
587 if (mVariablesList.isEmpty())
23
Assuming the condition is false
24
Taking false branch
588 throw NoVariableException(QString("No variables specified!").toStdString().c_str());
589 else if (mVariablesList.size()%2 != 0)
25
Assuming the condition is false
26
Taking false branch
590 throw NoVariableException(QString("Please specify variable pairs for plotParametric.").toStdString().c_str());
591
592 bool editCase = pPlotCurve ? true : false;
27
'?' condition is false
593
594 for (pair = 0; pair < mVariablesList.size(); pair += 2)
28
Assuming the condition is true
29
Loop condition is true. Entering loop body
37
Assuming the condition is true
38
Loop condition is true. Entering loop body
46
Assuming the condition is true
47
Loop condition is true. Entering loop body
55
Assuming the condition is true
56
Loop condition is true. Entering loop body
595 {
596 xVariable = mVariablesList.at(pair);
597 yVariable = mVariablesList.at(pair+1);
598 // if (!editCase)
599 // {
600 if (pair==0)
30
Taking true branch
39
Taking false branch
48
Taking false branch
57
Taking false branch
601 {
602 xTitle = xVariable;
603 yTitle = yVariable;
604 }
605 else
606 {
607 xTitle += ", "+xVariable;
608 yTitle += ", "+yVariable;
609 }
610 setXLabel(xTitle);
611 setYLabel(yTitle);
612 // }
613
614 //PLOT PLT
615 if (mFile.fileName().endsWith("plt"))
31
Assuming the condition is false
32
Taking false branch
40
Assuming the condition is false
41
Taking false branch
49
Assuming the condition is false
50
Taking false branch
58
Assuming the condition is false
59
Taking false branch
616 {
617 QString currentLine;
618 // open the file
619 mFile.open(QIODevice::ReadOnly);
620 mpTextStream = new QTextStream(&mFile);
621 // read the interval size from the file
622 int intervalSize;
623 while (!mpTextStream->atEnd())
624 {
625 currentLine = mpTextStream->readLine();
626 if (currentLine.startsWith("#IntervalSize"))
627 {
628 intervalSize = static_cast<QString>(currentLine.split("=").last()).toInt();
629 break;
630 }
631 }
632
633 QStringList variablesPlotted;
634 // Read variable values and plot them
635 while (!mpTextStream->atEnd())
636 {
637 currentLine = mpTextStream->readLine();
638 QString currentVariable;
639 if (currentLine.contains("DataSet:"))
640 {
641 currentVariable = currentLine.remove("DataSet: ");
642 if (mVariablesList.contains(currentVariable))
643 {
644 variablesPlotted.append(currentVariable);
645 if (variablesPlotted.size() == 1)
646 {
647 if (!editCase) {
648 pPlotCurve = new PlotCurve(QFileInfo(mFile).fileName(), yVariable + " vs " + xVariable, xVariable, yVariable, getUnit(), getDisplayUnit(), mpPlot);
649 pPlotCurve->setXVariable(xVariable);
650 pPlotCurve->setYVariable(yVariable);
651 mpPlot->addPlotCurve(pPlotCurve);
652 }
653 // clear previous curve data
654 pPlotCurve->clearXAxisVector();
655 pPlotCurve->clearYAxisVector();
656 }
657 // read the variable values now
658 currentLine = mpTextStream->readLine();
659 for(int j = 0; j < intervalSize; j++)
660 {
661 // add first variable to the xaxis vector and 2nd to yaxis vector
662 QStringList values = currentLine.split(",");
663 if (variablesPlotted.size() == 1)
664 pPlotCurve->addXAxisValue(QString(values[1]).toDouble());
665 else if (variablesPlotted.size() == 2)
666 pPlotCurve->addYAxisValue(QString(values[1]).toDouble());
667 currentLine = mpTextStream->readLine();
668 }
669 // when two variables are found plot then plot them
670 if (variablesPlotted.size() == 2)
671 {
672 pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize());
673 pPlotCurve->attach(mpPlot);
674 mpPlot->replot();
675 }
676 }
677 // if we have read all the variable we need to plot then simply break the loop
678 if (mVariablesList.size() == variablesPlotted.size())
679 break;
680 }
681 }
682 // check which requested variables are not found in the file
683 checkForErrors(mVariablesList, variablesPlotted);
684 // close the file
685 mFile.close();
686 }
687 //PLOT CSV
688 else if (mFile.fileName().endsWith("csv"))
33
Assuming the condition is false
34
Taking false branch
42
Assuming the condition is false
43
Taking false branch
51
Assuming the condition is false
52
Taking false branch
60
Assuming the condition is true
61
Taking true branch
689 {
690 /* open the file */
691 QStringList variablesPlotted;
692 struct csv_data *csvReader;
693 csvReader = read_csv(mFile.fileName().toStdString().c_str());
694 if (csvReader == NULL__null)
62
Assuming 'csvReader' is not equal to NULL
63
Taking false branch
695 throw PlotException(tr("Failed to open simulation result file %1").arg(mFile.fileName()));
696
697 double *xVals = NULL__null, *yVals = NULL__null;
64
'xVals' initialized to a null pointer value
698 // read in all values
699 for (int i = 0; i < csvReader->numvars; i++)
65
Assuming the condition is false
66
Loop condition is false. Execution continues on line 721
700 {
701 if ((xVariable.compare(csvReader->variables[i]) == 0))
702 {
703 variablesPlotted.append(csvReader->variables[i]);
704 xVals = read_csv_dataset(csvReader, csvReader->variables[i]);
705 if (xVals == NULL__null) {
706 omc_free_csv_reader(csvReader);
707 throw NoVariableException(tr("Variable doesnt exist: %1").arg(csvReader->variables[i]).toStdString().c_str());
708 }
709 }
710 if ((yVariable.compare(csvReader->variables[i]) == 0))
711 {
712 variablesPlotted.append(csvReader->variables[i]);
713 yVals = read_csv_dataset(csvReader, csvReader->variables[i]);
714 if (yVals == NULL__null) {
715 omc_free_csv_reader(csvReader);
716 throw NoVariableException(tr("Variable doesnt exist: %1").arg(csvReader->variables[i]).toStdString().c_str());
717 }
718 }
719 }
720
721 if (!editCase) {
67
Taking true branch
722 pPlotCurve = new PlotCurve(QFileInfo(mFile).fileName(), yVariable + " vs " + xVariable, xVariable, yVariable, getUnit(), getDisplayUnit(), mpPlot);
723 pPlotCurve->setXVariable(xVariable);
724 pPlotCurve->setYVariable(yVariable);
725 mpPlot->addPlotCurve(pPlotCurve);
726 }
727 // clear previous curve data
728 pPlotCurve->clearXAxisVector();
729 pPlotCurve->clearYAxisVector();
730 for (int i = 0 ; i < csvReader->numsteps ; i++)
68
Assuming the condition is true
69
Loop condition is true. Entering loop body
731 {
732 pPlotCurve->addXAxisValue(xVals[i]);
70
Array access (from variable 'xVals') results in a null pointer dereference
733 pPlotCurve->addYAxisValue(yVals[i]);
734 }
735 pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize());
736 pPlotCurve->attach(mpPlot);
737 mpPlot->replot();
738 // check which requested variables are not found in the file
739 checkForErrors(mVariablesList, variablesPlotted);
740 // close the file
741 omc_free_csv_reader(csvReader);
742 }
743 //PLOT MAT
744 else if(mFile.fileName().endsWith("mat"))
35
Assuming the condition is false
36
Taking false branch
44
Assuming the condition is false
45
Taking false branch
53
Assuming the condition is false
54
Taking false branch
745 {
746 //Declare variables
747 ModelicaMatReader reader;
748 ModelicaMatVariable_t *var;
749 const char *msg = "";
750
751 //Read the .mat file
752 if(0 != (msg = omc_new_matlab4_reader(mFile.fileName().toStdString().c_str(), &reader)))
753 throw PlotException(msg);
754
755 if (!editCase) {
756 pPlotCurve = new PlotCurve(QFileInfo(mFile).fileName(), yVariable + " vs " + xVariable, xVariable, yVariable, getUnit(), getDisplayUnit(), mpPlot);
757 pPlotCurve->setXVariable(xVariable);
758 pPlotCurve->setYVariable(yVariable);
759 mpPlot->addPlotCurve(pPlotCurve);
760 }
761 //Fill variable x with data
762 var = omc_matlab4_find_var(&reader, xVariable.toStdString().c_str());
763 if (!var) {
764 omc_free_matlab4_reader(&reader);
765 throw NoVariableException(QString("Variable doesn't exist : ").append(xVariable).toStdString().c_str());
766 }
767 // clear previous curve data
768 pPlotCurve->clearXAxisVector();
769 pPlotCurve->clearYAxisVector();
770 // if variable is not a parameter then
771 if (!var->isParam)
772 {
773 double *xVals = omc_matlab4_read_vals(&reader,var->index);
774 if (!xVals) {
775 omc_free_matlab4_reader(&reader);
776 throw NoVariableException(QString("Corrupt file. nvar %1").arg(reader.nvar).toStdString().c_str());
777 }
778 for (int i = 0 ; i < reader.nrows ; i++)
779 pPlotCurve->addXAxisValue(xVals[i]);
780 }
781 // if variable is a parameter then
782 else
783 {
784 double xval;
785 if (omc_matlab4_val(&xval,&reader,var,0.0)) {
786 omc_free_matlab4_reader(&reader);
787 throw NoVariableException(QString("Parameter doesn't have a value : ").append(xVariable).toStdString().c_str());
788 }
789 pPlotCurve->addYAxisValue(xval);
790 }
791 //Fill variable y with data
792 var = omc_matlab4_find_var(&reader, yVariable.toStdString().c_str());
793 if (!var) {
794 omc_free_matlab4_reader(&reader);
795 throw NoVariableException(QString("Variable doesn't exist : ").append(yVariable).toStdString().c_str());
796 }
797 // if variable is not a parameter then
798 if (!var->isParam)
799 {
800 double *yVals = omc_matlab4_read_vals(&reader,var->index);
801 if (!yVals) {
802 omc_free_matlab4_reader(&reader);
803 throw NoVariableException(QString("Corrupt file. nvar %1").arg(reader.nvar).toStdString().c_str());
804 }
805 for (int i = 0 ; i < reader.nrows ; i++)
806 pPlotCurve->addYAxisValue(yVals[i]);
807 }
808 // if variable is a parameter then
809 else
810 {
811 double yval;
812 if (omc_matlab4_val(&yval,&reader,var,0.0)) {
813 omc_free_matlab4_reader(&reader);
814 throw NoVariableException(QString("Parameter doesn't have a value : ").append(yVariable).toStdString().c_str());
815 }
816 pPlotCurve->addYAxisValue(yval);
817 }
818 pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize());
819 pPlotCurve->attach(mpPlot);
820 mpPlot->replot();
821 omc_free_matlab4_reader(&reader);
822 }
823 }
824}
825
826int setupInterp(double *vals, double val, int N, double &alpha){
827 //given sorted values array of length N and val, returns pointer to i-th element so that
828 //vals[i-1] < val <= vals[i] and sets an interpolation coefficient alpha
829 //if val is out of the array range, returns NULL
830 double *p;
831 if (val < vals[0] || vals[N-1] < val) return -1;
832 p = std::lower_bound(vals, vals+N, val);
833 if (p == vals) //first element
834 alpha = 0;
835 else
836 alpha = (val - *(p-1))/(*p-*(p-1));
837 return p-vals;
838}
839
840int readPLTDataset(QTextStream *mpTextStream, QString variable, int N, double* valsOut){
841 bool resetDone = false;
842 QString currentLine;
843 do { //find start of dataset of the varible
844 currentLine = mpTextStream->readLine();
845 if (currentLine.contains("DataSet:"))
846 {
847 currentLine.remove("DataSet: ");
848 if (currentLine == variable) break;
849 }
850 if (mpTextStream->atEnd() && !resetDone){
851 mpTextStream->seek(0);
852 resetDone = true;
853 //Reset is done for each last index+1, so that the file is searched once again.
854 //May be optimized.
855 }
856 } while (!mpTextStream->atEnd());
857 if (mpTextStream->atEnd())
858 return -1;
859 for (int i = 0; i < N; i++ ){
860 currentLine = mpTextStream->readLine();
861 QStringList values = currentLine.split(",");
862 if (values.count()!=2) throw PlotException("Faild to load the " + variable + "variable.");
863 valsOut[i] = QString(values[1]).toDouble();
864 }
865 return 0;
866}
867
868void readPLTArray(QTextStream *mpTextStream, QString variable, double alpha, int intervalSize, int it, QList<double> &arrLstOut){
869 int index = 1;
870 double vals[intervalSize];
871 do //loop over all indexes
872 {
873 //read the values
874 QString variableWithInd = variable;
875 if (QRegExp("der\\(\\D(\\w)*\\)").exactMatch(variableWithInd)){
876 variableWithInd.chop(1);
877 variableWithInd.append("["+QString::number(index)+"])");
878 } else {
879 variableWithInd.append("["+QString::number(index)+"]");
880 }
881 if (readPLTDataset(mpTextStream, variableWithInd, intervalSize, vals)){
882 if (index == 1)
883 throw NoVariableException(QObject::tr("Array variable doesnt exist: %1").arg(variable).toStdString().c_str());
884 else
885 break;
886 }
887 if (it == 0)
888 arrLstOut.push_back(vals[0]);
889 else
890 arrLstOut.push_back(alpha*vals[it-1] + (1-alpha)*vals[it]);
891 index++;
892 } while(true);
893 return;
894}
895
896double getTimeUnitFactor(QString timeUnit){
897 if (timeUnit == "ms") return 1000.0;
898 else if (timeUnit == "s") return 1.0;
899 else if (timeUnit == "min") return 1.0/6.0;
900 else if (timeUnit == "h") return 1.0/3600.0;
901 else if (timeUnit == "d") return 1.0/86400.0;
902 else throw PlotException(QObject::tr("Unknown unit in plotArray(Parametric)."));
903}
904
905void PlotWindow::updateTimeText(QString unit)
906{
907 double timeUnitFactor = getTimeUnitFactor(unit);
908 mpPlot->setFooter(QString("t = %1 " + unit).arg(getTime()*timeUnitFactor,0,'g',3));
909 mpPlot->replot();
910}
911
912void PlotWindow::plotArray(double time, PlotCurve *pPlotCurve)
913{
914 double *res;
915 QString currentLine;
916 setTime(time);
917 double timeUnitFactor = getTimeUnitFactor(getTimeUnit());
918 if (mVariablesList.isEmpty() and getPlotType() == PlotWindow::PLOTARRAY)
919 throw NoVariableException(QString("No variables specified!").toStdString().c_str());
920 bool editCase = pPlotCurve ? true : false;
921 //PLOT PLT
922 //we presume time is the first dataset and array elements datasets are consequent
923 if (mFile.fileName().endsWith("plt"))
924 {
925 /* open the file */
926 if (!mFile.open(QIODevice::ReadOnly))
927 throw PlotException(tr("Failed to open simulation result file %1").arg(mFile.fileName()));
928 mpTextStream = new QTextStream(&mFile);
929 // read the interval size from the file
930 int intervalSize = -1;
931 while (!mpTextStream->atEnd())
932 {
933 currentLine = mpTextStream->readLine();
934 if (currentLine.startsWith("#IntervalSize"))
935 {
936 intervalSize = static_cast<QString>(currentLine.split("=").last()).toInt();
937 break;
938 }
939 }
940 if (intervalSize == -1) {
941 mFile.close();
942 throw PlotException(tr("Interval size not specified.").toStdString().c_str());
943 }
944 // double vals[intervalSize];
945 //Read in timevector
946 double timeVals[intervalSize];
947 readPLTDataset(mpTextStream, "time", intervalSize, timeVals);
948 //Find indexes and alpha to interpolate data in particular time
949 double alpha;
950 int it = setupInterp(timeVals, time, intervalSize, alpha);
951 if (it < 0) {
952 mFile.close();
953 throw PlotException("Time out of bounds.");
954 }
955 QString currentVariable; //without index part
956 // Read variable values and plot them
957 for (QStringList::Iterator itVarList = mVariablesList.begin(); itVarList != mVariablesList.end(); itVarList++){ //loop over all variables to be plotted
958 currentVariable = *(itVarList);
959 if (editCase)
960 {
961 // clear previous curve data
962 pPlotCurve->clearXAxisVector();
963 pPlotCurve->clearYAxisVector();
964 } else {
965 pPlotCurve = new PlotCurve(QFileInfo(mFile).fileName(), currentVariable, "array index", currentVariable, getUnit(), getDisplayUnit(), mpPlot);
966 mpPlot->addPlotCurve(pPlotCurve);
967 }
968 QList<double> arrLst;
969 readPLTArray(mpTextStream, currentVariable, alpha, intervalSize, it, arrLst);
970 for (int i = 0; i < arrLst.length(); i++)
971 {
972 pPlotCurve->addXAxisValue(i);
973 pPlotCurve->addYAxisValue(arrLst[i]);
974 }
975 pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize());
976 pPlotCurve->attach(mpPlot);
977 mpPlot->setFooter(QString("t = %1 " + getTimeUnit()).arg(time*timeUnitFactor,0,'g',3));
978 mpPlot->replot();
979 }
980 mFile.close();
981 }
982 //PLOT CSV
983 else if (mFile.fileName().endsWith("csv"))
984 {
985 /* open the file */
986 struct csv_data *csvReader;
987 csvReader = read_csv(mFile.fileName().toStdString().c_str());
988 if (csvReader == NULL__null)
989 throw PlotException(tr("Failed to open simulation result file %1").arg(mFile.fileName()));
990 //Read in timevector
991 double *timeVals = read_csv_dataset(csvReader, "time");
992 if (timeVals == NULL__null)
993 {
994 omc_free_csv_reader(csvReader);
995 throw NoVariableException(tr("Variable doesnt exist: %1").arg("time").toStdString().c_str());
996 }
997 double alpha;
998 int it = setupInterp(timeVals, time, csvReader->numsteps, alpha);
999 if (it < 0) {
1000 omc_free_csv_reader(csvReader);
1001 throw PlotException("Time out of bounds.");
1002 }
1003 QStringList::Iterator itVarList;
1004 for (itVarList = mVariablesList.begin(); itVarList != mVariablesList.end(); itVarList++){
1005 if (!editCase) {
1006 pPlotCurve = new PlotCurve(QFileInfo(mFile).fileName(), *itVarList, "array index", *itVarList, getUnit(), getDisplayUnit(), mpPlot);
1007 mpPlot->addPlotCurve(pPlotCurve);
1008 }
1009 QList<double> res;
1010 double *arrElement;
1011 int i = 1;
1012 do {
1013 QString varNameQS = (*itVarList);
1014 if (QRegExp("der\\(\\D(\\w)*\\)").exactMatch(varNameQS)){
1015 varNameQS.chop(1);
1016 varNameQS.append("["+QString::number(i)+"])");
1017 } else {
1018 varNameQS.append("["+QString::number(i)+"]");
1019 }
1020 if (!(arrElement = read_csv_dataset(csvReader, varNameQS.toStdString().c_str()))) break;
1021 i++;
1022
1023 if (it == 0)
1024 res.push_back(arrElement[0]);
1025 else
1026 res.push_back(alpha*arrElement[it-1] + (1-alpha)*arrElement[it]);
1027 } while (true);
1028 pPlotCurve->clearXAxisVector();
1029 pPlotCurve->clearYAxisVector();
1030 for (int j = 0; j < res.count(); j++){
1031 pPlotCurve->addXAxisValue(j);
1032 pPlotCurve->addYAxisValue(res[j]);
1033 }
1034 pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize());
1035 pPlotCurve->attach(mpPlot);
1036 mpPlot->setFooter(QString("t = %1 " + getTimeUnit()).arg(time*timeUnitFactor,0,'g',3));
1037 mpPlot->replot();
1038
1039 }
1040 omc_free_csv_reader(csvReader);
1041 }
1042 //PLOT MAT
1043 else
1044 if(mFile.fileName().endsWith("mat"))
1045 {
1046 ModelicaMatReader reader;
1047 ModelicaMatVariable_t *var;
1048 QList<ModelicaMatVariable_t*> vars;
1049 const char *msg = "";
1050 QStringList variablesPlotted;
1051
1052 //Read in mat file
1053 if(0 != (msg = omc_new_matlab4_reader(mFile.fileName().toStdString().c_str(), &reader)))
1054 throw PlotException(msg);
1055 //calculate time
1056 double startTime = omc_matlab4_startTime(&reader);
1057 double stopTime = omc_matlab4_stopTime(&reader);
1058 if (reader.nvar < 1) {
1059 omc_free_matlab4_reader(&reader);
1060 throw NoVariableException("Variable doesnt exist: time");
1061 }
1062 if (time<startTime || stopTime<time) {
1063 omc_free_matlab4_reader(&reader);
1064 throw PlotException("Time out of bounds.");
1065 }
1066 QStringList::Iterator itVarList;
1067 for (itVarList = mVariablesList.begin(); itVarList != mVariablesList.end(); itVarList++){
1068 if (!editCase) {
1069 pPlotCurve = new PlotCurve(QFileInfo(mFile).fileName(), *itVarList, "array index", *itVarList, getUnit(), getDisplayUnit(), mpPlot);
1070 mpPlot->addPlotCurve(pPlotCurve);
1071 }
1072 int i = 1;
1073 do {
1074 QString varNameQS = (*itVarList);
1075 if (QRegExp("der\\(\\D(\\w)*\\)").exactMatch(varNameQS)){
1076 varNameQS.chop(1);
1077 varNameQS.append("["+QString::number(i)+"])");
1078 } else {
1079 varNameQS.append("["+QString::number(i)+"]");
1080 }
1081 if(!(var = omc_matlab4_find_var(&reader, varNameQS.toStdString().c_str()))) break;
1082 i++;
1083 vars.push_back(var);
1084 } while (true);
1085 QVector<ModelicaMatVariable_t*> varVec = vars.toVector();
1086 res = new double [vars.count()];
1087 omc_matlab4_read_vars_val(res, &reader, varVec.data(), vars.count(), time);
1088 pPlotCurve->clearXAxisVector();
1089 pPlotCurve->clearYAxisVector();
1090 for (int i = 0; i < vars.count(); i++){
1091 pPlotCurve->addXAxisValue(i);
1092 pPlotCurve->addYAxisValue(res[i]);
1093 }
1094 pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize());
1095 pPlotCurve->attach(mpPlot);
1096 mpPlot->setFooter(QString("t = %1 " + getTimeUnit()).arg(time*timeUnitFactor,0,'g',3));
1097 mpPlot->replot();
1098 delete[] res;
1099 }
1100 // if plottype is PLOT then check which requested variables are not found in the file
1101 if (getPlotType() == PlotWindow::PLOT)
1102 checkForErrors(mVariablesList, variablesPlotted);
1103 // close the file
1104 omc_free_matlab4_reader(&reader);
1105 }
1106}
1107
1108void PlotWindow::plotArrayParametric(double time, PlotCurve *pPlotCurve)
1109{
1110 QString xVariable, yVariable, xTitle, yTitle;
1111 int pair = 0;
1112 setTime(time);
1113 double timeUnitFactor = getTimeUnitFactor(getTimeUnit());
1114 if (mVariablesList.isEmpty())
1115 throw NoVariableException(QString("No variables specified!").toStdString().c_str());
1116 else if (mVariablesList.size()%2 != 0)
1117 throw NoVariableException(QString("Please specify variable pairs for plotParametric.").toStdString().c_str());
1118
1119 bool editCase = pPlotCurve ? true : false;
1120
1121 for (pair = 0; pair < mVariablesList.size(); pair += 2)
1122 {
1123 xVariable = mVariablesList.at(pair);
1124 yVariable = mVariablesList.at(pair+1);
1125 // if (!editCase)
1126 // {
1127 if (pair==0)
1128 {
1129 xTitle = xVariable;
1130 yTitle = yVariable;
1131 }
1132 else
1133 {
1134 xTitle += ", "+xVariable;
1135 yTitle += ", "+yVariable;
1136 }
1137 setXLabel(xTitle);
1138 setYLabel(yTitle);
1139 // }
1140
1141 //PLOT PLT
1142 //we presume time is the first dataset and array elements datasets are consequent
1143 if (mFile.fileName().endsWith("plt"))
1144 {
1145 /* open the file */
1146 if (!mFile.open(QIODevice::ReadOnly))
1147 throw PlotException(tr("Failed to open simulation result file %1").arg(mFile.fileName()));
1148 mpTextStream = new QTextStream(&mFile);
1149 // read the interval size from the file
1150 QString currentLine;
1151 int intervalSize = -1;
1152 while (!mpTextStream->atEnd())
1153 {
1154 currentLine = mpTextStream->readLine();
1155 if (currentLine.startsWith("#IntervalSize"))
1156 {
1157 intervalSize = static_cast<QString>(currentLine.split("=").last()).toInt();
1158 break;
1159 }
1160 }
1161 if (intervalSize == -1) {
1162 mFile.close();
1163 throw PlotException(tr("Interval size not specified.").toStdString().c_str());
1164 }
1165 //Read in timevector
1166 double timeVals[intervalSize];
1167 readPLTDataset(mpTextStream, "time", intervalSize, timeVals);
1168 //Find indexes and alpha to interpolate data in particular time
1169 double alpha;
1170 int it = setupInterp(timeVals, time, intervalSize, alpha);
1171 if (it < 0) {
1172 mFile.close();
1173 throw PlotException("Time out of bounds.");
1174 }
1175 if (editCase) {
1176 pPlotCurve->clearXAxisVector();
1177 pPlotCurve->clearYAxisVector();
1178 } else {
1179 pPlotCurve = new PlotCurve(QFileInfo(mFile).fileName(), yVariable + " vs " + xVariable, xVariable, yVariable, getUnit(), getDisplayUnit(), mpPlot);
1180 pPlotCurve->setXVariable(xVariable);
1181 pPlotCurve->setYVariable(yVariable);
1182 mpPlot->addPlotCurve(pPlotCurve);
1183 }
1184 //Read the values
1185 QList<double> xValsLst;
1186 readPLTArray(mpTextStream, xVariable, alpha, intervalSize, it, xValsLst);
1187 QList<double> yValsLst;
1188 readPLTArray(mpTextStream, yVariable, alpha, intervalSize, it, yValsLst);
1189 if (xValsLst.length() != yValsLst.length()) {
1190 mFile.close();
1191 throw PlotException(tr("Arrays must be of the same length in array parametric plot."));
1192 }
1193 for (int i = 0; i < xValsLst.length(); i++){
1194 pPlotCurve->addXAxisValue(xValsLst[i]);
1195 pPlotCurve->addYAxisValue(yValsLst[i]);
1196 }
1197 pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize());
1198 pPlotCurve->attach(mpPlot);
1199 mpPlot->setFooter(QString("t = %1 " + getTimeUnit()).arg(time*timeUnitFactor,0,'g',3));
1200 mpPlot->replot();
1201 mFile.close();
1202 }
1203 // //PLOT CSV
1204 else if (mFile.fileName().endsWith("csv"))
1205 {
1206 /* open the file */
1207 struct csv_data *csvReader;
1208 csvReader = read_csv(mFile.fileName().toStdString().c_str());
1209 if (csvReader == NULL__null)
1210 throw PlotException(tr("Failed to open simulation result file %1").arg(mFile.fileName()));
1211 //Read in timevector
1212 double *timeVals = read_csv_dataset(csvReader, "time");
1213 if (timeVals == NULL__null)
1214 {
1215 omc_free_csv_reader(csvReader);
1216 throw NoVariableException(tr("Variable doesnt exist: %1").arg("time").toStdString().c_str());
1217 }
1218 double alpha;
1219 int it = setupInterp(timeVals, time, csvReader->numsteps, alpha);
1220 if (it < 0) {
1221 omc_free_csv_reader(csvReader);
1222 throw PlotException("Time out of bounds.");
1223 }
1224 if (!editCase) {
1225 pPlotCurve = new PlotCurve(QFileInfo(mFile).fileName(), yVariable + " vs " + xVariable, xVariable, yVariable, getUnit(), getDisplayUnit(), mpPlot);
1226 pPlotCurve->setXVariable(xVariable);
1227 pPlotCurve->setYVariable(yVariable);
1228 mpPlot->addPlotCurve(pPlotCurve);
1229 }
1230 pPlotCurve->clearXAxisVector();
1231 pPlotCurve->clearYAxisVector();
1232 QStringList varPair;
1233 varPair << xVariable << yVariable;
1234 QList<double> res;
1235 for (int j = 0; j<2; j++){
1236 res.clear();
1237 double *arrElement;
1238 for (int i = 1; i++; true){
1239 QString varNameQS = varPair[j];
1240 if (QRegExp("der\\(\\D(\\w)*\\)").exactMatch(varNameQS)){
1241 varNameQS.chop(1);
1242 varNameQS.append("["+QString::number(i)+"])");
1243 } else {
1244 varNameQS.append("["+QString::number(i)+"]");
1245 }
1246 if (!(arrElement = read_csv_dataset(csvReader, varNameQS.toStdString().c_str()))) break;
1247
1248 if (it == 0)
1249 res.push_back(arrElement[0]);
1250 else
1251 res.push_back(alpha*arrElement[it-1] + (1-alpha)*arrElement[it]);
1252 }
1253 if (j == 0) { //xVar
1254 for (int i = 0; i < res.count(); i++)
1255 pPlotCurve->addXAxisValue(res[i]);
1256 }
1257 else { //yVar
1258 if (pPlotCurve->getSize()!=res.count()) {
1259 omc_free_csv_reader(csvReader);
1260 throw PlotException(tr("Arrays must be of the same length in array parametric plot."));
1261 }
1262 for (int i = 0; i < res.count(); i++)
1263 pPlotCurve->addYAxisValue(res[i]);
1264 }
1265 }
1266 pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize());
1267 pPlotCurve->attach(mpPlot);
1268 mpPlot->setFooter(QString("t = %1 " + getTimeUnit()).arg(time*timeUnitFactor,0,'g',3));
1269 mpPlot->replot();
1270 omc_free_csv_reader(csvReader);
1271 }
1272 //PLOT MAT
1273 else if(mFile.fileName().endsWith("mat"))
1274 {
1275 //Declare variables
1276 ModelicaMatReader reader;
1277 ModelicaMatVariable_t *var;
1278 double *res;
1279 const char *msg = "";
1280
1281 //Read the .mat file
1282 if(0 != (msg = omc_new_matlab4_reader(mFile.fileName().toStdString().c_str(), &reader)))
1283 throw PlotException(msg);
1284
1285 if (!editCase) {
1286 pPlotCurve = new PlotCurve(QFileInfo(mFile).fileName(), yVariable + " vs " + xVariable, xVariable, yVariable, getUnit(), getDisplayUnit(), mpPlot);
1287 pPlotCurve->setXVariable(xVariable);
1288 pPlotCurve->setYVariable(yVariable);
1289 mpPlot->addPlotCurve(pPlotCurve);
1290 }
1291 //calculate time
1292 double startTime = omc_matlab4_startTime(&reader);
1293 double stopTime = omc_matlab4_stopTime(&reader);
1294 if (reader.nvar < 1) {
1295 omc_free_matlab4_reader(&reader);
1296 throw NoVariableException("Variable doesnt exist: time");
1297 }
1298 if (time<startTime || stopTime<time) {
1299 omc_free_matlab4_reader(&reader);
1300 throw PlotException("Time out of bounds.");
1301 }
1302 pPlotCurve->clearXAxisVector();
1303 pPlotCurve->clearYAxisVector();
1304 QList<ModelicaMatVariable_t*> vars;
1305 QStringList varPair;
1306 varPair.push_back(xVariable);
1307 varPair.push_back(yVariable);
1308 //read x and y vals:
1309 for (int j = 0; j < 2; j++){
1310 vars.clear();
1311 int i = 1;
1312 do {
1313 QString varNameQS = varPair[j];
1314 if (QRegExp("der\\(\\D(\\w)*\\)").exactMatch(varNameQS)){
1315 varNameQS.chop(1);
1316 varNameQS.append("["+QString::number(i)+"])");
1317 } else {
1318 varNameQS.append("["+QString::number(i)+"]");
1319 }
1320 if(!(var = omc_matlab4_find_var(&reader, varNameQS.toStdString().c_str()))) break;
1321 i++;
1322 vars.push_back(var);
1323 } while (true);
1324 QVector<ModelicaMatVariable_t*> varVec = vars.toVector();
1325 res = new double [vars.count()];
1326 omc_matlab4_read_vars_val(res, &reader, varVec.data(), vars.count(), time);
1327 if (j == 0)
1328 for (int i = 0; i < vars.count(); i++)
1329 pPlotCurve->addXAxisValue(res[i]);
1330 else{
1331 if (pPlotCurve->getSize()!=vars.count()) {
1332 omc_free_matlab4_reader(&reader);
1333 throw PlotException("Arrays must be of the same length in array parametric plot.");
1334 }
1335 for (int i = 0; i < vars.count(); i++)
1336 pPlotCurve->addYAxisValue(res[i]);
1337 }
1338 delete[] res;
1339 }
1340 pPlotCurve->setData(pPlotCurve->getXAxisVector(), pPlotCurve->getYAxisVector(), pPlotCurve->getSize());
1341 pPlotCurve->attach(mpPlot);
1342 mpPlot->setFooter(QString("t = %1 " + getTimeUnit()).arg(time*timeUnitFactor,0,'g',3));
1343 mpPlot->replot();
1344 omc_free_matlab4_reader(&reader);
1345 }
1346 }
1347}
1348
1349QPair<QVector<double>*, QVector<double>*> PlotWindow::plotInteractive(PlotCurve *pPlotCurve)
1350{
1351 if (mVariablesList.isEmpty() && getPlotType() == PlotWindow::PLOTINTERACTIVE) {
1352 throw NoVariableException(QString(tr("No variables specified!")).toStdString().c_str());
1353 } else if (mVariablesList.size() != 1) {
1354 throw NoVariableException(QString(tr("Could not determine the variable name!")).toStdString().c_str());
1355 }
1356 QString variableName = mVariablesList.at(0);
1357 pPlotCurve = new PlotCurve(mInteractiveModelName, variableName, "time", variableName, getUnit(), getDisplayUnit(), mpPlot);
1358 // clear previous curve data
1359 pPlotCurve->clearXAxisVector();
1360 pPlotCurve->clearYAxisVector();
1361 pPlotCurve->setSamples(mpInteractiveData);
1362 mpPlot->addPlotCurve(pPlotCurve);
1363 pPlotCurve->attach(mpPlot);
1364 mpPlot->replot();
1365 return pPlotCurve->getAxisVectors();
1366}
1367
1368void PlotWindow::setInteractiveOwner(const QString &interactiveTreeItemOwner)
1369{
1370 mInteractiveTreeItemOwner = interactiveTreeItemOwner;
1371}
1372
1373void PlotWindow::setInteractivePort(const int port)
1374{
1375 mInteractivePort = port;
1376}
1377
1378void PlotWindow::setInteractivePlotData(QwtSeriesData<QPointF>* pInteractiveData)
1379{
1380 mpInteractiveData = pInteractiveData;
1381}
1382
1383void PlotWindow::setInteractiveModelName(const QString &modelName)
1384{
1385 mInteractiveModelName = modelName;
1386}
1387
1388void PlotWindow::setTitle(QString title)
1389{
1390 mpPlot->setTitle(title);
1391}
1392
1393void PlotWindow::updateCurves()
1394{
1395 for (auto & p : mpPlot->getPlotCurvesList()) {
1396 // append the last point to the plotting curve
1397 p->getPlotDirectPainter()->drawSeries(p, p->getSize() - 2, -1);
1398 }
1399}
1400
1401void PlotWindow::updateYAxis(QPair<double, double> minMaxValues)
1402{
1403 // replot if a value is out of bounds
1404 if (minMaxValues.first < mpPlot->axisScaleDiv(QwtPlot::yLeft).lowerBound() || minMaxValues.second > mpPlot->axisScaleDiv(QwtPlot::yLeft).upperBound()) {
1405 mpPlot->replot();
1406 }
1407}
1408
1409
1410void PlotWindow::setGrid(QString grid)
1411{
1412 if (grid.toLower().compare("simple") == 0)
1413 {
1414 setGrid(true);
1415 }
1416 else if (grid.toLower().compare("none") == 0)
1417 {
1418 setNoGrid(true);
1419 }
1420 else
1421 {
1422 setDetailedGrid(true);
1423 }
1424}
1425
1426QString PlotWindow::getGrid()
1427{
1428 return mGridType;
1429}
1430
1431QCheckBox* PlotWindow::getLogXCheckBox()
1432{
1433 return mpLogXCheckBox;
1434}
1435
1436QCheckBox* PlotWindow::getLogYCheckBox()
1437{
1438 return mpLogYCheckBox;
1439}
1440
1441void PlotWindow::setXLabel(QString label)
1442{
1443 mpPlot->setAxisTitle(QwtPlot::xBottom, label);
1444}
1445
1446void PlotWindow::setYLabel(QString label)
1447{
1448 mpPlot->setAxisTitle(QwtPlot::yLeft, label);
1449}
1450
1451void PlotWindow::setXRange(double min, double max)
1452{
1453 if (!(max == 0 && min == 0)) {
1454 mpPlot->setAxisScale(QwtPlot::xBottom, min, max);
1455 }
1456 mXRangeMin = QString::number(min);
1457 mXRangeMax = QString::number(max);
1458}
1459
1460QString PlotWindow::getXRangeMin()
1461{
1462 return mXRangeMin;
1463}
1464
1465QString PlotWindow::getXRangeMax()
1466{
1467 return mXRangeMax;
1468}
1469
1470void PlotWindow::setYRange(double min, double max)
1471{
1472 if (!(max == 0 && min == 0)) {
1473 mpPlot->setAxisScale(QwtPlot::yLeft, min, max);
1474 }
1475 mYRangeMin = QString::number(min);
1476 mYRangeMax = QString::number(max);
1477}
1478
1479QString PlotWindow::getYRangeMin()
1480{
1481 return mYRangeMin;
1482}
1483
1484QString PlotWindow::getYRangeMax()
1485{
1486 return mYRangeMax;
1487}
1488
1489void PlotWindow::setCurveWidth(double width)
1490{
1491 mCurveWidth = width;
1492}
1493
1494double PlotWindow::getCurveWidth()
1495{
1496 return mCurveWidth;
1497}
1498
1499void PlotWindow::setCurveStyle(int style)
1500{
1501 mCurveStyle = style;
1502}
1503
1504int PlotWindow::getCurveStyle()
1505{
1506 return mCurveStyle;
1507}
1508
1509void PlotWindow::setLegendFont(QFont font)
1510{
1511 mLegendFont = font;
1512}
1513
1514QFont PlotWindow::getLegendFont()
1515{
1516 return mLegendFont;
1517}
1518
1519void PlotWindow::setLegendPosition(QString position)
1520{
1521 if (position.toLower().compare("left") == 0)
1522 {
1523 mpPlot->insertLegend(0);
1524 mpPlot->setLegend(new Legend(mpPlot));
1525 mpPlot->insertLegend(mpPlot->getLegend(), QwtPlot::LeftLegend);
1526 }
1527 else if (position.toLower().compare("right") == 0)
1528 {
1529 mpPlot->insertLegend(0);
1530 mpPlot->setLegend(new Legend(mpPlot));
1531 mpPlot->insertLegend(mpPlot->getLegend(), QwtPlot::RightLegend);
1532 }
1533 else if (position.toLower().compare("top") == 0)
1534 {
1535 mpPlot->insertLegend(0);
1536 mpPlot->setLegend(new Legend(mpPlot));
1537 mpPlot->insertLegend(mpPlot->getLegend(), QwtPlot::TopLegend);
1538#if QWT_VERSION0x060200 > 0x060000
1539 /* we also want to align the legend to left. Qwt align it HCenter by default. */
1540 QwtLegend *pQwtLegend = qobject_cast<QwtLegend*>(mpPlot->legend());
1541 pQwtLegend->contentsWidget()->layout()->setAlignment(Qt::AlignTop | Qt::AlignLeft);
1542 mpPlot->updateLegend();
1543#endif
1544 }
1545 else if (position.toLower().compare("bottom") == 0)
1546 {
1547 mpPlot->insertLegend(0);
1548 mpPlot->setLegend(new Legend(mpPlot));
1549 mpPlot->insertLegend(mpPlot->getLegend(), QwtPlot::BottomLegend);
1550#if QWT_VERSION0x060200 > 0x060000
1551 /* we also want to align the legend to left. Qwt align it HCenter by default. */
1552 QwtLegend *pQwtLegend = qobject_cast<QwtLegend*>(mpPlot->legend());
1553 pQwtLegend->contentsWidget()->layout()->setAlignment(Qt::AlignBottom | Qt::AlignLeft);
1554 mpPlot->updateLegend();
1555#endif
1556 }
1557 else if (position.toLower().compare("none") == 0)
1558 {
1559 mpPlot->insertLegend(0);
1560 }
1561}
1562
1563QString PlotWindow::getLegendPosition()
1564{
1565 if (!mpPlot->legend())
1566 return "none";
1567 switch (mpPlot->plotLayout()->legendPosition())
1568 {
1569 case QwtPlot::LeftLegend:
1570 return "left";
1571 case QwtPlot::RightLegend:
1572 return "right";
1573 case QwtPlot::TopLegend:
1574 return "top";
1575 case QwtPlot::BottomLegend:
1576 return "bottom";
1577 default:
1578 return "top";
1579 }
1580}
1581
1582void PlotWindow::setFooter(QString footer)
1583{
1584#if QWT_VERSION0x060200 > 0x060000
1585 mpPlot->setFooter(footer);
1586#endif
1587}
1588
1589QString PlotWindow::getFooter()
1590{
1591#if QWT_VERSION0x060200 > 0x060000
1592 return mpPlot->footer().text();
1593#else
1594 return "";
1595#endif
1596}
1597
1598void PlotWindow::checkForErrors(QStringList variables, QStringList variablesPlotted)
1599{
1600 QStringList nonExistingVariables;
1601 foreach (QString variable, variables)for (auto _container_ = QtPrivate::qMakeForeachContainer(variables
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QString variable
= *_container_.i; _container_.control; _container_.control =
0)
1602 {
1603 if (!variablesPlotted.contains(variable))
1604 nonExistingVariables.append(variable);
1605 }
1606 if (!nonExistingVariables.isEmpty())
1607 {
1608 throw NoVariableException(QString("Following variable(s) are not found : ")
1609 .append(nonExistingVariables.join(",")).toStdString().c_str());
1610 }
1611}
1612
1613Plot* PlotWindow::getPlot()
1614{
1615 return mpPlot;
1616}
1617
1618void PlotWindow::receiveMessage(QStringList arguments)
1619{
1620 foreach (PlotCurve *pCurve, mpPlot->getPlotCurvesList())for (auto _container_ = QtPrivate::qMakeForeachContainer(mpPlot
->getPlotCurvesList()); _container_.control && _container_
.i != _container_.e; ++_container_.i, _container_.control ^= 1
) for (PlotCurve *pCurve = *_container_.i; _container_.control
; _container_.control = 0)
1621 {
1622 pCurve->detach();
1623 mpPlot->removeCurve(pCurve);
1624 }
1625 initializePlot(arguments);
1
Calling 'PlotWindow::initializePlot'
1626}
1627
1628void PlotWindow::closeEvent(QCloseEvent *event)
1629{
1630 emit closingDown();
1631 event->accept();
1632}
1633
1634void PlotWindow::enableZoomMode(bool on)
1635{
1636 mpPlot->getPlotZoomer()->setEnabled(on);
1637 if(on)
1638 {
1639 mpPlot->canvas()->setCursor(Qt::CrossCursor);
1640 }
1641}
1642
1643void PlotWindow::enablePanMode(bool on)
1644{
1645 mpPlot->getPlotPanner()->setEnabled(on);
1646 if(on)
1647 {
1648 mpPlot->canvas()->setCursor(Qt::OpenHandCursor);
1649 }
1650}
1651
1652void PlotWindow::exportDocument()
1653{
1654 static QString lastOpenDir;
1655 QString dir = lastOpenDir.isEmpty() ? QDir::homePath() : lastOpenDir;
1656 QString fileName = QFileDialog::getSaveFileName(this, tr("Save File As"), dir, tr("Image Files (*.png *.svg *.bmp)"));
1657
1658 if (!fileName.isEmpty()) {
1659 lastOpenDir = QFileInfo(fileName).absoluteDir().absolutePath();
1660 // export svg
1661 if (fileName.endsWith(".svg")) {
1662#if QWT_VERSION0x060200 < 0x060000
1663 QSvgGenerator generator;
1664 generator.setTitle(tr("OMPlot - OpenModelica Plot"));
1665 generator.setDescription(tr("Generated by OpenModelica Plot Tool"));
1666 generator.setFileName(fileName);
1667 generator.setSize(mpPlot->rect().size());
1668 mpPlot->print(generator);
1669#else
1670 QwtPlotRenderer plotRenderer;
1671 plotRenderer.setDiscardFlag(QwtPlotRenderer::DiscardBackground); /* removes the gray widget background when OMPlot is used as library. */
1672 plotRenderer.renderDocument(mpPlot, fileName, QSizeF(mpPlot->widthMM(), mpPlot->heightMM()));
1673#endif
1674 }
1675 // export png, bmp
1676 else
1677 {
1678#if QWT_VERSION0x060200 < 0x060000
1679 QPixmap pixmap(mpPlot->size());
1680 /* removes the gray widget background when OMPlot is used as library. */
1681 pixmap.fill(Qt::white);
1682 mpPlot->render(&pixmap, QPoint(), QRegion(), DrawChildren);
1683#else
1684 QwtPlotRenderer plotRenderer;
1685 plotRenderer.setDiscardFlag(QwtPlotRenderer::DiscardBackground); /* removes the gray widget background when OMPlot is used as library. */
1686 QPixmap pixmap(mpPlot->size());
1687 pixmap.fill(Qt::white);
1688 QPainter painter(&pixmap);
1689 QRect rect = mpPlot->geometry();
1690 painter.setWindow(rect);
1691 plotRenderer.render(mpPlot, &painter, rect);
1692#endif
1693 if (!pixmap.save(fileName)) {
1694 QMessageBox::critical(this, "Error", "Failed to save image " + fileName);
1695 }
1696 }
1697 }
1698}
1699
1700void PlotWindow::printPlot()
1701{
1702#if 1
1703 QPrinter printer;
1704#else
1705 QPrinter printer(QPrinter::HighResolution);
1706 printer.setOutputFileName("OMPlot.ps");
1707#endif
1708
1709 printer.setDocName("OMPlot");
1710 printer.setCreator("Plot Window");
1711 printer.setOrientation(QPrinter::Landscape);
1712
1713 QPrintDialog dialog(&printer);
1714 if ( dialog.exec() )
1715 {
1716#if QWT_VERSION0x060200 < 0x060000
1717 QwtPlotPrintFilter filter;
1718 if ( printer.colorMode() == QPrinter::GrayScale )
1719 {
1720 int options = QwtPlotPrintFilter::PrintAll;
1721 options &= ~QwtPlotPrintFilter::PrintBackground;
1722 options |= QwtPlotPrintFilter::PrintFrameWithScales;
1723 filter.setOptions(options);
1724 }
1725 mpPlot->print(printer, filter);
1726#else
1727 QwtPlotRenderer plotRenderer;
1728 plotRenderer.renderTo(mpPlot, printer);
1729#endif
1730 }
1731}
1732
1733void PlotWindow::setGrid(bool on)
1734{
1735 if (on)
1736 {
1737 mGridType = "simple";
1738 mpPlot->getPlotGrid()->setGrid();
1739 mpPlot->getPlotGrid()->attach(mpPlot);
1740 mpGridButton->setChecked(true);
1741 }
1742 mpPlot->replot();
1743}
1744
1745void PlotWindow::setDetailedGrid(bool on)
1746{
1747 if (on)
1748 {
1749 mGridType = "detailed";
1750 mpPlot->getPlotGrid()->setDetailedGrid();
1751 mpPlot->getPlotGrid()->attach(mpPlot);
1752 mpDetailedGridButton->setChecked(true);
1753 }
1754 mpPlot->replot();
1755}
1756
1757void PlotWindow::setNoGrid(bool on)
1758{
1759 if (on)
1760 {
1761 mGridType = "none";
1762 mpPlot->getPlotGrid()->detach();
1763 mpNoGridButton->setChecked(true);
1764 }
1765 mpPlot->replot();
1766}
1767
1768void PlotWindow::fitInView()
1769{
1770 mpPlot->getPlotZoomer()->zoom(0);
1771 mpPlot->setAxisAutoScale(QwtPlot::yLeft);
1772 mpPlot->setAxisAutoScale(QwtPlot::xBottom);
1773 mpPlot->replot();
1774 mpPlot->getPlotZoomer()->setZoomBase(false);
1775}
1776
1777void PlotWindow::setLogX(bool on)
1778{
1779 if(on)
1780 {
1781#if QWT_VERSION0x060200 >= 0x060100
1782 mpPlot->setAxisScaleEngine(QwtPlot::xBottom, new QwtLogScaleEngine);
1783#else
1784 mpPlot->setAxisScaleEngine(QwtPlot::xBottom, new QwtLog10ScaleEngine);
1785#endif
1786 }
1787 else
1788 {
1789 mpPlot->setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
1790 }
1791 mpPlot->setAxisAutoScale(QwtPlot::xBottom);
1792 mpLogXCheckBox->blockSignals(true);
1793 mpLogXCheckBox->setChecked(on);
1794 mpLogXCheckBox->blockSignals(false);
1795 mpPlot->replot();
1796}
1797
1798void PlotWindow::setLogY(bool on)
1799{
1800 if(on)
1801 {
1802#if QWT_VERSION0x060200 >= 0x060100
1803 mpPlot->setAxisScaleEngine(QwtPlot::yLeft, new QwtLogScaleEngine);
1804#else
1805 mpPlot->setAxisScaleEngine(QwtPlot::yLeft, new QwtLog10ScaleEngine);
1806#endif
1807 }
1808 else
1809 {
1810 mpPlot->setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
1811 }
1812 mpPlot->setAxisAutoScale(QwtPlot::yLeft);
1813 mpLogYCheckBox->blockSignals(true);
1814 mpLogYCheckBox->setChecked(on);
1815 mpLogYCheckBox->blockSignals(false);
1816 mpPlot->replot();
1817}
1818
1819void PlotWindow::setAutoScale(bool on)
1820{
1821 bool state = mpAutoScaleButton->blockSignals(true);
1822 mpAutoScaleButton->setChecked(on);
1823 mpAutoScaleButton->blockSignals(state);
1824}
1825
1826void PlotWindow::showSetupDialog()
1827{
1828 SetupDialog *pSetupDialog = new SetupDialog(this);
1829 pSetupDialog->exec();
1830}
1831
1832void PlotWindow::showSetupDialog(QString variable)
1833{
1834 SetupDialog *pSetupDialog = new SetupDialog(this);
1835 pSetupDialog->selectVariable(variable);
1836 pSetupDialog->exec();
1837}
1838
1839/*!
1840 \class VariablePageWidget
1841 \brief Represent the attribute of a plot variable.
1842 */
1843VariablePageWidget::VariablePageWidget(PlotCurve *pPlotCurve, SetupDialog *pSetupDialog)
1844 : QWidget(pSetupDialog)
1845{
1846 mpPlotCurve = pPlotCurve;
1847 // general group box
1848 mpGeneralGroupBox = new QGroupBox(tr("General"));
1849 mpLegendLabel = new QLabel(tr("Legend"));
1850 mpLegendTextBox = new QLineEdit(mpPlotCurve->title().text());
1851 mpResetLabelButton = new QPushButton(tr("Reset"));
1852 mpResetLabelButton->setAutoDefault(false);
1853 connect(mpResetLabelButton, SIGNAL(clicked())"2""clicked()", SLOT(resetLabel())"1""resetLabel()");
1854 mpFileLabel = new QLabel(tr("File"));
1855 mpFileTextBox = new QLabel(mpPlotCurve->getFileName());
1856 // appearance layout
1857 QGridLayout *pGeneralGroupBoxGridLayout = new QGridLayout;
1858 pGeneralGroupBoxGridLayout->addWidget(mpLegendLabel, 0, 0);
1859 pGeneralGroupBoxGridLayout->addWidget(mpLegendTextBox, 0, 1);
1860 pGeneralGroupBoxGridLayout->addWidget(mpResetLabelButton, 0, 2);
1861 pGeneralGroupBoxGridLayout->addWidget(mpFileLabel, 1, 0);
1862 pGeneralGroupBoxGridLayout->addWidget(mpFileTextBox, 1, 1, 1, 2);
1863 mpGeneralGroupBox->setLayout(pGeneralGroupBoxGridLayout);
1864 // Appearance group box
1865 mpAppearanceGroupBox = new QGroupBox(tr("Appearance"));
1866 mpColorLabel = new QLabel(tr("Color"));
1867 mpPickColorButton = new QPushButton(tr("Pick Color"));
1868 mpPickColorButton->setAutoDefault(false);
1869 //mpPickColorButton->setAutoDefault(false);
1870 connect(mpPickColorButton, SIGNAL(clicked())"2""clicked()", SLOT(pickColor())"1""pickColor()");
1871 mCurveColor = mpPlotCurve->pen().color();
1872 setCurvePickColorButtonIcon();
1873 mpAutomaticColorCheckBox = new QCheckBox(tr("Automatic Color"));
1874 mpAutomaticColorCheckBox->setChecked(!mpPlotCurve->hasCustomColor());
1875 // pattern
1876 mpPatternLabel = new QLabel(tr("Pattern"));
1877 mpPatternComboBox = new QComboBox;
1878 mpPatternComboBox->addItem("SolidLine", 1);
1879 mpPatternComboBox->addItem("DashLine", 2);
1880 mpPatternComboBox->addItem("DotLine", 3);
1881 mpPatternComboBox->addItem("DashDotLine", 4);
1882 mpPatternComboBox->addItem("DashDotDotLine", 5);
1883 mpPatternComboBox->addItem("Sticks", 6);
1884 mpPatternComboBox->addItem("Steps", 7);
1885 int index = mpPatternComboBox->findData(mpPlotCurve->getCurveStyle());
1886 if (index != -1) mpPatternComboBox->setCurrentIndex(index);
1887 // thickness
1888 mpThicknessLabel = new QLabel(tr("Thickness"));
1889 mpThicknessSpinBox = new QDoubleSpinBox;
1890 mpThicknessSpinBox->setValue(1);
1891 mpThicknessSpinBox->setSingleStep(1);
1892 mpThicknessSpinBox->setValue(mpPlotCurve->getCurveWidth());
1893 // hide
1894 mpHideCheckBox = new QCheckBox(tr("Hide"));
1895 mpHideCheckBox->setChecked(!mpPlotCurve->isVisible());
1896 // appearance layout
1897 QGridLayout *pAppearanceGroupBoxGridLayout = new QGridLayout;
1898 pAppearanceGroupBoxGridLayout->addWidget(mpColorLabel, 0, 0);
1899 pAppearanceGroupBoxGridLayout->addWidget(mpPickColorButton, 0, 1);
1900 pAppearanceGroupBoxGridLayout->addWidget(mpAutomaticColorCheckBox, 0, 2);
1901 pAppearanceGroupBoxGridLayout->addWidget(mpPatternLabel, 1, 0);
1902 pAppearanceGroupBoxGridLayout->addWidget(mpPatternComboBox, 1, 1, 1, 2);
1903 pAppearanceGroupBoxGridLayout->addWidget(mpThicknessLabel, 2, 0);
1904 pAppearanceGroupBoxGridLayout->addWidget(mpThicknessSpinBox, 2, 1, 1, 2);
1905 pAppearanceGroupBoxGridLayout->addWidget(mpHideCheckBox, 3, 0, 1, 3);
1906 mpAppearanceGroupBox->setLayout(pAppearanceGroupBoxGridLayout);
1907 // set layout
1908 QGridLayout *pMainLayout = new QGridLayout;
1909 pMainLayout->setContentsMargins(0, 0, 0, 0);
1910 pMainLayout->addWidget(mpGeneralGroupBox, 0, 0);
1911 pMainLayout->addWidget(mpAppearanceGroupBox, 1, 0);
1912 setLayout(pMainLayout);
1913}
1914
1915void VariablePageWidget::setCurvePickColorButtonIcon()
1916{
1917 QPixmap pixmap(QSize(10, 10));
1918 pixmap.fill(getCurveColor());
1919 mpPickColorButton->setIcon(pixmap);
1920}
1921
1922void VariablePageWidget::resetLabel()
1923{
1924 if (mpPlotCurve->getDisplayUnit().isEmpty()) {
1925 mpLegendTextBox->setText(mpPlotCurve->getName());
1926 } else {
1927 mpLegendTextBox->setText(mpPlotCurve->getName() + " [" + mpPlotCurve->getDisplayUnit() + "]");
1928 }
1929
1930}
1931
1932void VariablePageWidget::pickColor()
1933{
1934 QColor color = QColorDialog::getColor(getCurveColor());
1935 if (!color.isValid())
1936 return;
1937
1938 setCurveColor(color);
1939 setCurvePickColorButtonIcon();
1940 mpAutomaticColorCheckBox->setChecked(false);
1941}
1942
1943/*!
1944 \class SetupDialog
1945 \brief Contains a list of plot variables. Allows user to select the variable and then edit its attributes.
1946 */
1947/*!
1948 \param pPlotWindow - pointer to PlotWindow
1949 */
1950SetupDialog::SetupDialog(PlotWindow *pPlotWindow)
1951 : QDialog(pPlotWindow)
1952{
1953 setWindowTitle(tr("Plot Setup"));
1954 setAttribute(Qt::WA_DeleteOnClose);
1955
1956 mpPlotWindow = pPlotWindow;
1957 mpSetupTabWidget = new QTabWidget;
1958 // Variables Tab
1959 mpVariablesTab = new QWidget;
1960 mpVariableLabel = new QLabel(tr("Select a variable, then edit its properties below:"));
1961 // variables list
1962 mpVariablesListWidget = new QListWidget;
1963 mpVariablePagesStackedWidget = new QStackedWidget;
1964 QList<PlotCurve*> plotCurves = mpPlotWindow->getPlot()->getPlotCurvesList();
1965 foreach (PlotCurve *pPlotCurve, plotCurves)for (auto _container_ = QtPrivate::qMakeForeachContainer(plotCurves
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (PlotCurve
*pPlotCurve = *_container_.i; _container_.control; _container_
.control = 0)
{
1966 mpVariablePagesStackedWidget->addWidget(new VariablePageWidget(pPlotCurve, this));
1967 QListWidgetItem *pListItem = new QListWidgetItem(mpVariablesListWidget);
1968 pListItem->setText(pPlotCurve->getName());
1969 pListItem->setData(Qt::UserRole, pPlotCurve->getNameStructure());
1970 }
1971 connect(mpVariablesListWidget, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*))"2""currentItemChanged(QListWidgetItem*,QListWidgetItem*)", SLOT(variableSelected(QListWidgetItem*,QListWidgetItem*))"1""variableSelected(QListWidgetItem*,QListWidgetItem*)");
1972 // Variables Tab Layout
1973 QGridLayout *pVariablesTabGridLayout = new QGridLayout;
1974 pVariablesTabGridLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
1975 pVariablesTabGridLayout->addWidget(mpVariableLabel, 0, 0);
1976 pVariablesTabGridLayout->addWidget(mpVariablesListWidget, 1, 0);
1977 pVariablesTabGridLayout->addWidget(mpVariablePagesStackedWidget, 2, 0);
1978 mpVariablesTab->setLayout(pVariablesTabGridLayout);
1979 // title tab
1980 mpTitlesTab = new QWidget;
1981 mpPlotTitleLabel = new QLabel(tr("Plot Title"));
1982 mpPlotTitleTextBox = new QLineEdit(mpPlotWindow->getPlot()->title().text());
1983 mpTitleFontSizeLabel = new QLabel("Title Font Size");
1984 mpTitleFontSizeSpinBox = new QDoubleSpinBox;
1985 mpTitleFontSizeSpinBox->setRange(6, std::numeric_limits<double>::max());
1986 mpTitleFontSizeSpinBox->setValue(mpPlotWindow->getPlot()->titleLabel()->font().pointSizeF());
1987 mpTitleFontSizeSpinBox->setSingleStep(1);
1988 mpVerticalAxisLabel = new QLabel(tr("Vertical Axis Title"));
1989 mpVerticalAxisTextBox = new QLineEdit(mpPlotWindow->getPlot()->axisTitle(QwtPlot::yLeft).text());
1990 mpVerticalAxisTitleFontSizeLabel = new QLabel("Vertical Axis Title Font Size");
1991 mpVerticalAxisTitleFontSizeSpinBox = new QDoubleSpinBox;
1992 mpVerticalAxisTitleFontSizeSpinBox->setRange(6, std::numeric_limits<double>::max());
1993 mpVerticalAxisTitleFontSizeSpinBox->setValue(mpPlotWindow->getPlot()->axisWidget(QwtPlot::yLeft)->title().font().pointSizeF());
1994 mpVerticalAxisTitleFontSizeSpinBox->setSingleStep(1);
1995 mpVerticalAxisNumbersFontSizeLabel = new QLabel("Vertical Axis Numbers Font Size");
1996 mpVerticalAxisNumbersFontSizeSpinBox = new QDoubleSpinBox;
1997 mpVerticalAxisNumbersFontSizeSpinBox->setRange(6, std::numeric_limits<double>::max());
1998 mpVerticalAxisNumbersFontSizeSpinBox->setValue(mpPlotWindow->getPlot()->axisWidget(QwtPlot::yLeft)->font().pointSizeF());
1999 mpVerticalAxisNumbersFontSizeSpinBox->setSingleStep(1);
2000 mpHorizontalAxisLabel = new QLabel(tr("Horizontal Axis Title"));
2001 mpHorizontalAxisTextBox = new QLineEdit(mpPlotWindow->getPlot()->axisTitle(QwtPlot::xBottom).text());
2002 mpHorizontalAxisTitleFontSizeLabel = new QLabel("Horizontal Axis Title Font Size");
2003 mpHorizontalAxisTitleFontSizeSpinBox = new QDoubleSpinBox;
2004 mpHorizontalAxisTitleFontSizeSpinBox->setRange(6, std::numeric_limits<double>::max());
2005 mpHorizontalAxisTitleFontSizeSpinBox->setValue(mpPlotWindow->getPlot()->axisWidget(QwtPlot::xBottom)->title().font().pointSizeF());
2006 mpHorizontalAxisTitleFontSizeSpinBox->setSingleStep(1);
2007 mpHorizontalAxisNumbersFontSizeLabel = new QLabel("Horizontal Axis Numbers Font Size");
2008 mpHorizontalAxisNumbersFontSizeSpinBox = new QDoubleSpinBox;
2009 mpHorizontalAxisNumbersFontSizeSpinBox->setRange(6, std::numeric_limits<double>::max());
2010 mpHorizontalAxisNumbersFontSizeSpinBox->setValue(mpPlotWindow->getPlot()->axisWidget(QwtPlot::xBottom)->font().pointSizeF());
2011 mpHorizontalAxisNumbersFontSizeSpinBox->setSingleStep(1);
2012 mpPlotFooterLabel = new QLabel(tr("Plot Footer"));
2013 mpPlotFooterTextBox = new QLineEdit(mpPlotWindow->getFooter());
2014 mpFooterFontSizeLabel = new QLabel("Footer Font Size");
2015 mpFooterFontSizeSpinBox = new QDoubleSpinBox;
2016 mpFooterFontSizeSpinBox->setRange(6, std::numeric_limits<double>::max());
2017 mpFooterFontSizeSpinBox->setValue(mpPlotWindow->getPlot()->footerLabel()->font().pointSizeF());
2018 mpFooterFontSizeSpinBox->setSingleStep(1);
2019 // title tab layout
2020 QGridLayout *pTitlesTabGridLayout = new QGridLayout;
2021 pTitlesTabGridLayout->setAlignment(Qt::AlignTop | Qt::AlignLeft);
2022 pTitlesTabGridLayout->addWidget(mpPlotTitleLabel, 0, 0);
2023 pTitlesTabGridLayout->addWidget(mpPlotTitleTextBox, 0, 1);
2024 pTitlesTabGridLayout->addWidget(mpTitleFontSizeLabel, 1, 0);
2025 pTitlesTabGridLayout->addWidget(mpTitleFontSizeSpinBox, 1, 1);
2026 pTitlesTabGridLayout->addWidget(mpVerticalAxisLabel, 2, 0);
2027 pTitlesTabGridLayout->addWidget(mpVerticalAxisTextBox, 2, 1);
2028 pTitlesTabGridLayout->addWidget(mpVerticalAxisTitleFontSizeLabel, 3, 0);
2029 pTitlesTabGridLayout->addWidget(mpVerticalAxisTitleFontSizeSpinBox, 3, 1);
2030 pTitlesTabGridLayout->addWidget(mpVerticalAxisNumbersFontSizeLabel, 4, 0);
2031 pTitlesTabGridLayout->addWidget(mpVerticalAxisNumbersFontSizeSpinBox, 4, 1);
2032 pTitlesTabGridLayout->addWidget(mpHorizontalAxisLabel, 5, 0);
2033 pTitlesTabGridLayout->addWidget(mpHorizontalAxisTextBox, 5, 1);
2034 pTitlesTabGridLayout->addWidget(mpHorizontalAxisTitleFontSizeLabel, 6, 0);
2035 pTitlesTabGridLayout->addWidget(mpHorizontalAxisTitleFontSizeSpinBox, 6, 1);
2036 pTitlesTabGridLayout->addWidget(mpHorizontalAxisNumbersFontSizeLabel, 7, 0);
2037 pTitlesTabGridLayout->addWidget(mpHorizontalAxisNumbersFontSizeSpinBox, 7, 1);
2038#if QWT_VERSION0x060200 > 0x060000
2039 pTitlesTabGridLayout->addWidget(mpPlotFooterLabel, 8, 0);
2040 pTitlesTabGridLayout->addWidget(mpPlotFooterTextBox, 8, 1);
2041 pTitlesTabGridLayout->addWidget(mpFooterFontSizeLabel, 9, 0);
2042 pTitlesTabGridLayout->addWidget(mpFooterFontSizeSpinBox, 9, 1);
2043#endif
2044 mpTitlesTab->setLayout(pTitlesTabGridLayout);
2045 // legend tab
2046 mpLegendTab = new QWidget;
2047 mpLegendPositionLabel = new QLabel(tr("Legend Position"));
2048 mpLegendPositionComboBox = new QComboBox;
2049 mpLegendPositionComboBox->addItem(tr("Top"), "top");
2050 mpLegendPositionComboBox->addItem(tr("Right"), "right");
2051 mpLegendPositionComboBox->addItem(tr("Bottom"), "bottom");
2052 mpLegendPositionComboBox->addItem(tr("Left"), "left");
2053 mpLegendFontSizeLabel = new QLabel(tr("Legend Font Size"));
2054 mpLegendFontSizeSpinBox = new QDoubleSpinBox;
2055 mpLegendFontSizeSpinBox->setRange(6, std::numeric_limits<double>::max());
2056 mpLegendFontSizeSpinBox->setValue(mpPlotWindow->getLegendFont().pointSizeF());
2057 mpLegendFontSizeSpinBox->setSingleStep(1);
2058 // legend tab layout
2059 QGridLayout *pLegendTabGridLayout = new QGridLayout;
2060 pLegendTabGridLayout->setAlignment(Qt::AlignTop);
2061 pLegendTabGridLayout->addWidget(mpLegendPositionLabel, 0, 0);
2062 pLegendTabGridLayout->addWidget(mpLegendPositionComboBox, 0, 1);
2063 pLegendTabGridLayout->addWidget(mpLegendFontSizeLabel, 1, 0);
2064 pLegendTabGridLayout->addWidget(mpLegendFontSizeSpinBox, 1, 1);
2065 mpLegendTab->setLayout(pLegendTabGridLayout);
2066 // range tab
2067 mpRangeTab = new QWidget;
2068 mpAutoScaleCheckbox = new QCheckBox(tr("Auto Scale"));
2069 mpAutoScaleCheckbox->setChecked(mpPlotWindow->getAutoScaleButton()->isChecked());
2070 connect(mpAutoScaleCheckbox, SIGNAL(toggled(bool))"2""toggled(bool)", SLOT(autoScaleChecked(bool))"1""autoScaleChecked(bool)");
2071 // x-axis
2072 mpXAxisGroupBox = new QGroupBox(tr("X-Axis"));
2073 mpXMinimumLabel = new QLabel(tr("Minimum"));
2074 mpXMinimumTextBox = new QLineEdit(QString::number(mpPlotWindow->getPlot()->axisScaleDiv(QwtPlot::xBottom).lowerBound()));
2075 mpXMaximumLabel = new QLabel(tr("Maximum"));
2076 mpXMaximumTextBox = new QLineEdit(QString::number(mpPlotWindow->getPlot()->axisScaleDiv(QwtPlot::xBottom).upperBound()));
2077 QGridLayout *pXGridLayout = new QGridLayout;
2078 pXGridLayout->addWidget(mpXMinimumLabel, 0, 0);
2079 pXGridLayout->addWidget(mpXMinimumTextBox, 0, 1);
2080 pXGridLayout->addWidget(mpXMaximumLabel, 1, 0);
2081 pXGridLayout->addWidget(mpXMaximumTextBox, 1, 1);
2082 mpXAxisGroupBox->setLayout(pXGridLayout);
2083 mpXAxisGroupBox->setEnabled(!mpAutoScaleCheckbox->isChecked());
2084 // y-axis
2085 mpYAxisGroupBox = new QGroupBox(tr("Y-Axis"));
2086 mpYMinimumLabel = new QLabel(tr("Minimum"));
2087 mpYMinimumTextBox = new QLineEdit(QString::number(mpPlotWindow->getPlot()->axisScaleDiv(QwtPlot::yLeft).lowerBound()));
2088 mpYMaximumLabel = new QLabel(tr("Maximum"));
2089 mpYMaximumTextBox = new QLineEdit(QString::number(mpPlotWindow->getPlot()->axisScaleDiv(QwtPlot::yLeft).upperBound()));
2090 QGridLayout *pYGridLayout = new QGridLayout;
2091 pYGridLayout->addWidget(mpYMinimumLabel, 0, 0);
2092 pYGridLayout->addWidget(mpYMinimumTextBox, 0, 1);
2093 pYGridLayout->addWidget(mpYMaximumLabel, 1, 0);
2094 pYGridLayout->addWidget(mpYMaximumTextBox, 1, 1);
2095 mpYAxisGroupBox->setLayout(pYGridLayout);
2096 mpYAxisGroupBox->setEnabled(!mpAutoScaleCheckbox->isChecked());
2097 QDoubleValidator *pDoubleValidator = new QDoubleValidator(this);
2098 mpXMinimumTextBox->setValidator(pDoubleValidator);
2099 mpXMaximumTextBox->setValidator(pDoubleValidator);
2100 mpYMinimumTextBox->setValidator(pDoubleValidator);
2101 mpXMaximumTextBox->setValidator(pDoubleValidator);
2102 // range tab layout
2103 QVBoxLayout *pRangeTabVerticalLayout = new QVBoxLayout;
2104 pRangeTabVerticalLayout->setAlignment(Qt::AlignTop);
2105 pRangeTabVerticalLayout->addWidget(mpAutoScaleCheckbox);
2106 pRangeTabVerticalLayout->addWidget(mpXAxisGroupBox);
2107 pRangeTabVerticalLayout->addWidget(mpYAxisGroupBox);
2108 mpRangeTab->setLayout(pRangeTabVerticalLayout);
2109 // add tabs
2110 mpSetupTabWidget->addTab(mpVariablesTab, tr("Variables"));
2111 mpSetupTabWidget->addTab(mpTitlesTab, tr("Titles"));
2112 mpSetupTabWidget->addTab(mpLegendTab, tr("Legend"));
2113 mpSetupTabWidget->addTab(mpRangeTab, tr("Range"));
2114 // Create the buttons
2115 mpOkButton = new QPushButton(tr("OK"));
2116 mpOkButton->setAutoDefault(true);
2117 connect(mpOkButton, SIGNAL(clicked())"2""clicked()", this, SLOT(saveSetup())"1""saveSetup()");
2118 mpApplyButton = new QPushButton(tr("Apply"));
2119 mpApplyButton->setAutoDefault(false);
2120 connect(mpApplyButton, SIGNAL(clicked())"2""clicked()", this, SLOT(applySetup())"1""applySetup()");
2121 mpCancelButton = new QPushButton(tr("Cancel"));
2122 mpCancelButton->setAutoDefault(false);
2123 connect(mpCancelButton, SIGNAL(clicked())"2""clicked()", this, SLOT(reject())"1""reject()");
2124 mpButtonBox = new QDialogButtonBox(Qt::Horizontal);
2125 mpButtonBox->addButton(mpOkButton, QDialogButtonBox::ActionRole);
2126 mpButtonBox->addButton(mpApplyButton, QDialogButtonBox::ActionRole);
2127 mpButtonBox->addButton(mpCancelButton, QDialogButtonBox::ActionRole);
2128 // set the main layout
2129 QGridLayout *pMainLayout = new QGridLayout;
2130 pMainLayout->addWidget(mpSetupTabWidget, 0, 0);
2131 pMainLayout->addWidget(mpButtonBox, 1, 0, 1, 1, Qt::AlignRight);
2132 setLayout(pMainLayout);
2133 // select the first variable if its available.
2134 if (mpVariablesListWidget->count() > 0) {
2135 mpVariablesListWidget->setCurrentRow(0, QItemSelectionModel::Select);
2136 }
2137}
2138
2139void SetupDialog::selectVariable(QString variable)
2140{
2141 for (int i = 0 ; i < mpVariablesListWidget->count() ; i++)
2142 {
2143 if (mpVariablesListWidget->item(i)->data(Qt::UserRole).toString().compare(variable) == 0)
2144 {
2145 mpVariablesListWidget->setCurrentRow(i, QItemSelectionModel::ClearAndSelect);
2146 break;
2147 }
2148 }
2149}
2150
2151void SetupDialog::setupPlotCurve(VariablePageWidget *pVariablePageWidget)
2152{
2153 if (!pVariablePageWidget)
2154 return;
2155
2156 PlotCurve *pPlotCurve = pVariablePageWidget->getPlotCurve();
2157
2158 /* set the legend title */
2159 pPlotCurve->setTitle(pVariablePageWidget->getLegendTextBox()->text());
2160 /* set the curve color title */
2161 pPlotCurve->setCustomColor(!pVariablePageWidget->getAutomaticColorCheckBox()->isChecked());
2162 if (pVariablePageWidget->getAutomaticColorCheckBox()->isChecked())
2163 {
2164 pVariablePageWidget->setCurveColor(pPlotCurve->pen().color());
2165 pVariablePageWidget->setCurvePickColorButtonIcon();
2166 }
2167 else
2168 {
2169 QPen pen = pPlotCurve->pen();
2170 pen.setColor(pVariablePageWidget->getCurveColor());
2171 pPlotCurve->setPen(pen);
2172 }
2173 /* set the curve style */
2174 QComboBox *pPatternComboBox = pVariablePageWidget->getPatternComboBox();
2175 pPlotCurve->setCurveStyle(pPatternComboBox->itemData(pPatternComboBox->currentIndex()).toInt());
2176 /* set the curve width */
2177 pPlotCurve->setCurveWidth(pVariablePageWidget->getThicknessSpinBox()->value());
2178 /* set the curve visibility */
2179 pPlotCurve->setVisible(!pVariablePageWidget->getHideCheckBox()->isChecked());
2180 QwtText text = pPlotCurve->title();
2181 if (pPlotCurve->isVisible()) {
2182 text.setColor(QColor(Qt::black));
2183 } else {
2184 text.setColor(QColor(Qt::gray));
2185 }
2186 pPlotCurve->setTitle(text);
2187}
2188
2189void SetupDialog::variableSelected(QListWidgetItem *current, QListWidgetItem *previous)
2190{
2191 if (!current) {
2192 current = previous;
2193 }
2194
2195 mpVariablePagesStackedWidget->setCurrentIndex(mpVariablesListWidget->row(current));
2196}
2197
2198/*!
2199 * \brief SetupDialog::autoScaleChecked
2200 * SLOT activated when mpAutoScaleCheckbox toggled SIGNAL is raised.\n
2201 * Enabled/disables the range controls.
2202 * \param checked
2203 */
2204void SetupDialog::autoScaleChecked(bool checked)
2205{
2206 mpXAxisGroupBox->setEnabled(!checked);
2207 mpYAxisGroupBox->setEnabled(!checked);
2208}
2209
2210void SetupDialog::saveSetup()
2211{
2212 applySetup();
2213 accept();
2214}
2215
2216void SetupDialog::applySetup()
2217{
2218 // set the variables attributes
2219 for (int i = 0 ; i < mpVariablePagesStackedWidget->count() ; i++) {
2220 setupPlotCurve(qobject_cast<VariablePageWidget*>(mpVariablePagesStackedWidget->widget(i)));
2221 }
2222 // set the font sizes. Don't move this line. We should set the font sizes before calling setLegendPosition
2223 mpPlotWindow->getPlot()->setFontSizes(mpTitleFontSizeSpinBox->value(), mpVerticalAxisTitleFontSizeSpinBox->value(), mpVerticalAxisNumbersFontSizeSpinBox->value(),
2224 mpHorizontalAxisTitleFontSizeSpinBox->value(), mpHorizontalAxisNumbersFontSizeSpinBox->value(), mpFooterFontSizeSpinBox->value(), mpLegendFontSizeSpinBox->value());
2225 // set the titles
2226 mpPlotWindow->getPlot()->setTitle(mpPlotTitleTextBox->text());
2227 mpPlotWindow->getPlot()->setAxisTitle(QwtPlot::yLeft, mpVerticalAxisTextBox->text());
2228 mpPlotWindow->getPlot()->setAxisTitle(QwtPlot::xBottom, mpHorizontalAxisTextBox->text());
2229 mpPlotWindow->setFooter(mpPlotFooterTextBox->text());
2230 // set the legend
2231 mpPlotWindow->setLegendPosition(mpLegendPositionComboBox->itemData(mpLegendPositionComboBox->currentIndex()).toString());
2232 // set the auto scale
2233 mpPlotWindow->setAutoScale(mpAutoScaleCheckbox->isChecked());
2234 // set the range
2235 if (mpAutoScaleCheckbox->isChecked()) {
2236 mpPlotWindow->getPlot()->setAxisAutoScale(QwtPlot::xBottom);
2237 mpPlotWindow->getPlot()->setAxisAutoScale(QwtPlot::yLeft);
2238 } else {
2239 mpPlotWindow->setXRange(mpXMinimumTextBox->text().toDouble(), mpXMaximumTextBox->text().toDouble());
2240 mpPlotWindow->setYRange(mpYMinimumTextBox->text().toDouble(), mpYMaximumTextBox->text().toDouble());
2241 }
2242 // replot
2243 mpPlotWindow->getPlot()->replot();
2244}
2245
2246#include "util/omc_file.c"
2247#include "util/read_matlab4.c"
2248#include "util/libcsv.c"
2249#include "util/read_csv.c"