1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

LP-245 config: refactor and cleanup ConfigTaskWidget and co

most ConfigTaskWidget derived classes have minor changes (removal of unnecessary framework calls in constructor)

ConfigOPLinkWidget was heavily reworked to comply with ConfigTaskWidget requirements
ConfigOPLinkWidget doesn't trigger spurious unsaved popups anymore.

ConfigGadgetWidget now uses the OPLinkManager to listen to modem events
This commit is contained in:
Philippe Renon 2016-09-13 22:53:48 +02:00 committed by Philippe Renon
parent 99e7d711eb
commit a2082f449b
22 changed files with 459 additions and 515 deletions

View File

@ -176,8 +176,6 @@ ConfigMultiRotorWidget::ConfigMultiRotorWidget(QWidget *parent) :
m_aircraft->multiThrottleCurve->setXAxisLabel(tr("Input"));
m_aircraft->multiThrottleCurve->setYAxisLabel(tr("Output"));
updateEnableControls();
}
ConfigMultiRotorWidget::~ConfigMultiRotorWidget()

View File

@ -163,7 +163,7 @@ class ConfigTaskWidget;
* This class handles vehicle specific configuration UI and associated logic.
*
* This class derives from ConfigTaskWidget and overrides its the default "binding" mechanism.
* It does not use the "dirty" state management directlyand registers its relevant widgets with ConfigTaskWidget to do so.
* It does not use the "dirty" state management directly and registers its relevant widgets with ConfigTaskWidget to do so.
*/
class VehicleConfig : public ConfigTaskWidget {
Q_OBJECT

View File

@ -101,9 +101,6 @@ ConfigCCHWWidget::ConfigCCHWWidget(QWidget *parent) : ConfigTaskWidget(parent)
connect(m_telemetry->cchwHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
enableSaveButtons(false);
populateWidgets();
refreshWidgetsValues();
forceConnectedState();
}
ConfigCCHWWidget::~ConfigCCHWWidget()

View File

@ -103,7 +103,6 @@ ConfigCameraStabilizationWidget::ConfigCameraStabilizationWidget(QWidget *parent
connect(this, SIGNAL(defaultRequested(int)), this, SLOT(defaultRequestedSlot(int)));
disableMouseWheelEvents();
updateEnableControls();
}
ConfigCameraStabilizationWidget::~ConfigCameraStabilizationWidget()
@ -114,8 +113,7 @@ ConfigCameraStabilizationWidget::~ConfigCameraStabilizationWidget()
/*
* This overridden function refreshes widgets which have no direct relation
* to any of UAVObjects. It saves their dirty state first because update comes
* from UAVObjects, and then restores it. Aftewards it calls base class
* function to take care of other widgets which were dynamically added.
* from UAVObjects, and then restores it.
*/
void ConfigCameraStabilizationWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
@ -172,8 +170,7 @@ void ConfigCameraStabilizationWidget::refreshWidgetsValuesImpl(UAVObject *obj)
/*
* This overridden function updates UAVObjects which have no direct relation
* to any of widgets. Aftewards it calls base class function to take care of
* other object to widget relations which were dynamically added.
* to any of widgets.
*/
void ConfigCameraStabilizationWidget::updateObjectsFromWidgetsImpl()
{

View File

@ -74,9 +74,6 @@ ConfigCCAttitudeWidget::ConfigCCAttitudeWidget(QWidget *parent) :
addWidgetBinding("AttitudeSettings", "BoardRotation", ui->pitchBias, AttitudeSettings::BOARDROTATION_PITCH);
addWidgetBinding("AttitudeSettings", "BoardRotation", ui->yawBias, AttitudeSettings::BOARDROTATION_YAW);
addWidget(ui->zeroBias);
populateWidgets();
refreshWidgetsValues();
forceConnectedState();
}
ConfigCCAttitudeWidget::~ConfigCCAttitudeWidget()

View File

@ -43,16 +43,18 @@
#include "configsparky2hwwidget.h"
#include "defaultattitudewidget.h"
#include "defaulthwsettingswidget.h"
#include "uavobjectutilmanager.h"
#include <extensionsystem/pluginmanager.h>
#include <uavobjectutilmanager.h>
#include <uavtalk/telemetrymanager.h>
#include <uavtalk/oplinkmanager.h>
#include "utils/mytabbedstackwidget.h"
#include <QDebug>
#include <QStringList>
#include <QWidget>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QPushButton>
#include <QMessageBox>
#include <QDebug>
ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
{
@ -66,85 +68,80 @@ ConfigGadgetWidget::ConfigGadgetWidget(QWidget *parent) : QWidget(parent)
layout->addWidget(stackWidget);
setLayout(layout);
QWidget *qwd;
QIcon *icon = new QIcon();
QWidget *widget;
QIcon *icon;
icon = new QIcon();
icon->addFile(":/configgadget/images/hardware_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/hardware_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new DefaultHwSettingsWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::hardware, qwd, *icon, QString("Hardware"));
widget = new DefaultHwSettingsWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::hardware, widget, *icon, QString("Hardware"));
icon = new QIcon();
icon = new QIcon();
icon->addFile(":/configgadget/images/vehicle_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/vehicle_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new ConfigVehicleTypeWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::aircraft, qwd, *icon, QString("Vehicle"));
widget = new ConfigVehicleTypeWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::aircraft, widget, *icon, QString("Vehicle"));
icon = new QIcon();
icon = new QIcon();
icon->addFile(":/configgadget/images/input_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/input_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new ConfigInputWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::input, qwd, *icon, QString("Input"));
widget = new ConfigInputWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::input, widget, *icon, QString("Input"));
icon = new QIcon();
icon = new QIcon();
icon->addFile(":/configgadget/images/output_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/output_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new ConfigOutputWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::output, qwd, *icon, QString("Output"));
widget = new ConfigOutputWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::output, widget, *icon, QString("Output"));
icon = new QIcon();
icon = new QIcon();
icon->addFile(":/configgadget/images/ins_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/ins_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new DefaultAttitudeWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::sensors, qwd, *icon, QString("Attitude"));
widget = new DefaultAttitudeWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::sensors, widget, *icon, QString("Attitude"));
icon = new QIcon();
icon = new QIcon();
icon->addFile(":/configgadget/images/stabilization_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/stabilization_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new ConfigStabilizationWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::stabilization, qwd, *icon, QString("Stabilization"));
widget = new ConfigStabilizationWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::stabilization, widget, *icon, QString("Stabilization"));
icon = new QIcon();
icon = new QIcon();
icon->addFile(":/configgadget/images/camstab_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/camstab_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new ConfigCameraStabilizationWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::camerastabilization, qwd, *icon, QString("Gimbal"));
widget = new ConfigCameraStabilizationWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::camerastabilization, widget, *icon, QString("Gimbal"));
icon = new QIcon();
icon = new QIcon();
icon->addFile(":/configgadget/images/txpid_normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/txpid_selected.png", QSize(), QIcon::Selected, QIcon::Off);
qwd = new ConfigTxPIDWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::txpid, qwd, *icon, QString("TxPID"));
widget = new ConfigTxPIDWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::txpid, widget, *icon, QString("TxPID"));
stackWidget->setCurrentIndex(ConfigGadgetWidget::hardware);
// Listen to autopilot connection events
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
TelemetryManager *telMngr = pm->getObject<TelemetryManager>();
connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
// And check whether by any chance we are not already connected
if (telMngr->isConnected()) {
// connect to autopilot connection events
TelemetryManager *tm = pm->getObject<TelemetryManager>();
connect(tm, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
connect(tm, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
// check if we are already connected
if (tm->isConnected()) {
onAutopilotConnect();
}
// connect to oplink manager
OPLinkManager *om = pm->getObject<OPLinkManager>();
connect(om, SIGNAL(connected()), this, SLOT(onOPLinkConnect()));
connect(om, SIGNAL(disconnected()), this, SLOT(onOPLinkDisconnect()));
// check if we are already connected
if (om->isConnected()) {
onOPLinkConnect();
}
help = 0;
connect(stackWidget, SIGNAL(currentAboutToShow(int, bool *)), this, SLOT(tabAboutToChange(int, bool *)));
// Connect to the OPLinkStatus object updates
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
oplinkStatusObj = dynamic_cast<UAVDataObject *>(objManager->getObject("OPLinkStatus"));
if (oplinkStatusObj != NULL) {
connect(oplinkStatusObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateOPLinkStatus(UAVObject *)));
} else {
qDebug() << "Error: Object is unknown (OPLinkStatus).";
}
// Create the timer that is used to timeout the connection to the OPLink.
oplinkTimeout = new QTimer(this);
connect(oplinkTimeout, SIGNAL(timeout()), this, SLOT(onOPLinkDisconnect()));
oplinkConnected = false;
}
ConfigGadgetWidget::~ConfigGadgetWidget()
@ -165,56 +162,88 @@ void ConfigGadgetWidget::resizeEvent(QResizeEvent *event)
QWidget::resizeEvent(event);
}
void ConfigGadgetWidget::onAutopilotDisconnect()
{
QWidget *qwd = new DefaultAttitudeWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::sensors, qwd);
qwd = new DefaultHwSettingsWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::hardware, qwd);
emit autopilotDisconnected();
}
void ConfigGadgetWidget::onAutopilotConnect()
{
qDebug() << "ConfigGadgetWidget onAutopilotConnect";
// First of all, check what Board type we are talking to, and
// if necessary, remove/add tabs in the config gadget:
qDebug() << "ConfigGadgetWidget::onAutopilotConnect";
// Check what Board type we are talking to, and if necessary, remove/add tabs in the config gadget
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
if (utilMngr) {
int board = utilMngr->getBoardModel();
if ((board & 0xff00) == 0x0400) {
// CopterControl family
QWidget *qwd = new ConfigCCAttitudeWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::sensors, qwd);
qwd = new ConfigCCHWWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::hardware, qwd);
ConfigTaskWidget *widget;
widget = new ConfigCCAttitudeWidget(this);
widget->forceConnectedState();
stackWidget->replaceTab(ConfigGadgetWidget::sensors, widget);
widget = new ConfigCCHWWidget(this);
widget->forceConnectedState();
stackWidget->replaceTab(ConfigGadgetWidget::hardware, widget);
} else if ((board & 0xff00) == 0x0900) {
// Revolution family
QWidget *qwd = new ConfigRevoWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::sensors, qwd);
ConfigTaskWidget *widget;
widget = new ConfigRevoWidget(this);
widget->forceConnectedState();
stackWidget->replaceTab(ConfigGadgetWidget::sensors, widget);
if (board == 0x0903 || board == 0x0904) {
qwd = new ConfigRevoHWWidget(this);
widget = new ConfigRevoHWWidget(this);
} else if (board == 0x0905) {
qwd = new ConfigRevoNanoHWWidget(this);
widget = new ConfigRevoNanoHWWidget(this);
}
stackWidget->replaceTab(ConfigGadgetWidget::hardware, qwd);
widget->forceConnectedState();
stackWidget->replaceTab(ConfigGadgetWidget::hardware, widget);
} else if ((board & 0xff00) == 0x9200) {
// Sparky2
QWidget *qwd = new ConfigRevoWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::sensors, qwd);
qwd = new ConfigSparky2HWWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::hardware, qwd);
ConfigTaskWidget *widget;
widget = new ConfigRevoWidget(this);
widget->forceConnectedState();
stackWidget->replaceTab(ConfigGadgetWidget::sensors, widget);
widget = new ConfigSparky2HWWidget(this);
widget->forceConnectedState();
stackWidget->replaceTab(ConfigGadgetWidget::hardware, widget);
} else {
// Unknown board
qDebug() << "Unknown board " << board;
}
}
}
emit autopilotConnected();
void ConfigGadgetWidget::onAutopilotDisconnect()
{
qDebug() << "ConfigGadgetWidget::onAutopilotDiconnect";
QWidget *widget;
widget = new DefaultAttitudeWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::sensors, widget);
widget = new DefaultHwSettingsWidget(this);
stackWidget->replaceTab(ConfigGadgetWidget::hardware, widget);
}
void ConfigGadgetWidget::onOPLinkConnect()
{
qDebug() << "ConfigGadgetWidget::onOPLinkConnect";
ConfigTaskWidget *widget;
QIcon *icon;
icon = new QIcon();
icon->addFile(":/configgadget/images/pipx-normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/pipx-selected.png", QSize(), QIcon::Selected, QIcon::Off);
widget = new ConfigOPLinkWidget(this);
widget->forceConnectedState();
stackWidget->insertTab(ConfigGadgetWidget::oplink, widget, *icon, QString("OPLink"));
}
void ConfigGadgetWidget::onOPLinkDisconnect()
{
qDebug() << "ConfigGadgetWidget::onOPLinkDisconnect";
if (stackWidget->currentIndex() == ConfigGadgetWidget::oplink) {
stackWidget->setCurrentIndex(0);
}
stackWidget->removeTab(ConfigGadgetWidget::oplink);
}
void ConfigGadgetWidget::tabAboutToChange(int i, bool *proceed)
@ -236,35 +265,3 @@ void ConfigGadgetWidget::tabAboutToChange(int i, bool *proceed)
}
}
}
/*!
\brief Called by updates to @OPLinkStatus
*/
void ConfigGadgetWidget::updateOPLinkStatus(UAVObject *)
{
// Restart the disconnection timer.
oplinkTimeout->start(5000);
if (!oplinkConnected) {
qDebug() << "ConfigGadgetWidget onOPLinkConnect";
QIcon *icon = new QIcon();
icon->addFile(":/configgadget/images/pipx-normal.png", QSize(), QIcon::Normal, QIcon::Off);
icon->addFile(":/configgadget/images/pipx-selected.png", QSize(), QIcon::Selected, QIcon::Off);
QWidget *qwd = new ConfigOPLinkWidget(this);
stackWidget->insertTab(ConfigGadgetWidget::oplink, qwd, *icon, QString("OPLink"));
oplinkConnected = true;
}
}
void ConfigGadgetWidget::onOPLinkDisconnect()
{
qDebug() << "ConfigGadgetWidget onOPLinkDisconnect";
oplinkTimeout->stop();
oplinkConnected = false;
if (stackWidget->currentIndex() == ConfigGadgetWidget::oplink) {
stackWidget->setCurrentIndex(0);
}
stackWidget->removeTab(ConfigGadgetWidget::oplink);
}

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file configgadgetwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
@ -27,53 +28,35 @@
#ifndef CONFIGGADGETWIDGET_H
#define CONFIGGADGETWIDGET_H
#include "extensionsystem/pluginmanager.h"
#include "uavobjectmanager.h"
#include "uavobject.h"
#include "objectpersistence.h"
#include "utils/pathutils.h"
#include "utils/mytabbedstackwidget.h"
#include "../uavobjectwidgetutils/configtaskwidget.h"
#include <QWidget>
#include <QList>
#include <QTextBrowser>
#include <QMessageBox>
class QTextBrowser;
class MyTabbedStackWidget;
class ConfigGadgetWidget : public QWidget {
Q_OBJECT
QTextBrowser *help;
public:
enum widgetTabs { hardware = 0, aircraft, input, output, sensors, stabilization, camerastabilization, txpid, oplink };
ConfigGadgetWidget(QWidget *parent = 0);
~ConfigGadgetWidget();
enum widgetTabs { hardware = 0, aircraft, input, output, sensors, stabilization, camerastabilization, txpid, oplink };
void startInputWizard();
public slots:
void onAutopilotConnect();
void onAutopilotDisconnect();
void tabAboutToChange(int i, bool *);
void updateOPLinkStatus(UAVObject *object);
void onOPLinkDisconnect();
signals:
void autopilotConnected();
void autopilotDisconnected();
void oplinkConnect();
void oplinkDisconnect();
protected:
void resizeEvent(QResizeEvent *event);
private slots:
void onAutopilotConnect();
void onAutopilotDisconnect();
void onOPLinkConnect();
void onOPLinkDisconnect();
void tabAboutToChange(int i, bool *);
private:
UAVDataObject *oplinkStatusObj;
// A timer that timesout the connction to the OPLink.
QTimer *oplinkTimeout;
bool oplinkConnected;
MyTabbedStackWidget *stackWidget;
QTextBrowser *help;
};
#endif // CONFIGGADGETWIDGET_H

View File

@ -266,9 +266,6 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) :
autoLoadWidgets();
populateWidgets();
refreshWidgetsValues();
// Connect the help button
connect(ui->inputHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
@ -451,8 +448,6 @@ ConfigInputWidget::ConfigInputWidget(QWidget *parent) :
groundChannelOrder << ManualControlSettings::CHANNELGROUPS_THROTTLE <<
ManualControlSettings::CHANNELGROUPS_YAW <<
ManualControlSettings::CHANNELGROUPS_ACCESSORY0;
updateEnableControls();
}
void ConfigInputWidget::buildOptionComboBox(QComboBox *combo, UAVObjectField *field, int index, bool applyLimits)

View File

@ -33,11 +33,14 @@
#include <coreplugin/generalsettings.h>
#include <uavobjectmanager.h>
#include <uavobjectutilmanager.h>
#include <oplinksettings.h>
#include <oplinkstatus.h>
#include <QMessageBox>
#include <QDateTime>
#include <QDebug>
// Channel range and Frequency display
static const int MAX_CHANNEL_NUM = 250;
@ -45,40 +48,43 @@ static const int MIN_CHANNEL_RANGE = 10;
static const float FIRST_FREQUENCY = 430.000;
static const float FREQUENCY_STEP = 0.040;
ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(parent)
ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(parent, false), statusUpdated(false)
{
m_oplink = new Ui_OPLinkWidget();
m_oplink->setupUi(this);
// Connect to the OPLinkStatus object updates
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
oplinkStatusObj = dynamic_cast<UAVDataObject *>(objManager->getObject("OPLinkStatus"));
oplinkStatusObj = dynamic_cast<OPLinkStatus *>(getObject("OPLinkStatus"));
Q_ASSERT(oplinkStatusObj);
connect(oplinkStatusObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateStatus(UAVObject *)));
// Connect to the OPLinkSettings object updates
oplinkSettingsObj = dynamic_cast<OPLinkSettings *>(objManager->getObject("OPLinkSettings"));
oplinkSettingsObj = dynamic_cast<OPLinkSettings *>(getObject("OPLinkSettings"));
Q_ASSERT(oplinkSettingsObj);
connect(oplinkSettingsObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateSettings(UAVObject *)));
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Core::Internal::GeneralSettings *settings = pm->getObject<Core::Internal::GeneralSettings>();
if (!settings->useExpertMode()) {
m_oplink->Apply->setVisible(false);
}
addApplySaveButtons(m_oplink->Apply, m_oplink->Save);
addWidget(m_oplink->FirmwareVersion);
addWidget(m_oplink->SerialNumber);
addWidget(m_oplink->MinFreq);
addWidget(m_oplink->MaxFreq);
addWidget(m_oplink->UnbindButton);
addWidget(m_oplink->PairSignalStrengthBar1);
addWidget(m_oplink->PairSignalStrengthLabel1);
addWidgetBinding("OPLinkSettings", "Protocol", m_oplink->Protocol);
addWidgetBinding("OPLinkSettings", "LinkType", m_oplink->LinkType);
addWidgetBinding("OPLinkSettings", "CoordID", m_oplink->CoordID);
addWidgetBinding("OPLinkSettings", "CustomDeviceID", m_oplink->CustomDeviceID);
addWidgetBinding("OPLinkSettings", "MinChannel", m_oplink->MinimumChannel);
addWidgetBinding("OPLinkSettings", "MaxChannel", m_oplink->MaximumChannel);
addWidgetBinding("OPLinkSettings", "MaxRFPower", m_oplink->MaxRFTxPower);
addWidgetBinding("OPLinkSettings", "ComSpeed", m_oplink->ComSpeed);
addWidgetBinding("OPLinkSettings", "MainPort", m_oplink->MainPort);
addWidgetBinding("OPLinkSettings", "FlexiPort", m_oplink->FlexiPort);
addWidgetBinding("OPLinkSettings", "VCPPort", m_oplink->VCPPort);
addWidgetBinding("OPLinkSettings", "MaxRFPower", m_oplink->MaxRFTxPower);
addWidgetBinding("OPLinkSettings", "MinChannel", m_oplink->MinimumChannel);
addWidgetBinding("OPLinkSettings", "MaxChannel", m_oplink->MaximumChannel);
addWidgetBinding("OPLinkSettings", "CoordID", m_oplink->CoordID);
addWidgetBinding("OPLinkSettings", "Protocol", m_oplink->Protocol);
addWidgetBinding("OPLinkSettings", "LinkType", m_oplink->LinkType);
addWidgetBinding("OPLinkSettings", "ComSpeed", m_oplink->ComSpeed);
addWidgetBinding("OPLinkSettings", "CustomDeviceID", m_oplink->CustomDeviceID);
addWidgetBinding("OPLinkStatus", "DeviceID", m_oplink->DeviceID);
addWidgetBinding("OPLinkStatus", "RxGood", m_oplink->Good);
@ -106,7 +112,6 @@ ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(paren
connect(m_oplink->LinkType, SIGNAL(currentIndexChanged(int)), this, SLOT(linkTypeChanged()));
connect(m_oplink->MinimumChannel, SIGNAL(valueChanged(int)), this, SLOT(minChannelChanged()));
connect(m_oplink->MaximumChannel, SIGNAL(valueChanged(int)), this, SLOT(maxChannelChanged()));
connect(m_oplink->CustomDeviceID, SIGNAL(editingFinished()), this, SLOT(updateCustomDeviceID()));
connect(m_oplink->MainPort, SIGNAL(currentIndexChanged(int)), this, SLOT(mainPortChanged()));
connect(m_oplink->FlexiPort, SIGNAL(currentIndexChanged(int)), this, SLOT(flexiPortChanged()));
connect(m_oplink->VCPPort, SIGNAL(currentIndexChanged(int)), this, SLOT(vcpPortChanged()));
@ -114,8 +119,11 @@ ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(paren
// Connect the Unbind button
connect(m_oplink->UnbindButton, SIGNAL(released()), this, SLOT(unbind()));
m_oplink->CustomDeviceID->setInputMask("HHHHHHHH");
m_oplink->CoordID->setInputMask("HHHHHHHH");
// all upper case hex
m_oplink->CustomDeviceID->setInputMask(">HHHHHHHH");
m_oplink->CustomDeviceID->setPlaceholderText("AutoGen");
m_oplink->CoordID->setInputMask(">HHHHHHHH");
m_oplink->MinimumChannel->setKeyboardTracking(false);
m_oplink->MaximumChannel->setKeyboardTracking(false);
@ -123,138 +131,121 @@ ConfigOPLinkWidget::ConfigOPLinkWidget(QWidget *parent) : ConfigTaskWidget(paren
m_oplink->MaximumChannel->setMaximum(MAX_CHANNEL_NUM);
m_oplink->MinimumChannel->setMaximum(MAX_CHANNEL_NUM - MIN_CHANNEL_RANGE);
// Request and update of the setting object.
settingsUpdated = false;
setWikiURL("OPLink+Configuration");
autoLoadWidgets();
disableMouseWheelEvents();
updateEnableControls();
autoLoadWidgets();
}
ConfigOPLinkWidget::~ConfigOPLinkWidget()
{}
/*!
\brief Called by updates to @OPLinkStatus
*/
void ConfigOPLinkWidget::updateStatus(UAVObject *object)
void ConfigOPLinkWidget::onConnectImpl()
{
// qDebug() << "ConfigOPLinkWidget::onConnectImpl()";
statusUpdated = false;
// Request and update of the setting object if we haven't received it yet.
if (!settingsUpdated) {
oplinkSettingsObj->requestUpdate();
// this is only really needed for OPLM
oplinkSettingsObj->requestUpdate();
updateSettings();
}
void ConfigOPLinkWidget::refreshWidgetsValuesImpl(UAVObject *obj)
{
// qDebug() << "ConfigOPLinkWidget::refreshWidgetsValuesImpl()" << obj;
if (obj == oplinkStatusObj) {
updateStatus();
} else if (obj == oplinkSettingsObj) {
updateSettings();
}
}
void ConfigOPLinkWidget::updateStatus()
{
// qDebug() << "ConfigOPLinkWidget::updateStatus";
// Update the link state
UAVObjectField *linkField = object->getField("LinkState");
m_oplink->LinkState->setText(linkField->getValue().toString());
bool linkConnected = (linkField->getValue() == linkField->getOptions().at(OPLinkStatus::LINKSTATE_CONNECTED));
// TODO link state should be shown
// m_oplink->LinkState->setText(oplinkStatusObj->linkState().toString());
bool linkConnected = (oplinkStatusObj->linkState() == OPLinkStatus_LinkState::Connected);
m_oplink->PairSignalStrengthBar1->setValue(linkConnected ? m_oplink->RSSI->text().toInt() : -127);
m_oplink->PairSignalStrengthLabel1->setText(QString("%1dB").arg(m_oplink->PairSignalStrengthBar1->value()));
// Enable components based on the board type connected.
switch (oplinkStatusObj->boardType()) {
case 0x09: // Revolution, DiscoveryF4Bare, RevoNano, RevoProto
case 0x92: // Sparky2
m_oplink->MainPort->setVisible(false);
m_oplink->MainPortLabel->setVisible(false);
m_oplink->FlexiPort->setVisible(false);
m_oplink->FlexiPortLabel->setVisible(false);
m_oplink->VCPPort->setVisible(false);
m_oplink->VCPPortLabel->setVisible(false);
break;
case 0x03: // OPLinkMini
m_oplink->MainPort->setVisible(true);
m_oplink->MainPortLabel->setVisible(true);
m_oplink->FlexiPort->setVisible(true);
m_oplink->FlexiPortLabel->setVisible(true);
m_oplink->VCPPort->setVisible(true);
m_oplink->VCPPortLabel->setVisible(true);
break;
default:
// This shouldn't happen.
break;
}
if (!statusUpdated) {
statusUpdated = true;
// update static info
updateInfo();
}
}
void ConfigOPLinkWidget::updateInfo()
{
// qDebug() << "ConfigOPLinkWidget::updateInfo";
// Update the Description field
// TODO use UAVObjectUtilManager::descriptionToStructure()
UAVObjectField *descField = object->getField("Description");
if (descField->getValue(0) != QChar(255)) {
/*
* This looks like a binary with a description at the end:
* 4 bytes: header: "OpFw".
* 4 bytes: GIT commit tag (short version of SHA1).
* 4 bytes: Unix timestamp of compile time.
* 2 bytes: target platform. Should follow same rule as BOARD_TYPE and BOARD_REVISION in board define files.
* 26 bytes: commit tag if it is there, otherwise branch name. '-dirty' may be added if needed. Zero-padded.
* 20 bytes: SHA1 sum of the firmware.
* 20 bytes: SHA1 sum of the uavo definitions.
* 20 bytes: free for now.
*/
char buf[OPLinkStatus::DESCRIPTION_NUMELEM];
for (unsigned int i = 0; i < 26; ++i) {
buf[i] = descField->getValue(i + 14).toChar().toLatin1();
}
buf[26] = '\0';
QString descstr(buf);
quint32 gitDate = descField->getValue(11).toChar().toLatin1() & 0xFF;
for (int i = 1; i < 4; i++) {
gitDate = gitDate << 8;
gitDate += descField->getValue(11 - i).toChar().toLatin1() & 0xFF;
}
QString date = QDateTime::fromTime_t(gitDate).toUTC().toString("yyyy-MM-dd HH:mm");
m_oplink->FirmwareVersion->setText(descstr + " " + date);
quint8 *desc = oplinkStatusObj->getData().Description;
// extract desc into byte array
QByteArray ba;
for (unsigned int i = 0; i < OPLinkStatus::DESCRIPTION_NUMELEM; i++) {
ba.append(desc[i]);
}
// parse byte array intto device descriptor
deviceDescriptorStruct dds;
UAVObjectUtilManager::descriptionToStructure(ba, dds);
// update UI
if (!dds.gitTag.isEmpty()) {
m_oplink->FirmwareVersion->setText(dds.gitTag + " " + dds.gitDate);
} else {
m_oplink->FirmwareVersion->setText(tr("Unknown"));
}
// Update the serial number field
UAVObjectField *serialField = object->getField("CPUSerial");
char buf[OPLinkStatus::CPUSERIAL_NUMELEM * 2 + 1];
for (unsigned int i = 0; i < OPLinkStatus::CPUSERIAL_NUMELEM; ++i) {
unsigned char val = serialField->getValue(i).toUInt() >> 4;
unsigned char val = oplinkStatusObj->cpuSerial(i) >> 4;
buf[i * 2] = ((val < 10) ? '0' : '7') + val;
val = serialField->getValue(i).toUInt() & 0xf;
val = oplinkStatusObj->cpuSerial(i) & 0xf;
buf[i * 2 + 1] = ((val < 10) ? '0' : '7') + val;
}
buf[OPLinkStatus::CPUSERIAL_NUMELEM * 2] = '\0';
m_oplink->SerialNumber->setText(buf);
updateEnableControls();
}
/*!
\brief Called by updates to @OPLinkSettings
*/
void ConfigOPLinkWidget::updateSettings(UAVObject *object)
void ConfigOPLinkWidget::updateSettings()
{
Q_UNUSED(object);
// qDebug() << "ConfigOPLinkWidget::updateSettings";
if (!settingsUpdated) {
settingsUpdated = true;
// Enable components based on the board type connected.
UAVObjectField *board_type_field = oplinkStatusObj->getField("BoardType");
switch (board_type_field->getValue().toInt()) {
case 0x09: // Revolution, DiscoveryF4Bare, RevoNano, RevoProto
case 0x92: // Sparky2
m_oplink->MainPort->setVisible(false);
m_oplink->MainPortLabel->setVisible(false);
m_oplink->FlexiPort->setVisible(false);
m_oplink->FlexiPortLabel->setVisible(false);
m_oplink->VCPPort->setVisible(false);
m_oplink->VCPPortLabel->setVisible(false);
m_oplink->LinkType->setEnabled(true);
break;
case 0x03: // OPLinkMini
m_oplink->MainPort->setVisible(true);
m_oplink->MainPortLabel->setVisible(true);
m_oplink->FlexiPort->setVisible(true);
m_oplink->FlexiPortLabel->setVisible(true);
m_oplink->VCPPort->setVisible(true);
m_oplink->VCPPortLabel->setVisible(true);
m_oplink->LinkType->setEnabled(true);
break;
default:
// This shouldn't happen.
break;
}
updateEnableControls();
}
}
void ConfigOPLinkWidget::updateEnableControls()
{
enableControls(true);
updateCustomDeviceID();
updateCoordID();
protocolChanged();
}
void ConfigOPLinkWidget::disconnected()
{
if (settingsUpdated) {
settingsUpdated = false;
}
}
void ConfigOPLinkWidget::protocolChanged()
{
bool is_enabled = !isComboboxOptionSelected(m_oplink->Protocol, OPLinkSettings::PROTOCOL_DISABLED);
bool is_coordinator = isComboboxOptionSelected(m_oplink->Protocol, OPLinkSettings::PROTOCOL_OPLINKCOORDINATOR);
bool is_receiver = isComboboxOptionSelected(m_oplink->Protocol, OPLinkSettings::PROTOCOL_OPLINKRECEIVER);
@ -263,12 +254,15 @@ void ConfigOPLinkWidget::protocolChanged()
bool is_oplm = m_oplink->MainPort->isVisible();
bool is_bound = (m_oplink->CoordID->text() != "");
m_oplink->ComSpeed->setEnabled(!is_ppm_only && !is_openlrs && is_enabled);
m_oplink->CoordID->setEnabled(is_receiver & is_enabled);
m_oplink->UnbindButton->setEnabled(is_bound && !is_coordinator && is_enabled);
m_oplink->ComSpeed->setEnabled(is_enabled && !is_ppm_only && !is_openlrs);
m_oplink->CoordID->setEnabled(is_enabled && is_receiver);
m_oplink->UnbindButton->setEnabled(is_enabled && is_bound && !is_coordinator);
m_oplink->CustomDeviceID->setEnabled(is_coordinator);
m_oplink->MinimumChannel->setEnabled(is_receiver || is_coordinator);
m_oplink->MaximumChannel->setEnabled(is_receiver || is_coordinator);
// ports
m_oplink->MainPort->setEnabled(is_oplm);
m_oplink->FlexiPort->setEnabled(is_oplm);
m_oplink->VCPPort->setEnabled(is_oplm);
@ -283,9 +277,14 @@ void ConfigOPLinkWidget::protocolChanged()
m_oplink->MaxRFTxPower->setEnabled(is_enabled && !is_openlrs);
}
void ConfigOPLinkWidget::protocolChanged()
{
updateSettings();
}
void ConfigOPLinkWidget::linkTypeChanged()
{
protocolChanged();
updateSettings();
}
void ConfigOPLinkWidget::minChannelChanged()
@ -395,45 +394,18 @@ void ConfigOPLinkWidget::vcpPortChanged()
}
}
void ConfigOPLinkWidget::updateCoordID()
{
bool coordinatorNotSet = (m_oplink->CoordID->text() == "0");
if (settingsUpdated && coordinatorNotSet) {
m_oplink->CoordID->clear();
}
}
void ConfigOPLinkWidget::updateCustomDeviceID()
{
bool customDeviceIDNotSet = (m_oplink->CustomDeviceID->text() == "0");
if (settingsUpdated && customDeviceIDNotSet) {
m_oplink->CustomDeviceID->clear();
m_oplink->CustomDeviceID->setPlaceholderText("AutoGen");
}
}
void ConfigOPLinkWidget::unbind()
{
if (settingsUpdated) {
// Clear the coordinator ID
oplinkSettingsObj->getField("CoordID")->setValue(0);
m_oplink->CoordID->setText("0");
// Clear the coordinator ID
oplinkSettingsObj->setCoordID(0);
m_oplink->CoordID->clear();
// Clear the OpenLRS settings
oplinkSettingsObj->getField("Version")->setValue(0);
oplinkSettingsObj->getField("SerialBaudrate")->setValue(0);
oplinkSettingsObj->getField("RFFrequency")->setValue(0);
oplinkSettingsObj->getField("RFPower")->setValue(0);
oplinkSettingsObj->getField("RFChannelSpacing")->setValue(0);
oplinkSettingsObj->getField("ModemParams")->setValue(0);
oplinkSettingsObj->getField("Flags")->setValue(0);
}
// Clear the OpenLRS settings
oplinkSettingsObj->setVersion((quint16)0);
oplinkSettingsObj->setSerialBaudrate(0);
oplinkSettingsObj->setRFFrequency(0);
oplinkSettingsObj->setRFPower((quint16)0);
oplinkSettingsObj->setRFChannelSpacing((quint16)0);
oplinkSettingsObj->setModemParams((quint16)0);
oplinkSettingsObj->setFlags((quint16)0);
}
/**
@}
@}
*/

View File

@ -30,7 +30,8 @@
#include "configtaskwidget.h"
#include "oplinksettings.h"
class OPLinkStatus;
class OPLinkSettings;
class Ui_OPLinkWidget;
@ -41,38 +42,36 @@ public:
ConfigOPLinkWidget(QWidget *parent = 0);
~ConfigOPLinkWidget();
public slots:
void updateStatus(UAVObject *object1);
void updateSettings(UAVObject *object1);
protected:
virtual void onConnectImpl();
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
private:
Ui_OPLinkWidget *m_oplink;
// The OPLink status UAVObject
UAVDataObject *oplinkStatusObj;
// The OPLink ssettins UAVObject
OPLinkStatus *oplinkStatusObj;
OPLinkSettings *oplinkSettingsObj;
// Are the settings current?
bool settingsUpdated;
// Is the status current?
bool statusUpdated;
protected:
void updateEnableControls();
void updateStatus();
void updateInfo();
void updateSettings();
private slots:
void disconnected();
void linkTypeChanged();
void protocolChanged();
void linkTypeChanged();
void minChannelChanged();
void maxChannelChanged();
void updateCoordID();
void updateCustomDeviceID();
void unbind();
void channelChanged(bool isMax);
void mainPortChanged();
void flexiPortChanged();
void vcpPortChanged();
void unbind();
};
#endif // CONFIGOPLINKWIDGET_H

View File

@ -137,12 +137,8 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
SystemAlarms *systemAlarmsObj = SystemAlarms::GetInstance(getObjectManager());
connect(systemAlarmsObj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateWarnings(UAVObject *)));
// TODO why do we do that ?
disconnect(this, SLOT(refreshWidgetsValues(UAVObject *)));
populateWidgets();
refreshWidgetsValues();
updateEnableControls();
}
ConfigOutputWidget::~ConfigOutputWidget()

View File

@ -78,10 +78,6 @@ ConfigRevoHWWidget::ConfigRevoHWWidget(QWidget *parent) : ConfigTaskWidget(paren
connect(m_ui->cchwHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
setupCustomCombos();
enableControls(true);
populateWidgets();
refreshWidgetsValues();
forceConnectedState();
}
ConfigRevoHWWidget::~ConfigRevoHWWidget()

View File

@ -54,8 +54,6 @@ ConfigRevoNanoHWWidget::ConfigRevoNanoHWWidget(QWidget *parent) : ConfigTaskWidg
addApplySaveButtons(m_ui->saveTelemetryToRAM, m_ui->saveTelemetryToSD);
forceConnectedState();
addWidgetBinding("HwSettings", "RM_FlexiPort", m_ui->cbFlexi);
addWidgetBinding("HwSettings", "RM_MainPort", m_ui->cbMain);
addWidgetBinding("HwSettings", "RM_RcvrPort", m_ui->cbRcvr, 0, 1, true);
@ -75,10 +73,6 @@ ConfigRevoNanoHWWidget::ConfigRevoNanoHWWidget(QWidget *parent) : ConfigTaskWidg
connect(m_ui->cchwHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
setupCustomCombos();
enableControls(true);
populateWidgets();
refreshWidgetsValues();
setDirty(false);
}
ConfigRevoNanoHWWidget::~ConfigRevoNanoHWWidget()

View File

@ -1,7 +1,7 @@
/**
******************************************************************************
*
* @file ConfigRevoWidget.h
* @file configrevowidget.h
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
@ -226,13 +226,7 @@ ConfigRevoWidget::ConfigRevoWidget(QWidget *parent) :
// Connect the help button
connect(m_ui->attitudeHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
populateWidgets();
enableAllCalibrations();
updateEnableControls();
forceConnectedState();
refreshWidgetsValues();
}
ConfigRevoWidget::~ConfigRevoWidget()

View File

@ -1,8 +1,9 @@
/**
******************************************************************************
*
* @file configahrstwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @file configrevowidget.h
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin

View File

@ -75,10 +75,6 @@ ConfigSparky2HWWidget::ConfigSparky2HWWidget(QWidget *parent) : ConfigTaskWidget
connect(m_ui->cchwHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
setupCustomCombos();
enableControls(true);
populateWidgets();
refreshWidgetsValues();
forceConnectedState();
}
ConfigSparky2HWWidget::~ConfigSparky2HWWidget()

View File

@ -31,7 +31,6 @@
#include <extensionsystem/pluginmanager.h>
#include <coreplugin/generalsettings.h>
#include "uavobjectutilmanager.h"
#include "objectpersistence.h"
#include "altitudeholdsettings.h"
@ -58,7 +57,7 @@
#include <QAction>
ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTaskWidget(parent),
boardModel(0), m_stabSettingsBankCount(0), m_currentStabSettingsBank(0)
m_stabSettingsBankCount(0), m_currentStabSettingsBank(0)
{
ui = new Ui_StabilizationWidget();
ui->setupUi(this);
@ -144,15 +143,14 @@ ConfigStabilizationWidget::ConfigStabilizationWidget(QWidget *parent) : ConfigTa
addWidget(ui->thrustPIDScalingCurve);
connect(this, SIGNAL(widgetContentsChanged(QWidget *)), this, SLOT(processLinkedWidgets(QWidget *)));
connect(this, SIGNAL(autoPilotConnected()), this, SLOT(onBoardConnected()));
addWidget(ui->expoPlot);
connect(ui->expoSpinnerRoll, SIGNAL(valueChanged(int)), this, SLOT(replotExpoRoll(int)));
connect(ui->expoSpinnerPitch, SIGNAL(valueChanged(int)), this, SLOT(replotExpoPitch(int)));
connect(ui->expoSpinnerYaw, SIGNAL(valueChanged(int)), this, SLOT(replotExpoYaw(int)));
ui->AltitudeHold->setEnabled(false);
disableMouseWheelEvents();
updateEnableControls();
}
void ConfigStabilizationWidget::setupStabBanksGUI()
@ -646,15 +644,17 @@ void ConfigStabilizationWidget::processLinkedWidgets(QWidget *widget)
}
}
void ConfigStabilizationWidget::onBoardConnected()
void ConfigStabilizationWidget::onConnectImpl()
{
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectUtilManager *utilMngr = pm->getObject<UAVObjectUtilManager>();
Q_ASSERT(utilMngr);
boardModel = utilMngr->getBoardModel();
// If Revolution/Sparky2 board enable Althold tab, otherwise disable it
ui->AltitudeHold->setEnabled(((boardModel & 0xff00) == 0x0900) || ((boardModel & 0xff00) == 0x9200));
bool enableAltitudeHold = (((boardModel() & 0xff00) == 0x0900) || ((boardModel() & 0xff00) == 0x9200));
ui->AltitudeHold->setEnabled(enableAltitudeHold);
}
void ConfigStabilizationWidget::onDisconnectImpl()
{
ui->AltitudeHold->setEnabled(false);
}
void ConfigStabilizationWidget::stabBankChanged(int index)
@ -686,7 +686,7 @@ void ConfigStabilizationWidget::stabBankChanged(int index)
bool ConfigStabilizationWidget::shouldObjectBeSaved(UAVObject *object)
{
// AltitudeHoldSettings should only be saved for Revolution/Sparky2 board to avoid error.
if (((boardModel & 0xff00) != 0x0900) && ((boardModel & 0xff00) != 0x9200)) {
if (((boardModel() & 0xff00) != 0x0900) && ((boardModel() & 0xff00) != 0x9200)) {
return dynamic_cast<AltitudeHoldSettings *>(object) == 0;
} else {
return true;

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @file configstabilizationwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
@ -51,11 +52,14 @@ class ConfigStabilizationWidget : public ConfigTaskWidget {
public:
ConfigStabilizationWidget(QWidget *parent = 0);
~ConfigStabilizationWidget();
bool shouldObjectBeSaved(UAVObject *object);
protected:
QString mapObjectName(const QString objectName);
virtual void onConnectImpl();
virtual void onDisconnectImpl();
virtual void refreshWidgetsValuesImpl(UAVObject *obj);
virtual void updateObjectsFromWidgetsImpl();
@ -71,7 +75,6 @@ private:
static const int EXPO_CURVE_POINTS_COUNT = 100;
constexpr static const double EXPO_CURVE_CONSTANT = 1.01395948;
int boardModel;
int m_stabSettingsBankCount;
int m_currentStabSettingsBank;
@ -96,7 +99,6 @@ private slots:
void realtimeUpdatesSlot(bool value);
void linkCheckBoxes(bool value);
void processLinkedWidgets(QWidget *);
void onBoardConnected();
void stabBankChanged(int index);
void resetThrottleCurveToDefault();
void throttleCurveUpdated();

View File

@ -98,9 +98,6 @@ ConfigTxPIDWidget::ConfigTxPIDWidget(QWidget *parent) : ConfigTaskWidget(parent)
addWidget(m_txpid->TxPIDEnable);
addWidget(m_txpid->enableAutoCalcYaw);
enableControls(false);
populateWidgets();
refreshWidgetsValues();
disableMouseWheelEvents();
}

View File

@ -152,12 +152,9 @@ ConfigVehicleTypeWidget::ConfigVehicleTypeWidget(QWidget *parent) : ConfigTaskWi
// Connect the help pushbutton
connect(m_aircraft->airframeHelp, SIGNAL(clicked()), this, SLOT(openHelp()));
refreshWidgetsValues();
addWidget(m_aircraft->nameEdit);
disableMouseWheelEvents();
updateEnableControls();
}
/**
@ -316,6 +313,8 @@ VehicleConfig *ConfigVehicleTypeWidget::getVehicleConfigWidget(int frameCategory
// add config widget to UI
int index = m_aircraft->airframesWidget->insertWidget(m_aircraft->airframesWidget->count(), vehiculeConfig);
m_vehicleIndexMap[frameCategory] = index;
// and enable controls (needed?)
updateEnableControls();
}
int index = m_vehicleIndexMap.value(frameCategory);

View File

@ -31,6 +31,7 @@
#include "uavobject.h"
#include "uavobjectutilmanager.h"
#include "uavtalk/telemetrymanager.h"
#include "uavtalk/oplinkmanager.h"
#include "uavsettingsimportexport/uavsettingsimportexportfactory.h"
#include "smartsavebutton.h"
#include "mixercurvewidget.h"
@ -46,18 +47,29 @@
#include <QUrl>
#include <QWidget>
ConfigTaskWidget::ConfigTaskWidget(QWidget *parent) : QWidget(parent), m_currentBoardId(-1), m_isConnected(false), m_isWidgetUpdatesAllowed(true), m_isDirty(false), m_refreshing(false),
ConfigTaskWidget::ConfigTaskWidget(QWidget *parent, bool autopilot) : QWidget(parent),
m_currentBoardId(-1), m_isConnected(false), m_isWidgetUpdatesAllowed(true), m_isDirty(false), m_refreshing(false),
m_wikiURL("Welcome"), m_saveButton(NULL), m_outOfLimitsStyle("background-color: rgb(255, 0, 0);"), m_realtimeUpdateTimer(NULL)
{
m_autopilot = autopilot;
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()));
if (m_autopilot) {
// connect to telemetry manager
TelemetryManager *tm = m_pluginManager->getObject<TelemetryManager>();
connect(tm, SIGNAL(connected()), this, SLOT(onConnect()));
connect(tm, SIGNAL(disconnected()), this, SLOT(onDisconnect()));
} else {
// connect to oplink manager
OPLinkManager *om = m_pluginManager->getObject<OPLinkManager>();
connect(om, SIGNAL(connected()), this, SLOT(onConnect()));
connect(om, SIGNAL(disconnected()), this, SLOT(onDisconnect()));
}
}
void ConfigTaskWidget::addWidget(QWidget *widget)
@ -280,63 +292,56 @@ UAVObjectManager *ConfigTaskWidget::getObjectManager()
return objMngr;
}
bool ConfigTaskWidget::isConnected() const
{
bool connected = false;
void ConfigTaskWidget::onAutopilotDisconnect()
if (m_autopilot) {
TelemetryManager *tm = m_pluginManager->getObject<TelemetryManager>();
connected = tm->isConnected();
} else {
OPLinkManager *om = m_pluginManager->getObject<OPLinkManager>();
connected = om->isConnected();
}
return connected;
}
// dynamic widgets don't receive the connected signal. This should be called instead.
void ConfigTaskWidget::forceConnectedState()
{
onConnect();
}
void ConfigTaskWidget::onConnect()
{
if (m_autopilot) {
m_currentBoardId = m_objectUtilManager->getBoardModel();
}
invalidateObjects();
m_isConnected = true;
resetLimits();
setDirty(false);
refreshWidgetsValues();
updateEnableControls();
// call specific implementation
onConnectImpl();
}
void ConfigTaskWidget::onDisconnect()
{
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);
}
// call specific implementation
onDisconnectImpl();
void ConfigTaskWidget::onAutopilotConnect()
{
if (m_objectUtilManager) {
m_currentBoardId = m_objectUtilManager->getBoardModel();
}
invalidateObjects();
m_isConnected = true;
setDirty(false);
enableControls(true);
refreshWidgetsValues();
}
void ConfigTaskWidget::populateWidgets()
{
m_refreshing = true;
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);
}
}
m_refreshing = false;
// reset board ID
m_currentBoardId = -1;
}
void ConfigTaskWidget::refreshWidgetsValues(UAVObject *obj)
@ -347,8 +352,6 @@ void ConfigTaskWidget::refreshWidgetsValues(UAVObject *obj)
m_refreshing = true;
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) {
@ -368,8 +371,6 @@ void ConfigTaskWidget::refreshWidgetsValues(UAVObject *obj)
void ConfigTaskWidget::updateObjectsFromWidgets()
{
emit updateObjectsFromWidgetsRequested();
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
if (binding->object() != NULL && binding->field() != NULL) {
binding->updateObjectFieldFromValue();
@ -567,7 +568,10 @@ bool ConfigTaskWidget::allObjectsUpdated()
bool result = true;
foreach(UAVObject * object, m_updatedObjects.keys()) {
result = result & m_updatedObjects[object];
result &= m_updatedObjects[object];
if (!result) {
break;
}
}
return result;
}
@ -736,11 +740,16 @@ void ConfigTaskWidget::autoLoadWidgets()
}
}
}
refreshWidgetsValues();
forceShadowUpdates();
/*
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
// TODO is this refresh necessary ?
refreshWidgetsValues();
// TODO is this necessary ?
forceShadowUpdates();
}
void ConfigTaskWidget::dumpBindings()
{
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
if (binding->widget()) {
qDebug() << "Binding :" << binding->widget()->objectName();
qDebug() << " Object :" << binding->object()->getName();
@ -754,8 +763,7 @@ void ConfigTaskWidget::autoLoadWidgets()
qDebug() << " Scale :" << shadow->scale();
}
}
}
*/
}
}
void ConfigTaskWidget::addWidgetToReloadGroups(QWidget *widget, QList<int> *reloadGroupIDs)
@ -1033,6 +1041,20 @@ bool ConfigTaskWidget::setWidgetFromField(QWidget *widget, UAVObjectField *field
}
}
void ConfigTaskWidget::resetLimits()
{
// 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.
foreach(WidgetBinding * binding, m_widgetBindingsPerObject) {
QComboBox *cb;
if (binding->widget() && (cb = qobject_cast<QComboBox *>(binding->widget()))) {
cb->clear();
}
}
}
void ConfigTaskWidget::checkWidgetsLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, QVariant value, double scale)
{
if (!hasLimits) {
@ -1126,19 +1148,17 @@ QString ConfigTaskWidget::mapObjectName(const QString objectName)
void ConfigTaskWidget::updateEnableControls()
{
TelemetryManager *telMngr = m_pluginManager->getObject<TelemetryManager>();
Q_ASSERT(telMngr);
enableControls(telMngr->isConnected());
enableControls(isConnected());
}
void ConfigTaskWidget::buildOptionComboBox(QComboBox *combo, UAVObjectField *field, int index, bool applyLimits)
{
QStringList options = field->getOptions();
// qDebug() << "buildOptionComboBox" << field << applyLimits << m_currentBoardId;
for (int optionIndex = 0; optionIndex < options.count(); optionIndex++) {
if (applyLimits) {
// qDebug() << " " << options.at(optionIndex) << field->isWithinLimits(options.at(optionIndex), index, m_currentBoardId);
if (m_currentBoardId > -1 && field->isWithinLimits(options.at(optionIndex), index, m_currentBoardId)) {
combo->addItem(options.at(optionIndex), QVariant(optionIndex));
}
@ -1278,11 +1298,9 @@ QVariant WidgetBinding::value() const
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();
}
*/
// if (m_object && m_field) {
// qDebug() << "WidgetBinding" << m_object->getName() << ":" << m_field->getName() << "value =" << value.toString();
// }
}
void WidgetBinding::updateObjectFieldFromValue()

View File

@ -99,9 +99,17 @@ class UAVOBJECTWIDGETUTILS_EXPORT ConfigTaskWidget : public QWidget {
Q_OBJECT
public:
ConfigTaskWidget(QWidget *parent = 0);
ConfigTaskWidget(QWidget *parent = 0, bool autopilot = true);
virtual ~ConfigTaskWidget();
void forceConnectedState();
bool isDirty();
void setDirty(bool value);
virtual bool shouldObjectBeSaved(UAVObject *object);
protected:
// Combobox helper functions
static bool isComboboxOptionSelected(QComboBox *combo, int optionValue);
static int getComboboxSelectedOption(QComboBox *combo);
@ -118,6 +126,8 @@ public:
void addUAVObject(QString objectName, QList<int> *reloadGroups = NULL);
void addUAVObject(UAVObject *objectName, QList<int> *reloadGroups = NULL);
// TODO should be protected (see VehicleConfig::registerWidgets(ConfigTaskWidget &parent)
public:
void addWidget(QWidget *widget);
void addWidgetBinding(QString objectName, QString fieldName, QWidget *widget, int index = 0, double scale = 1,
@ -125,6 +135,7 @@ public:
void addWidgetBinding(UAVObject *object, UAVObjectField *field, QWidget *widget, int index = 0, double scale = 1,
bool isLimited = false, QList<int> *reloadGroupIDs = 0, quint32 instID = 0);
protected:
void addWidgetBinding(QString objectName, QString fieldName, QWidget *widget, QString elementName, double scale,
bool isLimited = false, QList<int> *reloadGroupIDs = 0, quint32 instID = 0);
void addWidgetBinding(UAVObject *object, UAVObjectField *field, QWidget *widget, QString elementName, double scale,
@ -144,9 +155,6 @@ public:
void autoLoadWidgets();
bool isDirty();
virtual void setDirty(bool value);
bool allObjectsUpdated();
void setOutOfLimitsStyle(QString style)
{
@ -155,37 +163,55 @@ public:
void addHelpButton(QPushButton *button, QString url);
void setWikiURL(QString url);
void forceShadowUpdates();
void forceConnectedState();
virtual bool shouldObjectBeSaved(UAVObject *object);
public slots:
void onAutopilotDisconnect();
void onAutopilotConnect();
void invalidateObjects();
protected slots:
void apply();
void save();
void setWidgetBindingObjectEnabled(QString objectName, bool enabled);
signals:
// fired when a widgets contents changes
void widgetContentsChanged(QWidget *widget);
// fired when the framework requests that the widgets values be populated, use for custom behaviour
void populateWidgetsRequested();
// fired when the framework requests that the widgets values be refreshed, use for custom behaviour
void refreshWidgetsValuesRequested();
// fired when the framework requests that the UAVObject values be updated from the widgets value, use for custom behaviour
void updateObjectsFromWidgetsRequested();
// fired when the autopilot connects
void autoPilotConnected();
// fired when the autopilot disconnects
void autoPilotDisconnected();
void defaultRequested(int group);
void enableControlsChanged(bool enable);
protected:
int boardModel()
{
return m_currentBoardId;
}
virtual void enableControls(bool enable);
virtual QString mapObjectName(const QString objectName);
virtual UAVObject *getObject(const QString name, quint32 instId = 0);
virtual void buildOptionComboBox(QComboBox *combo, UAVObjectField *field, int index, bool applyLimits);
void updateEnableControls();
bool isConnected() const;
virtual void onConnectImpl() {};
virtual void onDisconnectImpl() {};
virtual void refreshWidgetsValuesImpl(UAVObject *) {};
virtual void updateObjectsFromWidgetsImpl() {};
protected slots:
void setWidgetBindingObjectEnabled(QString objectName, bool enabled);
void clearDirty();
virtual void widgetsContentsChanged();
// void populateWidgets();
void refreshWidgetsValues(UAVObject *obj = NULL);
void updateObjectsFromWidgets();
private slots:
void onConnect();
void onDisconnect();
void disableObjectUpdates();
void enableObjectUpdates();
void objectUpdated(UAVObject *object);
void invalidateObjects();
void defaultButtonClicked();
void reloadButtonClicked();
void helpButtonPressed();
private:
struct objectComparator {
@ -210,6 +236,11 @@ private:
bool haslimits;
};
// indicates if this is an "autopilot" widget (CC3D, Revolution, ...) or an OPLink widget
// TODO the logic that this flag controls should be moved to derived classes
bool m_autopilot;
// only valid for "autopilot" widgets
int m_currentBoardId;
bool m_isConnected;
@ -218,8 +249,9 @@ private:
bool m_refreshing;
QStringList m_objects;
QString m_wikiURL; // Wiki address for help button
// Concatenated with WIKI_URL_ROOT
// Wiki address for help button (will be concatenated with WIKI_URL_ROOT)
QString m_wikiURL;
QMultiHash<int, WidgetBinding *> m_reloadGroups;
QMultiHash<QWidget *, WidgetBinding *> m_widgetBindingsPerWidget;
@ -243,34 +275,18 @@ private:
void connectWidgetUpdatesToSlot(QWidget *widget, const char *function);
void disconnectWidgetUpdatesToSlot(QWidget *widget, const char *function);
void resetLimits();
void loadWidgetLimits(QWidget *widget, UAVObjectField *field, int index, bool applyLimits, double scale);
void checkWidgetsLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, QVariant value, double scale);
void dumpBindings();
int fieldIndexFromElementName(QString objectName, QString fieldName, QString elementName);
void doAddWidgetBinding(QString objectName, QString fieldName, QWidget *widget, int index = 0, double scale = 1,
bool isLimited = false, QList<int> *reloadGroupIDs = 0, quint32 instID = 0);
protected:
virtual void refreshWidgetsValuesImpl(UAVObject *) {};
virtual void updateObjectsFromWidgetsImpl() {};
protected slots:
virtual void disableObjectUpdates();
virtual void enableObjectUpdates();
virtual void clearDirty();
virtual void widgetsContentsChanged();
virtual void populateWidgets();
void refreshWidgetsValues(UAVObject *obj = NULL);
void updateObjectsFromWidgets();
virtual void helpButtonPressed();
protected:
virtual void enableControls(bool enable);
virtual QString mapObjectName(const QString objectName);
virtual UAVObject *getObject(const QString name, quint32 instId = 0);
virtual void buildOptionComboBox(QComboBox *combo, UAVObjectField *field, int index, bool applyLimits);
void checkWidgetsLimits(QWidget *widget, UAVObjectField *field, int index, bool hasLimits, QVariant value, double scale);
void updateEnableControls();
};
#endif // CONFIGTASKWIDGET_H