Unverified Commit 40708809 authored by Don Gagne's avatar Don Gagne Committed by GitHub

Merge pull request #5987 from DonLakeFlyer/ParameterCategories

Parameter Editor Category->Group hierarchy support
parents ce0e3ad0 b0f60168
......@@ -497,6 +497,16 @@ int Fact::decimalPlaces(void) const
}
}
QString Fact::category(void) const
{
if (_metaData) {
return _metaData->category();
} else {
qWarning() << kMissingMetadata << name();
return QString();
}
}
QString Fact::group(void) const
{
if (_metaData) {
......
......@@ -48,6 +48,7 @@ public:
Q_PROPERTY(QStringList enumStrings READ enumStrings NOTIFY enumsChanged)
Q_PROPERTY(QString enumStringValue READ enumStringValue WRITE setEnumStringValue NOTIFY valueChanged)
Q_PROPERTY(QVariantList enumValues READ enumValues NOTIFY enumsChanged)
Q_PROPERTY(QString category READ category CONSTANT)
Q_PROPERTY(QString group READ group CONSTANT)
Q_PROPERTY(QString longDescription READ longDescription CONSTANT)
Q_PROPERTY(QVariant max READ cookedMax CONSTANT)
......@@ -91,6 +92,7 @@ public:
QStringList enumStrings (void) const;
QString enumStringValue (void); // This is not const, since an unknown value can modify the enum lists
QVariantList enumValues (void) const;
QString category (void) const;
QString group (void) const;
QString longDescription (void) const;
QVariant rawMax (void) const;
......
......@@ -32,6 +32,9 @@ const qreal FactMetaData::UnitConsts_s::milesToMeters = 1609.344;
const qreal FactMetaData::UnitConsts_s::feetToMeters = 0.3048;
const qreal FactMetaData::UnitConsts_s::inchesToCentimeters = 2.54;
const QString FactMetaData::defaultCategory = tr("Other");
const QString FactMetaData::defaultGroup = tr("Misc");
// Built in translations for all Facts
const FactMetaData::BuiltInTranslation_s FactMetaData::_rgBuiltInTranslations[] = {
{ "centi-degrees", "deg", FactMetaData::_centiDegreesToDegrees, FactMetaData::_degreesToCentiDegrees },
......@@ -76,43 +79,45 @@ const char* FactMetaData::_maxJsonKey = "max";
const char* FactMetaData::_hasControlJsonKey = "control";
FactMetaData::FactMetaData(QObject* parent)
: QObject(parent)
, _type(valueTypeInt32)
, _decimalPlaces(unknownDecimalPlaces)
, _rawDefaultValue(0)
: QObject (parent)
, _type (valueTypeInt32)
, _decimalPlaces (unknownDecimalPlaces)
, _rawDefaultValue (0)
, _defaultValueAvailable(false)
, _group("*Default Group")
, _rawMax(_maxForType())
, _maxIsDefaultForType(true)
, _rawMin(_minForType())
, _minIsDefaultForType(true)
, _rawTranslator(_defaultTranslator)
, _cookedTranslator(_defaultTranslator)
, _rebootRequired(false)
, _increment(std::numeric_limits<double>::quiet_NaN())
, _hasControl(true)
, _readOnly(false)
, _category (defaultCategory)
, _group (defaultGroup)
, _rawMax (_maxForType())
, _maxIsDefaultForType (true)
, _rawMin (_minForType())
, _minIsDefaultForType (true)
, _rawTranslator (_defaultTranslator)
, _cookedTranslator (_defaultTranslator)
, _rebootRequired (false)
, _increment (std::numeric_limits<double>::quiet_NaN())
, _hasControl (true)
, _readOnly (false)
{
}
FactMetaData::FactMetaData(ValueType_t type, QObject* parent)
: QObject(parent)
, _type(type)
, _decimalPlaces(unknownDecimalPlaces)
, _rawDefaultValue(0)
: QObject (parent)
, _type (type)
, _decimalPlaces (unknownDecimalPlaces)
, _rawDefaultValue (0)
, _defaultValueAvailable(false)
, _group("*Default Group")
, _rawMax(_maxForType())
, _maxIsDefaultForType(true)
, _rawMin(_minForType())
, _minIsDefaultForType(true)
, _rawTranslator(_defaultTranslator)
, _cookedTranslator(_defaultTranslator)
, _rebootRequired(false)
, _increment(std::numeric_limits<double>::quiet_NaN())
, _hasControl(true)
, _readOnly(false)
, _category (defaultCategory)
, _group (defaultGroup)
, _rawMax (_maxForType())
, _maxIsDefaultForType (true)
, _rawMin (_minForType())
, _minIsDefaultForType (true)
, _rawTranslator (_defaultTranslator)
, _cookedTranslator (_defaultTranslator)
, _rebootRequired (false)
, _increment (std::numeric_limits<double>::quiet_NaN())
, _hasControl (true)
, _readOnly (false)
{
}
......@@ -124,23 +129,24 @@ FactMetaData::FactMetaData(const FactMetaData& other, QObject* parent)
}
FactMetaData::FactMetaData(ValueType_t type, const QString name, QObject* parent)
: QObject(parent)
, _type(type)
, _decimalPlaces(unknownDecimalPlaces)
, _rawDefaultValue(0)
: QObject (parent)
, _type (type)
, _decimalPlaces (unknownDecimalPlaces)
, _rawDefaultValue (0)
, _defaultValueAvailable(false)
, _group("*Default Group")
, _rawMax(_maxForType())
, _maxIsDefaultForType(true)
, _rawMin(_minForType())
, _minIsDefaultForType(true)
, _name(name)
, _rawTranslator(_defaultTranslator)
, _cookedTranslator(_defaultTranslator)
, _rebootRequired(false)
, _increment(std::numeric_limits<double>::quiet_NaN())
, _hasControl(true)
, _readOnly(false)
, _category (defaultCategory)
, _group (defaultGroup)
, _rawMax (_maxForType())
, _maxIsDefaultForType (true)
, _rawMin (_minForType())
, _minIsDefaultForType (true)
, _name (name)
, _rawTranslator (_defaultTranslator)
, _cookedTranslator (_defaultTranslator)
, _rebootRequired (false)
, _increment (std::numeric_limits<double>::quiet_NaN())
, _hasControl (true)
, _readOnly (false)
{
}
......@@ -154,6 +160,7 @@ const FactMetaData& FactMetaData::operator=(const FactMetaData& other)
_bitmaskValues = other._bitmaskValues;
_enumStrings = other._enumStrings;
_enumValues = other._enumValues;
_category = other._category;
_group = other._group;
_longDescription = other._longDescription;
_rawMax = other._rawMax;
......
......@@ -84,6 +84,7 @@ public:
QVariantList bitmaskValues (void) const { return _bitmaskValues; }
QStringList enumStrings (void) const { return _enumStrings; }
QVariantList enumValues (void) const { return _enumValues; }
QString category (void) const { return _category; }
QString group (void) const { return _group; }
QString longDescription (void) const { return _longDescription;}
QVariant rawMax (void) const { return _rawMax; }
......@@ -118,6 +119,7 @@ public:
void setRawDefaultValue (const QVariant& rawDefaultValue);
void setBitmaskInfo (const QStringList& strings, const QVariantList& values);
void setEnumInfo (const QStringList& strings, const QVariantList& values);
void setCategory (const QString& category) { _category = category; }
void setGroup (const QString& group) { _group = group; }
void setLongDescription (const QString& longDescription) { _longDescription = longDescription;}
void setRawMax (const QVariant& rawMax);
......@@ -158,6 +160,9 @@ public:
static ValueType_t stringToType(const QString& typeString, bool& unknownType);
static size_t typeToSize(ValueType_t type);
static const QString defaultCategory;
static const QString defaultGroup;
private:
QVariant _minForType(void) const;
QVariant _maxForType(void) const;
......@@ -217,6 +222,7 @@ private:
QVariantList _bitmaskValues;
QStringList _enumStrings;
QVariantList _enumValues;
QString _category;
QString _group;
QString _longDescription;
QVariant _rawMax;
......
This diff is collapsed.
......@@ -84,7 +84,7 @@ public:
/// @param name Parameter name
Fact* getParameter(int componentId, const QString& name);
const QMap<int, QMap<QString, QStringList> >& getGroupMap(void);
const QMap<QString, QMap<QString, QStringList> >& getCategoryMap(void);
/// Returns error messages from loading
QString readParametersFromStream(QTextStream& stream);
......@@ -137,7 +137,7 @@ protected:
private:
static QVariant _stringToTypedVariant(const QString& string, FactMetaData::ValueType_t type, bool failOk = false);
int _actualComponentId(int componentId);
void _setupGroupMap(void);
void _setupCategoryMap(void);
void _readParameterRaw(int componentId, const QString& paramName, int paramIndex);
void _writeParameterRaw(int componentId, const QString& paramName, const QVariant& value);
void _writeLocalParamCache(int vehicleId, int componentId);
......@@ -159,10 +159,9 @@ private:
QMap<int, QVariantMap> _mapParameterName2Variant;
QMap<int, QMap<int, QString> > _mapParameterId2Name;
/// First mapping is by component id
/// Second mapping is group name, to Fact
QMap<int, QMap<QString, QStringList> > _mapGroup2ParameterName;
// Category map of default component parameters
QMap<QString /* category */, QMap<QString /* group */, QStringList /* parameter names */> > _categoryMap;
double _loadProgress; ///< Parameter load progess, [0.0,1.0]
bool _parametersReady; ///< true: parameter load complete
......
......@@ -233,14 +233,18 @@ void APMParameterMetaData::loadParameterFactMetaDataFile(const QString& metaData
QString group = name.split('_').first();
group = group.remove(QRegExp("[0-9]*$")); // remove any numbers from the end
QString category = xml.attributes().value("user").toString();
if (category.isEmpty()) {
category = QStringLiteral("Advanced");
}
QString shortDescription = xml.attributes().value("humanName").toString();
QString longDescription = xml.attributes().value("documentation").toString();
QString userLevel = xml.attributes().value("user").toString();
qCDebug(APMParameterMetaDataVerboseLog) << "Found parameter name:" << name
<< "short Desc:" << shortDescription
<< "longDescription:" << longDescription
<< "user level: " << userLevel
<< "category: " << category
<< "group: " << group;
Q_ASSERT(!rawMetaData);
......@@ -254,6 +258,7 @@ void APMParameterMetaData::loadParameterFactMetaDataFile(const QString& metaData
}
qCDebug(APMParameterMetaDataVerboseLog) << "inserting metadata for field" << name;
rawMetaData->name = name;
rawMetaData->category = category;
rawMetaData->group = group;
rawMetaData->shortDescription = shortDescription;
rawMetaData->longDescription = longDescription;
......@@ -301,7 +306,7 @@ void APMParameterMetaData::correctGroupMemberships(ParameterNametoFactMetaDataMa
foreach(const QString& groupName, groupMembers.keys()) {
if (groupMembers[groupName].count() == 1) {
foreach(const QString& parameter, groupMembers.value(groupName)) {
parameterToFactMetaDataMap[parameter]->group = "others";
parameterToFactMetaDataMap[parameter]->group = FactMetaData::defaultGroup;
}
}
}
......@@ -434,6 +439,7 @@ void APMParameterMetaData::addMetaDataToFact(Fact* fact, MAV_TYPE vehicleType)
}
metaData->setName(rawMetaData->name);
metaData->setCategory(rawMetaData->category);
metaData->setGroup(rawMetaData->group);
metaData->setRebootRequired(rawMetaData->rebootRequired);
......
......@@ -32,6 +32,7 @@ public:
{ }
QString name;
QString category;
QString group;
QString shortDescription;
QString longDescription;
......
......@@ -181,6 +181,11 @@ void PX4ParameterMetaData::loadParameterFactMetaDataFile(const QString& metaData
QString type = xml.attributes().value("type").toString();
QString strDefault = xml.attributes().value("default").toString();
QString category = xml.attributes().value("category").toString();
if (category.isEmpty()) {
category = QStringLiteral("Standard");
}
qCDebug(PX4ParameterMetaDataLog) << "Found parameter name:" << name << " type:" << type << " default:" << strDefault;
// Convert type from string to FactMetaData::ValueType_t
......@@ -196,7 +201,7 @@ void PX4ParameterMetaData::loadParameterFactMetaDataFile(const QString& metaData
metaData = new FactMetaData(foundType);
Q_CHECK_PTR(metaData);
if (_mapParameterName2FactMetaData.contains(name)) {
// We can't trust the meta dafa since we have dups
// We can't trust the meta data since we have dups
qCWarning(PX4ParameterMetaDataLog) << "Duplicate parameter found:" << name;
badMetaData = true;
// Reset to default meta data
......@@ -204,6 +209,7 @@ void PX4ParameterMetaData::loadParameterFactMetaDataFile(const QString& metaData
} else {
_mapParameterName2FactMetaData[name] = metaData;
metaData->setName(name);
metaData->setCategory(category);
metaData->setGroup(factGroup);
if (xml.attributes().hasAttribute("default") && !strDefault.isEmpty()) {
......
......@@ -46,8 +46,9 @@ FocusScope {
}
QGCLabel {
id: label
Layout.fillWidth: true
id: label
anchors.left: parent.left
anchors.right: parent.right
QGCColoredImage {
id: image
......
......@@ -7,13 +7,10 @@
*
****************************************************************************/
/// @file
/// @author Don Gagne <don@thegagnes.com>
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.2
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.2
import QGroundControl 1.0
import QGroundControl.Controls 1.0
......@@ -44,6 +41,8 @@ QGCView {
}
}
ExclusiveGroup { id: sectionGroup }
QGCViewPanel {
id: panel
anchors.fill: parent
......@@ -158,48 +157,58 @@ QGCView {
anchors.bottom: parent.bottom
clip: true
pixelAligned: true
contentHeight: groupedViewComponentColumn.height
contentWidth: groupedViewComponentColumn.width
contentHeight: groupedViewCategoryColumn.height
flickableDirection: Flickable.VerticalFlick
visible: !_searchFilter
Column {
id: groupedViewComponentColumn
spacing: Math.ceil(ScreenTools.defaultFontPixelHeight * 0.25)
ColumnLayout {
id: groupedViewCategoryColumn
anchors.left: parent.left
anchors.right: parent.right
spacing: Math.ceil(ScreenTools.defaultFontPixelHeight * 0.25)
Repeater {
model: controller.componentIds
model: controller.categories
Column {
id: componentColumn
spacing: Math.ceil(ScreenTools.defaultFontPixelHeight * 0.25)
Layout.fillWidth: true
spacing: Math.ceil(ScreenTools.defaultFontPixelHeight * 0.25)
readonly property int componentId: modelData
readonly property string category: modelData
QGCLabel {
text: qsTr("Component #: %1").arg(componentId.toString())
font.family: ScreenTools.demiboldFontFamily
anchors.horizontalCenter: parent.horizontalCenter
SectionHeader {
id: categoryHeader
text: category
checked: controller.currentCategory == text
exclusiveGroup: sectionGroup
onCheckedChanged: {
if (checked) {
controller.currentCategory = category
controller.currentGroup = controller.getGroupsForCategory(category)[0]
}
}
}
ExclusiveGroup { id: groupGroup }
ExclusiveGroup { id: buttonGroup }
Repeater {
model: controller.getGroupsForComponent(componentId)
model: categoryHeader.checked ? controller.getGroupsForCategory(category) : 0
QGCButton {
width: ScreenTools.defaultFontPixelWidth * 25
text: groupName
height: _rowHeight
exclusiveGroup: setupButtonGroup
checked: controller.currentGroup == text
exclusiveGroup: buttonGroup
readonly property string groupName: modelData
onClicked: {
checked = true
_rowWidth = 10
controller.currentComponentId = componentId
controller.currentGroup = groupName
_rowWidth = 10
controller.currentCategory = category
controller.currentGroup = groupName
}
}
}
......
......@@ -27,22 +27,23 @@
/// @Brief Constructs a new ParameterEditorController Widget. This widget is used within the PX4VehicleConfig set of screens.
ParameterEditorController::ParameterEditorController(void)
: _currentComponentId(_vehicle->defaultComponentId())
: _currentCategory("Standard") // FIXME: firmware specific
, _parameters(new QmlObjectListModel(this))
{
const QMap<int, QMap<QString, QStringList> >& groupMap = _vehicle->parameterManager()->getGroupMap();
foreach (int componentId, groupMap.keys()) {
_componentIds += QString("%1").arg(componentId);
}
const QMap<QString, QMap<QString, QStringList> >& categoryMap = _vehicle->parameterManager()->getCategoryMap();
_categories = categoryMap.keys();
// Move default category to front
_categories.removeOne(_currentCategory);
_categories.prepend(_currentCategory);
// Be careful about no parameters
if (groupMap.contains(_currentComponentId) && groupMap[_currentComponentId].size() != 0) {
_currentGroup = groupMap[_currentComponentId].keys()[0];
if (categoryMap.contains(_currentCategory) && categoryMap[_currentCategory].size() != 0) {
_currentGroup = categoryMap[_currentCategory].keys()[0];
}
_updateParameters();
connect(this, &ParameterEditorController::searchTextChanged, this, &ParameterEditorController::_updateParameters);
connect(this, &ParameterEditorController::currentComponentIdChanged, this, &ParameterEditorController::_updateParameters);
connect(this, &ParameterEditorController::currentGroupChanged, this, &ParameterEditorController::_updateParameters);
}
......@@ -51,29 +52,29 @@ ParameterEditorController::~ParameterEditorController()
}
QStringList ParameterEditorController::getGroupsForComponent(int componentId)
QStringList ParameterEditorController::getGroupsForCategory(const QString& category)
{
const QMap<int, QMap<QString, QStringList> >& groupMap = _vehicle->parameterManager()->getGroupMap();
const QMap<QString, QMap<QString, QStringList> >& categoryMap = _vehicle->parameterManager()->getCategoryMap();
return groupMap[componentId].keys();
return categoryMap[category].keys();
}
QStringList ParameterEditorController::getParametersForGroup(int componentId, QString group)
QStringList ParameterEditorController::getParametersForGroup(const QString& category, const QString& group)
{
const QMap<int, QMap<QString, QStringList> >& groupMap = _vehicle->parameterManager()->getGroupMap();
const QMap<QString, QMap<QString, QStringList> >& categoryMap = _vehicle->parameterManager()->getCategoryMap();
return groupMap[componentId][group];
return categoryMap[category][group];
}
QStringList ParameterEditorController::searchParametersForComponent(int componentId, const QString& searchText, bool searchInName, bool searchInDescriptions)
QStringList ParameterEditorController::searchParameters(const QString& searchText, bool searchInName, bool searchInDescriptions)
{
QStringList list;
foreach(const QString &paramName, _vehicle->parameterManager()->parameterNames(componentId)) {
foreach(const QString &paramName, _vehicle->parameterManager()->parameterNames(_vehicle->defaultComponentId())) {
if (searchText.isEmpty()) {
list += paramName;
} else {
Fact* fact = _vehicle->parameterManager()->getParameter(componentId, paramName);
Fact* fact = _vehicle->parameterManager()->getParameter(_vehicle->defaultComponentId(), paramName);
if (searchInName && fact->name().contains(searchText, Qt::CaseInsensitive)) {
list += paramName;
......@@ -161,9 +162,9 @@ void ParameterEditorController::_updateParameters(void)
QStringList searchItems = _searchText.split(' ', QString::SkipEmptyParts);
if (searchItems.isEmpty()) {
const QMap<int, QMap<QString, QStringList> >& groupMap = _vehicle->parameterManager()->getGroupMap();
foreach (const QString& parameter, groupMap[_currentComponentId][_currentGroup]) {
newParameterList.append(_vehicle->parameterManager()->getParameter(_currentComponentId, parameter));
const QMap<QString, QMap<QString, QStringList> >& categoryMap = _vehicle->parameterManager()->getCategoryMap();
foreach (const QString& parameter, categoryMap[_currentCategory][_currentGroup]) {
newParameterList.append(_vehicle->parameterManager()->getParameter(_vehicle->defaultComponentId(), parameter));
}
} else {
foreach(const QString &parameter, _vehicle->parameterManager()->parameterNames(_vehicle->defaultComponentId())) {
......
......@@ -31,14 +31,14 @@ public:
~ParameterEditorController();
Q_PROPERTY(QString searchText MEMBER _searchText NOTIFY searchTextChanged)
Q_PROPERTY(int currentComponentId MEMBER _currentComponentId NOTIFY currentComponentIdChanged)
Q_PROPERTY(QString currentCategory MEMBER _currentCategory NOTIFY currentCategoryChanged)
Q_PROPERTY(QString currentGroup MEMBER _currentGroup NOTIFY currentGroupChanged)
Q_PROPERTY(QmlObjectListModel* parameters MEMBER _parameters CONSTANT)
Q_PROPERTY(QVariantList componentIds MEMBER _componentIds CONSTANT)
Q_PROPERTY(QStringList categories MEMBER _categories CONSTANT)
Q_INVOKABLE QStringList getGroupsForComponent(int componentId);
Q_INVOKABLE QStringList getParametersForGroup(int componentId, QString group);
Q_INVOKABLE QStringList searchParametersForComponent(int componentId, const QString& searchText, bool searchInName=true, bool searchInDescriptions=true);
Q_INVOKABLE QStringList getGroupsForCategory(const QString& category);
Q_INVOKABLE QStringList getParametersForGroup(const QString& category, const QString& group);
Q_INVOKABLE QStringList searchParameters(const QString& searchText, bool searchInName=true, bool searchInDescriptions=true);
Q_INVOKABLE void clearRCToParam(void);
Q_INVOKABLE void saveToFile(const QString& filename);
......@@ -51,7 +51,7 @@ public:
signals:
void searchTextChanged(QString searchText);
void currentComponentIdChanged(int componentId);
void currentCategoryChanged(QString category);
void currentGroupChanged(QString group);
void showErrorMessage(const QString& errorMsg);
......@@ -59,9 +59,9 @@ private slots:
void _updateParameters(void);
private:
QVariantList _componentIds;
QStringList _categories;
QString _searchText;
int _currentComponentId;
QString _currentCategory;
QString _currentGroup;
QmlObjectListModel* _parameters;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment