1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-29 14:52:12 +01:00

Merge remote-tracking branch 'origin/ccfly/outputchannelform' into next

This commit is contained in:
James Cotton 2011-11-25 10:48:41 -06:00
commit 60664f6a26
7 changed files with 785 additions and 1347 deletions

View File

@ -1,7 +1,6 @@
TEMPLATE = lib
TARGET = Config
QT += svg
include(../../openpilotgcsplugin.pri)
include(../../libs/utils/utils.pri)
include(../../plugins/uavtalk/uavtalk.pri)
@ -10,9 +9,7 @@ include(../../plugins/uavobjects/uavobjects.pri)
include(../../plugins/uavobjectutil/uavobjectutil.pri)
include(../../plugins/uavsettingsimportexport/uavsettingsimportexport.pri)
INCLUDEPATH += ../../libs/eigen
OTHER_FILES += Config.pluginspec
HEADERS += configplugin.h \
configgadgetconfiguration.h \
configgadgetwidget.h \
@ -39,8 +36,8 @@ HEADERS += configplugin.h \
smartsavebutton.h \
defaulthwsettingswidget.h \
inputchannelform.h \
configcamerastabilizationwidget.h
configcamerastabilizationwidget.h \
outputchannelform.h
SOURCES += configplugin.cpp \
configgadgetconfiguration.cpp \
configgadgetwidget.cpp \
@ -69,10 +66,9 @@ SOURCES += configplugin.cpp \
smartsavebutton.cpp \
defaulthwsettingswidget.cpp \
inputchannelform.cpp \
configcamerastabilizationwidget.cpp
FORMS += \
airframe.ui \
configcamerastabilizationwidget.cpp \
outputchannelform.cpp
FORMS += airframe.ui \
cc_hw_settings.ui \
pro_hw_settings.ui \
ahrs.ui \
@ -84,10 +80,6 @@ FORMS += \
defaultattitude.ui \
defaulthwsettings.ui \
inputchannelform.ui \
camerastabilization.ui
camerastabilization.ui \
outputchannelform.ui
RESOURCES += configgadget.qrc

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file configservowidget.cpp
* @file configoutputwidget.cpp
* @author E. Lafargue & The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Servo input/output configuration panel for the config gadget
* @brief Servo output configuration panel for the config gadget
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -26,6 +26,7 @@
*/
#include "configoutputwidget.h"
#include "outputchannelform.h"
#include "uavtalk/telemetrymanager.h"
@ -39,6 +40,7 @@
#include <QDesktopServices>
#include <QUrl>
#include "actuatorcommand.h"
#include "actuatorsettings.h"
#include "systemalarms.h"
#include "uavsettingsimportexport/uavsettingsimportexportfactory.h"
@ -57,99 +59,20 @@ ConfigOutputWidget::ConfigOutputWidget(QWidget *parent) : ConfigTaskWidget(paren
setupButtons(m_config->saveRCOutputToRAM,m_config->saveRCOutputToSD);
addUAVObject("ActuatorSettings");
// First of all, put all the channel widgets into lists, so that we can
// manipulate those:
// NOTE: for historical reasons, we have objects below called ch0 to ch7, but the convention for OP is Channel 1 to Channel 8.
outLabels << m_config->ch0OutValue
<< m_config->ch1OutValue
<< m_config->ch2OutValue
<< m_config->ch3OutValue
<< m_config->ch4OutValue
<< m_config->ch5OutValue
<< m_config->ch6OutValue
<< m_config->ch7OutValue
<< m_config->ch8OutValue
<< m_config->ch9OutValue;
outSliders << m_config->ch0OutSlider
<< m_config->ch1OutSlider
<< m_config->ch2OutSlider
<< m_config->ch3OutSlider
<< m_config->ch4OutSlider
<< m_config->ch5OutSlider
<< m_config->ch6OutSlider
<< m_config->ch7OutSlider
<< m_config->ch8OutSlider
<< m_config->ch9OutSlider;
outMin << m_config->ch0OutMin
<< m_config->ch1OutMin
<< m_config->ch2OutMin
<< m_config->ch3OutMin
<< m_config->ch4OutMin
<< m_config->ch5OutMin
<< m_config->ch6OutMin
<< m_config->ch7OutMin
<< m_config->ch8OutMin
<< m_config->ch9OutMin;
outMax << m_config->ch0OutMax
<< m_config->ch1OutMax
<< m_config->ch2OutMax
<< m_config->ch3OutMax
<< m_config->ch4OutMax
<< m_config->ch5OutMax
<< m_config->ch6OutMax
<< m_config->ch7OutMax
<< m_config->ch8OutMax
<< m_config->ch9OutMax;
reversals << m_config->ch0Rev
<< m_config->ch1Rev
<< m_config->ch2Rev
<< m_config->ch3Rev
<< m_config->ch4Rev
<< m_config->ch5Rev
<< m_config->ch6Rev
<< m_config->ch7Rev
<< m_config->ch8Rev
<< m_config->ch9Rev;
links << m_config->ch0Link
<< m_config->ch1Link
<< m_config->ch2Link
<< m_config->ch3Link
<< m_config->ch4Link
<< m_config->ch5Link
<< m_config->ch6Link
<< m_config->ch7Link
<< m_config->ch8Link
<< m_config->ch9Link;
// NOTE: we have channel indices from 0 to 9, but the convention for OP is Channel 1 to Channel 10.
// Register for ActuatorSettings changes:
for (int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++) {
connect(outMin[i], SIGNAL(editingFinished()), this, SLOT(setChOutRange()));
connect(outMax[i], SIGNAL(editingFinished()), this, SLOT(setChOutRange()));
connect(reversals[i], SIGNAL(toggled(bool)), this, SLOT(reverseChannel(bool)));
// Now connect the channel out sliders to our signal to send updates in test mode
connect(outSliders[i], SIGNAL(valueChanged(int)), this, SLOT(sendChannelTest(int)));
addWidget(outMin[i]);
addWidget(outMax[i]);
addWidget(reversals[i]);
addWidget(outSliders[i]);
addWidget(links[i]);
for (unsigned int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++)
{
OutputChannelForm *form = new OutputChannelForm(i, this, i==0);
connect(m_config->channelOutTest, SIGNAL(toggled(bool)),
form, SLOT(enableChannelTest(bool)));
connect(form, SIGNAL(channelChanged(int,int)),
this, SLOT(sendChannelTest(int,int)));
m_config->channelLayout->addWidget(form);
}
connect(m_config->channelOutTest, SIGNAL(toggled(bool)), this, SLOT(runChannelTests(bool)));
for (int i = 0; i < links.count(); i++)
links[i]->setChecked(false);
for (int i = 0; i < links.count(); i++)
connect(links[i], SIGNAL(toggled(bool)), this, SLOT(linkToggled(bool)));
refreshWidgetsValues();
firstUpdate = true;
@ -179,37 +102,6 @@ ConfigOutputWidget::~ConfigOutputWidget()
// ************************************
/**
Toggles the channel linked state for use in testing mode
*/
void ConfigOutputWidget::linkToggled(bool state)
{
Q_UNUSED(state)
// find the minimum slider value for the linked ones
int min = 10000;
int linked_count = 0;
for (int i = 0; i < outSliders.count(); i++)
{
if (!links[i]->checkState()) continue;
int value = outSliders[i]->value();
if (min > value) min = value;
linked_count++;
}
if (linked_count <= 0)
return; // no linked channels
if (!m_config->channelOutTest->checkState())
return; // we are not in Test Output mode
// set the linked channels to the same value
for (int i = 0; i < outSliders.count(); i++)
{
if (!links[i]->checkState()) continue;
outSliders[i]->setValue(min);
}
}
/**
Toggles the channel testing mode by making the GCS take over
the ActuatorCommand objects
@ -257,79 +149,43 @@ void ConfigOutputWidget::runChannelTests(bool state)
mdata.gcsTelemetryAcked = false;
mdata.gcsTelemetryUpdateMode = UAVObject::UPDATEMODE_ONCHANGE;
mdata.gcsTelemetryUpdatePeriod = 100;
// Prevent stupid users from touching the minimum & maximum ranges while
// moving the sliders. Thanks Ivan for the tip :)
foreach (QSpinBox* box, outMin) {
box->setEnabled(false);
}
foreach (QSpinBox* box, outMax) {
box->setEnabled(false);
}
foreach (QCheckBox* box, reversals) {
box->setEnabled(false);
}
}
else
{
wasItMe=false;
mdata = accInitialData; // Restore metadata
foreach (QSpinBox* box, outMin) {
box->setEnabled(true);
}
foreach (QSpinBox* box, outMax) {
box->setEnabled(true);
}
foreach (QCheckBox* box, reversals) {
box->setEnabled(true);
}
}
obj->setMetadata(mdata);
obj->updated();
}
OutputChannelForm* ConfigOutputWidget::getOutputChannelForm(const int index) const
{
QList<OutputChannelForm*> outputChannelForms = findChildren<OutputChannelForm*>();
foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
if( outputChannelForm->index() == index)
return outputChannelForm;
}
// no OutputChannelForm found with given index
return NULL;
}
/**
* Set the label for a channel output assignement
*/
void ConfigOutputWidget::assignOutputChannel(UAVDataObject *obj, QString str)
{
//FIXME: use signal/ slot approach
UAVObjectField* field = obj->getField(str);
QStringList options = field->getOptions();
switch (options.indexOf(field->getValue().toString())) {
case 0:
m_config->ch0Output->setText(str);
break;
case 1:
m_config->ch1Output->setText(str);
break;
case 2:
m_config->ch2Output->setText(str);
break;
case 3:
m_config->ch3Output->setText(str);
break;
case 4:
m_config->ch4Output->setText(str);
break;
case 5:
m_config->ch5Output->setText(str);
break;
case 6:
m_config->ch6Output->setText(str);
break;
case 7:
m_config->ch7Output->setText(str);
break;
case 8:
m_config->ch8Output->setText(str);
break;
case 9:
m_config->ch9Output->setText(str);
break;
}
int index = options.indexOf(field->getValue().toString());
OutputChannelForm *outputChannelForm = getOutputChannelForm(index);
if(outputChannelForm)
outputChannelForm->setAssignment(str);
}
/**
@ -337,63 +193,36 @@ void ConfigOutputWidget::assignOutputChannel(UAVDataObject *obj, QString str)
*/
void ConfigOutputWidget::setSpinningArmed(bool val)
{
UAVDataObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorSettings")));
if (!obj) return;
UAVObjectField *field = obj->getField("MotorsSpinWhileArmed");
if (!field) return;
ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
Q_ASSERT(actuatorSettings);
ActuatorSettings::DataFields actuatorSettingsData = actuatorSettings->getData();
if(val)
field->setValue("TRUE");
actuatorSettingsData.MotorsSpinWhileArmed = ActuatorSettings::MOTORSSPINWHILEARMED_TRUE;
else
field->setValue("FALSE");
actuatorSettingsData.MotorsSpinWhileArmed = ActuatorSettings::MOTORSSPINWHILEARMED_FALSE;
// Apply settings
actuatorSettings->setData(actuatorSettingsData);
}
/**
Sends the channel value to the UAV to move the servo.
Returns immediately if we are not in testing mode
*/
void ConfigOutputWidget::sendChannelTest(int value)
void ConfigOutputWidget::sendChannelTest(int index, int value)
{
int in_value = value;
if (!m_config->channelOutTest->isChecked())
return;
QSlider *ob = (QSlider *)QObject::sender();
if (!ob) return;
int index = outSliders.indexOf(ob);
if (index < 0) return;
if(index < 0 || (unsigned)index >= ActuatorCommand::CHANNEL_NUMELEM)
return;
if (reversals[index]->isChecked())
value = outMin[index]->value() - value + outMax[index]->value(); // the chsnnel is reversed
// update the label
outLabels[index]->setText(QString::number(value));
if (links[index]->checkState())
{ // the channel is linked to other channels
// set the linked channels to the same value
for (int i = 0; i < outSliders.count(); i++)
{
if (i == index) continue;
if (!links[i]->checkState()) continue;
int val = in_value;
if (val < outSliders[i]->minimum()) val = outSliders[i]->minimum();
if (val > outSliders[i]->maximum()) val = outSliders[i]->maximum();
if (outSliders[i]->value() == val) continue;
outSliders[i]->setValue(val);
outLabels[i]->setText(QString::number(val));
}
}
if (!m_config->channelOutTest->isChecked())
return;
UAVDataObject *obj = dynamic_cast<UAVDataObject*>(getObjectManager()->getObject(QString("ActuatorCommand")));
if (!obj) return;
UAVObjectField *channel = obj->getField("Channel");
if (!channel) return;
channel->setValue(value, index);
obj->updated();
ActuatorCommand *actuatorCommand = ActuatorCommand::GetInstance(getObjectManager());
Q_ASSERT(actuatorCommand);
ActuatorCommand::DataFields actuatorCommandFields = actuatorCommand->getData();
actuatorCommandFields.Channel[index] = value;
actuatorCommand->setData(actuatorCommandFields);
}
@ -408,14 +237,21 @@ void ConfigOutputWidget::sendChannelTest(int value)
void ConfigOutputWidget::refreshWidgetsValues()
{
bool dirty=isDirty();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
// Reset all channel assignements:
for (int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++)
outLabels[i]->setText("-");
QList<OutputChannelForm*> outputChannelForms = findChildren<OutputChannelForm*>();
foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
outputChannelForm->setAssignment("-");
}
// Get the channel assignements:
// FIXME: Use static accessor method for retrieving channel assignments
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
Q_ASSERT(pm);
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
Q_ASSERT(objManager);
// Get the channel assignements:
UAVDataObject * obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj);
QList<UAVObjectField*> fieldList = obj->getFields();
@ -425,15 +261,17 @@ void ConfigOutputWidget::refreshWidgetsValues()
}
}
ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
Q_ASSERT(actuatorSettings);
ActuatorSettings::DataFields actuatorSettingsData = actuatorSettings->getData();
// Get the SpinWhileArmed setting
UAVObjectField *field = obj->getField(QString("MotorsSpinWhileArmed"));
m_config->spinningArmed->setChecked(field->getValue().toString().contains("TRUE"));
m_config->spinningArmed->setChecked(actuatorSettingsData.MotorsSpinWhileArmed == ActuatorSettings::MOTORSSPINWHILEARMED_TRUE);
// Get Output rates for both banks
field = obj->getField(QString("ChannelUpdateFreq"));
m_config->outputRate1->setValue(actuatorSettingsData.ChannelUpdateFreq[0]);
m_config->outputRate2->setValue(actuatorSettingsData.ChannelUpdateFreq[1]);
UAVObjectUtilManager* utilMngr = pm->getObject<UAVObjectUtilManager>();
m_config->outputRate1->setValue(field->getValue(0).toInt());
m_config->outputRate2->setValue(field->getValue(1).toInt());
if (utilMngr) {
int board = utilMngr->getBoardModel();
if ((board & 0xff00) == 1024) {
@ -446,8 +284,8 @@ void ConfigOutputWidget::refreshWidgetsValues()
m_config->outputRate2->setEnabled(true);
m_config->outputRate3->setEnabled(true);
m_config->outputRate4->setEnabled(true);
m_config->outputRate3->setValue(field->getValue(2).toInt());
m_config->outputRate4->setValue(field->getValue(3).toInt());
m_config->outputRate3->setValue(actuatorSettingsData.ChannelUpdateFreq[2]);
m_config->outputRate4->setValue(actuatorSettingsData.ChannelUpdateFreq[3]);
} else if ((board & 0xff00) == 256 ) {
// Mainboard family
m_config->outputRate1->setEnabled(true);
@ -463,34 +301,18 @@ void ConfigOutputWidget::refreshWidgetsValues()
}
}
// Get Channel ranges:
for (int i=0;i<ActuatorCommand::CHANNEL_NUMELEM;i++) {
field = obj->getField(QString("ChannelMin"));
int minValue = field->getValue(i).toInt();
outMin[i]->setValue(minValue);
field = obj->getField(QString("ChannelMax"));
int maxValue = field->getValue(i).toInt();
outMax[i]->setValue(maxValue);
if (maxValue>minValue) {
outSliders[i]->setMinimum(minValue);
outSliders[i]->setMaximum(maxValue);
reversals[i]->setChecked(false);
} else {
outSliders[i]->setMinimum(maxValue);
outSliders[i]->setMaximum(minValue);
reversals[i]->setChecked(true);
}
foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
int minValue = actuatorSettingsData.ChannelMin[outputChannelForm->index()];
int maxValue = actuatorSettingsData.ChannelMax[outputChannelForm->index()];
outputChannelForm->minmax(minValue, maxValue);
int neutral = actuatorSettingsData.ChannelNeutral[outputChannelForm->index()];
outputChannelForm->neutral(neutral);
}
field = obj->getField(QString("ChannelNeutral"));
for (int i=0; i<ActuatorCommand::CHANNEL_NUMELEM; i++) {
int value = field->getValue(i).toInt();
outSliders[i]->setValue(value);
outLabels[i]->setText(QString::number(value));
}
setDirty(dirty);
}
/**
@ -498,105 +320,27 @@ void ConfigOutputWidget::refreshWidgetsValues()
*/
void ConfigOutputWidget::updateObjectsFromWidgets()
{
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
UAVDataObject* obj = dynamic_cast<UAVDataObject*>(objManager->getObject(QString("ActuatorSettings")));
Q_ASSERT(obj);
ActuatorSettings *actuatorSettings = ActuatorSettings::GetInstance(getObjectManager());
Q_ASSERT(actuatorSettings);
ActuatorSettings::DataFields actuatorSettingsData = actuatorSettings->getData();
// Now send channel ranges:
UAVObjectField * field = obj->getField(QString("ChannelMax"));
for (int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++) {
field->setValue(outMax[i]->value(),i);
}
field = obj->getField(QString("ChannelMin"));
for (int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++) {
field->setValue(outMin[i]->value(),i);
}
field = obj->getField(QString("ChannelNeutral"));
for (int i = 0; i < ActuatorCommand::CHANNEL_NUMELEM; i++) {
field->setValue(outSliders[i]->value(),i);
}
field = obj->getField(QString("ChannelUpdateFreq"));
field->setValue(m_config->outputRate1->value(),0);
field->setValue(m_config->outputRate2->value(),1);
field->setValue(m_config->outputRate3->value(),2);
field->setValue(m_config->outputRate4->value(),3);
}
/**
Sets the minimum/maximum value of the channel 0 to seven output sliders.
Have to do it here because setMinimum is not a slot.
One added trick: if the slider is at its min when the value
is changed, then keep it on the min.
*/
void ConfigOutputWidget::setChOutRange()
{
QSpinBox *spinbox = (QSpinBox*)QObject::sender();
int index = outMin.indexOf(spinbox); // This is the channel number
if (index < 0)
index = outMax.indexOf(spinbox); // We can't know if the signal came from min or max
QSlider *slider = outSliders[index];
int oldMini = slider->minimum();
// int oldMaxi = slider->maximum();
if (outMin[index]->value()<outMax[index]->value())
// Set channel ranges
QList<OutputChannelForm*> outputChannelForms = findChildren<OutputChannelForm*>();
foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
slider->setRange(outMin[index]->value(), outMax[index]->value());
reversals[index]->setChecked(false);
}
else
{
slider->setRange(outMax[index]->value(), outMin[index]->value());
reversals[index]->setChecked(true);
actuatorSettingsData.ChannelMax[outputChannelForm->index()] = outputChannelForm->max();
actuatorSettingsData.ChannelMin[outputChannelForm->index()] = outputChannelForm->min();
actuatorSettingsData.ChannelNeutral[outputChannelForm->index()] = outputChannelForm->neutral();
}
if (slider->value() == oldMini)
slider->setValue(slider->minimum());
// if (slider->value() == oldMaxi)
// slider->setValue(slider->maximum()); // this can be dangerous if it happens to be controlling a motor at the time!
}
/**
Reverses the channel when the checkbox is clicked
*/
void ConfigOutputWidget::reverseChannel(bool state)
{
QCheckBox *checkbox = (QCheckBox*)QObject::sender();
int index = reversals.indexOf(checkbox); // This is the channel number
// Sanity check: if state became true, make sure the Maxvalue was higher than Minvalue
// the situations below can happen!
if (state && (outMax[index]->value()<outMin[index]->value()))
return;
if (!state && (outMax[index]->value()>outMin[index]->value()))
return;
// Now, swap the min & max values (only on the spinboxes, the slider
// does not change!
int temp = outMax[index]->value();
outMax[index]->setValue(outMin[index]->value());
outMin[index]->setValue(temp);
// Also update the channel value
// This is a trick to force the slider to update its value and
// emit the right signal itself, because our sendChannelTest(int) method
// relies on the object sender's identity.
if (outSliders[index]->value()<outSliders[index]->maximum()) {
outSliders[index]->setValue(outSliders[index]->value()+1);
outSliders[index]->setValue(outSliders[index]->value()-1);
} else {
outSliders[index]->setValue(outSliders[index]->value()-1);
outSliders[index]->setValue(outSliders[index]->value()+1);
}
// Set update rates
actuatorSettingsData.ChannelUpdateFreq[0] = m_config->outputRate1->value();
actuatorSettingsData.ChannelUpdateFreq[1] = m_config->outputRate2->value();
actuatorSettingsData.ChannelUpdateFreq[2] = m_config->outputRate3->value();
actuatorSettingsData.ChannelUpdateFreq[3] = m_config->outputRate4->value();
// Apply settings
actuatorSettings->setData(actuatorSettingsData);
}
void ConfigOutputWidget::openHelp()

View File

@ -1,13 +1,13 @@
/**
******************************************************************************
*
* @file configservowidget.h
* @file configoutputwidget.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Servo input/output configuration panel for the config gadget
* @brief Servo output configuration panel for the config gadget
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
@ -37,6 +37,7 @@
#include <QList>
class Ui_OutputWidget;
class OutputChannelForm;
class ConfigOutputWidget: public ConfigTaskWidget
{
@ -55,18 +56,12 @@ private:
void assignChannel(UAVDataObject *obj, QString str);
void assignOutputChannel(UAVDataObject *obj, QString str);
OutputChannelForm* getOutputChannelForm(const int index) const;
int mccDataRate;
UAVObject::Metadata accInitialData;
QList<QSlider*> outSliders;
QList<QSpinBox*> outMin;
QList<QSpinBox*> outMax;
QList<QCheckBox*> reversals;
QList<QCheckBox*> links;
QList<QLabel*> outLabels;
bool firstUpdate;
bool wasItMe;
@ -76,10 +71,7 @@ private slots:
virtual void refreshWidgetsValues();
void updateObjectsFromWidgets();
void runChannelTests(bool state);
void sendChannelTest(int value);
void setChOutRange();
void reverseChannel(bool state);
void linkToggled(bool state);
void sendChannelTest(int index, int value);
void setSpinningArmed(bool val);
void openHelp();
};

View File

@ -210,933 +210,7 @@ Leave at 50Hz for fixed wing.</string>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<widget class="QLabel" name="actuator0Label">
<property name="text">
<string>Channel 1:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="ch0OutMin">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Minimum PWM value, beware of not overdriving your servo.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QSlider" name="ch0OutSlider">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QSpinBox" name="ch0OutMax">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Maximum PWM value, beware of not overdriving your servo.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QLabel" name="ch0OutValue">
<property name="toolTip">
<string>Current value of slider.</string>
</property>
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QCheckBox" name="ch0Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="7">
<widget class="QCheckBox" name="ch0Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="7">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Link</string>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QLabel" name="label">
<property name="text">
<string>Rev.</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="actuator1Label">
<property name="text">
<string>Channel 2:</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QSpinBox" name="ch1OutMin">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QSlider" name="ch1OutSlider">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QSpinBox" name="ch1OutMax">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="2" column="5">
<widget class="QLabel" name="ch1OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="2" column="6">
<widget class="QCheckBox" name="ch1Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="7">
<widget class="QCheckBox" name="ch1Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="actuator2Label">
<property name="text">
<string>Channel 3:</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="ch2OutMin">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QSlider" name="ch2OutSlider">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QSpinBox" name="ch2OutMax">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="3" column="5">
<widget class="QLabel" name="ch2OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="3" column="6">
<widget class="QCheckBox" name="ch2Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="7">
<widget class="QCheckBox" name="ch2Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="actuator3Label">
<property name="text">
<string>Channel 4:</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QSpinBox" name="ch3OutMin">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QSlider" name="ch3OutSlider">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QSpinBox" name="ch3OutMax">
<property name="enabled">
<bool>true</bool>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="4" column="5">
<widget class="QLabel" name="ch3OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="4" column="6">
<widget class="QCheckBox" name="ch3Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="7">
<widget class="QCheckBox" name="ch3Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="actuator4Label">
<property name="text">
<string>Channel 5:</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QSpinBox" name="ch4OutMin">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QSlider" name="ch4OutSlider">
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="5" column="4">
<widget class="QSpinBox" name="ch4OutMax">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="5" column="5">
<widget class="QLabel" name="ch4OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="5" column="6">
<widget class="QCheckBox" name="ch4Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="5" column="7">
<widget class="QCheckBox" name="ch4Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="actuator5Label">
<property name="text">
<string>Channel 6:</string>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QSpinBox" name="ch5OutMin">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="6" column="3">
<widget class="QSlider" name="ch5OutSlider">
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="6" column="4">
<widget class="QSpinBox" name="ch5OutMax">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="6" column="5">
<widget class="QLabel" name="ch5OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="6" column="6">
<widget class="QCheckBox" name="ch5Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="7">
<widget class="QCheckBox" name="ch5Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="actuator6Label">
<property name="text">
<string>Channel 7:</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="actuator7Label">
<property name="text">
<string>Channel 8:</string>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QSpinBox" name="ch6OutMin">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="7" column="3">
<widget class="QSlider" name="ch6OutSlider">
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="7" column="4">
<widget class="QSpinBox" name="ch6OutMax">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="7" column="5">
<widget class="QLabel" name="ch6OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="7" column="6">
<widget class="QCheckBox" name="ch6Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="7" column="7">
<widget class="QCheckBox" name="ch6Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="QSpinBox" name="ch7OutMin">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="8" column="3">
<widget class="QSlider" name="ch7OutSlider">
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="8" column="4">
<widget class="QSpinBox" name="ch7OutMax">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="8" column="5">
<widget class="QLabel" name="ch7OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="8" column="6">
<widget class="QCheckBox" name="ch7Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="8" column="7">
<widget class="QCheckBox" name="ch7Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="ch0Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="ch1Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="ch2Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="ch3Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="ch4Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="ch5Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="ch6Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QLabel" name="ch7Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Assignment</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Min</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Neutral (slowest for motor)</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Max</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="actuator8Label">
<property name="text">
<string>Channel 9:</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="actuator9Label">
<property name="text">
<string>Channel 10:</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QLabel" name="ch8Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QLabel" name="ch9Output">
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="9" column="2">
<widget class="QSpinBox" name="ch8OutMin">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="10" column="2">
<widget class="QSpinBox" name="ch9OutMin">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="9" column="3">
<widget class="QSlider" name="ch8OutSlider">
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="10" column="3">
<widget class="QSlider" name="ch9OutSlider">
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="9" column="4">
<widget class="QSpinBox" name="ch8OutMax">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="10" column="4">
<widget class="QSpinBox" name="ch9OutMax">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="9" column="5">
<widget class="QLabel" name="ch8OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="10" column="5">
<widget class="QLabel" name="ch9OutValue">
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="9" column="6">
<widget class="QCheckBox" name="ch8Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="10" column="6">
<widget class="QCheckBox" name="ch9Rev">
<property name="font">
<font>
<family>FreeSans</family>
<pointsize>8</pointsize>
</font>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'FreeSans'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Check to invert the channel.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="9" column="7">
<widget class="QCheckBox" name="ch8Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="10" column="7">
<widget class="QCheckBox" name="ch9Link">
<property name="toolTip">
<string>Only used with Test Output mode</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
<layout class="QVBoxLayout" name="channelLayout"/>
</item>
<item>
<spacer name="verticalSpacer_2">
@ -1281,46 +355,6 @@ Applies and Saves all settings to SD</string>
<tabstop>outputRate2</tabstop>
<tabstop>outputRate3</tabstop>
<tabstop>outputRate4</tabstop>
<tabstop>ch0OutMin</tabstop>
<tabstop>ch0OutMax</tabstop>
<tabstop>ch1OutMin</tabstop>
<tabstop>ch1OutMax</tabstop>
<tabstop>ch2OutMin</tabstop>
<tabstop>ch2OutMax</tabstop>
<tabstop>ch3OutMin</tabstop>
<tabstop>ch3OutMax</tabstop>
<tabstop>ch4OutMin</tabstop>
<tabstop>ch4OutMax</tabstop>
<tabstop>ch5OutMin</tabstop>
<tabstop>ch5OutMax</tabstop>
<tabstop>ch6OutMin</tabstop>
<tabstop>ch6OutMax</tabstop>
<tabstop>ch7OutMin</tabstop>
<tabstop>ch7OutMax</tabstop>
<tabstop>ch0OutSlider</tabstop>
<tabstop>ch0Rev</tabstop>
<tabstop>ch0Link</tabstop>
<tabstop>ch1OutSlider</tabstop>
<tabstop>ch1Rev</tabstop>
<tabstop>ch1Link</tabstop>
<tabstop>ch2OutSlider</tabstop>
<tabstop>ch2Rev</tabstop>
<tabstop>ch2Link</tabstop>
<tabstop>ch3OutSlider</tabstop>
<tabstop>ch3Rev</tabstop>
<tabstop>ch3Link</tabstop>
<tabstop>ch4OutSlider</tabstop>
<tabstop>ch4Rev</tabstop>
<tabstop>ch4Link</tabstop>
<tabstop>ch5OutSlider</tabstop>
<tabstop>ch5Rev</tabstop>
<tabstop>ch5Link</tabstop>
<tabstop>ch6OutSlider</tabstop>
<tabstop>ch6Rev</tabstop>
<tabstop>ch6Link</tabstop>
<tabstop>ch7OutSlider</tabstop>
<tabstop>ch7Rev</tabstop>
<tabstop>ch7Link</tabstop>
<tabstop>channelOutTest</tabstop>
<tabstop>saveRCOutputToRAM</tabstop>
<tabstop>saveRCOutputToSD</tabstop>

View File

@ -0,0 +1,297 @@
/**
******************************************************************************
*
* @file outputchannelform.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Servo output configuration form for the config output gadget
*****************************************************************************/
/*
* 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 "outputchannelform.h"
#include "configoutputwidget.h"
OutputChannelForm::OutputChannelForm(const int index, QWidget *parent, const bool showLegend) :
QWidget(parent),
ui(),
m_index(index),
m_inChannelTest(false)
{
ui.setupUi(this);
if(!showLegend)
{
// Remove legend
QGridLayout *grid_layout = dynamic_cast<QGridLayout*>(layout());
Q_ASSERT(grid_layout);
for (int col = 0; col < grid_layout->columnCount(); col++)
{ // remove every item in first row
QLayoutItem *item = grid_layout->itemAtPosition(0, col);
if (!item) continue;
// get widget from layout item
QWidget *legend_widget = item->widget();
if (!legend_widget) continue;
// delete widget
grid_layout->removeWidget(legend_widget);
delete legend_widget;
}
}
// The convention for OP is Channel 1 to Channel 10.
ui.actuatorNumber->setText(QString("%1:").arg(m_index+1));
// Register for ActuatorSettings changes:
connect(ui.actuatorMin, SIGNAL(editingFinished()),
this, SLOT(setChannelRange()));
connect(ui.actuatorMax, SIGNAL(editingFinished()),
this, SLOT(setChannelRange()));
connect(ui.actuatorRev, SIGNAL(toggled(bool)),
this, SLOT(reverseChannel(bool)));
// Now connect the channel out sliders to our signal to send updates in test mode
connect(ui.actuatorNeutral, SIGNAL(valueChanged(int)),
this, SLOT(sendChannelTest(int)));
ui.actuatorLink->setChecked(false);
connect(ui.actuatorLink, SIGNAL(toggled(bool)),
this, SLOT(linkToggled(bool)));
}
OutputChannelForm::~OutputChannelForm()
{
// Do nothing
}
/**
* Restrict UI to protect users from accidental misuse.
*/
void OutputChannelForm::enableChannelTest(bool state)
{
if (m_inChannelTest == state) return;
m_inChannelTest = state;
if(m_inChannelTest)
{
// Prevent stupid users from touching the minimum & maximum ranges while
// moving the sliders. Thanks Ivan for the tip :)
ui.actuatorMin->setEnabled(false);
ui.actuatorMax->setEnabled(false);
ui.actuatorRev->setEnabled(false);
}
else
{
ui.actuatorMin->setEnabled(true);
ui.actuatorMax->setEnabled(true);
ui.actuatorRev->setEnabled(true);
}
}
/**
* Toggles the channel linked state for use in testing mode
*/
void OutputChannelForm::linkToggled(bool state)
{
Q_UNUSED(state)
if (!m_inChannelTest)
return; // we are not in Test Output mode
// find the minimum slider value for the linked ones
if (!parent()) return;
int min = 10000;
int linked_count = 0;
QList<OutputChannelForm*> outputChannelForms = parent()->findChildren<OutputChannelForm*>();
// set the linked channels of the parent widget to the same value
foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
if (!outputChannelForm->ui.actuatorLink->checkState())
continue;
if (this == outputChannelForm)
continue;
int value = outputChannelForm->ui.actuatorNeutral->value();
if(min > value) min = value;
linked_count++;
}
if (linked_count <= 0)
return; // no linked channels
// set the linked channels to the same value
foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
if (!outputChannelForm->ui.actuatorLink->checkState())
continue;
outputChannelForm->ui.actuatorNeutral->setValue(min);
}
}
/**
* Set maximal channel value.
*/
void OutputChannelForm::max(int maximum)
{
minmax(ui.actuatorMin->value(), maximum);
}
/**
* Set minimal channel value.
*/
void OutputChannelForm::min(int minimum)
{
minmax(minimum, ui.actuatorMax->value());
}
/**
* Set minimal and maximal channel value.
*/
void OutputChannelForm::minmax(int minimum, int maximum)
{
ui.actuatorMin->setValue(minimum);
ui.actuatorMax->setValue(maximum);
setChannelRange();
if(ui.actuatorMin->value() > ui.actuatorMax->value())
ui.actuatorRev->setChecked(true);
else
ui.actuatorRev->setChecked(false);
}
/**
* Set neutral of channel.
*/
void OutputChannelForm::neutral(int value)
{
ui.actuatorNeutral->setValue(value);
}
/**
* Set the channel assignment label.
*/
void OutputChannelForm::setAssignment(const QString &assignment)
{
ui.actuatorName->setText(assignment);
}
/**
* Sets the minimum/maximum value of the channel output sliders.
* Have to do it here because setMinimum is not a slot.
*
* One added trick: if the slider is at its min when the value
* is changed, then keep it on the min.
*/
void OutputChannelForm::setChannelRange()
{
int oldMini = ui.actuatorNeutral->minimum();
// int oldMaxi = ui.actuatorNeutral->maximum();
if (ui.actuatorMin->value() < ui.actuatorMax->value())
{
ui.actuatorNeutral->setRange(ui.actuatorMin->value(), ui.actuatorMax->value());
ui.actuatorRev->setChecked(false);
}
else
{
ui.actuatorNeutral->setRange(ui.actuatorMax->value(), ui.actuatorMin->value());
ui.actuatorRev->setChecked(true);
}
if (ui.actuatorNeutral->value() == oldMini)
ui.actuatorNeutral->setValue(ui.actuatorNeutral->minimum());
// if (ui.actuatorNeutral->value() == oldMaxi)
// ui.actuatorNeutral->setValue(ui.actuatorNeutral->maximum()); // this can be dangerous if it happens to be controlling a motor at the time!
}
/**
* Reverses the channel when the checkbox is clicked
*/
void OutputChannelForm::reverseChannel(bool state)
{
// Sanity check: if state became true, make sure the Maxvalue was higher than Minvalue
// the situations below can happen!
if (state && (ui.actuatorMax->value() < ui.actuatorMin->value()))
return;
if (!state && (ui.actuatorMax->value() > ui.actuatorMin->value()))
return;
// Now, swap the min & max values (only on the spinboxes, the slider
// does not change!
int temp = ui.actuatorMax->value();
ui.actuatorMax->setValue(ui.actuatorMin->value());
ui.actuatorMin->setValue(temp);
// Also update the channel value
// This is a trick to force the slider to update its value and
// emit the right signal itself, because our sendChannelTest(int) method
// relies on the object sender's identity.
if (ui.actuatorNeutral->value() < ui.actuatorNeutral->maximum())
{
ui.actuatorNeutral->setValue(ui.actuatorNeutral->value()+1);
ui.actuatorNeutral->setValue(ui.actuatorNeutral->value()-1);
}
else
{
ui.actuatorNeutral->setValue(ui.actuatorNeutral->value()-1);
ui.actuatorNeutral->setValue(ui.actuatorNeutral->value()+1);
}
}
/**
* Emits the channel value which will be send to the UAV to move the servo.
* Returns immediately if we are not in testing mode.
*/
void OutputChannelForm::sendChannelTest(int value)
{
int in_value = value;
QSlider *ob = (QSlider *)QObject::sender();
if (!ob) return;
if (ui.actuatorRev->isChecked())
value = ui.actuatorMin->value() - value + ui.actuatorMax->value(); // the channel is reversed
// update the label
ui.actuatorValue->setText(QString::number(value));
if (ui.actuatorLink->checkState() && parent())
{ // the channel is linked to other channels
QList<OutputChannelForm*> outputChannelForms = parent()->findChildren<OutputChannelForm*>();
// set the linked channels of the parent widget to the same value
foreach(OutputChannelForm *outputChannelForm, outputChannelForms)
{
if (this == outputChannelForm) continue;
if (!outputChannelForm->ui.actuatorLink->checkState()) continue;
int val = in_value;
if (val < outputChannelForm->ui.actuatorNeutral->minimum())
val = outputChannelForm->ui.actuatorNeutral->minimum();
if (val > outputChannelForm->ui.actuatorNeutral->maximum())
val = outputChannelForm->ui.actuatorNeutral->maximum();
if (outputChannelForm->ui.actuatorNeutral->value() == val) continue;
outputChannelForm->ui.actuatorNeutral->setValue(val);
outputChannelForm->ui.actuatorValue->setText(QString::number(val));
}
}
if (!m_inChannelTest)
return; // we are not in Test Output mode
emit channelChanged(index(), value);
}

View File

@ -0,0 +1,92 @@
/**
******************************************************************************
*
* @file outputchannelform.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2011.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup ConfigPlugin Config Plugin
* @{
* @brief Servo output configuration form for the config output gadget
*****************************************************************************/
/*
* 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
*/
#ifndef OUTPUTCHANNELFORM_H
#define OUTPUTCHANNELFORM_H
#include <QWidget>
#include "ui_outputchannelform.h"
class ConfigInputWidget;
class OutputChannelForm : public QWidget
{
Q_OBJECT
public:
explicit OutputChannelForm(const int index, QWidget *parent = NULL, const bool showLegend = false);
~OutputChannelForm();
friend class ConfigInputWidget;
void setAssignment(const QString &assignment);
int index() const;
public slots:
void max(int maximum);
int max() const;
void min(int minimum);
int min() const;
void minmax(int minimum, int maximum);
void neutral(int value);
int neutral() const;
void enableChannelTest(bool state);
signals:
void channelChanged(int index, int value);
private:
Ui::outputChannelForm ui;
/// Channel index
int m_index;
bool m_inChannelTest;
private slots:
void linkToggled(bool state);
void reverseChannel(bool state);
void sendChannelTest(int value);
void setChannelRange();
};
inline int OutputChannelForm::index() const
{
return m_index;
}
inline int OutputChannelForm::max() const
{
return ui.actuatorMax->value();
}
inline int OutputChannelForm::min() const
{
return ui.actuatorMin->value();
}
inline int OutputChannelForm::neutral() const
{
return ui.actuatorNeutral->value();
}
#endif // OUTPUTCHANNELFORM_H

View File

@ -0,0 +1,287 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>outputChannelForm</class>
<widget class="QWidget" name="outputChannelForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>562</width>
<height>49</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="topMargin">
<number>1</number>
</property>
<property name="bottomMargin">
<number>1</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="actuatorNumber">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Channel Number</string>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="actuatorName">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QSpinBox" name="actuatorMin">
<property name="toolTip">
<string>Minimum PWM value, beware of not overdriving your servo.</string>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="1" column="3">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="4">
<widget class="QSlider" name="actuatorNeutral">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximum">
<number>9999</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="6">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="9">
<widget class="QCheckBox" name="actuatorRev">
<property name="toolTip">
<string>Check to invert the channel.</string>
</property>
</widget>
</item>
<item row="1" column="10">
<widget class="QCheckBox" name="actuatorLink">
<property name="toolTip">
<string>Output mode</string>
</property>
</widget>
</item>
<item row="1" column="8">
<widget class="QSpinBox" name="actuatorMax">
<property name="toolTip">
<string>Maximum PWM value, beware of not overdriving your servo.</string>
</property>
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="legend0">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Assignment</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="legend1">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Min</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="legend2">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Neutral (slowest for motor)</string>
</property>
</widget>
</item>
<item row="0" column="8">
<widget class="QLabel" name="legend3">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Max</string>
</property>
</widget>
</item>
<item row="0" column="9">
<widget class="QLabel" name="legend4">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Rev.</string>
</property>
</widget>
</item>
<item row="0" column="10">
<widget class="QLabel" name="legend5">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Link</string>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QLabel" name="actuatorValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Current value of slider.</string>
</property>
<property name="text">
<string>0000</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="legend6">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>#</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="margin">
<number>0</number>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>