mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-09 20:46:07 +01:00
826d010119
Fixed a bug that prohibited fields not currently shown in gui ( in an inactive pid bank ) to update from UAVO updates.
1245 lines
45 KiB
C++
1245 lines
45 KiB
C++
/**
|
|
******************************************************************************
|
|
*
|
|
* @file configtaskwidget.cpp
|
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
* @addtogroup GCSPlugins GCS Plugins
|
|
* @{
|
|
* @addtogroup UAVObjectWidgetUtils Plugin
|
|
* @{
|
|
* @brief Utility plugin for UAVObject to Widget relation management
|
|
*****************************************************************************/
|
|
/*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
#include "configtaskwidget.h"
|
|
|
|
#include <uavtalk/telemetrymanager.h>
|
|
#include "uavsettingsimportexport/uavsettingsimportexportfactory.h"
|
|
|
|
#include <QWidget>
|
|
#include <QLineEdit>
|
|
#include <QToolButton>
|
|
|
|
ConfigTaskWidget::ConfigTaskWidget(QWidget *parent) : QWidget(parent), m_currentBoardId(-1), m_isConnected(false), m_isWidgetUpdatesAllowed(true),
|
|
m_saveButton(NULL), m_isDirty(false), m_outOfLimitsStyle("background-color: rgb(255, 0, 0);"), m_realtimeUpdateTimer(NULL)
|
|
{
|
|
m_pluginManager = ExtensionSystem::PluginManager::instance();
|
|
TelemetryManager *telMngr = m_pluginManager->getObject<TelemetryManager>();
|
|
m_objectUtilManager = m_pluginManager->getObject<UAVObjectUtilManager>();
|
|
connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect()), Qt::UniqueConnection);
|
|
connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()), Qt::UniqueConnection);
|
|
connect(telMngr, SIGNAL(connected()), this, SIGNAL(autoPilotConnected()), Qt::UniqueConnection);
|
|
connect(telMngr, SIGNAL(disconnected()), this, SIGNAL(autoPilotDisconnected()), Qt::UniqueConnection);
|
|
UAVSettingsImportExportFactory *importexportplugin = m_pluginManager->getObject<UAVSettingsImportExportFactory>();
|
|
connect(importexportplugin, SIGNAL(importAboutToBegin()), this, SLOT(invalidateObjects()));
|
|
}
|
|
|
|
void ConfigTaskWidget::addWidget(QWidget *widget)
|
|
{
|
|
addWidgetBinding("", "", widget);
|
|
}
|
|
|
|
void ConfigTaskWidget::addUAVObject(QString objectName, QList<int> *reloadGroups)
|
|
{
|
|
addWidgetBinding(objectName, "", NULL, 0, 1, false, reloadGroups);
|
|
}
|
|
|
|
void ConfigTaskWidget::addUAVObject(UAVObject *objectName, QList<int> *reloadGroups)
|
|
{
|
|
addUAVObject(objectName ? objectName->getName() : QString(), reloadGroups);
|
|
}
|
|
|
|
int ConfigTaskWidget::fieldIndexFromElementName(QString objectName, QString fieldName, QString elementName)
|
|
{
|
|
if (elementName.isEmpty() || objectName.isEmpty()) {
|
|
return 0;
|
|
}
|
|
|
|
QString singleObjectName = mapObjectName(objectName).split(",").at(0);
|
|
UAVObject *object = getObject(singleObjectName);
|
|
Q_ASSERT(object);
|
|
|
|
UAVObjectField *field = object->getField(fieldName);
|
|
Q_ASSERT(field);
|
|
|
|
return field->getElementNames().indexOf(elementName);
|
|
}
|
|
|
|
void ConfigTaskWidget::addWidgetBinding(QString objectName, QString fieldName, QWidget *widget, QString elementName)
|
|
{
|
|
addWidgetBinding(objectName, fieldName, widget, fieldIndexFromElementName(objectName, fieldName, elementName));
|
|
}
|
|
|
|
void ConfigTaskWidget::addWidgetBinding(UAVObject *object, UAVObjectField *field, QWidget *widget, QString elementName)
|
|
{
|
|
addWidgetBinding(object ? object->getName() : QString(), field ? field->getName() : QString(), widget, elementName);
|
|
}
|
|
|
|
void ConfigTaskWidget::addWidgetBinding(QString objectName, QString fieldName, QWidget *widget, QString elementName, double scale,
|
|
bool isLimited, QList<int> *reloadGroupIDs, quint32 instID)
|
|
{
|
|
addWidgetBinding(objectName, fieldName, widget, fieldIndexFromElementName(objectName, fieldName, elementName),
|
|
scale, isLimited, reloadGroupIDs, instID);
|
|
}
|
|
|
|
void ConfigTaskWidget::addWidgetBinding(UAVObject *object, UAVObjectField *field, QWidget *widget, QString elementName, double scale,
|
|
bool isLimited, QList<int> *reloadGroupIDs, quint32 instID)
|
|
{
|
|
addWidgetBinding(object ? object->getName() : QString(), field ? field->getName() : QString(), widget, elementName, scale,
|
|
isLimited, reloadGroupIDs, instID);
|
|
}
|
|
|
|
void ConfigTaskWidget::addWidgetBinding(UAVObject *object, UAVObjectField *field, QWidget *widget, int index, double scale,
|
|
bool isLimited, QList<int> *reloadGroupIDs, quint32 instID)
|
|
{
|
|
addWidgetBinding(object ? object->getName() : QString(), field ? field->getName() : QString(), widget, index, scale,
|
|
isLimited, reloadGroupIDs, instID);
|
|
}
|
|
|
|
void ConfigTaskWidget::addWidgetBinding(QString objectName, QString fieldName, QWidget *widget, int index, double scale,
|
|
bool isLimited, QList<int> *reloadGroupIDs, quint32 instID)
|
|
{
|
|
QString mappedObjectName = mapObjectName(objectName);
|
|
|
|
// If object name is comma separated list of objects, call one time per objectName
|
|
foreach(QString singleObjectName, mappedObjectName.split(",")) {
|
|
doAddWidgetBinding(singleObjectName, fieldName, widget, index, scale, isLimited, reloadGroupIDs, instID);
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::doAddWidgetBinding(QString objectName, QString fieldName, QWidget *widget, int index, double scale,
|
|
bool isLimited, QList<int> *reloadGroupIDs, quint32 instID)
|
|
{
|
|
if (addShadowWidgetBinding(objectName, fieldName, widget, index, scale, isLimited, reloadGroupIDs, instID)) {
|
|
return;
|
|
}
|
|
|
|
UAVObject *object = NULL;
|
|
UAVObjectField *field = NULL;
|
|
if (!objectName.isEmpty()) {
|
|
object = getObject(QString(objectName), instID);
|
|
Q_ASSERT(object);
|
|
m_updatedObjects.insert(object, true);
|
|
connect(object, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(objectUpdated(UAVObject *)));
|
|
connect(object, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshWidgetsValues(UAVObject *)), Qt::UniqueConnection);
|
|
}
|
|
|
|
if (!fieldName.isEmpty() && object) {
|
|
field = object->getField(QString(fieldName));
|
|
Q_ASSERT(field);
|
|
}
|
|
|
|
WidgetBinding *binding = new WidgetBinding(widget, object, field, index, scale, isLimited);
|
|
// Only the first binding per widget can be enabled.
|
|
binding->setIsEnabled(m_widgetBindingsPerWidget.count(widget) == 0);
|
|
m_widgetBindingsPerWidget.insert(widget, binding);
|
|
|
|
if (object) {
|
|
m_widgetBindingsPerObject.insert(object, binding);
|
|
if (m_saveButton) {
|
|
m_saveButton->addObject((UAVDataObject *)object);
|
|
}
|
|
}
|
|
|
|
if (!widget) {
|
|
if (reloadGroupIDs && object) {
|
|
foreach(int groupId, *reloadGroupIDs) {
|
|
m_reloadGroups.insert(groupId, binding);
|
|
}
|
|
}
|
|
} else {
|
|
connectWidgetUpdatesToSlot(widget, SLOT(widgetsContentsChanged()));
|
|
if (reloadGroupIDs) {
|
|
addWidgetToReloadGroups(widget, reloadGroupIDs);
|
|
}
|
|
if (binding->isEnabled()) {
|
|
loadWidgetLimits(widget, field, index, isLimited, scale);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::setWidgetBindingObjectEnabled(QString objectName, bool enabled)
|
|
{
|
|
UAVObject *object = getObject(objectName);
|
|
|
|
Q_ASSERT(object);
|
|
|
|
bool dirtyBack = isDirty();
|
|
|
|
foreach(WidgetBinding * binding, m_widgetBindingsPerObject.values(object)) {
|
|
binding->setIsEnabled(enabled);
|
|
if (enabled) {
|
|
if (binding->value().isValid() && !binding->value().isNull()) {
|
|
setWidgetFromVariant(binding->widget(), binding->value(), binding);
|
|
} else {
|
|
setWidgetFromField(binding->widget(), binding->field(), binding);
|
|
}
|
|
}
|
|
}
|
|
setDirty(dirtyBack);
|
|
}
|
|
|
|
ConfigTaskWidget::~ConfigTaskWidget()
|
|
{
|
|
if (m_saveButton) {
|
|
delete m_saveButton;
|
|
}
|
|
QSet<WidgetBinding *> deleteSet = m_widgetBindingsPerWidget.values().toSet();
|
|
foreach(WidgetBinding * binding, deleteSet) {
|
|
if (binding) {
|
|
delete binding;
|
|
}
|
|
}
|
|
if (m_realtimeUpdateTimer) {
|
|
delete m_realtimeUpdateTimer;
|
|
m_realtimeUpdateTimer = NULL;
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::saveObjectToSD(UAVObject *obj)
|
|
{
|
|
// saveObjectToSD is now handled by the UAVUtils plugin in one
|
|
// central place (and one central queue)
|
|
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
|
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
|
|
|
|
utilMngr->saveObjectToSD(obj);
|
|
}
|
|
|
|
UAVObjectManager *ConfigTaskWidget::getObjectManager()
|
|
{
|
|
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
|
UAVObjectManager *objMngr = pm->getObject<UAVObjectManager>();
|
|
|
|
Q_ASSERT(objMngr);
|
|
return objMngr;
|
|
}
|
|
|
|
|
|
void ConfigTaskWidget::onAutopilotDisconnect()
|
|
{
|
|
m_isConnected = false;
|
|
|
|
// Reset board ID and clear bound combo box lists to force repopulation
|
|
// when we get another connected signal. This means that we get the
|
|
// correct values in combo boxes bound to fields with limits applied.
|
|
m_currentBoardId = -1;
|
|
|
|
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
|
|
QComboBox *cb;
|
|
|
|
if (binding->widget() && (cb = qobject_cast<QComboBox *>(binding->widget()))) {
|
|
cb->clear();
|
|
}
|
|
}
|
|
|
|
enableControls(false);
|
|
invalidateObjects();
|
|
}
|
|
|
|
// dynamic widgets don't recieve the connected signal. This should be called instead.
|
|
void ConfigTaskWidget::forceConnectedState()
|
|
{
|
|
if (m_objectUtilManager) {
|
|
m_currentBoardId = m_objectUtilManager->getBoardModel();
|
|
}
|
|
m_isConnected = true;
|
|
setDirty(false);
|
|
}
|
|
|
|
void ConfigTaskWidget::onAutopilotConnect()
|
|
{
|
|
if (m_objectUtilManager) {
|
|
m_currentBoardId = m_objectUtilManager->getBoardModel();
|
|
}
|
|
invalidateObjects();
|
|
m_isConnected = true;
|
|
setDirty(false);
|
|
enableControls(true);
|
|
refreshWidgetsValues();
|
|
}
|
|
|
|
void ConfigTaskWidget::populateWidgets()
|
|
{
|
|
bool dirtyBack = isDirty();
|
|
emit populateWidgetsRequested();
|
|
|
|
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
|
|
if (binding->isEnabled() && binding->object() != NULL && binding->field() != NULL && binding->widget() != NULL) {
|
|
setWidgetFromField(binding->widget(), binding->field(), binding);
|
|
}
|
|
}
|
|
setDirty(dirtyBack);
|
|
}
|
|
|
|
void ConfigTaskWidget::refreshWidgetsValues(UAVObject *obj)
|
|
{
|
|
if (!m_isWidgetUpdatesAllowed) {
|
|
return;
|
|
}
|
|
|
|
bool dirtyBack = isDirty();
|
|
emit refreshWidgetsValuesRequested();
|
|
QList<WidgetBinding *> bindings = obj == NULL ? m_widgetBindingsPerObject.values() : m_widgetBindingsPerObject.values(obj);
|
|
foreach(WidgetBinding * binding, bindings) {
|
|
if (binding->field() != NULL && binding->widget() != NULL) {
|
|
if (binding->isEnabled()) {
|
|
setWidgetFromField(binding->widget(), binding->field(), binding);
|
|
} else {
|
|
binding->updateValueFromObjectField();
|
|
}
|
|
}
|
|
}
|
|
setDirty(dirtyBack);
|
|
}
|
|
|
|
void ConfigTaskWidget::updateObjectsFromWidgets()
|
|
{
|
|
emit updateObjectsFromWidgetsRequested();
|
|
|
|
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
|
|
if (binding->object() != NULL && binding->field() != NULL) {
|
|
binding->updateObjectFieldFromValue();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::helpButtonPressed()
|
|
{
|
|
QString url = m_helpButtons.value((QPushButton *)sender(), QString());
|
|
|
|
if (!url.isEmpty()) {
|
|
QDesktopServices::openUrl(QUrl(url, QUrl::StrictMode));
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::addApplySaveButtons(QPushButton *update, QPushButton *save)
|
|
{
|
|
if (!m_saveButton) {
|
|
m_saveButton = new SmartSaveButton(this);
|
|
connect(m_saveButton, SIGNAL(preProcessOperations()), this, SLOT(updateObjectsFromWidgets()));
|
|
connect(m_saveButton, SIGNAL(saveSuccessfull()), this, SLOT(clearDirty()));
|
|
connect(m_saveButton, SIGNAL(beginOp()), this, SLOT(disableObjectUpdates()));
|
|
connect(m_saveButton, SIGNAL(endOp()), this, SLOT(enableObjectUpdates()));
|
|
}
|
|
if (update && save) {
|
|
m_saveButton->addButtons(save, update);
|
|
} else if (update) {
|
|
m_saveButton->addApplyButton(update);
|
|
} else if (save) {
|
|
m_saveButton->addSaveButton(save);
|
|
}
|
|
foreach(WidgetBinding * binding, m_widgetBindingsPerWidget) {
|
|
m_saveButton->addObject((UAVDataObject *)binding->object());
|
|
}
|
|
updateEnableControls();
|
|
}
|
|
|
|
void ConfigTaskWidget::enableControls(bool enable)
|
|
{
|
|
if (m_saveButton) {
|
|
m_saveButton->enableControls(enable);
|
|
}
|
|
|
|
foreach(QPushButton * button, m_reloadButtons) {
|
|
button->setEnabled(enable);
|
|
}
|
|
|
|
foreach(WidgetBinding * binding, m_widgetBindingsPerWidget) {
|
|
if (binding->isEnabled() && binding->widget()) {
|
|
binding->widget()->setEnabled(enable);
|
|
foreach(ShadowWidgetBinding * shadow, binding->shadows()) {
|
|
shadow->widget()->setEnabled(enable);
|
|
}
|
|
}
|
|
}
|
|
emit enableControlsChanged(enable);
|
|
}
|
|
|
|
bool ConfigTaskWidget::shouldObjectBeSaved(UAVObject *object)
|
|
{
|
|
Q_UNUSED(object);
|
|
return true;
|
|
}
|
|
|
|
void ConfigTaskWidget::forceShadowUpdates()
|
|
{
|
|
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
|
|
if (!binding->isEnabled()) {
|
|
continue;
|
|
}
|
|
QVariant widgetValue = getVariantFromWidget(binding->widget(), binding);
|
|
|
|
foreach(ShadowWidgetBinding * shadow, binding->shadows()) {
|
|
disconnectWidgetUpdatesToSlot(shadow->widget(), SLOT(widgetsContentsChanged()));
|
|
|
|
checkWidgetsLimits(shadow->widget(), binding->field(), binding->index(), shadow->isLimited(), widgetValue, shadow->scale());
|
|
|
|
WidgetBinding tmpBinding(shadow->widget(), binding->object(), binding->field(), binding->index(), shadow->scale(), shadow->isLimited());
|
|
setWidgetFromVariant(shadow->widget(), widgetValue, &tmpBinding);
|
|
|
|
emit widgetContentsChanged(shadow->widget());
|
|
connectWidgetUpdatesToSlot(shadow->widget(), SLOT(widgetsContentsChanged()));
|
|
}
|
|
}
|
|
setDirty(true);
|
|
}
|
|
|
|
void ConfigTaskWidget::widgetsContentsChanged()
|
|
{
|
|
QWidget *emitter = ((QWidget *)sender());
|
|
emit widgetContentsChanged(emitter);
|
|
QVariant value;
|
|
|
|
foreach(WidgetBinding * binding, m_widgetBindingsPerWidget.values(emitter)) {
|
|
if (binding && binding->isEnabled()) {
|
|
if (binding->widget() == emitter) {
|
|
value = getVariantFromWidget(emitter, binding);
|
|
checkWidgetsLimits(emitter, binding->field(), binding->index(), binding->isLimited(), value, binding->scale());
|
|
} else {
|
|
foreach(ShadowWidgetBinding * shadow, binding->shadows()) {
|
|
if (shadow->widget() == emitter) {
|
|
WidgetBinding tmpBinding(shadow->widget(), binding->object(), binding->field(),
|
|
binding->index(), shadow->scale(), shadow->isLimited());
|
|
value = getVariantFromWidget(emitter, &tmpBinding);
|
|
checkWidgetsLimits(emitter, binding->field(), binding->index(), shadow->isLimited(), value, shadow->scale());
|
|
}
|
|
}
|
|
}
|
|
binding->setValue(value);
|
|
|
|
if (binding->widget() != emitter) {
|
|
disconnectWidgetUpdatesToSlot(binding->widget(), SLOT(widgetsContentsChanged()));
|
|
|
|
checkWidgetsLimits(binding->widget(), binding->field(), binding->index(), binding->isLimited(),
|
|
value, binding->scale());
|
|
setWidgetFromVariant(binding->widget(), value, binding);
|
|
emit widgetContentsChanged(binding->widget());
|
|
|
|
connectWidgetUpdatesToSlot(binding->widget(), SLOT(widgetsContentsChanged()));
|
|
}
|
|
foreach(ShadowWidgetBinding * shadow, binding->shadows()) {
|
|
if (shadow->widget() != emitter) {
|
|
disconnectWidgetUpdatesToSlot(shadow->widget(), SLOT(widgetsContentsChanged()));
|
|
|
|
checkWidgetsLimits(shadow->widget(), binding->field(), binding->index(), shadow->isLimited(),
|
|
value, shadow->scale());
|
|
WidgetBinding tmp(shadow->widget(), binding->object(), binding->field(), binding->index(), shadow->scale(), shadow->isLimited());
|
|
setWidgetFromVariant(shadow->widget(), value, &tmp);
|
|
emit widgetContentsChanged(shadow->widget());
|
|
|
|
connectWidgetUpdatesToSlot(shadow->widget(), SLOT(widgetsContentsChanged()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (m_saveButton) {
|
|
m_saveButton->resetIcons();
|
|
}
|
|
setDirty(true);
|
|
}
|
|
|
|
void ConfigTaskWidget::clearDirty()
|
|
{
|
|
setDirty(false);
|
|
}
|
|
|
|
void ConfigTaskWidget::setDirty(bool value)
|
|
{
|
|
m_isDirty = value;
|
|
}
|
|
|
|
bool ConfigTaskWidget::isDirty()
|
|
{
|
|
if (m_isConnected) {
|
|
return m_isDirty;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::disableObjectUpdates()
|
|
{
|
|
m_isWidgetUpdatesAllowed = false;
|
|
foreach(WidgetBinding * binding, m_widgetBindingsPerWidget) {
|
|
if (binding->object()) {
|
|
disconnect(binding->object(), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshWidgetsValues(UAVObject *)));
|
|
}
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::enableObjectUpdates()
|
|
{
|
|
m_isWidgetUpdatesAllowed = true;
|
|
foreach(WidgetBinding * binding, m_widgetBindingsPerWidget) {
|
|
if (binding->object()) {
|
|
connect(binding->object(), SIGNAL(objectUpdated(UAVObject *)), this, SLOT(refreshWidgetsValues(UAVObject *)), Qt::UniqueConnection);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::objectUpdated(UAVObject *object)
|
|
{
|
|
m_updatedObjects[object] = true;
|
|
}
|
|
|
|
bool ConfigTaskWidget::allObjectsUpdated()
|
|
{
|
|
bool result = true;
|
|
|
|
foreach(UAVObject * object, m_updatedObjects.keys()) {
|
|
result = result & m_updatedObjects[object];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void ConfigTaskWidget::addHelpButton(QPushButton *button, QString url)
|
|
{
|
|
m_helpButtons.insert(button, url);
|
|
connect(button, SIGNAL(clicked()), this, SLOT(helpButtonPressed()));
|
|
}
|
|
|
|
void ConfigTaskWidget::invalidateObjects()
|
|
{
|
|
foreach(UAVObject * obj, m_updatedObjects.keys()) {
|
|
m_updatedObjects[obj] = false;
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::apply()
|
|
{
|
|
if (m_saveButton) {
|
|
m_saveButton->apply();
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::save()
|
|
{
|
|
if (m_saveButton) {
|
|
m_saveButton->save();
|
|
}
|
|
}
|
|
|
|
bool ConfigTaskWidget::addShadowWidgetBinding(QString objectName, QString fieldName, QWidget *widget, int index, double scale, bool isLimited,
|
|
QList<int> *defaultReloadGroups, quint32 instID)
|
|
{
|
|
foreach(WidgetBinding * binding, m_widgetBindingsPerWidget) {
|
|
if (!binding->object() || !binding->widget() || !binding->field()) {
|
|
continue;
|
|
}
|
|
if (binding->matches(objectName, fieldName, index, instID)) {
|
|
binding->addShadow(widget, scale, isLimited);
|
|
|
|
m_widgetBindingsPerWidget.insert(widget, binding);
|
|
connectWidgetUpdatesToSlot(widget, SLOT(widgetsContentsChanged()));
|
|
if (defaultReloadGroups) {
|
|
addWidgetToReloadGroups(widget, defaultReloadGroups);
|
|
}
|
|
if (binding->isEnabled()) {
|
|
loadWidgetLimits(widget, binding->field(), binding->index(), isLimited, scale);
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void ConfigTaskWidget::autoLoadWidgets()
|
|
{
|
|
QPushButton *saveButtonWidget = NULL;
|
|
QPushButton *applyButtonWidget = NULL;
|
|
|
|
foreach(QWidget * widget, this->findChildren<QWidget *>()) {
|
|
QVariant info = widget->property("objrelation");
|
|
|
|
if (info.isValid()) {
|
|
bindingStruct uiRelation;
|
|
uiRelation.buttonType = none;
|
|
uiRelation.scale = 1;
|
|
uiRelation.index = -1;
|
|
uiRelation.elementName = QString();
|
|
uiRelation.haslimits = false;
|
|
foreach(QString str, info.toStringList()) {
|
|
QString prop = str.split(":").at(0);
|
|
QString value = str.split(":").at(1);
|
|
|
|
if (prop == "objname") {
|
|
uiRelation.objectName = value;
|
|
} else if (prop == "fieldname") {
|
|
uiRelation.fieldName = value;
|
|
} else if (prop == "element") {
|
|
uiRelation.elementName = value;
|
|
} else if (prop == "index") {
|
|
uiRelation.index = value.toInt();
|
|
} else if (prop == "scale") {
|
|
if (value == "null") {
|
|
uiRelation.scale = 1;
|
|
} else {
|
|
uiRelation.scale = value.toDouble();
|
|
}
|
|
} else if (prop == "haslimits") {
|
|
if (value == "yes") {
|
|
uiRelation.haslimits = true;
|
|
} else {
|
|
uiRelation.haslimits = false;
|
|
}
|
|
} else if (prop == "button") {
|
|
if (value == "save") {
|
|
uiRelation.buttonType = save_button;
|
|
} else if (value == "apply") {
|
|
uiRelation.buttonType = apply_button;
|
|
} else if (value == "reload") {
|
|
uiRelation.buttonType = reload_button;
|
|
} else if (value == "default") {
|
|
uiRelation.buttonType = default_button;
|
|
} else if (value == "help") {
|
|
uiRelation.buttonType = help_button;
|
|
}
|
|
} else if (prop == "buttongroup") {
|
|
foreach(QString s, value.split(",")) {
|
|
uiRelation.buttonGroup.append(s.toInt());
|
|
}
|
|
} else if (prop == "url") {
|
|
uiRelation.url = str.mid(str.indexOf(":") + 1);
|
|
}
|
|
}
|
|
if (!uiRelation.buttonType == none) {
|
|
QPushButton *button = NULL;
|
|
switch (uiRelation.buttonType) {
|
|
case save_button:
|
|
saveButtonWidget = qobject_cast<QPushButton *>(widget);
|
|
if (saveButtonWidget) {
|
|
addApplySaveButtons(NULL, saveButtonWidget);
|
|
}
|
|
break;
|
|
case apply_button:
|
|
applyButtonWidget = qobject_cast<QPushButton *>(widget);
|
|
if (applyButtonWidget) {
|
|
addApplySaveButtons(applyButtonWidget, NULL);
|
|
}
|
|
break;
|
|
case default_button:
|
|
button = qobject_cast<QPushButton *>(widget);
|
|
if (button) {
|
|
addDefaultButton(button, uiRelation.buttonGroup.at(0));
|
|
}
|
|
break;
|
|
case reload_button:
|
|
button = qobject_cast<QPushButton *>(widget);
|
|
if (button) {
|
|
addReloadButton(button, uiRelation.buttonGroup.at(0));
|
|
}
|
|
break;
|
|
case help_button:
|
|
button = qobject_cast<QPushButton *>(widget);
|
|
if (button) {
|
|
addHelpButton(button, uiRelation.url);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
} else {
|
|
QWidget *wid = qobject_cast<QWidget *>(widget);
|
|
if (wid) {
|
|
if (uiRelation.index != -1) {
|
|
addWidgetBinding(uiRelation.objectName, uiRelation.fieldName, wid, uiRelation.index, uiRelation.scale, uiRelation.haslimits, &uiRelation.buttonGroup);
|
|
} else {
|
|
addWidgetBinding(uiRelation.objectName, uiRelation.fieldName, wid, uiRelation.elementName, uiRelation.scale, uiRelation.haslimits, &uiRelation.buttonGroup);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
refreshWidgetsValues();
|
|
forceShadowUpdates();
|
|
|
|
/*
|
|
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
|
|
if (binding->widget()) {
|
|
qDebug() << "Binding :" << binding->widget()->objectName();
|
|
qDebug() << " Object :" << binding->object()->getName();
|
|
qDebug() << " Field :" << binding->field()->getName();
|
|
qDebug() << " Scale :" << binding->scale();
|
|
qDebug() << " Enabled:" << binding->isEnabled();
|
|
}
|
|
foreach(ShadowWidgetBinding * shadow, binding->shadows()) {
|
|
if (shadow->widget()) {
|
|
qDebug() << " Shadow:" << shadow->widget()->objectName();
|
|
qDebug() << " Scale :" << shadow->scale();
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
void ConfigTaskWidget::addWidgetToReloadGroups(QWidget *widget, QList<int> *reloadGroupIDs)
|
|
{
|
|
foreach(WidgetBinding * binding, m_widgetBindingsPerWidget) {
|
|
bool addBinding = false;
|
|
|
|
if (binding->widget() == widget) {
|
|
addBinding = true;
|
|
} else {
|
|
foreach(ShadowWidgetBinding * shadow, binding->shadows()) {
|
|
if (shadow->widget() == widget) {
|
|
addBinding = true;
|
|
}
|
|
}
|
|
}
|
|
if (addBinding) {
|
|
foreach(int groupID, *reloadGroupIDs) {
|
|
m_reloadGroups.insert(groupID, binding);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::addDefaultButton(QPushButton *button, int buttonGroup)
|
|
{
|
|
button->setProperty("group", buttonGroup);
|
|
connect(button, SIGNAL(clicked()), this, SLOT(defaultButtonClicked()));
|
|
}
|
|
|
|
void ConfigTaskWidget::addReloadButton(QPushButton *button, int buttonGroup)
|
|
{
|
|
button->setProperty("group", buttonGroup);
|
|
m_reloadButtons.append(button);
|
|
connect(button, SIGNAL(clicked()), this, SLOT(reloadButtonClicked()));
|
|
}
|
|
|
|
void ConfigTaskWidget::defaultButtonClicked()
|
|
{
|
|
int groupID = sender()->property("group").toInt();
|
|
emit defaultRequested(groupID);
|
|
|
|
QList<WidgetBinding *> bindings = m_reloadGroups.values(groupID);
|
|
foreach(WidgetBinding * binding, bindings) {
|
|
if (!binding->isEnabled() || !binding->object() || !binding->field()) {
|
|
continue;
|
|
}
|
|
UAVDataObject *temp = ((UAVDataObject *)binding->object())->dirtyClone();
|
|
setWidgetFromField(binding->widget(), temp->getField(binding->field()->getName()), binding);
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::reloadButtonClicked()
|
|
{
|
|
if (m_realtimeUpdateTimer) {
|
|
return;
|
|
}
|
|
int groupID = sender()->property("group").toInt();
|
|
QList<WidgetBinding *> bindings = m_reloadGroups.values(groupID);
|
|
if (bindings.isEmpty()) {
|
|
return;
|
|
}
|
|
ObjectPersistence *objper = dynamic_cast<ObjectPersistence *>(getObjectManager()->getObject(ObjectPersistence::NAME));
|
|
m_realtimeUpdateTimer = new QTimer(this);
|
|
QEventLoop *eventLoop = new QEventLoop(this);
|
|
connect(m_realtimeUpdateTimer, SIGNAL(timeout()), eventLoop, SLOT(quit()));
|
|
connect(objper, SIGNAL(objectUpdated(UAVObject *)), eventLoop, SLOT(quit()));
|
|
|
|
QList<objectComparator> temp;
|
|
foreach(WidgetBinding * binding, bindings) {
|
|
if (binding->isEnabled() && binding->object() != NULL) {
|
|
objectComparator value;
|
|
value.objid = binding->object()->getObjID();
|
|
value.objinstid = binding->object()->getInstID();
|
|
if (temp.contains(value)) {
|
|
continue;
|
|
} else {
|
|
temp.append(value);
|
|
}
|
|
ObjectPersistence::DataFields data;
|
|
data.Operation = ObjectPersistence::OPERATION_LOAD;
|
|
data.Selection = ObjectPersistence::SELECTION_SINGLEOBJECT;
|
|
data.ObjectID = binding->object()->getObjID();
|
|
data.InstanceID = binding->object()->getInstID();
|
|
objper->setData(data);
|
|
objper->updated();
|
|
m_realtimeUpdateTimer->start(500);
|
|
eventLoop->exec();
|
|
if (m_realtimeUpdateTimer->isActive()) {
|
|
binding->object()->requestUpdate();
|
|
if (binding->widget()) {
|
|
setWidgetFromField(binding->widget(), binding->field(), binding);
|
|
}
|
|
}
|
|
m_realtimeUpdateTimer->stop();
|
|
}
|
|
}
|
|
if (eventLoop) {
|
|
delete eventLoop;
|
|
eventLoop = NULL;
|
|
}
|
|
if (m_realtimeUpdateTimer) {
|
|
delete m_realtimeUpdateTimer;
|
|
m_realtimeUpdateTimer = NULL;
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::connectWidgetUpdatesToSlot(QWidget *widget, const char *function)
|
|
{
|
|
if (!widget) {
|
|
return;
|
|
}
|
|
if (QComboBox * cb = qobject_cast<QComboBox *>(widget)) {
|
|
connect(cb, SIGNAL(currentIndexChanged(int)), this, function, Qt::UniqueConnection);
|
|
} else if (QSlider * cb = qobject_cast<QSlider *>(widget)) {
|
|
connect(cb, SIGNAL(valueChanged(int)), this, function, Qt::UniqueConnection);
|
|
} else if (MixerCurveWidget * cb = qobject_cast<MixerCurveWidget *>(widget)) {
|
|
connect(cb, SIGNAL(curveUpdated()), this, function, Qt::UniqueConnection);
|
|
} else if (QTableWidget * cb = qobject_cast<QTableWidget *>(widget)) {
|
|
connect(cb, SIGNAL(cellChanged(int, int)), this, function, Qt::UniqueConnection);
|
|
} else if (QSpinBox * cb = qobject_cast<QSpinBox *>(widget)) {
|
|
connect(cb, SIGNAL(valueChanged(int)), this, function, Qt::UniqueConnection);
|
|
} else if (QDoubleSpinBox * cb = qobject_cast<QDoubleSpinBox *>(widget)) {
|
|
connect(cb, SIGNAL(valueChanged(double)), this, function, Qt::UniqueConnection);
|
|
} else if (QLineEdit * cb = qobject_cast<QLineEdit *>(widget)) {
|
|
connect(cb, SIGNAL(textChanged(QString)), this, function, Qt::UniqueConnection);
|
|
} else if (QCheckBox * cb = qobject_cast<QCheckBox *>(widget)) {
|
|
connect(cb, SIGNAL(stateChanged(int)), this, function, Qt::UniqueConnection);
|
|
} else if (QPushButton * cb = qobject_cast<QPushButton *>(widget)) {
|
|
connect(cb, SIGNAL(clicked()), this, function, Qt::UniqueConnection);
|
|
} else if (QToolButton * cb = qobject_cast<QToolButton *>(widget)) {
|
|
connect(cb, SIGNAL(clicked()), this, function, Qt::UniqueConnection);
|
|
} else {
|
|
qDebug() << __FUNCTION__ << "widget binding not implemented" << widget->metaObject()->className();
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::disconnectWidgetUpdatesToSlot(QWidget *widget, const char *function)
|
|
{
|
|
if (!widget) {
|
|
return;
|
|
}
|
|
if (QComboBox * cb = qobject_cast<QComboBox *>(widget)) {
|
|
disconnect(cb, SIGNAL(currentIndexChanged(int)), this, function);
|
|
} else if (QSlider * cb = qobject_cast<QSlider *>(widget)) {
|
|
disconnect(cb, SIGNAL(valueChanged(int)), this, function);
|
|
} else if (MixerCurveWidget * cb = qobject_cast<MixerCurveWidget *>(widget)) {
|
|
disconnect(cb, SIGNAL(curveUpdated()), this, function);
|
|
} else if (QTableWidget * cb = qobject_cast<QTableWidget *>(widget)) {
|
|
disconnect(cb, SIGNAL(cellChanged(int, int)), this, function);
|
|
} else if (QSpinBox * cb = qobject_cast<QSpinBox *>(widget)) {
|
|
disconnect(cb, SIGNAL(valueChanged(int)), this, function);
|
|
} else if (QDoubleSpinBox * cb = qobject_cast<QDoubleSpinBox *>(widget)) {
|
|
disconnect(cb, SIGNAL(valueChanged(double)), this, function);
|
|
} else if (QLineEdit * cb = qobject_cast<QLineEdit *>(widget)) {
|
|
disconnect(cb, SIGNAL(textChanged(double)), this, function);
|
|
} else if (QCheckBox * cb = qobject_cast<QCheckBox *>(widget)) {
|
|
disconnect(cb, SIGNAL(stateChanged(int)), this, function);
|
|
} else if (QPushButton * cb = qobject_cast<QPushButton *>(widget)) {
|
|
disconnect(cb, SIGNAL(clicked()), this, function);
|
|
} else if (QToolButton * cb = qobject_cast<QToolButton *>(widget)) {
|
|
disconnect(cb, SIGNAL(clicked()), this, function);
|
|
} else {
|
|
qDebug() << __FUNCTION__ << "widget binding not implemented" << widget->metaObject()->className();
|
|
}
|
|
}
|
|
|
|
QVariant ConfigTaskWidget::getVariantFromWidget(QWidget *widget, WidgetBinding *binding)
|
|
{
|
|
double scale = binding->scale();
|
|
|
|
if (QComboBox * cb = qobject_cast<QComboBox *>(widget)) {
|
|
if (binding->isInteger()) {
|
|
return cb->currentIndex();
|
|
}
|
|
return (QString)cb->currentText();
|
|
} else if (QDoubleSpinBox * cb = qobject_cast<QDoubleSpinBox *>(widget)) {
|
|
return (double)(cb->value() * scale);
|
|
} else if (QSpinBox * cb = qobject_cast<QSpinBox *>(widget)) {
|
|
return (double)(cb->value() * scale);
|
|
} else if (QSlider * cb = qobject_cast<QSlider *>(widget)) {
|
|
return (double)(cb->value() * scale);
|
|
} else if (QCheckBox * cb = qobject_cast<QCheckBox *>(widget)) {
|
|
return (QString)(cb->isChecked() ? "TRUE" : "FALSE");
|
|
} else if (QLineEdit * cb = qobject_cast<QLineEdit *>(widget)) {
|
|
QString value = (QString)cb->displayText();
|
|
if (binding->units() == "hex") {
|
|
bool ok;
|
|
return value.toUInt(&ok, 16);
|
|
} else {
|
|
return value;
|
|
}
|
|
} else {
|
|
return QVariant();
|
|
}
|
|
}
|
|
|
|
bool ConfigTaskWidget::setWidgetFromVariant(QWidget *widget, QVariant value, WidgetBinding *binding)
|
|
{
|
|
double scale = binding->scale();
|
|
|
|
if (QComboBox * cb = qobject_cast<QComboBox *>(widget)) {
|
|
bool ok = true;
|
|
if (binding->isInteger()) {
|
|
cb->setCurrentIndex(value.toInt(&ok));
|
|
} else {
|
|
cb->setCurrentIndex(cb->findText(value.toString()));
|
|
}
|
|
return ok;
|
|
} else if (QLabel * cb = qobject_cast<QLabel *>(widget)) {
|
|
if (scale == 0) {
|
|
cb->setText(value.toString());
|
|
} else {
|
|
cb->setText(QString::number((value.toDouble() / scale)));
|
|
}
|
|
return true;
|
|
} else if (QDoubleSpinBox * cb = qobject_cast<QDoubleSpinBox *>(widget)) {
|
|
cb->setValue((double)(value.toDouble() / scale));
|
|
return true;
|
|
} else if (QSpinBox * cb = qobject_cast<QSpinBox *>(widget)) {
|
|
cb->setValue((int)qRound(value.toDouble() / scale));
|
|
return true;
|
|
} else if (QSlider * cb = qobject_cast<QSlider *>(widget)) {
|
|
cb->setValue((int)qRound(value.toDouble() / scale));
|
|
return true;
|
|
} else if (QCheckBox * cb = qobject_cast<QCheckBox *>(widget)) {
|
|
bool bvalue = value.toString() == "TRUE";
|
|
cb->setChecked(bvalue);
|
|
return true;
|
|
} else if (QLineEdit * cb = qobject_cast<QLineEdit *>(widget)) {
|
|
if ((scale == 0) || (scale == 1)) {
|
|
if (binding->units() == "hex") {
|
|
cb->setText(QString::number(value.toUInt(), 16).toUpper());
|
|
} else {
|
|
cb->setText(value.toString());
|
|
}
|
|
} else {
|
|
cb->setText(QString::number((value.toDouble() / scale)));
|
|
}
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool ConfigTaskWidget::setWidgetFromField(QWidget *widget, UAVObjectField *field, WidgetBinding *binding)
|
|
{
|
|
if (!widget || !field) {
|
|
return false;
|
|
}
|
|
if (QComboBox * cb = qobject_cast<QComboBox *>(widget)) {
|
|
if (cb->count() == 0) {
|
|
loadWidgetLimits(cb, field, binding->index(), binding->isLimited(), binding->scale());
|
|
}
|
|
}
|
|
QVariant value = field->getValue(binding->index());
|
|
checkWidgetsLimits(widget, field, binding->index(), binding->isLimited(), value, binding->scale());
|
|
bool result = setWidgetFromVariant(widget, value, binding);
|
|
if (result) {
|
|
return true;
|
|
} else {
|
|
qDebug() << __FUNCTION__ << "widget to uavobject relation not implemented" << widget->metaObject()->className();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::checkWidgetsLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, QVariant value, double scale)
|
|
{
|
|
if (!hasLimits) {
|
|
return;
|
|
}
|
|
if (!field->isWithinLimits(value, index, m_currentBoardId)) {
|
|
if (!widget->property("styleBackup").isValid()) {
|
|
widget->setProperty("styleBackup", widget->styleSheet());
|
|
}
|
|
widget->setStyleSheet(m_outOfLimitsStyle);
|
|
widget->setProperty("wasOverLimits", (bool)true);
|
|
if (QComboBox * cb = qobject_cast<QComboBox *>(widget)) {
|
|
if (cb->findText(value.toString()) == -1) {
|
|
cb->addItem(value.toString());
|
|
}
|
|
} else if (QDoubleSpinBox * cb = qobject_cast<QDoubleSpinBox *>(widget)) {
|
|
if ((double)(value.toDouble() / scale) > cb->maximum()) {
|
|
cb->setMaximum((double)(value.toDouble() / scale));
|
|
} else if ((double)(value.toDouble() / scale) < cb->minimum()) {
|
|
cb->setMinimum((double)(value.toDouble() / scale));
|
|
}
|
|
} else if (QSpinBox * cb = qobject_cast<QSpinBox *>(widget)) {
|
|
if ((int)qRound(value.toDouble() / scale) > cb->maximum()) {
|
|
cb->setMaximum((int)qRound(value.toDouble() / scale));
|
|
} else if ((int)qRound(value.toDouble() / scale) < cb->minimum()) {
|
|
cb->setMinimum((int)qRound(value.toDouble() / scale));
|
|
}
|
|
} else if (QSlider * cb = qobject_cast<QSlider *>(widget)) {
|
|
if ((int)qRound(value.toDouble() / scale) > cb->maximum()) {
|
|
cb->setMaximum((int)qRound(value.toDouble() / scale));
|
|
} else if ((int)qRound(value.toDouble() / scale) < cb->minimum()) {
|
|
cb->setMinimum((int)qRound(value.toDouble() / scale));
|
|
}
|
|
}
|
|
} else if (widget->property("wasOverLimits").isValid()) {
|
|
if (widget->property("wasOverLimits").toBool()) {
|
|
widget->setProperty("wasOverLimits", (bool)false);
|
|
if (widget->property("styleBackup").isValid()) {
|
|
QString style = widget->property("styleBackup").toString();
|
|
widget->setStyleSheet(style);
|
|
}
|
|
loadWidgetLimits(widget, field, index, hasLimits, scale);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ConfigTaskWidget::loadWidgetLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, double scale)
|
|
{
|
|
if (!widget || !field) {
|
|
return;
|
|
}
|
|
if (QComboBox * cb = qobject_cast<QComboBox *>(widget)) {
|
|
cb->clear();
|
|
QStringList option = field->getOptions();
|
|
if (hasLimits) {
|
|
// Only add options to combo box if we have a board id to check limits for.
|
|
// We could enter this method while there is no board connected and without
|
|
// this check, we would add all the board dependent options whether they were
|
|
// valid or not. Ultimately this method will be called again when the connected
|
|
// signal is handled.
|
|
if (m_currentBoardId > -1) {
|
|
foreach(QString str, option) {
|
|
if (field->isWithinLimits(str, index, m_currentBoardId)) {
|
|
cb->addItem(str);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
cb->addItems(option);
|
|
}
|
|
}
|
|
if (!hasLimits) {
|
|
return;
|
|
} else if (QDoubleSpinBox * cb = qobject_cast<QDoubleSpinBox *>(widget)) {
|
|
if (field->getMaxLimit(index).isValid()) {
|
|
cb->setMaximum((double)(field->getMaxLimit(index, m_currentBoardId).toDouble() / scale));
|
|
}
|
|
if (field->getMinLimit(index, m_currentBoardId).isValid()) {
|
|
cb->setMinimum((double)(field->getMinLimit(index, m_currentBoardId).toDouble() / scale));
|
|
}
|
|
} else if (QSpinBox * cb = qobject_cast<QSpinBox *>(widget)) {
|
|
if (field->getMaxLimit(index, m_currentBoardId).isValid()) {
|
|
cb->setMaximum((int)qRound(field->getMaxLimit(index, m_currentBoardId).toDouble() / scale));
|
|
}
|
|
if (field->getMinLimit(index, m_currentBoardId).isValid()) {
|
|
cb->setMinimum((int)qRound(field->getMinLimit(index, m_currentBoardId).toDouble() / scale));
|
|
}
|
|
} else if (QSlider * cb = qobject_cast<QSlider *>(widget)) {
|
|
if (field->getMaxLimit(index, m_currentBoardId).isValid()) {
|
|
cb->setMaximum((int)qRound(field->getMaxLimit(index, m_currentBoardId).toDouble() / scale));
|
|
}
|
|
if (field->getMinLimit(index, m_currentBoardId).isValid()) {
|
|
cb->setMinimum((int)(field->getMinLimit(index, m_currentBoardId).toDouble() / scale));
|
|
}
|
|
}
|
|
}
|
|
|
|
UAVObject *ConfigTaskWidget::getObject(const QString name, quint32 instId)
|
|
{
|
|
return m_pluginManager->getObject<UAVObjectManager>()->getObject(name, instId);
|
|
}
|
|
|
|
QString ConfigTaskWidget::mapObjectName(const QString objectName)
|
|
{
|
|
return objectName;
|
|
}
|
|
|
|
void ConfigTaskWidget::updateEnableControls()
|
|
{
|
|
TelemetryManager *telMngr = m_pluginManager->getObject<TelemetryManager>();
|
|
|
|
Q_ASSERT(telMngr);
|
|
|
|
enableControls(telMngr->isConnected());
|
|
}
|
|
|
|
void ConfigTaskWidget::disableMouseWheelEvents()
|
|
{
|
|
// Disable mouse wheel events
|
|
foreach(QSpinBox * sp, findChildren<QSpinBox *>()) {
|
|
sp->installEventFilter(this);
|
|
}
|
|
foreach(QDoubleSpinBox * sp, findChildren<QDoubleSpinBox *>()) {
|
|
sp->installEventFilter(this);
|
|
}
|
|
foreach(QSlider * sp, findChildren<QSlider *>()) {
|
|
sp->installEventFilter(this);
|
|
}
|
|
foreach(QComboBox * sp, findChildren<QComboBox *>()) {
|
|
sp->installEventFilter(this);
|
|
}
|
|
}
|
|
|
|
bool ConfigTaskWidget::eventFilter(QObject *obj, QEvent *evt)
|
|
{
|
|
// Filter all wheel events, and ignore them
|
|
if (evt->type() == QEvent::Wheel &&
|
|
(qobject_cast<QAbstractSpinBox *>(obj) ||
|
|
qobject_cast<QComboBox *>(obj) ||
|
|
qobject_cast<QAbstractSlider *>(obj))) {
|
|
evt->ignore();
|
|
return true;
|
|
}
|
|
return QWidget::eventFilter(obj, evt);
|
|
}
|
|
|
|
WidgetBinding::WidgetBinding(QWidget *widget, UAVObject *object, UAVObjectField *field, int index, double scale, bool isLimited) :
|
|
ShadowWidgetBinding(widget, scale, isLimited), m_isEnabled(true)
|
|
{
|
|
m_object = object;
|
|
m_field = field;
|
|
m_index = index;
|
|
}
|
|
|
|
WidgetBinding::~WidgetBinding()
|
|
{}
|
|
|
|
QString WidgetBinding::units() const
|
|
{
|
|
if (m_field) {
|
|
return m_field->getUnits();
|
|
}
|
|
return QString();
|
|
}
|
|
|
|
QString WidgetBinding::type() const
|
|
{
|
|
if (m_field) {
|
|
return m_field->getTypeAsString();
|
|
}
|
|
return QString();
|
|
}
|
|
|
|
bool WidgetBinding::isInteger() const
|
|
{
|
|
if (m_field) {
|
|
return m_field->isInteger();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
UAVObject *WidgetBinding::object() const
|
|
{
|
|
return m_object;
|
|
}
|
|
|
|
UAVObjectField *WidgetBinding::field() const
|
|
{
|
|
return m_field;
|
|
}
|
|
|
|
int WidgetBinding::index() const
|
|
{
|
|
return m_index;
|
|
}
|
|
|
|
QList<ShadowWidgetBinding *> WidgetBinding::shadows() const
|
|
{
|
|
return m_shadows;
|
|
}
|
|
|
|
void WidgetBinding::addShadow(QWidget *widget, double scale, bool isLimited)
|
|
{
|
|
ShadowWidgetBinding *shadow = NULL;
|
|
|
|
// Prefer anything else to QLabel and prefer QDoubleSpinBox to anything else
|
|
if ((qobject_cast<QLabel *>(m_widget) && !qobject_cast<QLabel *>(widget)) ||
|
|
(!qobject_cast<QDoubleSpinBox *>(m_widget) && qobject_cast<QDoubleSpinBox *>(widget))) {
|
|
shadow = new ShadowWidgetBinding(m_widget, m_scale, m_isLimited);
|
|
m_isLimited = isLimited;
|
|
m_scale = scale;
|
|
m_widget = widget;
|
|
} else {
|
|
shadow = new ShadowWidgetBinding(widget, scale, isLimited);
|
|
}
|
|
m_shadows.append(shadow);
|
|
}
|
|
|
|
bool WidgetBinding::matches(QString objectName, QString fieldName, int index, quint32 instanceId)
|
|
{
|
|
if (m_object && m_field) {
|
|
return m_object->getName() == objectName && m_object->getInstID() == instanceId &&
|
|
m_field->getName() == fieldName && m_index == index;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool WidgetBinding::isEnabled() const
|
|
{
|
|
return m_isEnabled;
|
|
}
|
|
|
|
void WidgetBinding::setIsEnabled(bool isEnabled)
|
|
{
|
|
m_isEnabled = isEnabled;
|
|
}
|
|
|
|
QVariant WidgetBinding::value() const
|
|
{
|
|
return m_value;
|
|
}
|
|
|
|
void WidgetBinding::setValue(const QVariant &value)
|
|
{
|
|
m_value = value;
|
|
/*
|
|
if (m_object && m_field) {
|
|
qDebug() << "WidgetBinding" << m_object->getName() << ":" << m_field->getName() << "value =" << value.toString();
|
|
}
|
|
*/
|
|
}
|
|
|
|
void WidgetBinding::updateObjectFieldFromValue()
|
|
{
|
|
if (m_value.isValid()) {
|
|
m_field->setValue(m_value, m_index);
|
|
}
|
|
}
|
|
|
|
void WidgetBinding::updateValueFromObjectField()
|
|
{
|
|
if (m_field->getValue(m_index).isValid()) {
|
|
m_value = m_field->getValue(m_index);
|
|
}
|
|
}
|
|
|
|
ShadowWidgetBinding::ShadowWidgetBinding(QWidget *widget, double scale, bool isLimited)
|
|
{
|
|
m_widget = widget;
|
|
m_scale = scale;
|
|
m_isLimited = isLimited;
|
|
}
|
|
|
|
ShadowWidgetBinding::~ShadowWidgetBinding()
|
|
{}
|
|
|
|
QWidget *ShadowWidgetBinding::widget() const
|
|
{
|
|
return m_widget;
|
|
}
|
|
|
|
double ShadowWidgetBinding::scale() const
|
|
{
|
|
return m_scale;
|
|
}
|
|
|
|
bool ShadowWidgetBinding::isLimited() const
|
|
{
|
|
return m_isLimited;
|
|
}
|