LP-56 - Better txpid option namings, fix tabs-spaces, tooltips. headers, variable...
[librepilot.git] / ground / openpilotgcs / src / plugins / scope / scopegadgetoptionspage.cpp
blobfe080c984ebe6cd80bdd2ec33d5846320c13358b
1 /**
2 ******************************************************************************
4 * @file scopegadgetoptionspage.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
6 * @addtogroup GCSPlugins GCS Plugins
7 * @{
8 * @addtogroup ScopePlugin Scope Gadget Plugin
9 * @{
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
21 * for more details.
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"
35 #include <qpalette.h>
38 ScopeGadgetOptionsPage::ScopeGadgetOptionsPage(ScopeGadgetConfiguration *config, QObject *parent) :
39 IOptionsPage(parent),
40 m_config(config)
42 // nothing to do here...
45 // creates options page widget (uses the UI file)
46 QWidget *ScopeGadgetOptionsPage::createPage(QWidget *parent)
48 Q_UNUSED(parent);
50 options_page = new Ui::ScopeGadgetOptionsPage();
51 // main widget
52 QWidget *optionsPageWidget = new QWidget;
53 // main layout
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))) {
163 evt->ignore();
164 return true;
166 return ScopeGadgetOptionsPage::eventFilter(obj, evt);
169 void ScopeGadgetOptionsPage::on_mathFunctionComboBox_currentIndexChanged(int currentIndex)
171 if (currentIndex > 0) {
172 options_page->spnMeanSamples->setEnabled(true);
173 } else {
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();
196 if (listItem == 0) {
197 return;
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);
216 if (!parseOK) {
217 mean = 1;
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));
244 if (obj == NULL) {
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) {
250 continue;
253 if (field->getElementNames().count() > 1) {
254 foreach(QString elemName, field->getElementNames()) {
255 options_page->cmbUAVField->addItem(field->getName() + "-" + elemName);
257 } else {
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);
287 if (!parseOK) {
288 newPlotCurveConfigs->yScalePower = 0;
291 QVariant varColor = listItem->data(Qt::UserRole + 3);
292 int rgb = varColor.toInt(&parseOK);
293 if (!parseOK) {
294 newPlotCurveConfigs->color = QColor(Qt::black).rgb();
295 } else {
296 newPlotCurveConfigs->color = (QRgb)rgb;
299 newPlotCurveConfigs->yMeanSamples = listItem->data(Qt::UserRole + 4).toInt(&parseOK);
300 if (!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);
328 if (!parseOK) {
329 scale = 0;
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);
345 } else {
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)));
429 if (!obj) {
430 qDebug() << "Object " << uavObject << " is missing";
431 continue;
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.");
436 return;
440 options_page->lblWarnings->setText("");