2 ******************************************************************************
4 * @file scopegadgetoptionspage.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
6 * @addtogroup GCSPlugins GCS Plugins
8 * @addtogroup ScopePlugin Scope Gadget Plugin
10 * @brief The scope Gadget, graphically plots the states of UAVObjects
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "scopegadgetoptionspage.h"
30 #include "extensionsystem/pluginmanager.h"
31 #include "uavobjectmanager.h"
32 #include "uavdataobject.h"
38 ScopeGadgetOptionsPage::ScopeGadgetOptionsPage(ScopeGadgetConfiguration
*config
, QObject
*parent
) :
42 // nothing to do here...
45 // creates options page widget (uses the UI file)
46 QWidget
*ScopeGadgetOptionsPage::createPage(QWidget
*parent
)
50 options_page
= new Ui::ScopeGadgetOptionsPage();
52 QWidget
*optionsPageWidget
= new QWidget
;
54 options_page
->setupUi(optionsPageWidget
);
56 options_page
->cmbPlotType
->addItem("Sequential Plot", "");
57 options_page
->cmbPlotType
->addItem("Chronological Plot", "");
59 // Fills the combo boxes for the UAVObjects
60 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
61 UAVObjectManager
*objManager
= pm
->getObject
<UAVObjectManager
>();
62 QList
< QList
<UAVDataObject
*> > objList
= objManager
->getDataObjects();
63 foreach(QList
<UAVDataObject
*> list
, objList
) {
64 foreach(UAVDataObject
* obj
, list
) {
65 options_page
->cmbUAVObjects
->addItem(obj
->getName());
69 // Connect signals to slots cmbUAVObjects.currentIndexChanged
70 connect(options_page
->cmbUAVObjects
, SIGNAL(currentIndexChanged(QString
)), this, SLOT(on_cmbUAVObjects_currentIndexChanged(QString
)));
72 options_page
->mathFunctionComboBox
->addItem("None");
73 options_page
->mathFunctionComboBox
->addItem("Boxcar average");
74 options_page
->mathFunctionComboBox
->addItem("Standard deviation");
76 if (options_page
->cmbUAVObjects
->currentIndex() >= 0) {
77 on_cmbUAVObjects_currentIndexChanged(options_page
->cmbUAVObjects
->currentText());
80 options_page
->cmbScale
->addItem("10^-9", -9);
81 options_page
->cmbScale
->addItem("10^-6", -6);
82 options_page
->cmbScale
->addItem("10^-5", -5);
83 options_page
->cmbScale
->addItem("10^-4", -4);
84 options_page
->cmbScale
->addItem("10^-3", -3);
85 options_page
->cmbScale
->addItem("10^-2", -2);
86 options_page
->cmbScale
->addItem("10^-1", -1);
87 options_page
->cmbScale
->addItem("1", 0);
88 options_page
->cmbScale
->addItem("10^1", 1);
89 options_page
->cmbScale
->addItem("10^2", 2);
90 options_page
->cmbScale
->addItem("10^3", 3);
91 options_page
->cmbScale
->addItem("10^4", 4);
92 options_page
->cmbScale
->addItem("10^5", 5);
93 options_page
->cmbScale
->addItem("10^6", 6);
94 options_page
->cmbScale
->addItem("10^9", 9);
95 options_page
->cmbScale
->addItem("10^12", 12);
96 options_page
->cmbScale
->setCurrentIndex(7);
98 // Set widget values from settings
99 options_page
->cmbPlotType
->setCurrentIndex(m_config
->plotType());
100 options_page
->mathFunctionComboBox
->setCurrentIndex(m_config
->mathFunctionType());
101 options_page
->spnDataSize
->setValue(m_config
->dataSize());
102 options_page
->spnRefreshInterval
->setValue(m_config
->refreshInterval());
104 // add the configured curves
105 foreach(PlotCurveConfiguration
* plotData
, m_config
->plotCurveConfigs()) {
106 QString uavObject
= plotData
->uavObject
;
107 QString uavField
= plotData
->uavField
;
108 int scale
= plotData
->yScalePower
;
109 int mean
= plotData
->yMeanSamples
;
110 QString mathFunction
= plotData
->mathFunction
;
111 QVariant varColor
= plotData
->color
;
112 bool antialiased
= plotData
->drawAntialiased
;
114 addPlotCurveConfig(uavObject
, uavField
, scale
, mean
, mathFunction
, varColor
, antialiased
);
117 if (m_config
->plotCurveConfigs().count() > 0) {
118 options_page
->lstCurves
->setCurrentRow(0, QItemSelectionModel::ClearAndSelect
);
121 connect(options_page
->btnAddCurve
, SIGNAL(clicked()), this, SLOT(on_btnAddCurve_clicked()));
122 connect(options_page
->btnRemoveCurve
, SIGNAL(clicked()), this, SLOT(on_btnRemoveCurve_clicked()));
123 connect(options_page
->lstCurves
, SIGNAL(currentRowChanged(int)), this, SLOT(on_lstCurves_currentRowChanged(int)));
124 connect(options_page
->btnColor
, SIGNAL(clicked()), this, SLOT(on_btnColor_clicked()));
125 connect(options_page
->mathFunctionComboBox
, SIGNAL(currentIndexChanged(int)), this, SLOT(on_mathFunctionComboBox_currentIndexChanged(int)));
126 connect(options_page
->spnRefreshInterval
, SIGNAL(valueChanged(int)), this, SLOT(on_spnRefreshInterval_valueChanged(int)));
128 setYAxisWidgetFromPlotCurve();
130 // logging path setup
131 options_page
->LoggingPath
->setExpectedKind(Utils::PathChooser::Directory
);
132 options_page
->LoggingPath
->setPromptDialogTitle(tr("Choose Logging Directory"));
133 options_page
->LoggingPath
->setPath(m_config
->getLoggingPath());
134 options_page
->LoggingConnect
->setChecked(m_config
->getLoggingNewFileOnConnect());
135 options_page
->LoggingEnable
->setChecked(m_config
->getLoggingEnabled());
136 connect(options_page
->LoggingEnable
, SIGNAL(clicked()), this, SLOT(on_loggingEnable_clicked()));
137 on_loggingEnable_clicked();
139 // Disable mouse wheel events
140 foreach(QSpinBox
* sp
, findChildren
<QSpinBox
*>()) {
141 sp
->installEventFilter(this);
143 foreach(QDoubleSpinBox
* sp
, findChildren
<QDoubleSpinBox
*>()) {
144 sp
->installEventFilter(this);
146 foreach(QSlider
* sp
, findChildren
<QSlider
*>()) {
147 sp
->installEventFilter(this);
149 foreach(QComboBox
* sp
, findChildren
<QComboBox
*>()) {
150 sp
->installEventFilter(this);
153 return optionsPageWidget
;
156 bool ScopeGadgetOptionsPage::eventFilter(QObject
*obj
, QEvent
*evt
)
158 // Filter all wheel events, and ignore them
159 if (evt
->type() == QEvent::Wheel
&&
160 (qobject_cast
<QAbstractSpinBox
*>(obj
) ||
161 qobject_cast
<QComboBox
*>(obj
) ||
162 qobject_cast
<QAbstractSlider
*>(obj
))) {
166 return ScopeGadgetOptionsPage::eventFilter(obj
, evt
);
169 void ScopeGadgetOptionsPage::on_mathFunctionComboBox_currentIndexChanged(int currentIndex
)
171 if (currentIndex
> 0) {
172 options_page
->spnMeanSamples
->setEnabled(true);
174 options_page
->spnMeanSamples
->setEnabled(false);
178 void ScopeGadgetOptionsPage::on_btnColor_clicked()
180 QColor color
= QColorDialog::getColor(QColor(options_page
->btnColor
->text()));
182 if (color
.isValid()) {
183 setButtonColor(color
);
188 \brief Populate the widgets that containts the configs for the Y-Axis from
189 the selected plot curve
191 void ScopeGadgetOptionsPage::setYAxisWidgetFromPlotCurve()
193 bool parseOK
= false;
194 QListWidgetItem
*listItem
= options_page
->lstCurves
->currentItem();
200 // WHAT IS UserRole DOING?
201 int currentIndex
= options_page
->cmbUAVObjects
->findText(listItem
->data(Qt::UserRole
+ 0).toString());
202 options_page
->cmbUAVObjects
->setCurrentIndex(currentIndex
);
204 currentIndex
= options_page
->cmbUAVField
->findText(listItem
->data(Qt::UserRole
+ 1).toString());
205 options_page
->cmbUAVField
->setCurrentIndex(currentIndex
);
207 currentIndex
= options_page
->cmbScale
->findData(listItem
->data(Qt::UserRole
+ 2), Qt::UserRole
, Qt::MatchExactly
);
208 options_page
->cmbScale
->setCurrentIndex(currentIndex
);
210 QVariant varColor
= listItem
->data(Qt::UserRole
+ 3);
211 int rgb
= varColor
.toInt(&parseOK
);
213 setButtonColor(QColor((QRgb
)rgb
));
215 int mean
= listItem
->data(Qt::UserRole
+ 4).toInt(&parseOK
);
219 options_page
->spnMeanSamples
->setValue(mean
);
221 currentIndex
= options_page
->mathFunctionComboBox
->findText(listItem
->data(Qt::UserRole
+ 5).toString());
222 options_page
->mathFunctionComboBox
->setCurrentIndex(currentIndex
);
223 options_page
->drawAntialiasedCheckBox
->setChecked(listItem
->data(Qt::UserRole
+ 6).toBool());
226 void ScopeGadgetOptionsPage::setButtonColor(const QColor
&color
)
228 options_page
->btnColor
->setAutoFillBackground(true);
229 options_page
->btnColor
->setText(color
.name());
230 options_page
->btnColor
->setPalette(QPalette(color
));
234 \brief When a new UAVObject is selected, populate the UAVObject field combo box with the correct values.
236 void ScopeGadgetOptionsPage::on_cmbUAVObjects_currentIndexChanged(QString val
)
238 options_page
->cmbUAVField
->clear();
240 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
241 UAVObjectManager
*objManager
= pm
->getObject
<UAVObjectManager
>();
242 UAVDataObject
*obj
= dynamic_cast<UAVDataObject
*>(objManager
->getObject(val
));
245 return; // Rare case: the config contained a UAVObject name which does not exist anymore.
247 QList
<UAVObjectField
*> fieldList
= obj
->getFields();
248 foreach(UAVObjectField
* field
, fieldList
) {
249 if (field
->getType() == UAVObjectField::STRING
) {
253 if (field
->getElementNames().count() > 1) {
254 foreach(QString elemName
, field
->getElementNames()) {
255 options_page
->cmbUAVField
->addItem(field
->getName() + "-" + elemName
);
258 options_page
->cmbUAVField
->addItem(field
->getName());
264 * Called when the user presses apply or OK.
266 * Saves the current values
269 void ScopeGadgetOptionsPage::apply()
271 bool parseOK
= false;
273 // Apply configuration changes
274 m_config
->setPlotType(options_page
->cmbPlotType
->currentIndex());
275 m_config
->setMathFunctionType(options_page
->mathFunctionComboBox
->currentIndex());
276 m_config
->setDataSize(options_page
->spnDataSize
->value());
277 m_config
->setRefreashInterval(options_page
->spnRefreshInterval
->value());
279 QList
<PlotCurveConfiguration
*> plotCurveConfigs
;
280 for (int iIndex
= 0; iIndex
< options_page
->lstCurves
->count(); iIndex
++) {
281 QListWidgetItem
*listItem
= options_page
->lstCurves
->item(iIndex
);
283 PlotCurveConfiguration
*newPlotCurveConfigs
= new PlotCurveConfiguration();
284 newPlotCurveConfigs
->uavObject
= listItem
->data(Qt::UserRole
+ 0).toString();
285 newPlotCurveConfigs
->uavField
= listItem
->data(Qt::UserRole
+ 1).toString();
286 newPlotCurveConfigs
->yScalePower
= listItem
->data(Qt::UserRole
+ 2).toInt(&parseOK
);
288 newPlotCurveConfigs
->yScalePower
= 0;
291 QVariant varColor
= listItem
->data(Qt::UserRole
+ 3);
292 int rgb
= varColor
.toInt(&parseOK
);
294 newPlotCurveConfigs
->color
= QColor(Qt::black
).rgb();
296 newPlotCurveConfigs
->color
= (QRgb
)rgb
;
299 newPlotCurveConfigs
->yMeanSamples
= listItem
->data(Qt::UserRole
+ 4).toInt(&parseOK
);
301 newPlotCurveConfigs
->yMeanSamples
= 1;
304 newPlotCurveConfigs
->mathFunction
= listItem
->data(Qt::UserRole
+ 5).toString();
305 newPlotCurveConfigs
->drawAntialiased
= listItem
->data(Qt::UserRole
+ 6).toBool();
307 plotCurveConfigs
.append(newPlotCurveConfigs
);
310 m_config
->replacePlotCurveConfig(plotCurveConfigs
);
312 // save the logging config
313 m_config
->setLoggingPath(options_page
->LoggingPath
->path());
314 m_config
->setLoggingNewFileOnConnect(options_page
->LoggingConnect
->isChecked());
315 m_config
->setLoggingEnabled(options_page
->LoggingEnable
->isChecked());
319 \brief Add a new curve to the plot.
321 void ScopeGadgetOptionsPage::on_btnAddCurve_clicked()
323 bool parseOK
= false;
324 QString uavObject
= options_page
->cmbUAVObjects
->currentText();
325 QString uavField
= options_page
->cmbUAVField
->currentText();
326 int scale
= options_page
->cmbScale
->itemData(options_page
->cmbScale
->currentIndex()).toInt(&parseOK
);
332 int mean
= options_page
->spnMeanSamples
->value();
333 QString mathFunction
= options_page
->mathFunctionComboBox
->currentText();
336 QVariant varColor
= (int)QColor(options_page
->btnColor
->text()).rgb();
338 bool antialiased
= options_page
->drawAntialiasedCheckBox
->isChecked();
339 // Find an existing plot curve config based on the uavobject and uav field. If it
340 // exists, update it, else add a new one.
341 if (options_page
->lstCurves
->count() &&
342 options_page
->lstCurves
->currentItem()->text() == uavObject
+ "." + uavField
) {
343 QListWidgetItem
*listWidgetItem
= options_page
->lstCurves
->currentItem();
344 setCurvePlotProperties(listWidgetItem
, uavObject
, uavField
, scale
, mean
, mathFunction
, varColor
, antialiased
);
346 addPlotCurveConfig(uavObject
, uavField
, scale
, mean
, mathFunction
, varColor
, antialiased
);
348 options_page
->lstCurves
->setCurrentRow(options_page
->lstCurves
->count() - 1);
352 void ScopeGadgetOptionsPage::addPlotCurveConfig(QString uavObject
, QString uavField
, int scale
, int mean
, QString mathFunction
, QVariant varColor
, bool antialias
)
354 // Add a new curve config to the list
355 QString listItemDisplayText
= uavObject
+ "." + uavField
;
357 options_page
->lstCurves
->addItem(listItemDisplayText
);
358 QListWidgetItem
*listWidgetItem
= options_page
->lstCurves
->item(options_page
->lstCurves
->count() - 1);
360 setCurvePlotProperties(listWidgetItem
, uavObject
, uavField
, scale
, mean
, mathFunction
, varColor
, antialias
);
363 void ScopeGadgetOptionsPage::setCurvePlotProperties(QListWidgetItem
*listWidgetItem
, QString uavObject
, QString uavField
, int scale
,
364 int mean
, QString mathFunction
, QVariant varColor
, bool antialias
)
366 bool parseOK
= false;
368 // Set the properties of the newly added list item
369 QRgb rgbColor
= (QRgb
)varColor
.toInt(&parseOK
);
370 QColor color
= QColor(rgbColor
);
372 listWidgetItem
->setTextColor(color
);
374 // Store some additional data for the plot curve on the list item
375 listWidgetItem
->setData(Qt::UserRole
+ 0, QVariant(uavObject
));
376 listWidgetItem
->setData(Qt::UserRole
+ 1, QVariant(uavField
));
377 listWidgetItem
->setData(Qt::UserRole
+ 2, QVariant(scale
));
378 listWidgetItem
->setData(Qt::UserRole
+ 3, varColor
);
379 listWidgetItem
->setData(Qt::UserRole
+ 4, QVariant(mean
));
380 listWidgetItem
->setData(Qt::UserRole
+ 5, QVariant(mathFunction
));
381 listWidgetItem
->setData(Qt::UserRole
+ 6, QVariant(antialias
));
385 Remove a curve config from the plot.
387 void ScopeGadgetOptionsPage::on_btnRemoveCurve_clicked()
389 options_page
->lstCurves
->takeItem(options_page
->lstCurves
->currentIndex().row());
392 void ScopeGadgetOptionsPage::finish()
396 When a different plot curve config is selected, populate its values into the widgets.
398 void ScopeGadgetOptionsPage::on_lstCurves_currentRowChanged(int currentRow
)
400 Q_UNUSED(currentRow
);
401 setYAxisWidgetFromPlotCurve();
404 void ScopeGadgetOptionsPage::on_loggingEnable_clicked()
406 bool en
= options_page
->LoggingEnable
->isChecked();
408 options_page
->LoggingPath
->setEnabled(en
);
409 options_page
->LoggingConnect
->setEnabled(en
);
410 options_page
->LoggingLabel
->setEnabled(en
);
413 void ScopeGadgetOptionsPage::on_spnRefreshInterval_valueChanged(int)
415 validateRefreshInterval();
418 void ScopeGadgetOptionsPage::validateRefreshInterval()
420 ExtensionSystem::PluginManager
*pm
= ExtensionSystem::PluginManager::instance();
421 UAVObjectManager
*objManager
= pm
->getObject
<UAVObjectManager
>();
423 for (int iIndex
= 0; iIndex
< options_page
->lstCurves
->count(); iIndex
++) {
424 QListWidgetItem
*listItem
= options_page
->lstCurves
->item(iIndex
);
426 QString uavObject
= listItem
->data(Qt::UserRole
+ 0).toString();
428 UAVDataObject
*obj
= dynamic_cast<UAVDataObject
*>(objManager
->getObject((uavObject
)));
430 qDebug() << "Object " << uavObject
<< " is missing";
434 if (options_page
->spnRefreshInterval
->value() < obj
->getMetadata().flightTelemetryUpdatePeriod
) {
435 options_page
->lblWarnings
->setText("The refresh interval is faster than some or all telemetry objects.");
440 options_page
->lblWarnings
->setText("");