]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/jobgraphs/jobplot.cpp
Only use the svg files for the generation of the png files.
[bacula/bacula] / bacula / src / qt-console / jobgraphs / jobplot.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of John Walker.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28  
29 /*
30  *   Version $Id$
31  *
32  *  JobPlots Class
33  *
34  *   Dirk Bartley, March 2007
35  *
36  */ 
37
38 #include <QtGui>
39 #include "bat.h"
40 #include "jobgraphs/jobplot.h"
41
42
43 JobPlotPass::JobPlotPass()
44 {
45    use = false;
46 }
47
48 JobPlotPass& JobPlotPass::operator=(const JobPlotPass &cp)
49 {
50    use = cp.use;
51    recordLimitCheck = cp.recordLimitCheck;
52    daysLimitCheck = cp.daysLimitCheck;
53    recordLimitSpin = cp.recordLimitSpin;
54    daysLimitSpin = cp.daysLimitSpin;
55    jobCombo = cp.jobCombo;
56    clientCombo = cp.clientCombo;
57    volumeCombo = cp.volumeCombo;
58    fileSetCombo = cp.fileSetCombo;
59    purgedCombo = cp.purgedCombo;
60    levelCombo = cp.levelCombo;
61    statusCombo = cp.statusCombo;
62    return *this;
63 }
64
65 /*
66  * Constructor for the controls class which inherits QScrollArea and a ui header
67  */
68 JobPlotControls::JobPlotControls()
69 {
70    setupUi(this);
71 }
72
73 /*
74  * Constructor, this class does not inherit anything but pages.
75  */
76 JobPlot::JobPlot(QTreeWidgetItem *parentTreeWidgetItem, JobPlotPass &passVals)
77 {
78    setupUserInterface();
79    m_name = "Job Plot";
80    pgInitialize(parentTreeWidgetItem);
81    readSplitterSettings();
82    QTreeWidgetItem* thisitem = mainWin->getFromHash(this);
83    thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/graph1.png")));
84    m_drawn = false;
85
86    /* this invokes the pass values = operator function */
87    m_pass = passVals;
88    m_closeable = true;
89    dockPage();
90    /* If the values of the controls are predetermined (from joblist), then set
91     * this class as current window at the front of the stack */
92    if (m_pass.use)
93       setCurrent();
94    m_jobPlot->replot();
95 }
96
97 /*
98  * Kill, crush Destroy
99  */
100 JobPlot::~JobPlot()
101 {
102    if (m_drawn)
103       writeSettings();
104    m_pjd.clear();
105 }
106
107 /*
108  * This is called when the page selector has this page selected
109  */
110 void JobPlot::currentStackItem()
111 {
112    if (!m_drawn) {
113       setupControls();
114       reGraph();
115       m_drawn=true;
116    }
117 }
118
119 /*
120  * Slot for the refrehs push button, also called from constructor.
121  */
122 void JobPlot::reGraph()
123 {
124    /* clear m_pjd */
125    m_pjd.clear();
126    runQuery();
127    m_jobPlot->clear();
128    addCurve();
129    m_jobPlot->replot();
130 }
131
132 /*
133  * Setup the control widgets for the graph, this are the objects from JobPlotControls
134  */
135 void JobPlot::setupControls()
136 {
137    QStringList graphType = QStringList() << /* "Fitted" <<*/ "Sticks" << "Lines" << "Steps" << "None";
138    controls->plotTypeCombo->addItems(graphType);
139    QStringList symbolType = QStringList() << "Ellipse" << "Rect" << "Diamond" << "Triangle"
140             << "DTrianle" << "UTriangle" << "LTriangle" << "RTriangle" << "Cross" << "XCross"
141             << "HLine" << "Vline" << "Star1" << "Star2" << "Hexagon" << "None";
142    controls->fileSymbolTypeCombo->addItems(symbolType);
143    controls->byteSymbolTypeCombo->addItems(symbolType);
144    readControlSettings();
145
146    controls->fileCheck->setCheckState(Qt::Checked);
147    controls->byteCheck->setCheckState(Qt::Checked);
148    connect(controls->plotTypeCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(setPlotType(QString)));
149    connect(controls->fileSymbolTypeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setFileSymbolType(int)));
150    connect(controls->byteSymbolTypeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setByteSymbolType(int)));
151    connect(controls->fileCheck, SIGNAL(stateChanged(int)), this, SLOT(fileCheckChanged(int)));
152    connect(controls->byteCheck, SIGNAL(stateChanged(int)), this, SLOT(byteCheckChanged(int)));
153    connect(controls->refreshButton, SIGNAL(pressed()), this, SLOT(reGraph()));
154
155    controls->clientComboBox->addItem("Any");
156    controls->clientComboBox->addItems(m_console->client_list);
157
158    QStringList volumeList;
159    m_console->getVolumeList(volumeList);
160    controls->volumeComboBox->addItem("Any");
161    controls->volumeComboBox->addItems(volumeList);
162    controls->jobComboBox->addItem("Any");
163    controls->jobComboBox->addItems(m_console->job_list);
164    controls->levelComboBox->addItem("Any");
165    controls->levelComboBox->addItems( QStringList() << "F" << "D" << "I");
166    controls->purgedComboBox->addItem("Any");
167    controls->purgedComboBox->addItems( QStringList() << "0" << "1");
168    controls->fileSetComboBox->addItem("Any");
169    controls->fileSetComboBox->addItems(m_console->fileset_list);
170    QStringList statusLongList;
171    m_console->getStatusList(statusLongList);
172    controls->statusComboBox->addItem("Any");
173    controls->statusComboBox->addItems(statusLongList);
174
175    if (m_pass.use) {
176       controls->limitCheckBox->setCheckState(m_pass.recordLimitCheck);
177       controls->limitSpinBox->setValue(m_pass.recordLimitSpin);
178       controls->daysCheckBox->setCheckState(m_pass.daysLimitCheck);
179       controls->daysSpinBox->setValue(m_pass.daysLimitSpin);
180       int jobIndex = controls->jobComboBox->findText(m_pass.jobCombo, Qt::MatchExactly); 
181       if (jobIndex != -1)
182          controls->jobComboBox->setCurrentIndex(jobIndex);
183       int clientIndex = controls->clientComboBox->findText(m_pass.clientCombo, Qt::MatchExactly);
184       if (clientIndex != -1)
185          controls->clientComboBox->setCurrentIndex(clientIndex);
186       int volumeIndex = controls->volumeComboBox->findText(m_pass.volumeCombo, Qt::MatchExactly);
187       if (volumeIndex != -1)
188          controls->volumeComboBox->setCurrentIndex(volumeIndex);
189       int filesetIndex = controls->fileSetComboBox->findText(m_pass.fileSetCombo, Qt::MatchExactly);
190       if (filesetIndex != -1)
191          controls->fileSetComboBox->setCurrentIndex(filesetIndex);
192       int purgedIndex = controls->purgedComboBox->findText(m_pass.purgedCombo, Qt::MatchExactly); 
193       if (purgedIndex != -1)
194          controls->purgedComboBox->setCurrentIndex(purgedIndex);
195       int levelIndex = controls->levelComboBox->findText(m_pass.levelCombo, Qt::MatchExactly); 
196       if (levelIndex != -1)
197          controls->levelComboBox->setCurrentIndex(levelIndex);
198       int statusIndex = controls->statusComboBox->findText(m_pass.statusCombo, Qt::MatchExactly); 
199       if (statusIndex != -1)
200          controls->statusComboBox->setCurrentIndex(statusIndex);
201    } else {
202       /* Set Defaults for check and spin for limits */
203       controls->limitCheckBox->setCheckState(mainWin->m_recordLimitCheck ? Qt::Checked : Qt::Unchecked);
204       controls->limitSpinBox->setValue(mainWin->m_recordLimitVal);
205       controls->daysCheckBox->setCheckState(mainWin->m_daysLimitCheck ? Qt::Checked : Qt::Unchecked);
206       controls->daysSpinBox->setValue(mainWin->m_daysLimitVal);
207    } 
208 }
209
210 /*
211  * Setup the control widgets for the graph, this are the objects from JobPlotControls
212  */
213 void JobPlot::runQuery()
214 {
215    /* Set up query */
216    QString query("");
217    query += "SELECT DISTINCT "
218             " Job.Starttime AS JobStart,"
219             " Job.Jobfiles AS FileCount,"
220             " Job.JobBytes AS Bytes,"
221             " Job.JobId AS JobId"
222             " FROM Job"
223             " LEFT OUTER JOIN Client ON (Client.ClientId=Job.ClientId)"
224             " LEFT OUTER JOIN FileSet ON (FileSet.FileSetId=Job.FileSetId)"
225             " LEFT OUTER JOIN Status ON (Job.JobStatus=Status.JobStatus)"
226             " LEFT OUTER JOIN JobMedia ON (JobMedia.JobId=Job.JobId)"
227             " LEFT OUTER JOIN Media ON (JobMedia.MediaId=Media.MediaId)";
228    QStringList conditions;
229    int jobIndex = controls->jobComboBox->currentIndex();
230    if ((jobIndex != -1) && (controls->jobComboBox->itemText(jobIndex) != "Any"))
231       conditions.append("Job.Name='" + controls->jobComboBox->itemText(jobIndex) + "'");
232    int clientIndex = controls->clientComboBox->currentIndex();
233    if ((clientIndex != -1) && (controls->clientComboBox->itemText(clientIndex) != "Any"))
234       conditions.append("Client.Name='" + controls->clientComboBox->itemText(clientIndex) + "'");
235    int volumeIndex = controls->volumeComboBox->currentIndex();
236    if ((volumeIndex != -1) && (controls->volumeComboBox->itemText(volumeIndex) != "Any"))
237       conditions.append("Media.VolumeName='" + controls->volumeComboBox->itemText(volumeIndex) + "'");
238    int fileSetIndex = controls->fileSetComboBox->currentIndex();
239    if ((fileSetIndex != -1) && (controls->fileSetComboBox->itemText(fileSetIndex) != "Any"))
240       conditions.append("FileSet.FileSet='" + controls->fileSetComboBox->itemText(fileSetIndex) + "'");
241    int purgedIndex = controls->purgedComboBox->currentIndex();
242    if ((purgedIndex != -1) && (controls->purgedComboBox->itemText(purgedIndex) != "Any"))
243       conditions.append("Job.PurgedFiles='" + controls->purgedComboBox->itemText(purgedIndex) + "'");
244    int levelIndex = controls->levelComboBox->currentIndex();
245    if ((levelIndex != -1) && (controls->levelComboBox->itemText(levelIndex) != "Any"))
246       conditions.append("Job.Level='" + controls->levelComboBox->itemText(levelIndex) + "'");
247    int statusIndex = controls->statusComboBox->currentIndex();
248    if ((statusIndex != -1) && (controls->statusComboBox->itemText(statusIndex) != "Any"))
249       conditions.append("Status.JobStatusLong='" + controls->statusComboBox->itemText(statusIndex) + "'");
250    /* If Limit check box For limit by days is checked  */
251    if (controls->daysCheckBox->checkState() == Qt::Checked) {
252       QDateTime stamp = QDateTime::currentDateTime().addDays(-controls->daysSpinBox->value());
253       QString since = stamp.toString(Qt::ISODate);
254       conditions.append("Job.Starttime>'" + since + "'");
255    }
256    bool first = true;
257    foreach (QString condition, conditions) {
258       if (first) {
259          query += " WHERE " + condition;
260          first = false;
261       } else {
262          query += " AND " + condition;
263       }
264    }
265    /* Descending */
266    query += " ORDER BY Job.Starttime DESC, Job.JobId DESC";
267    /* If Limit check box for limit records returned is checked  */
268    if (controls->limitCheckBox->checkState() == Qt::Checked) {
269       QString limit;
270       limit.setNum(controls->limitSpinBox->value());
271       query += " LIMIT " + limit;
272    }
273
274    if (mainWin->m_sqlDebug) {
275       Pmsg1(000, "Query cmd : %s\n",query.toUtf8().data());
276    }
277    QString resultline;
278    QStringList results;
279    if (m_console->sql_cmd(query, results)) {
280
281       QString field;
282       QStringList fieldlist;
283    
284       int row = 0;
285       /* Iterate through the record returned from the query */
286       foreach (resultline, results) {
287          PlotJobData *plotJobData = new PlotJobData();
288          fieldlist = resultline.split("\t");
289          int column = 0;
290          QString statusCode("");
291          /* Iterate through fields in the record */
292          foreach (field, fieldlist) {
293             field = field.trimmed();  /* strip leading & trailing spaces */
294             if (column == 0) {
295                plotJobData->dt = QDateTime::fromString(field, mainWin->m_dtformat);
296             } else if (column == 1) {
297                plotJobData->files = field.toDouble();
298             } else if (column == 2) {
299                plotJobData->bytes = field.toDouble();
300             }
301             column++;
302             m_pjd.prepend(plotJobData);
303          }
304          row++;
305       }
306    } 
307    if ((controls->volumeComboBox->itemText(volumeIndex) != "Any") && (results.count() == 0)){
308       /* for context sensitive searches, let the user know if there were no
309        *        * results */
310       QMessageBox::warning(this, tr("Bat"),
311           tr("The Jobs query returned no results.\n"
312          "Press OK to continue?"), QMessageBox::Ok );
313    }
314 }
315
316 /*
317  * The user interface that used to be in the ui header.  I wanted to have a
318  * scroll area which is not in designer.
319  */
320 void JobPlot::setupUserInterface()
321 {
322    QSizePolicy sizePolicy(static_cast<QSizePolicy::Policy>(1), static_cast<QSizePolicy::Policy>(5));
323    sizePolicy.setHorizontalStretch(0);
324    sizePolicy.setVerticalStretch(0);
325    sizePolicy.setVerticalStretch(0);
326    sizePolicy.setVerticalPolicy(QSizePolicy::Ignored);
327    sizePolicy.setHorizontalPolicy(QSizePolicy::Ignored);
328    m_gridLayout = new QGridLayout(this);
329    m_gridLayout->setSpacing(6);
330    m_gridLayout->setMargin(9);
331    m_gridLayout->setObjectName(QString::fromUtf8("m_gridLayout"));
332    m_splitter = new QSplitter(this);
333    m_splitter->setObjectName(QString::fromUtf8("m_splitter"));
334    m_splitter->setOrientation(Qt::Horizontal);
335    m_jobPlot = new QwtPlot(m_splitter);
336    m_jobPlot->setObjectName(QString::fromUtf8("m_jobPlot"));
337    m_jobPlot->setSizePolicy(sizePolicy);
338    m_jobPlot->setMinimumSize(QSize(0, 0));
339    QScrollArea *area = new QScrollArea(m_splitter);
340    area->setObjectName(QString::fromUtf8("area"));
341    controls = new JobPlotControls();
342    area->setWidget(controls);
343    
344    m_splitter->addWidget(m_jobPlot);
345    m_splitter->addWidget(area);
346
347    m_gridLayout->addWidget(m_splitter, 0, 0, 1, 1);
348 }
349
350 /*
351  * Add the curves to the plot
352  */
353 void JobPlot::addCurve()
354 {
355    m_jobPlot->setTitle("Files and Bytes backed up");
356    m_jobPlot->insertLegend(new QwtLegend(), QwtPlot::RightLegend);
357
358    // Set axis titles
359    m_jobPlot->enableAxis(QwtPlot::yRight);
360    m_jobPlot->setAxisTitle(QwtPlot::yRight, "<-- Bytes Kb");
361    m_jobPlot->setAxisTitle(m_jobPlot->xBottom, "date of backup -->");
362    m_jobPlot->setAxisTitle(m_jobPlot->yLeft, "Number of Files -->");
363    m_jobPlot->setAxisScaleDraw(QwtPlot::xBottom, new DateTimeScaleDraw());
364
365    // Insert new curves
366    m_fileCurve = new QwtPlotCurve("Files");
367    m_fileCurve->setPen(QPen(Qt::red));
368    m_fileCurve->setCurveType(m_fileCurve->Yfx);
369    m_fileCurve->setYAxis(QwtPlot::yLeft);
370
371    m_byteCurve = new QwtPlotCurve("Bytes");
372    m_byteCurve->setPen(QPen(Qt::blue));
373    m_byteCurve->setCurveType(m_byteCurve->Yfx);
374    m_byteCurve->setYAxis(QwtPlot::yRight);
375    setPlotType(controls->plotTypeCombo->currentText());
376    setFileSymbolType(controls->fileSymbolTypeCombo->currentIndex());
377    setByteSymbolType(controls->byteSymbolTypeCombo->currentIndex());
378
379    m_fileCurve->attach(m_jobPlot);
380    m_byteCurve->attach(m_jobPlot);
381
382    // attach data
383    int size = m_pjd.count();
384    double tval[size];
385    double fval[size];
386    double bval[size];
387    int j = 0;
388    foreach (PlotJobData* plotJobData, m_pjd) {
389 //      printf("%.0f %.0f %s\n", plotJobData->bytes, plotJobData->files,
390 //              plotJobData->dt.toString(mainWin->m_dtformat).toUtf8().data());
391       fval[j] = plotJobData->files;
392       bval[j] = plotJobData->bytes / 1024;
393       tval[j] = plotJobData->dt.toTime_t();
394 //      printf("%i %.0f %.0f %.0f\n", j, tval[j], fval[j], bval[j]);
395       j++;
396    }
397    m_fileCurve->setData(tval,fval,size);
398    m_byteCurve->setData(tval,bval,size);
399
400    for (int year=2000; year<2010; year++) {
401       for (int month=1; month<=12; month++) {
402          QString monthBegin;
403          if (month > 9) {
404             QTextStream(&monthBegin) << year << "-" << month << "-01 00:00:00";
405          } else {
406             QTextStream(&monthBegin) << year << "-0" << month << "-01 00:00:00";
407          }
408          QDateTime mdt = QDateTime::fromString(monthBegin, mainWin->m_dtformat);
409          double monbeg = mdt.toTime_t();
410    
411          //  ...a vertical line at the first of each month
412          QwtPlotMarker *mX = new QwtPlotMarker();
413          mX->setLabel(mdt.toString("MMM-d"));
414          mX->setLabelAlignment(Qt::AlignRight|Qt::AlignTop);
415          mX->setLineStyle(QwtPlotMarker::VLine);
416          QPen pen(Qt::darkGray);
417          pen.setStyle(Qt::DashDotDotLine);
418          mX->setLinePen(pen);
419          mX->setXValue(monbeg);
420          mX->attach(m_jobPlot);
421       }
422    }
423 }
424
425 /*
426  * slot to respond to the plot type combo changing
427  */
428 void JobPlot::setPlotType(QString currentText)
429 {
430    QwtPlotCurve::CurveStyle style = QwtPlotCurve::NoCurve;
431    if (currentText == "Fitted") {
432       style = QwtPlotCurve::Lines;
433       m_fileCurve->setCurveAttribute(QwtPlotCurve::Fitted);
434       m_byteCurve->setCurveAttribute(QwtPlotCurve::Fitted);
435    } else if (currentText == "Sticks") {
436       style = QwtPlotCurve::Sticks;
437    } else if (currentText == "Lines") {
438       style = QwtPlotCurve::Lines;
439       m_fileCurve->setCurveAttribute(QwtPlotCurve::Fitted);
440       m_byteCurve->setCurveAttribute(QwtPlotCurve::Fitted);
441    } else if (currentText == "Steps") {
442       style = QwtPlotCurve::Steps;
443    } else if (currentText == "None") {
444       style = QwtPlotCurve::NoCurve;
445    }
446    m_fileCurve->setStyle(style);
447    m_byteCurve->setStyle(style);
448    m_jobPlot->replot();
449 }
450
451 /*
452  * slot to respond to the symbol type combo changing
453  */
454 void JobPlot::setFileSymbolType(int index)
455 {
456    setSymbolType(index, 0);
457 }
458
459 void JobPlot::setByteSymbolType(int index)
460 {
461    setSymbolType(index, 1);
462 }
463 void JobPlot::setSymbolType(int index, int type)
464 {
465    QwtSymbol sym;
466    sym.setPen(QColor(Qt::black));
467    sym.setSize(7);
468    if (index == 0) {
469       sym.setStyle(QwtSymbol::Ellipse);
470    } else if (index == 1) {
471       sym.setStyle(QwtSymbol::Rect);
472    } else if (index == 2) {
473       sym.setStyle(QwtSymbol::Diamond);
474    } else if (index == 3) {
475       sym.setStyle(QwtSymbol::Triangle);
476    } else if (index == 4) {
477       sym.setStyle(QwtSymbol::DTriangle);
478    } else if (index == 5) {
479       sym.setStyle(QwtSymbol::UTriangle);
480    } else if (index == 6) {
481       sym.setStyle(QwtSymbol::LTriangle);
482    } else if (index == 7) {
483       sym.setStyle(QwtSymbol::RTriangle);
484    } else if (index == 8) {
485       sym.setStyle(QwtSymbol::Cross);
486    } else if (index == 9) {
487       sym.setStyle(QwtSymbol::XCross);
488    } else if (index == 10) {
489       sym.setStyle(QwtSymbol::HLine);
490    } else if (index == 11) {
491       sym.setStyle(QwtSymbol::VLine);
492    } else if (index == 12) {
493       sym.setStyle(QwtSymbol::Star1);
494    } else if (index == 13) {
495       sym.setStyle(QwtSymbol::Star2);
496    } else if (index == 14) {
497       sym.setStyle(QwtSymbol::Hexagon);
498    }
499    if (type == 0) {
500       sym.setBrush(QColor(Qt::yellow));
501       m_fileCurve->setSymbol(sym);
502    }
503    if (type == 1) {
504       sym.setBrush(QColor(Qt::blue));
505       m_byteCurve->setSymbol(sym);
506    }
507    m_jobPlot->replot();
508 }
509
510 /*
511  * slot to respond to the file check box changing state
512  */
513 void JobPlot::fileCheckChanged(int newstate)
514 {
515    if (newstate == Qt::Unchecked) {
516       m_fileCurve->detach();
517       m_jobPlot->enableAxis(QwtPlot::yLeft, false);
518    } else {
519       m_fileCurve->attach(m_jobPlot);
520       m_jobPlot->enableAxis(QwtPlot::yLeft);
521    }
522    m_jobPlot->replot();
523 }
524
525 /*
526  * slot to respond to the byte check box changing state
527  */
528 void JobPlot::byteCheckChanged(int newstate)
529 {
530    if (newstate == Qt::Unchecked) {
531       m_byteCurve->detach();
532       m_jobPlot->enableAxis(QwtPlot::yRight, false);
533    } else {
534       m_byteCurve->attach(m_jobPlot);
535       m_jobPlot->enableAxis(QwtPlot::yRight);
536    }
537    m_jobPlot->replot();
538 }
539
540 /*
541  * Save user settings associated with this page
542  */
543 void JobPlot::writeSettings()
544 {
545    QSettings settings(m_console->m_dir->name(), "bat");
546    settings.beginGroup("JobPlot");
547    settings.setValue("m_splitterSizes", m_splitter->saveState());
548    settings.setValue("fileSymbolTypeCombo", controls->fileSymbolTypeCombo->currentText());
549    settings.setValue("byteSymbolTypeCombo", controls->byteSymbolTypeCombo->currentText());
550    settings.setValue("plotTypeCombo", controls->plotTypeCombo->currentText());
551    settings.endGroup();
552 }
553
554 /* 
555  * Read settings values for Controls
556  */
557 void JobPlot::readControlSettings()
558 {
559    QSettings settings(m_console->m_dir->name(), "bat");
560    settings.beginGroup("JobPlot");
561    int fileSymbolTypeIndex = controls->fileSymbolTypeCombo->findText(settings.value("fileSymbolTypeCombo").toString(), Qt::MatchExactly);
562    if (fileSymbolTypeIndex == -1) fileSymbolTypeIndex = 2;
563       controls->fileSymbolTypeCombo->setCurrentIndex(fileSymbolTypeIndex);
564    int byteSymbolTypeIndex = controls->byteSymbolTypeCombo->findText(settings.value("byteSymbolTypeCombo").toString(), Qt::MatchExactly);
565    if (byteSymbolTypeIndex == -1) byteSymbolTypeIndex = 3;
566       controls->byteSymbolTypeCombo->setCurrentIndex(byteSymbolTypeIndex);
567    int plotTypeIndex = controls->plotTypeCombo->findText(settings.value("plotTypeCombo").toString(), Qt::MatchExactly);
568    if (plotTypeIndex == -1) plotTypeIndex = 2;
569       controls->plotTypeCombo->setCurrentIndex(plotTypeIndex);
570    settings.endGroup();
571 }
572
573 /*
574  * Read and restore user settings associated with this page
575  */
576 void JobPlot::readSplitterSettings()
577 {
578    QSettings settings(m_console->m_dir->name(), "bat");
579    settings.beginGroup("JobPlot");
580    m_splitter->restoreState(settings.value("m_splitterSizes").toByteArray());
581    settings.endGroup();
582 }