12 changed files with 37 additions and 1878 deletions
@ -1,125 +0,0 @@
@@ -1,125 +0,0 @@
|
||||
/*=====================================================================
|
||||
|
||||
QGroundControl Open Source Ground Control Station |
||||
|
||||
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
|
||||
This file is part of the QGROUNDCONTROL project |
||||
|
||||
QGROUNDCONTROL 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. |
||||
|
||||
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
======================================================================*/ |
||||
|
||||
/**
|
||||
* @file |
||||
* @brief Definition of class ParameterInterface |
||||
* @author Lorenz Meier <mavteam@student.ethz.ch> |
||||
* |
||||
*/ |
||||
|
||||
#include <QTreeWidget> |
||||
|
||||
#include "ParameterInterface.h" |
||||
#include "UASManager.h" |
||||
#include "ui_ParameterInterface.h" |
||||
#include "QGCSensorSettingsWidget.h" |
||||
|
||||
#include <QDebug> |
||||
#include <QSettings> |
||||
|
||||
ParameterInterface::ParameterInterface(QWidget *parent) : |
||||
QWidget(parent), |
||||
paramWidgets(new QMap<int, QGCParamWidget*>()), |
||||
curr(-1), |
||||
m_ui(new Ui::parameterWidget) |
||||
{ |
||||
m_ui->setupUi(this); |
||||
|
||||
QSettings settings; |
||||
|
||||
// Get current MAV list
|
||||
QList<UASInterface*> systems = UASManager::instance()->getUASList(); |
||||
|
||||
// Add each of them
|
||||
foreach (UASInterface* sys, systems) { |
||||
addUAS(sys); |
||||
} |
||||
|
||||
// Setup MAV connections
|
||||
connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(addUAS(UASInterface*))); |
||||
connect(UASManager::instance(), SIGNAL(activeUASSetListIndex(int)), this, SLOT(selectUAS(int))); |
||||
this->setVisible(false); |
||||
} |
||||
|
||||
ParameterInterface::~ParameterInterface() |
||||
{ |
||||
delete paramWidgets; |
||||
delete m_ui; |
||||
} |
||||
|
||||
void ParameterInterface::selectUAS(int index) |
||||
{ |
||||
m_ui->stackedWidget->setCurrentIndex(index); |
||||
m_ui->sensorSettings->setCurrentIndex(index); |
||||
curr = index; |
||||
} |
||||
|
||||
/**
|
||||
* |
||||
* @param uas System to add to list |
||||
*/ |
||||
void ParameterInterface::addUAS(UASInterface* uas) |
||||
{ |
||||
int uasId = uas->getUASID(); |
||||
qDebug() << "ParameterInterface::addUAS : " << uasId ; |
||||
|
||||
if (paramWidgets->contains(uasId) ) { |
||||
return; |
||||
} |
||||
|
||||
QGCParamWidget* paramWidget = new QGCParamWidget(this); |
||||
paramWidget = (QGCParamWidget*)paramWidget->initWithUAS(uas); |
||||
|
||||
QString ptrStr; |
||||
ptrStr.sprintf("QGCParamWidget %8p (parent %8p)", paramWidget,this); |
||||
qDebug() << "Created " << ptrStr << " for UAS id: " << uasId << " count: " << paramWidgets->count(); |
||||
|
||||
paramWidgets->insert(uasId, paramWidget); |
||||
m_ui->stackedWidget->addWidget(paramWidget); |
||||
|
||||
QGCSensorSettingsWidget* sensor = NULL; |
||||
|
||||
sensor = new QGCSensorSettingsWidget(uas, this); |
||||
m_ui->sensorSettings->addWidget(sensor); |
||||
|
||||
// Set widgets as default
|
||||
if (curr == -1) { |
||||
// Clear
|
||||
if (m_ui->sensorSettings && sensor) |
||||
m_ui->sensorSettings->setCurrentWidget(sensor); |
||||
m_ui->stackedWidget->setCurrentWidget(paramWidget); |
||||
curr = 0; |
||||
} |
||||
} |
||||
|
||||
void ParameterInterface::changeEvent(QEvent *e) |
||||
{ |
||||
switch (e->type()) { |
||||
case QEvent::LanguageChange: |
||||
m_ui->retranslateUi(this); |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
} |
@ -1,38 +0,0 @@
@@ -1,38 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<ui version="4.0"> |
||||
<class>parameterWidget</class> |
||||
<widget class="QWidget" name="parameterWidget"> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>0</x> |
||||
<y>0</y> |
||||
<width>707</width> |
||||
<height>572</height> |
||||
</rect> |
||||
</property> |
||||
<property name="windowTitle"> |
||||
<string>Form</string> |
||||
</property> |
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="100,1"> |
||||
<property name="margin"> |
||||
<number>0</number> |
||||
</property> |
||||
<item> |
||||
<widget class="QStackedWidget" name="stackedWidget"> |
||||
<property name="currentIndex"> |
||||
<number>-1</number> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QStackedWidget" name="sensorSettings"> |
||||
<property name="currentIndex"> |
||||
<number>-1</number> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
</layout> |
||||
</widget> |
||||
<resources/> |
||||
<connections/> |
||||
</ui> |
@ -1,506 +0,0 @@
@@ -1,506 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<ui version="4.0"> |
||||
<class>UASView</class> |
||||
<widget class="QWidget" name="UASView"> |
||||
<property name="geometry"> |
||||
<rect> |
||||
<x>0</x> |
||||
<y>0</y> |
||||
<width>428</width> |
||||
<height>419</height> |
||||
</rect> |
||||
</property> |
||||
<property name="sizePolicy"> |
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum"> |
||||
<horstretch>0</horstretch> |
||||
<verstretch>0</verstretch> |
||||
</sizepolicy> |
||||
</property> |
||||
<property name="minimumSize"> |
||||
<size> |
||||
<width>200</width> |
||||
<height>100</height> |
||||
</size> |
||||
</property> |
||||
<property name="windowTitle"> |
||||
<string>Form</string> |
||||
</property> |
||||
<property name="styleSheet"> |
||||
<string>QWidget#colorIcon {} |
||||
|
||||
QWidget { |
||||
background-color: #252528; |
||||
color: #DDDDDF; |
||||
border-color: #EEEEEE; |
||||
background-clip: margin; |
||||
} |
||||
|
||||
QGroupBox { |
||||
border: 1px solid #EEEEEE; |
||||
border-radius: 5px; |
||||
padding: 0px 0px 0px 0px; |
||||
margin: 0px; |
||||
} |
||||
|
||||
QGroupBox::title { |
||||
subcontrol-origin: margin; |
||||
subcontrol-position: top center; /* position at the top center */ |
||||
margin: 0 3px 0px 3px; |
||||
padding: 0 3px 0px 0px; |
||||
font: bold 8px; |
||||
} |
||||
|
||||
QGroupBox#heartbeatIcon { |
||||
background-color: red; |
||||
} |
||||
|
||||
QPushButton { |
||||
font-weight: bold; |
||||
font-size: 12px; |
||||
border: 1px solid #999999; |
||||
border-radius: 10px; |
||||
max-width: 40px; |
||||
padding: 2px; |
||||
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #777777, stop: 1 #555555); |
||||
} |
||||
|
||||
QPushButton:pressed { |
||||
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #444444, stop: 1 #555555); |
||||
} |
||||
|
||||
QPushButton#landButton { |
||||
color: #000000; |
||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, |
||||
stop:0 #ffee01, stop:1 #ae8f00) url("ICONDIR/control/emergency-button.png"); |
||||
} |
||||
|
||||
QPushButton:pressed#landButton { |
||||
color: #000000; |
||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, |
||||
stop:0 #bbaa00, stop:1 #a05b00) url("ICONDIR/control/emergency-button.png"); |
||||
} |
||||
|
||||
QPushButton#killButton { |
||||
color: #000000; |
||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, |
||||
stop:0 #ffb917, stop:1 #b37300) url("ICONDIR/control/emergency-button.png"); |
||||
} |
||||
|
||||
QPushButton:pressed#killButton { |
||||
color: #000000; |
||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1, |
||||
stop:0 #bb8500, stop:1 #903000) url("ICONDIR/control/emergency-button.png"); |
||||
} |
||||
|
||||
QProgressBar { |
||||
border: 1px solid white; |
||||
border-radius: 4px; |
||||
text-align: center; |
||||
padding: 2px; |
||||
color: white; |
||||
background-color: #111111; |
||||
} |
||||
|
||||
QProgressBar:horizontal { |
||||
height: 12px; |
||||
} |
||||
|
||||
QProgressBar QLabel { |
||||
font-size: 8px; |
||||
} |
||||
|
||||
QProgressBar:vertical { |
||||
width: 12px; |
||||
} |
||||
|
||||
QProgressBar::chunk { |
||||
background-color: #656565; |
||||
} |
||||
|
||||
QProgressBar::chunk#batteryBar { |
||||
background-color: green; |
||||
} |
||||
|
||||
QProgressBar::chunk#speedBar { |
||||
background-color: yellow; |
||||
} |
||||
|
||||
QProgressBar::chunk#thrustBar { |
||||
background-color: orange; |
||||
}</string> |
||||
</property> |
||||
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0,10" columnstretch="0,10"> |
||||
<property name="margin"> |
||||
<number>0</number> |
||||
</property> |
||||
<item row="1" column="0" colspan="2"> |
||||
<spacer name="verticalSpacer"> |
||||
<property name="orientation"> |
||||
<enum>Qt::Vertical</enum> |
||||
</property> |
||||
<property name="sizeHint" stdset="0"> |
||||
<size> |
||||
<width>391</width> |
||||
<height>3</height> |
||||
</size> |
||||
</property> |
||||
</spacer> |
||||
</item> |
||||
<item row="0" column="0"> |
||||
<widget class="QGroupBox" name="groupBox"> |
||||
<property name="title"> |
||||
<string/> |
||||
</property> |
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0,0,0,0"> |
||||
<property name="horizontalSpacing"> |
||||
<number>5</number> |
||||
</property> |
||||
<property name="verticalSpacing"> |
||||
<number>2</number> |
||||
</property> |
||||
<property name="margin"> |
||||
<number>5</number> |
||||
</property> |
||||
<item row="0" column="0" rowspan="2" colspan="3"> |
||||
<widget class="QLabel" name="nameLabel"> |
||||
<property name="maximumSize"> |
||||
<size> |
||||
<width>16777215</width> |
||||
<height>16</height> |
||||
</size> |
||||
</property> |
||||
<property name="font"> |
||||
<font> |
||||
<pointsize>13</pointsize> |
||||
<weight>75</weight> |
||||
<bold>true</bold> |
||||
</font> |
||||
</property> |
||||
<property name="text"> |
||||
<string>UAS001</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="1" column="3"> |
||||
<widget class="QLabel" name="positionLabel"> |
||||
<property name="minimumSize"> |
||||
<size> |
||||
<width>0</width> |
||||
<height>12</height> |
||||
</size> |
||||
</property> |
||||
<property name="maximumSize"> |
||||
<size> |
||||
<width>16777215</width> |
||||
<height>12</height> |
||||
</size> |
||||
</property> |
||||
<property name="font"> |
||||
<font> |
||||
<pointsize>9</pointsize> |
||||
</font> |
||||
</property> |
||||
<property name="text"> |
||||
<string>00.0 00.0 00.0 m</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="1" column="4"> |
||||
<widget class="QLabel" name="gpsLabel"> |
||||
<property name="minimumSize"> |
||||
<size> |
||||
<width>0</width> |
||||
<height>12</height> |
||||
</size> |
||||
</property> |
||||
<property name="maximumSize"> |
||||
<size> |
||||
<width>16777215</width> |
||||
<height>12</height> |
||||
</size> |
||||
</property> |
||||
<property name="font"> |
||||
<font> |
||||
<pointsize>9</pointsize> |
||||
</font> |
||||
</property> |
||||
<property name="text"> |
||||
<string>00 00 00 N 00 00 00 E</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="2" column="0" colspan="2"> |
||||
<widget class="QLabel" name="timeRemainingLabel"> |
||||
<property name="font"> |
||||
<font> |
||||
<pointsize>8</pointsize> |
||||
</font> |
||||
</property> |
||||
<property name="text"> |
||||
<string>00:00:00</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="2" column="2"> |
||||
<widget class="QLabel" name="timeElapsedLabel"> |
||||
<property name="font"> |
||||
<font> |
||||
<pointsize>8</pointsize> |
||||
</font> |
||||
</property> |
||||
<property name="text"> |
||||
<string>00:00:00</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="2" column="3" rowspan="3"> |
||||
<widget class="QProgressBar" name="speedBar"> |
||||
<property name="font"> |
||||
<font> |
||||
<pointsize>8</pointsize> |
||||
</font> |
||||
</property> |
||||
<property name="value"> |
||||
<number>24</number> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="2" column="4" rowspan="3"> |
||||
<widget class="QProgressBar" name="thrustBar"> |
||||
<property name="font"> |
||||
<font> |
||||
<pointsize>8</pointsize> |
||||
</font> |
||||
</property> |
||||
<property name="value"> |
||||
<number>24</number> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="10" column="2" rowspan="2"> |
||||
<spacer name="horizontalSpacer"> |
||||
<property name="orientation"> |
||||
<enum>Qt::Horizontal</enum> |
||||
</property> |
||||
<property name="sizeHint" stdset="0"> |
||||
<size> |
||||
<width>10</width> |
||||
<height>20</height> |
||||
</size> |
||||
</property> |
||||
</spacer> |
||||
</item> |
||||
<item row="11" column="3" colspan="2"> |
||||
<layout class="QHBoxLayout" name="horizontalLayout"> |
||||
<property name="spacing"> |
||||
<number>10</number> |
||||
</property> |
||||
<property name="sizeConstraint"> |
||||
<enum>QLayout::SetDefaultConstraint</enum> |
||||
</property> |
||||
<item> |
||||
<widget class="QPushButton" name="liftoffButton"> |
||||
<property name="minimumSize"> |
||||
<size> |
||||
<width>35</width> |
||||
<height>0</height> |
||||
</size> |
||||
</property> |
||||
<property name="text"> |
||||
<string/> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QPushButton" name="holdButton"> |
||||
<property name="minimumSize"> |
||||
<size> |
||||
<width>35</width> |
||||
<height>0</height> |
||||
</size> |
||||
</property> |
||||
<property name="text"> |
||||
<string/> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QPushButton" name="skipButton"> |
||||
<property name="minimumSize"> |
||||
<size> |
||||
<width>35</width> |
||||
<height>0</height> |
||||
</size> |
||||
</property> |
||||
<property name="text"> |
||||
<string/> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QPushButton" name="returnButton"> |
||||
<property name="minimumSize"> |
||||
<size> |
||||
<width>35</width> |
||||
<height>0</height> |
||||
</size> |
||||
</property> |
||||
<property name="text"> |
||||
<string/> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QPushButton" name="landButton"> |
||||
<property name="minimumSize"> |
||||
<size> |
||||
<width>35</width> |
||||
<height>0</height> |
||||
</size> |
||||
</property> |
||||
<property name="text"> |
||||
<string/> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item> |
||||
<widget class="QPushButton" name="killButton"> |
||||
<property name="minimumSize"> |
||||
<size> |
||||
<width>35</width> |
||||
<height>0</height> |
||||
</size> |
||||
</property> |
||||
<property name="text"> |
||||
<string/> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
</layout> |
||||
</item> |
||||
<item row="11" column="5"> |
||||
<spacer name="horizontalSpacer_2"> |
||||
<property name="orientation"> |
||||
<enum>Qt::Horizontal</enum> |
||||
</property> |
||||
<property name="sizeHint" stdset="0"> |
||||
<size> |
||||
<width>2</width> |
||||
<height>20</height> |
||||
</size> |
||||
</property> |
||||
</spacer> |
||||
</item> |
||||
<item row="9" column="2"> |
||||
<widget class="QLabel" name="stateLabel"> |
||||
<property name="font"> |
||||
<font> |
||||
<pointsize>8</pointsize> |
||||
<weight>75</weight> |
||||
<bold>true</bold> |
||||
</font> |
||||
</property> |
||||
<property name="text"> |
||||
<string>UNINIT</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="7" column="3" rowspan="4"> |
||||
<widget class="QLabel" name="statusTextLabel"> |
||||
<property name="maximumSize"> |
||||
<size> |
||||
<width>16777215</width> |
||||
<height>12</height> |
||||
</size> |
||||
</property> |
||||
<property name="font"> |
||||
<font> |
||||
<pointsize>10</pointsize> |
||||
</font> |
||||
</property> |
||||
<property name="text"> |
||||
<string>Unknown status</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="3" column="0"> |
||||
<widget class="QLabel" name="groundDistanceLabel"> |
||||
<property name="font"> |
||||
<font> |
||||
<pointsize>8</pointsize> |
||||
</font> |
||||
</property> |
||||
<property name="text"> |
||||
<string>00.00 m</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="3" column="2"> |
||||
<widget class="QLabel" name="altitudeLabel"> |
||||
<property name="font"> |
||||
<font> |
||||
<pointsize>8</pointsize> |
||||
</font> |
||||
</property> |
||||
<property name="text"> |
||||
<string>00.00 m</string> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="8" column="1" rowspan="4"> |
||||
<widget class="QProgressBar" name="batteryBar"> |
||||
<property name="maximumSize"> |
||||
<size> |
||||
<width>20</width> |
||||
<height>40</height> |
||||
</size> |
||||
</property> |
||||
<property name="font"> |
||||
<font> |
||||
<pointsize>6</pointsize> |
||||
</font> |
||||
</property> |
||||
<property name="value"> |
||||
<number>24</number> |
||||
</property> |
||||
<property name="orientation"> |
||||
<enum>Qt::Vertical</enum> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
<item row="8" column="0" rowspan="4"> |
||||
<widget class="QGroupBox" name="heartbeatIcon"> |
||||
<property name="maximumSize"> |
||||
<size> |
||||
<width>20</width> |
||||
<height>40</height> |
||||
</size> |
||||
</property> |
||||
<property name="title"> |
||||
<string/> |
||||
</property> |
||||
</widget> |
||||
</item> |
||||
</layout> |
||||
</widget> |
||||
</item> |
||||
<item row="0" column="1"> |
||||
<spacer name="horizontalSpacer_3"> |
||||
<property name="orientation"> |
||||
<enum>Qt::Horizontal</enum> |
||||
</property> |
||||
<property name="sizeHint" stdset="0"> |
||||
<size> |
||||
<width>74</width> |
||||
<height>20</height> |
||||
</size> |
||||
</property> |
||||
</spacer> |
||||
</item> |
||||
</layout> |
||||
<zorder>groupBox</zorder> |
||||
<zorder>horizontalSpacer_3</zorder> |
||||
</widget> |
||||
<resources/> |
||||
<connections/> |
||||
</ui> |
@ -1,138 +0,0 @@
@@ -1,138 +0,0 @@
|
||||
#include "QGCBaseParamWidget.h" |
||||
|
||||
#include <QFile> |
||||
#include <QVariant> |
||||
#include <QTextStream> |
||||
|
||||
#include "QGCUASParamManagerInterface.h" |
||||
#include "UASInterface.h" |
||||
#include "QGCApplication.h" |
||||
#include "QGCFileDialog.h" |
||||
|
||||
QGCBaseParamWidget::QGCBaseParamWidget(QWidget *parent) : |
||||
QWidget(parent), |
||||
paramMgr(NULL), |
||||
mav(NULL), |
||||
updatingParamNameLock("") |
||||
{ |
||||
} |
||||
|
||||
QGCBaseParamWidget* QGCBaseParamWidget::initWithUAS(UASInterface *uas) |
||||
{ |
||||
setUAS(uas); |
||||
return this; |
||||
} |
||||
|
||||
void QGCBaseParamWidget::setUAS(UASInterface* uas) |
||||
{ |
||||
if (uas != mav) { |
||||
if (mav) { |
||||
//TODO disconnect any connections as needed
|
||||
disconnectViewSignalsAndSlots(); |
||||
disconnectFromParamManager(); |
||||
clearOnboardParamDisplay(); |
||||
clearPendingParamDisplay(); |
||||
} |
||||
|
||||
mav = uas; |
||||
|
||||
if (mav) { |
||||
connectToParamManager(); |
||||
connectViewSignalsAndSlots(); |
||||
layoutWidget(); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
void QGCBaseParamWidget::connectToParamManager() |
||||
{ |
||||
paramMgr = mav->getParamManager(); |
||||
//TODO route via paramManager instead?
|
||||
// Listen to updated param signals from the data model
|
||||
connect(paramMgr, SIGNAL(parameterUpdated(int, QString , QVariant )), |
||||
this, SLOT(handleOnboardParamUpdate(int,QString,QVariant))); |
||||
|
||||
connect(paramMgr, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), |
||||
this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); |
||||
|
||||
// Listen for param list reload finished
|
||||
connect(paramMgr, SIGNAL(parameterListUpToDate()), |
||||
this, SLOT(handleOnboardParameterListUpToDate())); |
||||
if (paramMgr->parametersReady()) { |
||||
handleOnboardParameterListUpToDate(); |
||||
} |
||||
|
||||
// Listen to communications status messages so we can display them
|
||||
connect(paramMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), |
||||
this, SLOT(handleParamStatusMsgUpdate(QString , int ))); |
||||
} |
||||
|
||||
|
||||
void QGCBaseParamWidget::disconnectFromParamManager() |
||||
{ |
||||
disconnect(paramMgr, SIGNAL(parameterUpdated(int, QString , QVariant )), |
||||
this, SLOT(handleOnboardParamUpdate(int,QString,QVariant))); |
||||
|
||||
disconnect(paramMgr, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), |
||||
this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); |
||||
|
||||
disconnect(paramMgr, SIGNAL(parameterListUpToDate()), |
||||
this, SLOT(handleOnboardParameterListUpToDate())); |
||||
|
||||
// Listen to communications status messages so we can display them
|
||||
disconnect(paramMgr, SIGNAL(parameterStatusMsgUpdated(QString,int)), |
||||
this, SLOT(handleParamStatusMsgUpdate(QString , int ))); |
||||
|
||||
paramMgr = NULL; |
||||
} |
||||
|
||||
|
||||
|
||||
void QGCBaseParamWidget::requestOnboardParamsUpdate() |
||||
{ |
||||
paramMgr->requestParameterList(); |
||||
} |
||||
|
||||
void QGCBaseParamWidget::requestOnboardParamUpdate(QString parameterName) |
||||
{ |
||||
paramMgr->requestParameterUpdate(paramMgr->getDefaultComponentId(), parameterName); |
||||
} |
||||
|
||||
|
||||
void QGCBaseParamWidget::saveParametersToFile() |
||||
{ |
||||
if (!mav) |
||||
return; |
||||
QString fileName = QGCFileDialog::getSaveFileName( |
||||
this, tr("Save Parameters"), qgcApp()->savedParameterFilesLocation(), tr("Parameter Files (*.params)"), "params", true); |
||||
if (!fileName.isEmpty()) { |
||||
QFile file(fileName); |
||||
// TODO Display error message to the user if the file can't be created
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { |
||||
return; |
||||
} |
||||
QTextStream outstream(&file); |
||||
paramMgr->writeOnboardParamsToStream(outstream,mav->getUASName()); |
||||
file.close(); |
||||
} |
||||
} |
||||
|
||||
|
||||
void QGCBaseParamWidget::loadParametersFromFile() |
||||
{ |
||||
if (!mav) |
||||
return; |
||||
QString fileName = QGCFileDialog::getOpenFileName( |
||||
this, tr("Load Parameters"), qgcApp()->savedParameterFilesLocation(), |
||||
tr("Parameter Files (*.params);;All Files (*)")); |
||||
QFile file(fileName); |
||||
// TODO Display error message to the user if the file can't be opened
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { |
||||
return; |
||||
} |
||||
QTextStream in(&file); |
||||
paramMgr->readPendingParamsFromStream(in); |
||||
file.close(); |
||||
} |
@ -1,62 +0,0 @@
@@ -1,62 +0,0 @@
|
||||
#ifndef QGCBASEPARAMWIDGET_H |
||||
#define QGCBASEPARAMWIDGET_H |
||||
|
||||
#include <QVariant> |
||||
#include <QWidget> |
||||
|
||||
|
||||
|
||||
|
||||
//forward declarations
|
||||
class QGCUASParamManagerInterface; |
||||
class UASInterface; |
||||
|
||||
|
||||
class QGCBaseParamWidget : public QWidget |
||||
{ |
||||
Q_OBJECT |
||||
public: |
||||
explicit QGCBaseParamWidget(QWidget *parent = 0); |
||||
virtual QGCBaseParamWidget* initWithUAS(UASInterface* uas);///< Two-stage construction: initialize this object
|
||||
virtual void setUAS(UASInterface* uas);///< Allows swapping the underlying UAS
|
||||
|
||||
protected: |
||||
virtual void setParameterStatusMsg(const QString& msg) = 0; |
||||
virtual void layoutWidget() = 0;///< Layout the appearance of this widget
|
||||
virtual void connectViewSignalsAndSlots() = 0;///< Connect view signals/slots as needed
|
||||
virtual void disconnectViewSignalsAndSlots() = 0;///< Disconnect view signals/slots as needed
|
||||
virtual void connectToParamManager(); ///>Connect to any required param manager signals
|
||||
virtual void disconnectFromParamManager(); ///< Disconnect from any connected param manager signals
|
||||
|
||||
signals: |
||||
|
||||
public slots: |
||||
virtual void handleOnboardParamUpdate(int component,const QString& parameterName, QVariant value) = 0; |
||||
virtual void handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) = 0; |
||||
virtual void handleOnboardParameterListUpToDate() = 0; |
||||
virtual void handleParamStatusMsgUpdate(QString msg, int level) = 0; |
||||
/** @brief Clear the rendering of onboard parameters */ |
||||
virtual void clearOnboardParamDisplay() = 0; |
||||
/** @brief Clear the rendering of pending parameters */ |
||||
virtual void clearPendingParamDisplay() = 0; |
||||
|
||||
/** @brief Request list of parameters from MAV */ |
||||
virtual void requestOnboardParamsUpdate(); |
||||
|
||||
/** @brief Request single parameter from MAV */ |
||||
virtual void requestOnboardParamUpdate(QString parameterName); |
||||
|
||||
|
||||
/** @brief Store parameters to a file */ |
||||
virtual void saveParametersToFile(); |
||||
/** @brief Load parameters from a file */ |
||||
virtual void loadParametersFromFile(); |
||||
|
||||
protected: |
||||
QGCUASParamManagerInterface* paramMgr; |
||||
UASInterface* mav; |
||||
QString updatingParamNameLock; ///< Name of param currently being updated-- used for reducing echo on param change
|
||||
|
||||
}; |
||||
|
||||
#endif // QGCBASEPARAMWIDGET_H
|
@ -1,96 +0,0 @@
@@ -1,96 +0,0 @@
|
||||
/*=====================================================================
|
||||
|
||||
QGroundControl Open Source Ground Control Station |
||||
|
||||
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
|
||||
This file is part of the QGROUNDCONTROL project |
||||
|
||||
QGROUNDCONTROL 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. |
||||
|
||||
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
======================================================================*/ |
||||
|
||||
/// @file
|
||||
/// @author Thomas Gubler <thomasgubler@gmail.com>
|
||||
|
||||
#include "QGCParamTreeWidget.h" |
||||
#include <QMenu> |
||||
#include <QTreeWidgetItem> |
||||
#include <QDebug> |
||||
|
||||
QGCParamTreeWidget::QGCParamTreeWidget(QWidget *parent) : |
||||
QTreeWidget(parent) |
||||
{ |
||||
setContextMenuPolicy(Qt::CustomContextMenu); |
||||
|
||||
QObject::connect(this, &QGCParamTreeWidget::customContextMenuRequested, |
||||
this, &QGCParamTreeWidget::showContextMenu); |
||||
qDebug() << "create QGCParamTreeWidget"; |
||||
|
||||
} |
||||
|
||||
QGCParamTreeWidget::~QGCParamTreeWidget() |
||||
{ |
||||
|
||||
} |
||||
|
||||
void QGCParamTreeWidget::showContextMenu(const QPoint &pos) |
||||
{ |
||||
QMenu menu; |
||||
QTreeWidgetItem* item = itemAt(pos); |
||||
|
||||
// Only show context menu for parameter items and not for group items
|
||||
// (show for TEST_P but not for TEST)
|
||||
// If a context menu is needed later for the groups then move this 'if'
|
||||
// to below where the actions are created and filter out certain actions
|
||||
// for the outer nodes
|
||||
if (indexOfTopLevelItem(item) > -1 || |
||||
indexOfTopLevelItem(item->parent()) > -1) { |
||||
return; |
||||
} |
||||
|
||||
QString param_id = item->data(0, Qt::DisplayRole).toString(); |
||||
|
||||
// Refresh single parameter
|
||||
QAction* act = new QAction(tr("Refresh this param"), this); |
||||
act->setProperty("action", "refresh"); |
||||
act->setProperty("param_id", param_id); |
||||
connect(act, &QAction::triggered, this, |
||||
&QGCParamTreeWidget::contextMenuAction); |
||||
menu.addAction(act); |
||||
|
||||
// RC to parameter mapping
|
||||
act = new QAction(tr("Map Parameter to RC"), this); |
||||
act->setProperty("action", "maprc"); |
||||
act->setProperty("param_id", param_id); |
||||
connect(act, &QAction::triggered, this, |
||||
&QGCParamTreeWidget::contextMenuAction); |
||||
menu.addAction(act); |
||||
menu.exec(mapToGlobal(pos)); |
||||
} |
||||
|
||||
void QGCParamTreeWidget::contextMenuAction() { |
||||
QString action = qobject_cast<QAction*>( |
||||
sender())->property("action").toString(); |
||||
QString param_id = qobject_cast<QAction*>( |
||||
sender())->property("param_id").toString(); |
||||
|
||||
if (action == "refresh") { |
||||
emit refreshParamRequest(param_id); |
||||
} else if (action == "maprc") { |
||||
emit mapRCToParamRequest(param_id); |
||||
} else { |
||||
qDebug() << "Undefined context menu action"; |
||||
} |
||||
} |
@ -1,567 +0,0 @@
@@ -1,567 +0,0 @@
|
||||
/*=====================================================================
|
||||
|
||||
QGroundControl Open Source Ground Control Station |
||||
|
||||
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
|
||||
This file is part of the QGROUNDCONTROL project |
||||
|
||||
QGROUNDCONTROL 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. |
||||
|
||||
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
======================================================================*/ |
||||
/**
|
||||
* @file |
||||
* @brief Implementation of class QGCParamWidget |
||||
* @author Lorenz Meier <mail@qgroundcontrol.org> |
||||
*/ |
||||
#include <cmath> |
||||
#include <float.h> |
||||
#include <QApplication> |
||||
#include <QDebug> |
||||
#include <QFile> |
||||
#include <QGridLayout> |
||||
|
||||
#include <QList> |
||||
#include <QPushButton> |
||||
#include <QSettings> |
||||
#include <QTime> |
||||
#include <QTimer> |
||||
#include <QEventLoop> |
||||
|
||||
#include "MainWindow.h" |
||||
#include "QGC.h" |
||||
#include "QGCParamWidget.h" |
||||
#include "UASInterface.h" |
||||
#include "UASParameterCommsMgr.h" |
||||
#include "QGCMapRCToParamDialog.h" |
||||
|
||||
/**
|
||||
* @param uas MAV to set the parameters on |
||||
* @param parent Parent widget |
||||
*/ |
||||
QGCParamWidget::QGCParamWidget(QWidget *parent) : |
||||
QGCBaseParamWidget(parent), |
||||
componentItems(new QMap<int, QTreeWidgetItem*>()), |
||||
statusLabel(new QLabel(this)), |
||||
tree(new QGCParamTreeWidget(this)), |
||||
_fullParamListLoaded(false) |
||||
{ |
||||
|
||||
|
||||
} |
||||
|
||||
|
||||
|
||||
void QGCParamWidget::disconnectViewSignalsAndSlots() |
||||
{ |
||||
disconnect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), |
||||
this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); |
||||
disconnect(tree, &QGCParamTreeWidget::mapRCToParamRequest, this, |
||||
&QGCParamWidget::configureRCToParam); |
||||
} |
||||
|
||||
|
||||
void QGCParamWidget::connectViewSignalsAndSlots() |
||||
{ |
||||
// Listen for edits to the tree UI
|
||||
connect(tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), |
||||
this, SLOT(parameterItemChanged(QTreeWidgetItem*,int))); |
||||
connect(tree, &QGCParamTreeWidget::mapRCToParamRequest, this, |
||||
&QGCParamWidget::configureRCToParam); |
||||
connect(tree, &QGCParamTreeWidget::refreshParamRequest, this, |
||||
&QGCParamWidget::requestOnboardParamUpdate); |
||||
} |
||||
|
||||
|
||||
void QGCParamWidget::addActionButtonsToLayout(QGridLayout* layout) |
||||
{ |
||||
QPushButton* refreshButton = new QPushButton(tr("Get")); |
||||
refreshButton->setToolTip(tr("Fetch parameters currently in volatile memory of aircraft.")); |
||||
refreshButton->setWhatsThis(tr("Fetch parameters currently in volatile memory of aircraft.")); |
||||
connect(refreshButton, SIGNAL(clicked()), |
||||
this, SLOT(requestOnboardParamsUpdate())); |
||||
layout->addWidget(refreshButton, 2, 0); |
||||
|
||||
QPushButton* setButton = new QPushButton(tr("Set")); |
||||
setButton->setToolTip(tr("Send pending parameters to volatile onboard memory")); |
||||
setButton->setWhatsThis(tr("Send pending parameters to volatile onboard memory")); |
||||
connect(setButton, SIGNAL(clicked()), |
||||
paramMgr, SLOT(sendPendingParameters())); |
||||
layout->addWidget(setButton, 2, 1); |
||||
|
||||
QPushButton* writeButton = new QPushButton(tr("Write (ROM)")); |
||||
writeButton->setToolTip(tr("Copy parameters in volatile memory of the aircraft to persistent memory. Transmit your parameters first to write these.")); |
||||
writeButton->setWhatsThis(tr("Copy parameters in volatile memory of the aircraft to persistent memory. Transmit your parameters first to write these.")); |
||||
connect(writeButton, SIGNAL(clicked()), |
||||
paramMgr, SLOT(copyVolatileParamsToPersistent())); |
||||
layout->addWidget(writeButton, 2, 2); |
||||
|
||||
QPushButton* loadFileButton = new QPushButton(tr("Load File")); |
||||
loadFileButton->setToolTip(tr("Load parameters from a file into qgroundcontrol. To write these to the aircraft, use transmit after loading them.")); |
||||
loadFileButton->setWhatsThis(tr("Load parameters from a file into qgroundcontrol. To write these to the aircraft, use transmit after loading them.")); |
||||
connect(loadFileButton, SIGNAL(clicked()), |
||||
this, SLOT(loadParametersFromFile())); |
||||
layout->addWidget(loadFileButton, 3, 0); |
||||
|
||||
QPushButton* saveFileButton = new QPushButton(tr("Save File")); |
||||
saveFileButton->setToolTip(tr("Save parameters in this view to a file on this computer.")); |
||||
saveFileButton->setWhatsThis(tr("Save parameters in this view to a file on this computer.")); |
||||
connect(saveFileButton, SIGNAL(clicked()), |
||||
this, SLOT(saveParametersToFile())); |
||||
layout->addWidget(saveFileButton, 3, 1); |
||||
|
||||
QPushButton* readButton = new QPushButton(tr("Read (ROM)")); |
||||
readButton->setToolTip(tr("Copy parameters from persistent onboard memory to volatile onboard memory of aircraft. DOES NOT update the parameters in this view: click refresh after copying them to get them.")); |
||||
readButton->setWhatsThis(tr("Copy parameters from persistent onboard memory to volatile onboard memory of aircraft. DOES NOT update the parameters in this view: click refresh after copying them to get them.")); |
||||
connect(readButton, SIGNAL(clicked()), |
||||
paramMgr, SLOT(copyPersistentParamsToVolatile())); |
||||
layout->addWidget(readButton, 3, 2); |
||||
|
||||
QPushButton* unsetRCToParamMapButton = new QPushButton(tr("Clear Rc to Param")); |
||||
unsetRCToParamMapButton->setToolTip(tr("Remove any bindings between RC channels and parameters.")); |
||||
unsetRCToParamMapButton->setWhatsThis(tr("Remove any bindings between RC channels and parameters.")); |
||||
connect(unsetRCToParamMapButton, &QPushButton::clicked, |
||||
mav, &UASInterface::unsetRCToParameterMap); |
||||
layout->addWidget(unsetRCToParamMapButton, 4, 1); |
||||
|
||||
} |
||||
|
||||
void QGCParamWidget::layoutWidget() |
||||
{ |
||||
|
||||
statusLabel->setAutoFillBackground(true); |
||||
|
||||
QGridLayout* layout = new QGridLayout(this); |
||||
layout->setHorizontalSpacing(6); |
||||
layout->setVerticalSpacing(6); |
||||
layout->setMargin(0); |
||||
layout->setSizeConstraint(QLayout::SetMinimumSize); |
||||
|
||||
// Parameter tree
|
||||
layout->addWidget(tree, 0, 0, 1, 3); |
||||
|
||||
// Status line
|
||||
statusLabel->setText(tr("Click refresh to download parameters")); |
||||
layout->addWidget(statusLabel, 1, 0, 1, 3); |
||||
|
||||
// BUTTONS
|
||||
addActionButtonsToLayout(layout); |
||||
|
||||
// Set correct vertical scaling
|
||||
layout->setRowStretch(0, 100); |
||||
layout->setRowStretch(1, 10); |
||||
layout->setRowStretch(2, 10); |
||||
layout->setRowStretch(3, 10); |
||||
|
||||
// Set layout
|
||||
this->setLayout(layout); |
||||
|
||||
// Set header
|
||||
QStringList headerItems; |
||||
headerItems.append("Parameter"); |
||||
headerItems.append("Value"); |
||||
tree->setHeaderLabels(headerItems); |
||||
tree->setColumnCount(2); |
||||
tree->setColumnWidth(0,200); |
||||
tree->setColumnWidth(1,120); |
||||
tree->setExpandsOnDoubleClick(true); |
||||
|
||||
tree->setVisible(true); |
||||
} |
||||
|
||||
|
||||
void QGCParamWidget::addComponentItem(int compId, QString compName) |
||||
{ |
||||
|
||||
QString compLine = QString("%1 (#%2)").arg(compName).arg(compId); |
||||
|
||||
//QString ptrStr = QString().sprintf("%8p", this);
|
||||
//qDebug() << "QGCParamWidget" << ptrStr << "addComponentItem:" << compLine;
|
||||
|
||||
if (componentItems->contains(compId)) { |
||||
// Update existing component item
|
||||
componentItems->value(compId)->setData(0, Qt::DisplayRole, compLine); |
||||
//components->value(component)->setData(1, Qt::DisplayRole, QString::number(component));
|
||||
componentItems->value(compId)->setFirstColumnSpanned(true); |
||||
} else { |
||||
// Add new component item
|
||||
QStringList list(compLine); |
||||
QTreeWidgetItem* compItem = new QTreeWidgetItem(list); |
||||
compItem->setFirstColumnSpanned(true); |
||||
componentItems->insert(compId, compItem); |
||||
// Create parameter grouping for this component and update maps
|
||||
paramGroups.insert(compId, new QMap<QString, QTreeWidgetItem*>()); |
||||
tree->addTopLevelItem(compItem); |
||||
tree->update(); |
||||
} |
||||
|
||||
} |
||||
|
||||
void QGCParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) |
||||
{ |
||||
//qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock;
|
||||
|
||||
if (updatingParamNameLock == paramName) { |
||||
//qDebug() << "ignoring bounce from " << paramName;
|
||||
return; |
||||
} |
||||
else { |
||||
updatingParamNameLock = paramName; |
||||
} |
||||
|
||||
QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); |
||||
if (paramItem) { |
||||
if (isPending) { |
||||
paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); |
||||
paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); |
||||
//ensure that the adjusted item is visible
|
||||
tree->expandItem(paramItem->parent()); |
||||
} |
||||
else { |
||||
paramItem->setBackground(0, Qt::NoBrush); |
||||
paramItem->setBackground(1, Qt::NoBrush); |
||||
} |
||||
} |
||||
|
||||
updatingParamNameLock.clear(); |
||||
|
||||
} |
||||
|
||||
void QGCParamWidget::handleOnboardParamUpdate(int compId, const QString& paramName, QVariant value) |
||||
{ |
||||
//qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock;
|
||||
if (paramName == updatingParamNameLock) { |
||||
//qDebug() << "handlePendingParamUpdate ignoring bounce from " << paramName;
|
||||
return; |
||||
} |
||||
updatingParamNameLock = paramName; |
||||
updateParameterDisplay(compId, paramName, value); |
||||
updatingParamNameLock.clear(); |
||||
} |
||||
|
||||
|
||||
void QGCParamWidget::handleOnboardParameterListUpToDate() |
||||
{ |
||||
// Don't load full param list more than once
|
||||
if (_fullParamListLoaded) { |
||||
return; |
||||
} |
||||
|
||||
_fullParamListLoaded = true; |
||||
|
||||
//turn off updates while we refresh the entire list
|
||||
tree->setUpdatesEnabled(false); |
||||
|
||||
//rewrite the component item tree after receiving the full list
|
||||
QMap<int, QMap<QString, QVariant>*>::iterator i; |
||||
QMap<int, QMap<QString, QVariant>*>* onboardParams = paramMgr->dataModel()->getAllOnboardParams(); |
||||
|
||||
for (i = onboardParams->begin(); i != onboardParams->end(); ++i) { |
||||
int compId = i.key(); |
||||
QMap<QString, QVariant>* paramPairs = onboardParams->value(compId); |
||||
QMap<QString, QVariant>::iterator j; |
||||
for (j = paramPairs->begin(); j != paramPairs->end(); j++) { |
||||
updatingParamNameLock = j.key(); |
||||
updateParameterDisplay(compId, j.key(),j.value()); |
||||
updatingParamNameLock.clear(); |
||||
} |
||||
} |
||||
|
||||
// Expand visual tree
|
||||
tree->expandItem(tree->topLevelItem(0)); |
||||
tree->setUpdatesEnabled(true); |
||||
tree->update(); |
||||
|
||||
} |
||||
|
||||
QTreeWidgetItem* QGCParamWidget::findChildWidgetItemForParam(QTreeWidgetItem* parentItem, const QString& paramName) |
||||
{ |
||||
QTreeWidgetItem* childItem = NULL; |
||||
|
||||
for (int i = 0; i < parentItem->childCount(); i++) { |
||||
QTreeWidgetItem* child = parentItem->child(i); |
||||
QString key = child->data(0, Qt::DisplayRole).toString(); |
||||
if (key == paramName) { |
||||
childItem = child; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
return childItem; |
||||
} |
||||
|
||||
QTreeWidgetItem* QGCParamWidget::getParentWidgetItemForParam(int compId, const QString& paramName) |
||||
{ |
||||
QTreeWidgetItem* parentItem = componentItems->value(compId); |
||||
|
||||
QString splitToken = "_"; |
||||
// Check if auto-grouping can work
|
||||
if (paramName.contains(splitToken)) { |
||||
QString parentStr = paramName.section(splitToken, 0, 0, QString::SectionSkipEmpty); |
||||
QMap<QString, QTreeWidgetItem*>* compParamGroups = paramGroups.value(compId); |
||||
if (!compParamGroups->contains(parentStr)) { |
||||
// Insert group item
|
||||
QStringList glist; |
||||
glist.append(parentStr); |
||||
QTreeWidgetItem* groupItem = new QTreeWidgetItem(glist); |
||||
|
||||
compParamGroups->insert(parentStr, groupItem); |
||||
|
||||
// insert new group alphabetized
|
||||
QList<QString> groupKeys = compParamGroups->uniqueKeys(); |
||||
int insertIdx = groupKeys.indexOf(parentStr); |
||||
componentItems->value(compId)->insertChild(insertIdx,groupItem); |
||||
} |
||||
|
||||
//parent item for this parameter item will be a group widget item
|
||||
parentItem = compParamGroups->value(parentStr); |
||||
} |
||||
else { |
||||
//parent item for this parameter will be the top level (component) widget item
|
||||
parentItem = componentItems->value(compId); |
||||
} |
||||
|
||||
return parentItem; |
||||
} |
||||
|
||||
void QGCParamWidget::insertParamAlphabetical(int indexLowerBound, int indexUpperBound, QTreeWidgetItem* parentItem, QTreeWidgetItem* paramItem) |
||||
{ |
||||
if (indexLowerBound >= indexUpperBound) |
||||
{ |
||||
if (paramItem->text(0).compare(parentItem->child(indexLowerBound)->text(0)) < 0) { |
||||
parentItem->insertChild(indexLowerBound, paramItem); |
||||
} |
||||
else |
||||
{ |
||||
if (indexLowerBound < parentItem->childCount() - 1) { |
||||
parentItem->insertChild(indexLowerBound + 1, paramItem); |
||||
} |
||||
else |
||||
{ |
||||
parentItem->addChild(paramItem); |
||||
} |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
int midpoint = indexLowerBound + ((indexUpperBound - indexLowerBound) / 2); |
||||
|
||||
if (paramItem->text(0).compare(parentItem->child(midpoint)->text(0)) < 0) |
||||
{ |
||||
insertParamAlphabetical(indexLowerBound, midpoint - 1, parentItem, paramItem); |
||||
} else |
||||
{ |
||||
insertParamAlphabetical(midpoint + 1, indexUpperBound, parentItem, paramItem); |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
QTreeWidgetItem* QGCParamWidget::updateParameterDisplay(int compId, QString parameterName, QVariant value) |
||||
{ |
||||
//qDebug() << "QGCParamWidget::updateParameterDisplay" << parameterName;
|
||||
|
||||
// Filter the parameters according to the filter list
|
||||
if (_filterList.count() != 0) { |
||||
bool filterFound = false; |
||||
foreach(QString paramFilter, _filterList) { |
||||
if (paramFilter.endsWith("*") && parameterName.startsWith(paramFilter.left(paramFilter.size() - 1))) { |
||||
filterFound = true; |
||||
break; |
||||
} |
||||
if (paramFilter == parameterName) { |
||||
filterFound = true; |
||||
break; |
||||
} |
||||
} |
||||
if (!filterFound) { |
||||
return NULL; |
||||
} |
||||
} |
||||
|
||||
// Reference to item in tree
|
||||
QTreeWidgetItem* paramItem = NULL; |
||||
|
||||
// Add component item if necessary
|
||||
if (!componentItems->contains(compId)) { |
||||
QString componentName = tr("Component #%1").arg(compId); |
||||
addComponentItem(compId, componentName); |
||||
} |
||||
|
||||
//default parent item for this parameter widget item will be the top level component item
|
||||
QTreeWidgetItem* parentItem = getParentWidgetItemForParam(compId,parameterName); |
||||
if (parentItem) { |
||||
paramItem = findChildWidgetItemForParam(parentItem,parameterName); |
||||
if (!paramItem) { |
||||
// Insert parameter into map
|
||||
QStringList plist; |
||||
plist.append(parameterName); |
||||
// CREATE PARAMETER ITEM
|
||||
paramItem = new QTreeWidgetItem(plist); |
||||
// CONFIGURE PARAMETER ITEM
|
||||
if (value.type() == QVariant::Char) { |
||||
paramItem->setData(1, Qt::DisplayRole, value.toUInt()); |
||||
} |
||||
else { |
||||
paramItem->setData(1, Qt::DisplayRole, value); |
||||
} |
||||
paramItem->setFlags(paramItem->flags() | Qt::ItemIsEditable); |
||||
|
||||
//Insert alphabetically
|
||||
if (parentItem->childCount() > 0) { |
||||
insertParamAlphabetical(0, parentItem->childCount() - 1, parentItem, paramItem); |
||||
} else |
||||
{ |
||||
parentItem->addChild(paramItem); |
||||
} |
||||
|
||||
//only add the tooltip when the parameter item is first added
|
||||
QString paramDesc = paramMgr->dataModel()->getParamDescription(parameterName); |
||||
if (!paramDesc.isEmpty()) { |
||||
QString tooltipFormat; |
||||
if (paramMgr->dataModel()->isParamDefaultKnown(parameterName)) { |
||||
tooltipFormat = tr("Default: %1, %2"); |
||||
double paramDefValue = paramMgr->dataModel()->getParamDefault(parameterName); |
||||
tooltipFormat = tooltipFormat.arg(paramDefValue).arg(paramDesc); |
||||
} |
||||
else { |
||||
tooltipFormat = paramDesc; |
||||
} |
||||
paramItem->setToolTip(0, tooltipFormat); |
||||
paramItem->setToolTip(1, tooltipFormat); |
||||
} |
||||
} |
||||
|
||||
//update the parameterItem's data
|
||||
if (value.type() == QVariant::Char) { |
||||
paramItem->setData(1, Qt::DisplayRole, value.toUInt()); |
||||
} |
||||
else { |
||||
paramItem->setData(1, Qt::DisplayRole, value); |
||||
} |
||||
|
||||
} |
||||
|
||||
if (paramItem) { |
||||
// Reset background color
|
||||
paramItem->setBackground(0, Qt::NoBrush); |
||||
paramItem->setBackground(1, Qt::NoBrush); |
||||
|
||||
paramItem->setTextColor(0, QGC::colorDarkWhite); |
||||
paramItem->setTextColor(1, QGC::colorDarkWhite); |
||||
|
||||
if (paramItem == tree->currentItem()) { |
||||
//need to unset current item to clear highlighting (green by default)
|
||||
tree->setCurrentItem(NULL); //clear the selected line
|
||||
} |
||||
|
||||
} |
||||
|
||||
return paramItem; |
||||
} |
||||
|
||||
|
||||
|
||||
void QGCParamWidget::parameterItemChanged(QTreeWidgetItem* paramItem, int column) |
||||
{ |
||||
if (paramItem && column > 0) { |
||||
|
||||
QString key = paramItem->data(0, Qt::DisplayRole).toString(); |
||||
//qDebug() << "parameterItemChanged:" << key << "with updatingParamNameLock:" << updatingParamNameLock;
|
||||
|
||||
if (key == updatingParamNameLock) { |
||||
//qDebug() << "parameterItemChanged ignoring bounce from " << key;
|
||||
return; |
||||
} |
||||
else { |
||||
updatingParamNameLock = key; |
||||
} |
||||
|
||||
QTreeWidgetItem* parent = paramItem->parent(); |
||||
while (parent->parent() != NULL) { |
||||
parent = parent->parent(); |
||||
} |
||||
// Parent is now top-level component
|
||||
int componentId = componentItems->key(parent); |
||||
QVariant value = paramItem->data(1, Qt::DisplayRole); |
||||
|
||||
|
||||
bool pending = paramMgr->dataModel()->updatePendingParamWithValue(componentId,key,value); |
||||
|
||||
// If the value will result in an update
|
||||
if (pending) { |
||||
// Set parameter on changed list to be transmitted to MAV
|
||||
statusLabel->setText(tr("Pending: %1:%2: %3").arg(componentId).arg(key).arg(value.toFloat(), 5, 'f', 1, QChar(' '))); |
||||
|
||||
paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); |
||||
paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); |
||||
} |
||||
else { |
||||
QMap<QString , QVariant>* pendingParams = paramMgr->dataModel()->getPendingParamsForComponent(componentId); |
||||
int pendingCount = pendingParams->count(); |
||||
statusLabel->setText(tr("Pending items: %1").arg(pendingCount)); |
||||
paramItem->setBackground(0, Qt::NoBrush); |
||||
paramItem->setBackground(1, Qt::NoBrush); |
||||
} |
||||
|
||||
|
||||
if (paramItem == tree->currentItem()) { |
||||
//need to unset current item to clear highlighting (green by default)
|
||||
tree->setCurrentItem(NULL); //clear the selected line
|
||||
} |
||||
|
||||
updatingParamNameLock.clear(); |
||||
} |
||||
} |
||||
|
||||
void QGCParamWidget::setParameterStatusMsg(const QString& msg) |
||||
{ |
||||
statusLabel->setText(msg); |
||||
} |
||||
|
||||
|
||||
void QGCParamWidget::clearOnboardParamDisplay() |
||||
{ |
||||
tree->clear(); |
||||
componentItems->clear(); |
||||
} |
||||
|
||||
void QGCParamWidget::clearPendingParamDisplay() |
||||
{ |
||||
tree->clear(); |
||||
componentItems->clear(); |
||||
} |
||||
|
||||
|
||||
void QGCParamWidget::handleParamStatusMsgUpdate(QString msg, int level) |
||||
{ |
||||
QColor bgColor = QGC::colorGreen; |
||||
if ((int)UASParameterCommsMgr::ParamCommsStatusLevel_Warning == level) { |
||||
bgColor = QGC::colorOrange; |
||||
} |
||||
else if ((int)UASParameterCommsMgr::ParamCommsStatusLevel_Error == level) { |
||||
bgColor = QGC::colorRed; |
||||
} |
||||
|
||||
QPalette pal = statusLabel->palette(); |
||||
pal.setColor(backgroundRole(), bgColor); |
||||
statusLabel->setPalette(pal); |
||||
statusLabel->setText(msg); |
||||
} |
||||
|
||||
void QGCParamWidget::configureRCToParam(QString param_id) { |
||||
QGCMapRCToParamDialog * d = new QGCMapRCToParamDialog(param_id, |
||||
mav, this); |
||||
d->exec(); |
||||
} |
@ -1,112 +0,0 @@
@@ -1,112 +0,0 @@
|
||||
/*=====================================================================
|
||||
|
||||
QGroundControl Open Source Ground Control Station |
||||
|
||||
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
|
||||
|
||||
This file is part of the QGROUNDCONTROL project |
||||
|
||||
QGROUNDCONTROL 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. |
||||
|
||||
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
======================================================================*/ |
||||
|
||||
/**
|
||||
* @file |
||||
* @brief Declaration of class QGCParamWidget |
||||
* @author Lorenz Meier <mail@qgroundcontrol.org> |
||||
*/ |
||||
|
||||
#ifndef QGCPARAMWIDGET_H |
||||
#define QGCPARAMWIDGET_H |
||||
|
||||
#include <QWidget> |
||||
#include <QTreeWidget> |
||||
#include <QMap> |
||||
#include <QLabel> |
||||
#include <QTimer> |
||||
#include "QGCParamTreeWidget.h" |
||||
|
||||
#include "QGCBaseParamWidget.h" |
||||
|
||||
|
||||
//forward declarations
|
||||
class QGridLayout; |
||||
class UASInterface; |
||||
|
||||
/**
|
||||
* @brief Widget to read/set onboard parameters |
||||
*/ |
||||
class QGCParamWidget : public QGCBaseParamWidget |
||||
{ |
||||
Q_OBJECT |
||||
public: |
||||
QGCParamWidget(QWidget *parent = 0); |
||||
|
||||
/// @brief Sets the list of parameters which should be shown by this editor. Parameter names can be
|
||||
/// wildcarded at the end such as this: "RC*". Which will filter to all parameters which begin
|
||||
/// with "RC". The wildcard (*) can only be at the end of the string.
|
||||
void setFilterList(const QStringList& filterList) { _filterList = filterList; } |
||||
|
||||
protected: |
||||
virtual void setParameterStatusMsg(const QString& msg); |
||||
virtual void layoutWidget();///< Layout the appearance of this widget
|
||||
virtual void connectViewSignalsAndSlots();///< Connect view signals/slots as needed
|
||||
virtual void disconnectViewSignalsAndSlots();///< Connect view signals/slots as needed
|
||||
|
||||
virtual QTreeWidgetItem* getParentWidgetItemForParam(int compId, const QString& paramName); |
||||
virtual QTreeWidgetItem* findChildWidgetItemForParam(QTreeWidgetItem* parentItem, const QString& paramName); |
||||
|
||||
/** @brief Add a component item as a child of this widget
|
||||
* @param compId Component id of the component |
||||
* @param compName Human friendly name of the component |
||||
*/ |
||||
void addComponentItem(int compId, QString compName); |
||||
|
||||
virtual void addActionButtonsToLayout(QGridLayout* layout); |
||||
|
||||
public slots: |
||||
virtual void handleOnboardParamUpdate(int component,const QString& parameterName, QVariant value); |
||||
virtual void handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); |
||||
virtual void handleOnboardParameterListUpToDate(); |
||||
virtual void handleParamStatusMsgUpdate(QString msg, int level); |
||||
|
||||
virtual void clearOnboardParamDisplay(); |
||||
virtual void clearPendingParamDisplay(); |
||||
|
||||
/** @brief Adds parameter at the correct location by a alphapetical comparison of the parameter names */ |
||||
void insertParamAlphabetical(int indexLowerBound, int indexUpperBound, QTreeWidgetItem* parentItem, QTreeWidgetItem* paramItem); |
||||
|
||||
/** @brief Ensure that view of parameter matches data in the model */ |
||||
QTreeWidgetItem* updateParameterDisplay(int component, QString parameterName, QVariant value); |
||||
|
||||
/** @brief Update when user changes parameters */ |
||||
void parameterItemChanged(QTreeWidgetItem* prev, int column); |
||||
|
||||
/** Promt configuration for param map config from user */ |
||||
void configureRCToParam(QString param_id); |
||||
|
||||
|
||||
|
||||
protected: |
||||
QMap<int, QTreeWidgetItem*>* componentItems; ///< The tree of component items, stored by component ID
|
||||
QMap<int, QMap<QString, QTreeWidgetItem*>* > paramGroups; ///< Parameter groups to organize component items
|
||||
QLabel* statusLabel; ///< User-facing parameter status label
|
||||
QGCParamTreeWidget* tree; ///< The parameter tree
|
||||
QStringList _filterList; |
||||
|
||||
private: |
||||
bool _fullParamListLoaded; |
||||
}; |
||||
|
||||
#endif // QGCPARAMWIDGET_H
|
@ -1,130 +0,0 @@
@@ -1,130 +0,0 @@
|
||||
#include "QGCPendingParamWidget.h" |
||||
|
||||
#include <QGridLayout> |
||||
#include <QPushButton> |
||||
|
||||
#include "UASManager.h" |
||||
#include "UASParameterCommsMgr.h" |
||||
|
||||
|
||||
QGCPendingParamWidget::QGCPendingParamWidget(QObject *parent) : |
||||
QGCParamWidget((QWidget*)parent) |
||||
{ |
||||
//this subclass doesn't display status updates
|
||||
statusLabel->hide(); |
||||
} |
||||
|
||||
|
||||
void QGCPendingParamWidget::connectToParamManager() |
||||
{ |
||||
paramMgr = mav->getParamManager(); |
||||
|
||||
// Listen to updated param signals from the data model
|
||||
connect(paramMgr, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), |
||||
this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); |
||||
} |
||||
|
||||
|
||||
void QGCPendingParamWidget::disconnectFromParamManager() |
||||
{ |
||||
// Listen to updated param signals from the data model
|
||||
disconnect(paramMgr, SIGNAL(pendingParamUpdate(int , const QString&, QVariant , bool )), |
||||
this, SLOT(handlePendingParamUpdate(int , const QString& , QVariant, bool ))); |
||||
|
||||
paramMgr = NULL; |
||||
} |
||||
|
||||
|
||||
void QGCPendingParamWidget::disconnectViewSignalsAndSlots() |
||||
{ |
||||
//we ignore edits from the tree view
|
||||
} |
||||
|
||||
|
||||
void QGCPendingParamWidget::connectViewSignalsAndSlots() |
||||
{ |
||||
//we ignore edits from the tree view
|
||||
} |
||||
|
||||
void QGCPendingParamWidget::handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending) |
||||
{ |
||||
// qDebug() << "handlePendingParamUpdate:" << paramName << "with updatingParamNameLock:" << updatingParamNameLock;
|
||||
|
||||
if (updatingParamNameLock == paramName) { |
||||
//qDebug() << "ignoring bounce from " << paramName;
|
||||
return; |
||||
} |
||||
else { |
||||
updatingParamNameLock = paramName; |
||||
} |
||||
|
||||
QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); |
||||
|
||||
if (isPending) { |
||||
QTreeWidgetItem* paramItem = updateParameterDisplay(compId,paramName,value); |
||||
paramItem->setFlags(paramItem->flags() & ~Qt::ItemIsEditable); //disallow editing
|
||||
paramItem->setBackground(0, QBrush(QColor(QGC::colorOrange))); |
||||
paramItem->setBackground(1, QBrush(QColor(QGC::colorOrange))); |
||||
tree->expandAll(); |
||||
} |
||||
else { |
||||
//we don't display non-pending items
|
||||
QTreeWidgetItem* groupItem = paramItem->parent(); |
||||
if (NULL != groupItem) { |
||||
tree->setUpdatesEnabled(false); |
||||
QTreeWidgetItem* componentItem = NULL; |
||||
if (1 == groupItem->childCount()) { |
||||
componentItem = groupItem->parent(); |
||||
} |
||||
|
||||
//always remove the actual paramItem from its parent
|
||||
groupItem->removeChild(paramItem); |
||||
|
||||
//now we may need to remove the groupItem if it has no more children
|
||||
if (NULL != componentItem) { |
||||
//remove the group from our internal data structures
|
||||
QMap<QString, QTreeWidgetItem*>* compParamGroups = paramGroups.value(compId); |
||||
QString groupStr = paramName.section("_", 0, 0, QString::SectionSkipEmpty); |
||||
compParamGroups->remove(groupStr); |
||||
//remove the group item from componentItems
|
||||
componentItems->value(compId)->removeChild(groupItem); |
||||
// remove the group item from the tree widget itself
|
||||
componentItem->removeChild(groupItem); |
||||
|
||||
if (0 == componentItem->childCount()) { |
||||
//the component itself no longer has any pending changes: remove it
|
||||
paramGroups.remove(compId); |
||||
componentItems->remove(compId); |
||||
QTreeWidgetItem* compTop = tree->takeTopLevelItem(tree->indexOfTopLevelItem(componentItem)); |
||||
delete compTop; //we own it after take
|
||||
} |
||||
} |
||||
tree->setUpdatesEnabled(true); |
||||
tree->update(); |
||||
|
||||
} |
||||
} |
||||
|
||||
updatingParamNameLock.clear(); |
||||
|
||||
} |
||||
|
||||
void QGCPendingParamWidget::addActionButtonsToLayout(QGridLayout* layout) |
||||
{ |
||||
|
||||
QPushButton* setButton = new QPushButton(tr("Set")); |
||||
setButton->setToolTip(tr("Send pending parameters to volatile onboard memory")); |
||||
setButton->setWhatsThis(tr("Send pending parameters to volatile onboard memory")); |
||||
connect(setButton, SIGNAL(clicked()), |
||||
paramMgr, SLOT(sendPendingParameters())); |
||||
layout->addWidget(setButton, 2, 0); |
||||
|
||||
QPushButton* clearButton = new QPushButton(tr("Clear")); |
||||
clearButton->setToolTip(tr("Clear pending parameters without sending")); |
||||
clearButton->setWhatsThis(tr("Clear pending parameters without sending")); |
||||
connect(clearButton, SIGNAL(clicked()), |
||||
paramMgr, SLOT(clearAllPendingParams())); |
||||
layout->addWidget(clearButton, 2, 1); |
||||
|
||||
|
||||
} |
@ -1,33 +0,0 @@
@@ -1,33 +0,0 @@
|
||||
#ifndef QGCPENDINGPARAMWIDGET_H |
||||
#define QGCPENDINGPARAMWIDGET_H |
||||
|
||||
|
||||
#include "QGCParamWidget.h" |
||||
|
||||
class QGridLayout; |
||||
|
||||
class QGCPendingParamWidget : public QGCParamWidget |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
explicit QGCPendingParamWidget(QObject* parent); |
||||
|
||||
protected: |
||||
virtual void connectToParamManager(); |
||||
virtual void disconnectFromParamManager(); |
||||
|
||||
virtual void connectViewSignalsAndSlots(); |
||||
virtual void disconnectViewSignalsAndSlots(); |
||||
|
||||
virtual void addActionButtonsToLayout(QGridLayout* layout); |
||||
|
||||
|
||||
signals: |
||||
|
||||
public slots: |
||||
virtual void handlePendingParamUpdate(int compId, const QString& paramName, QVariant value, bool isPending); |
||||
|
||||
}; |
||||
|
||||
#endif // QGCPENDINGPARAMWIDGET_H
|
Loading…
Reference in new issue