1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-29 07:24:13 +01:00

LP-567 rewrite uavobjecttreemodel to better handle dynamic changes

don't rebuild the model when toggling options (categories, meta, scientific notation)
fixes a number of issues when adding/removing/removing items dynamically
for example, new object instances would not appear if added dynamically

selection and expansion states are not lost when toogling options
note that toggling categories is not really well behaved concerning expansion state...
This commit is contained in:
Philippe Renon 2018-03-25 19:03:15 +02:00
parent a02bea9aed
commit f27258a598
10 changed files with 630 additions and 482 deletions

View File

@ -1,28 +0,0 @@
/**
******************************************************************************
*
* @file fieldtreeitem.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup UAVObjectBrowserPlugin UAVObject Browser Plugin
* @{
* @brief The UAVObject Browser gadget plugin
*****************************************************************************/
/*
* 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 "fieldtreeitem.h"

View File

@ -31,6 +31,7 @@
#include "treeitem.h"
#include <QStringList>
#include <QSettings>
#include <QWidget>
#include <QSpinBox>
#include <QDoubleSpinBox>
@ -53,11 +54,11 @@
class FieldTreeItem : public TreeItem {
public:
FieldTreeItem(int index, const QList<QVariant> &data, UAVObjectField *field, TreeItem *parentItem) :
TreeItem(data, parentItem), m_index(index), m_field(field)
FieldTreeItem(int index, const QList<QVariant> &data, UAVObjectField *field) :
TreeItem(data), m_index(index), m_field(field)
{}
FieldTreeItem(int index, const QVariant &data, UAVObjectField *field, TreeItem *parentItem) :
TreeItem(data, parentItem), m_index(index), m_field(field)
FieldTreeItem(int index, const QVariant &data, UAVObjectField *field) :
TreeItem(data), m_index(index), m_field(field)
{}
bool isEditable() const
@ -109,12 +110,12 @@ protected:
class EnumFieldTreeItem : public FieldTreeItem {
public:
EnumFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data, TreeItem *parentItem) :
FieldTreeItem(index, data, field, parentItem), m_enumOptions(field->getOptions())
EnumFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data) :
FieldTreeItem(index, data, field), m_enumOptions(field->getOptions())
{}
EnumFieldTreeItem(UAVObjectField *field, int index, const QVariant &data, TreeItem *parentItem) :
FieldTreeItem(index, data, field, parentItem), m_enumOptions(field->getOptions())
EnumFieldTreeItem(UAVObjectField *field, int index, const QVariant &data) :
FieldTreeItem(index, data, field), m_enumOptions(field->getOptions())
{}
QString enumOptions(int index)
@ -174,13 +175,13 @@ private:
class IntFieldTreeItem : public FieldTreeItem {
public:
IntFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data, TreeItem *parentItem) :
FieldTreeItem(index, data, field, parentItem)
IntFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data) :
FieldTreeItem(index, data, field)
{
setMinMaxValues();
}
IntFieldTreeItem(UAVObjectField *field, int index, const QVariant &data, TreeItem *parentItem) :
FieldTreeItem(index, data, field, parentItem)
IntFieldTreeItem(UAVObjectField *field, int index, const QVariant &data) :
FieldTreeItem(index, data, field)
{
setMinMaxValues();
}
@ -259,11 +260,11 @@ private:
class FloatFieldTreeItem : public FieldTreeItem {
public:
FloatFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data, bool scientific, TreeItem *parentItem) :
FieldTreeItem(index, data, field, parentItem), m_useScientificNotation(scientific) {}
FloatFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data, const QSettings &settings) :
FieldTreeItem(index, data, field), m_settings(settings) {}
FloatFieldTreeItem(UAVObjectField *field, int index, const QVariant &data, bool scientific, TreeItem *parentItem) :
FieldTreeItem(index, data, field, parentItem), m_useScientificNotation(scientific) {}
FloatFieldTreeItem(UAVObjectField *field, int index, const QVariant &data, const QSettings &settings) :
FieldTreeItem(index, data, field), m_settings(settings) {}
QVariant fieldToData() const
{
@ -277,7 +278,9 @@ public:
QWidget *createEditor(QWidget *parent) const
{
if (m_useScientificNotation) {
bool useScientificNotation = m_settings.value("useScientificNotation", false).toBool();
if (useScientificNotation) {
QScienceSpinBox *editor = new QScienceSpinBox(parent);
editor->setDecimals(6);
editor->setMinimum(-std::numeric_limits<float>::max());
@ -294,7 +297,9 @@ public:
QVariant getEditorValue(QWidget *editor) const
{
if (m_useScientificNotation) {
bool useScientificNotation = m_settings.value("useScientificNotation", false).toBool();
if (useScientificNotation) {
QScienceSpinBox *spinBox = static_cast<QScienceSpinBox *>(editor);
spinBox->interpretText();
return spinBox->value();
@ -307,7 +312,9 @@ public:
void setEditorValue(QWidget *editor, QVariant value) const
{
if (m_useScientificNotation) {
bool useScientificNotation = m_settings.value("useScientificNotation", false).toBool();
if (useScientificNotation) {
QScienceSpinBox *spinBox = static_cast<QScienceSpinBox *>(editor);
spinBox->setValue(value.toDouble());
} else {
@ -317,17 +324,17 @@ public:
}
private:
bool m_useScientificNotation;
const QSettings &m_settings;
};
class HexFieldTreeItem : public FieldTreeItem {
public:
HexFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data, TreeItem *parentItem) :
FieldTreeItem(index, data, field, parentItem)
HexFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data) :
FieldTreeItem(index, data, field)
{}
HexFieldTreeItem(UAVObjectField *field, int index, const QVariant &data, TreeItem *parentItem) :
FieldTreeItem(index, data, field, parentItem)
HexFieldTreeItem(UAVObjectField *field, int index, const QVariant &data) :
FieldTreeItem(index, data, field)
{}
QVariant fieldToData() const
@ -382,12 +389,12 @@ private:
class CharFieldTreeItem : public FieldTreeItem {
public:
CharFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data, TreeItem *parentItem) :
FieldTreeItem(index, data, field, parentItem)
CharFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data) :
FieldTreeItem(index, data, field)
{}
CharFieldTreeItem(UAVObjectField *field, int index, const QVariant &data, TreeItem *parentItem) :
FieldTreeItem(index, data, field, parentItem)
CharFieldTreeItem(UAVObjectField *field, int index, const QVariant &data) :
FieldTreeItem(index, data, field)
{}
QVariant fieldToData() const

View File

@ -144,16 +144,16 @@ void HighlightManager::checkItemsExpired()
int TreeItem::m_highlightTimeMs = 300;
TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parentItem) :
TreeItem::TreeItem(const QList<QVariant> &data) :
m_itemData(data),
m_parentItem(parentItem),
m_parentItem(0),
m_changed(false),
m_highlighted(false),
m_highlightManager(0)
{}
TreeItem::TreeItem(const QVariant &data, TreeItem *parentItem) :
m_parentItem(parentItem),
TreeItem::TreeItem(const QVariant &data) :
m_parentItem(0),
m_changed(false),
m_highlighted(false),
m_highlightManager(0)
@ -166,16 +166,32 @@ TreeItem::~TreeItem()
qDeleteAll(m_childItems);
}
void TreeItem::appendChild(TreeItem *child)
void TreeItem::setParentItem(TreeItem *parentItem)
{
m_childItems.append(child);
if (m_parentItem) {
m_parentItem->removeChild(this, false);
}
m_parentItem = parentItem;
}
void TreeItem::insertChild(TreeItem *child)
void TreeItem::appendChild(TreeItem *childItem)
{
int index = nameIndex(child->data(0).toString());
m_childItems.append(childItem);
childItem->setParentItem(this);
}
m_childItems.insert(index, child);
void TreeItem::insertChild(TreeItem *childItem, int index)
{
m_childItems.insert(index, childItem);
childItem->setParentItem(this);
}
void TreeItem::removeChild(TreeItem *childItem, bool reparent)
{
m_childItems.removeOne(childItem);
if (reparent) {
childItem->setParentItem(0);
}
}
TreeItem *TreeItem::child(int index) const
@ -202,6 +218,16 @@ int TreeItem::columnCount() const
return m_itemData.count();
}
void TreeItem::setDescription(QString desc)
{
// Split around 40 characters
int idx = desc.indexOf(" ", 40);
desc.insert(idx, QString("<br>"));
desc.remove("@Ref", Qt::CaseInsensitive);
m_description = desc;
}
QVariant TreeItem::data(int column) const
{
return m_itemData.value(column);
@ -270,6 +296,62 @@ QTime TreeItem::getHighlightExpires() const
return m_highlightExpires;
}
int TreeItem::childIndex(QString name) const
{
for (int i = 0; i < childCount(); ++i) {
if (name == child(i)->data(0).toString()) {
return i;
}
}
return -1;
}
TreeItem *TreeItem::childByName(QString name) const
{
int index = childIndex(name);
return (index >= 0) ? m_childItems[index] : 0;
}
int TreeItem::insertionIndex(TreeItem *item) const
{
QString name = item->data(0).toString();
for (int i = 0; i < childCount(); ++i) {
if (name < child(i)->data(0).toString()) {
return i;
}
}
return childCount();
}
int TreeItem::maxHexStringLength(UAVObjectField::FieldType type)
{
switch (type) {
case UAVObjectField::INT8:
return 2;
case UAVObjectField::INT16:
return 4;
case UAVObjectField::INT32:
return 8;
case UAVObjectField::UINT8:
return 2;
case UAVObjectField::UINT16:
return 4;
case UAVObjectField::UINT32:
return 8;
default:
Q_ASSERT(false);
}
return 0;
}
QVariant ArrayFieldTreeItem::data(int column) const
{
if (column == 1) {

View File

@ -29,6 +29,7 @@
#define TREEITEM_H
#include "uavobject.h"
#include "uavdataobject.h"
#include "uavmetaobject.h"
#include "uavobjectfield.h"
@ -95,46 +96,49 @@ public:
static const int TITLE_COLUMN = 0;
static const int DATA_COLUMN = 1;
TreeItem(const QList<QVariant> &data, TreeItem *parentItem = 0);
TreeItem(const QVariant &data, TreeItem *parentItem = 0);
TreeItem(const QList<QVariant> &data);
TreeItem(const QVariant &data);
virtual ~TreeItem();
void appendChild(TreeItem *child);
void insertChild(TreeItem *child);
TreeItem *child(int index) const;
QList<TreeItem *> children() const
{
return m_childItems;
}
int childCount() const;
int columnCount() const;
virtual QVariant data(int column = 1) const;
QString description() const
{
return m_description;
}
void setDescription(QString d)
{
// Split around 40 characters
int idx = d.indexOf(" ", 40);
d.insert(idx, QString("<br>"));
d.remove("@Ref", Qt::CaseInsensitive);
m_description = d;
}
// only column 1 (TreeItem::dataColumn) is changed with setData currently
// other columns are initialized in constructor
virtual void setData(QVariant value, int column = 1);
int row() const;
TreeItem *parentItem() const
{
return m_parentItem;
}
void setParentItem(TreeItem *parentItem);
void appendChild(TreeItem *childItem);
void insertChild(TreeItem *childItem, int index);
void removeChild(TreeItem *childItem, bool reparent = true);
TreeItem *child(int index) const;
QList<TreeItem *> children() const
{
return m_childItems;
}
int childCount() const;
int columnCount() const;
QString description() const
{
return m_description;
}
void setDescription(QString desc);
virtual QVariant data(int column = 1) const;
virtual void setData(QVariant value, int column = 1);
int row() const;
virtual bool isEditable() const
{
return false;
}
virtual void update();
virtual void apply();
@ -174,52 +178,13 @@ public:
return true;
}
int nameIndex(QString name) const
{
for (int i = 0; i < childCount(); ++i) {
if (name < child(i)->data(0).toString()) {
return i;
}
}
return childCount();
}
int childIndex(QString name) const;
TreeItem *findChildByName(QString name) const
{
foreach(TreeItem * child, m_childItems) {
if (name == child->data(0).toString()) {
return child;
}
}
return 0;
}
TreeItem *childByName(QString name) const;
static int maxHexStringLength(UAVObjectField::FieldType type)
{
switch (type) {
case UAVObjectField::INT8:
return 2;
int insertionIndex(TreeItem *item) const;
case UAVObjectField::INT16:
return 4;
case UAVObjectField::INT32:
return 8;
case UAVObjectField::UINT8:
return 2;
case UAVObjectField::UINT16:
return 4;
case UAVObjectField::UINT32:
return 8;
default:
Q_ASSERT(false);
}
return 0;
}
static int maxHexStringLength(UAVObjectField::FieldType type);
private:
static int m_highlightTimeMs;
@ -238,52 +203,25 @@ private:
HighlightManager *m_highlightManager;
};
class DataObjectTreeItem;
class MetaObjectTreeItem;
class TopTreeItem : public TreeItem {
public:
TopTreeItem(const QList<QVariant> &data, TreeItem *parentItem) :
TreeItem(data, parentItem)
TopTreeItem(const QList<QVariant> &data) :
TreeItem(data)
{}
TopTreeItem(const QVariant &data, TreeItem *parentItem) :
TreeItem(data, parentItem)
TopTreeItem(const QVariant &data) :
TreeItem(data)
{}
void addObjectTreeItem(quint32 objectId, DataObjectTreeItem *oti)
{
m_objectTreeItemsPerObjectIds[objectId] = oti;
}
DataObjectTreeItem *findDataObjectTreeItemByObjectId(quint32 objectId)
{
return m_objectTreeItemsPerObjectIds.value(objectId, 0);
}
void addMetaObjectTreeItem(quint32 objectId, MetaObjectTreeItem *oti)
{
m_metaObjectTreeItemsPerObjectIds[objectId] = oti;
}
MetaObjectTreeItem *findMetaObjectTreeItemByObjectId(quint32 objectId)
{
return m_metaObjectTreeItemsPerObjectIds.value(objectId, 0);
}
private:
QHash<quint32, DataObjectTreeItem *> m_objectTreeItemsPerObjectIds;
QHash<quint32, MetaObjectTreeItem *> m_metaObjectTreeItemsPerObjectIds;
};
class ObjectTreeItem : public TreeItem {
public:
ObjectTreeItem(const QList<QVariant> &data, UAVObject *object, TreeItem *parentItem) :
TreeItem(data, parentItem), m_obj(object)
ObjectTreeItem(UAVObject *object, const QList<QVariant> &data) :
TreeItem(data), m_obj(object)
{
setDescription(m_obj->getDescription());
}
ObjectTreeItem(const QVariant &data, UAVObject *object, TreeItem *parentItem) :
TreeItem(data, parentItem), m_obj(object)
ObjectTreeItem(UAVObject *object, const QVariant &data) :
TreeItem(data), m_obj(object)
{
setDescription(m_obj->getDescription());
}
@ -299,23 +237,33 @@ private:
class MetaObjectTreeItem : public ObjectTreeItem {
public:
MetaObjectTreeItem(UAVObject *object, const QList<QVariant> &data, TreeItem *parentItem) :
ObjectTreeItem(data, object, parentItem)
MetaObjectTreeItem(UAVMetaObject *object, const QList<QVariant> &data) :
ObjectTreeItem(object, data)
{}
MetaObjectTreeItem(UAVObject *object, const QVariant &data, TreeItem *parentItem) :
ObjectTreeItem(data, object, parentItem)
MetaObjectTreeItem(UAVMetaObject *object, const QVariant &data) :
ObjectTreeItem(object, data)
{}
UAVMetaObject *metaObject() const
{
return static_cast<UAVMetaObject *>(object());
}
};
class DataObjectTreeItem : public ObjectTreeItem {
public:
DataObjectTreeItem(const QList<QVariant> &data, UAVObject *object, TreeItem *parentItem) :
ObjectTreeItem(data, object, parentItem)
DataObjectTreeItem(UAVDataObject *object, const QList<QVariant> &data) :
ObjectTreeItem(object, data)
{}
DataObjectTreeItem(const QVariant &data, UAVObject *object, TreeItem *parentItem) :
ObjectTreeItem(data, object, parentItem)
DataObjectTreeItem(UAVDataObject *object, const QVariant &data) :
ObjectTreeItem(object, data)
{}
UAVDataObject *dataObject() const
{
return static_cast<UAVDataObject *>(object());
}
virtual void apply()
{
foreach(TreeItem * child, children()) {
@ -346,11 +294,11 @@ public:
class InstanceTreeItem : public DataObjectTreeItem {
public:
InstanceTreeItem(UAVObject *object, const QList<QVariant> &data, TreeItem *parentItem) :
DataObjectTreeItem(data, object, parentItem)
InstanceTreeItem(UAVDataObject *object, const QList<QVariant> &data) :
DataObjectTreeItem(object, data)
{}
InstanceTreeItem(UAVObject *object, const QVariant &data, TreeItem *parentItem) :
DataObjectTreeItem(data, object, parentItem)
InstanceTreeItem(UAVDataObject *object, const QVariant &data) :
DataObjectTreeItem(object, data)
{}
virtual void apply()
@ -366,11 +314,11 @@ public:
class ArrayFieldTreeItem : public TreeItem {
public:
ArrayFieldTreeItem(UAVObjectField *field, const QList<QVariant> &data, TreeItem *parentItem) :
TreeItem(data, parentItem), m_field(field)
ArrayFieldTreeItem(UAVObjectField *field, const QList<QVariant> &data) :
TreeItem(data), m_field(field)
{}
ArrayFieldTreeItem(UAVObjectField *field, const QVariant &data, TreeItem *parentItem) :
TreeItem(data, parentItem), m_field(field)
ArrayFieldTreeItem(UAVObjectField *field, const QVariant &data) :
TreeItem(data), m_field(field)
{}
QVariant data(int column) const;

View File

@ -51,7 +51,7 @@ void UAVObjectBrowser::loadConfiguration(IUAVGadgetConfiguration *config)
m_widget->setManuallyChangedColor(m->manuallyChangedColor());
m_widget->setRecentlyUpdatedTimeout(m->recentlyUpdatedTimeout());
m_widget->setOnlyHighlightChangedValues(m->onlyHighlightChangedValues());
m_widget->setViewOptions(m->categorizedView(), m->scientificView(), m->showMetaData(), m->showDescription());
m_widget->setViewOptions(m->categorizedView(), m->showMetaData(), m->scientificView(), m->showDescription());
m_widget->setSplitterState(m->splitterState());
}

View File

@ -7,28 +7,27 @@ include(../../plugin.pri)
include(uavobjectbrowser_dependencies.pri)
HEADERS += \
browserplugin.h \
treeitem.h \
fieldtreeitem.h \
browseritemdelegate.h \
uavobjecttreemodel.h \
uavobjectbrowserconfiguration.h \
uavobjectbrowseroptionspage.h \
uavobjectbrowser.h \
uavobjectbrowserwidget.h \
uavobjectbrowserfactory.h \
uavobjectbrowseroptionspage.h \
uavobjecttreemodel.h \
treeitem.h \
browseritemdelegate.h \
fieldtreeitem.h
browserplugin.h
SOURCES += \
browserplugin.cpp \
treeitem.cpp \
browseritemdelegate.cpp \
uavobjecttreemodel.cpp \
uavobjectbrowserconfiguration.cpp \
uavobjectbrowseroptionspage.cpp \
uavobjectbrowser.cpp \
uavobjectbrowserfactory.cpp \
uavobjectbrowserwidget.cpp \
uavobjectbrowseroptionspage.cpp \
uavobjecttreemodel.cpp \
treeitem.cpp \
browseritemdelegate.cpp \
fieldtreeitem.cpp
browserplugin.cpp
OTHER_FILES += UAVObjectBrowser.pluginspec

View File

@ -95,12 +95,12 @@ UAVObjectBrowserWidget::~UAVObjectBrowserWidget()
delete m_browser;
}
void UAVObjectBrowserWidget::setViewOptions(bool categorized, bool scientific, bool metadata, bool description)
void UAVObjectBrowserWidget::setViewOptions(bool showCategories, bool showMetadata, bool useScientificNotation, bool showDescription)
{
m_viewoptions->cbCategorized->setChecked(categorized);
m_viewoptions->cbMetaData->setChecked(metadata);
m_viewoptions->cbScientific->setChecked(scientific);
m_viewoptions->cbDescription->setChecked(description);
m_viewoptions->cbCategorized->setChecked(showCategories);
m_viewoptions->cbMetaData->setChecked(showMetadata);
m_viewoptions->cbScientific->setChecked(useScientificNotation);
m_viewoptions->cbDescription->setChecked(showDescription);
}
void UAVObjectBrowserWidget::setSplitterState(QByteArray state)
@ -264,15 +264,16 @@ void UAVObjectBrowserWidget::viewSlot()
UAVObjectTreeModel *UAVObjectBrowserWidget::createTreeModel()
{
UAVObjectTreeModel *model = new UAVObjectTreeModel(this,
m_viewoptions->cbCategorized->isChecked(),
m_viewoptions->cbMetaData->isChecked(),
m_viewoptions->cbScientific->isChecked());
UAVObjectTreeModel *model = new UAVObjectTreeModel(this);
model->setShowCategories(m_viewoptions->cbCategorized->isChecked());
model->setShowMetadata(m_viewoptions->cbMetaData->isChecked());
model->setUseScientificNotation(m_viewoptions->cbScientific->isChecked());
model->setRecentlyUpdatedColor(m_recentlyUpdatedColor);
model->setManuallyChangedColor(m_manuallyChangedColor);
model->setRecentlyUpdatedTimeout(m_recentlyUpdatedTimeout);
model->setUnknowObjectColor(m_unknownObjectColor);
model->setUnknownObjectColor(m_unknownObjectColor);
model->setOnlyHighlightChangedValues(m_onlyHighlightChangedValues);
return model;
@ -280,15 +281,14 @@ UAVObjectTreeModel *UAVObjectBrowserWidget::createTreeModel()
void UAVObjectBrowserWidget::updateViewOptions()
{
bool categorize = m_viewoptions->cbCategorized->isChecked();
bool showCategories = m_viewoptions->cbCategorized->isChecked();
bool useScientificNotation = m_viewoptions->cbScientific->isChecked();
bool showMetadata = m_viewoptions->cbMetaData->isChecked();
bool showDesc = m_viewoptions->cbDescription->isChecked();
m_model->setShowCategories(categorize);
m_model->setShowCategories(showCategories);
m_model->setShowMetadata(showMetadata);
m_model->setShowScientificNotation(useScientificNotation);
m_model->resetModelData();
m_model->setUseScientificNotation(useScientificNotation);
// force an expand all if search text is not empty
if (!m_browser->searchLine->text().isEmpty()) {
@ -296,7 +296,7 @@ void UAVObjectBrowserWidget::updateViewOptions()
}
// persist options
emit viewOptionsChanged(categorize, useScientificNotation, showMetadata, showDesc);
emit viewOptionsChanged(showCategories, useScientificNotation, showMetadata, showDesc);
}
void UAVObjectBrowserWidget::splitterMoved()

View File

@ -62,7 +62,7 @@ public:
void setUnknownObjectColor(QColor color)
{
m_unknownObjectColor = color;
m_model->setUnknowObjectColor(color);
m_model->setUnknownObjectColor(color);
}
void setRecentlyUpdatedColor(QColor color)
{
@ -84,7 +84,7 @@ public:
m_onlyHighlightChangedValues = hilight;
m_model->setOnlyHighlightChangedValues(hilight);
}
void setViewOptions(bool categorized, bool scientific, bool metadata, bool description);
void setViewOptions(bool showCategories, bool showMetadata, bool useScientificNotation, bool showDescription);
void setSplitterState(QByteArray state);
public slots:

View File

@ -36,29 +36,14 @@
#include <QColor>
UAVObjectTreeModel::UAVObjectTreeModel(QObject *parent, bool categorize, bool showMetadata, bool useScientificNotation) :
QAbstractItemModel(parent),
m_categorize(categorize),
m_showMetadata(showMetadata),
m_useScientificFloatNotation(useScientificNotation),
m_recentlyUpdatedTimeout(500), // ms
m_recentlyUpdatedColor(QColor(255, 230, 230)),
m_manuallyChangedColor(QColor(230, 230, 255)),
m_unknownObjectColor(QColor(Qt::gray))
UAVObjectTreeModel::UAVObjectTreeModel(QObject *parent) : QAbstractItemModel(parent)
{
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
Q_ASSERT(objManager);
connect(objManager, SIGNAL(newObject(UAVObject *)), this, SLOT(newObject(UAVObject *)));
connect(objManager, SIGNAL(newInstance(UAVObject *)), this, SLOT(newObject(UAVObject *)));
m_highlightManager = new HighlightManager();
connect(m_highlightManager, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *)));
connect(m_highlightManager, &HighlightManager::updateHighlight, this, &refreshHighlight);
TreeItem::setHighlightTime(m_recentlyUpdatedTimeout);
setupModelData(objManager);
TreeItem::setHighlightTime(recentlyUpdatedTimeout());
setupModelData();
}
UAVObjectTreeModel::~UAVObjectTreeModel()
@ -67,165 +52,188 @@ UAVObjectTreeModel::~UAVObjectTreeModel()
delete m_highlightManager;
}
void UAVObjectTreeModel::resetModelData()
bool UAVObjectTreeModel::showCategories() const
{
m_highlightManager->reset();
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
Q_ASSERT(objManager);
emit beginResetModel();
delete m_rootItem;
m_rootItem = NULL;
setupModelData(objManager);
emit endResetModel();
return m_settings.value("showCategories", false).toBool();
}
void UAVObjectTreeModel::setShowCategories(bool showCategories)
void UAVObjectTreeModel::setShowCategories(bool show)
{
if (showCategories == m_categorize) {
if (show == showCategories()) {
return;
}
m_categorize = showCategories;
m_settings.setValue("showCategories", show);
toggleCategoryItems();
}
void UAVObjectTreeModel::setShowMetadata(bool showMetadata)
bool UAVObjectTreeModel::showMetadata() const
{
if (showMetadata == m_showMetadata) {
return m_settings.value("showMetadata", false).toBool();
}
void UAVObjectTreeModel::setShowMetadata(bool show)
{
if (show == showMetadata()) {
return;
}
m_showMetadata = showMetadata;
m_settings.setValue("showMetadata", show);
toggleMetaItems();
}
void UAVObjectTreeModel::setShowScientificNotation(bool showScientificNotation)
bool UAVObjectTreeModel::useScientificNotation()
{
if (showScientificNotation == m_useScientificFloatNotation) {
return;
}
m_useScientificFloatNotation = showScientificNotation;
return m_settings.value("useScientificNotation", false).toBool();
}
void UAVObjectTreeModel::setupModelData(UAVObjectManager *objManager)
void UAVObjectTreeModel::setUseScientificNotation(bool useScientificNotation)
{
m_settings.setValue("useScientificNotation", useScientificNotation);
}
QColor UAVObjectTreeModel::unknownObjectColor() const
{
return m_settings.value("unknownObjectColor", QColor(Qt::gray)).value<QColor>();
}
void UAVObjectTreeModel::setUnknownObjectColor(QColor color)
{
m_settings.setValue("unknownObjectColor", color);
}
QColor UAVObjectTreeModel::recentlyUpdatedColor() const
{
return m_settings.value("recentlyUpdatedColor", QColor(255, 230, 230)).value<QColor>();
}
void UAVObjectTreeModel::setRecentlyUpdatedColor(QColor color)
{
m_settings.setValue("recentlyUpdatedColor", color);
}
QColor UAVObjectTreeModel::manuallyChangedColor() const
{
return m_settings.value("manuallyChangedColor", QColor(230, 230, 255)).value<QColor>();
}
void UAVObjectTreeModel::setManuallyChangedColor(QColor color)
{
m_settings.setValue("manuallyChangedColor", color);
}
int UAVObjectTreeModel::recentlyUpdatedTimeout() const
{
return m_settings.value("recentlyUpdatedTimeout", 500).toInt();
}
void UAVObjectTreeModel::setRecentlyUpdatedTimeout(int timeout)
{
m_settings.setValue("recentlyUpdatedTimeout", timeout);
TreeItem::setHighlightTime(timeout);
}
bool UAVObjectTreeModel::onlyHighlightChangedValues() const
{
return m_settings.value("onlyHighlightChangedValues", false).toBool();
}
void UAVObjectTreeModel::setOnlyHighlightChangedValues(bool highlight)
{
m_settings.setValue("onlyHighlightChangedValues", highlight);
}
void UAVObjectTreeModel::setupModelData()
{
// root
QList<QVariant> rootData;
rootData << tr("Property") << tr("Value") << tr("Unit");
m_rootItem = new TreeItem(rootData);
m_rootItem->setHighlightManager(m_highlightManager);
m_settingsTree = new TopTreeItem(tr("Settings"), m_rootItem);
m_settingsTree = new TopTreeItem(tr("Settings"));
m_settingsTree->setHighlightManager(m_highlightManager);
m_nonSettingsTree = new TopTreeItem(tr("Data Objects"), m_rootItem);
m_nonSettingsTree = new TopTreeItem(tr("Data Objects"));
m_nonSettingsTree->setHighlightManager(m_highlightManager);
// tree item takes ownership of its children
m_rootItem->appendChild(m_settingsTree);
m_rootItem->appendChild(m_nonSettingsTree);
// tree item takes ownership of their children
appendItem(m_rootItem, m_settingsTree);
appendItem(m_rootItem, m_nonSettingsTree);
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
Q_ASSERT(objManager);
connect(objManager, &UAVObjectManager::newObject, this, &newObject, Qt::UniqueConnection);
connect(objManager, &UAVObjectManager::newInstance, this, &newObject, Qt::UniqueConnection);
QList< QList<UAVDataObject *> > objList = objManager->getDataObjects();
foreach(QList<UAVDataObject *> list, objList) {
foreach(UAVDataObject * obj, list) {
disconnect(obj, 0, this, 0);
addDataObject(obj);
addObject(obj);
}
}
}
void UAVObjectTreeModel::resetModelData()
{
m_highlightManager->reset();
emit beginResetModel();
delete m_rootItem;
m_rootItem = NULL;
setupModelData();
emit endResetModel();
}
void UAVObjectTreeModel::newObject(UAVObject *obj)
{
UAVDataObject *dobj = qobject_cast<UAVDataObject *>(obj);
UAVDataObject *dataObj = qobject_cast<UAVDataObject *>(obj);
if (dobj) {
addDataObject(dobj);
if (dataObj) {
addObject(dataObj);
}
}
void UAVObjectTreeModel::addDataObject(UAVDataObject *obj)
void UAVObjectTreeModel::addObject(UAVDataObject *obj)
{
TopTreeItem *root = obj->isSettingsObject() ? m_settingsTree : m_nonSettingsTree;
TreeItem *parent = root;
if (m_categorize && obj->getCategory() != 0 && !obj->getCategory().isEmpty()) {
QStringList categoryPath = obj->getCategory().split('/');
parent = createCategoryItems(categoryPath, root);
connect(obj, &UAVDataObject::objectUpdated, this, &updateObject, Qt::UniqueConnection);
connect(obj, &UAVDataObject::isKnownChanged, this, &updateIsKnown, Qt::UniqueConnection);
if (obj->getInstID() == 0) {
UAVMetaObject *metaObj = obj->getMetaObject();
connect(metaObj, &UAVDataObject::objectUpdated, this, &updateObject, Qt::UniqueConnection);
}
ObjectTreeItem *existing = root->findDataObjectTreeItemByObjectId(obj->getObjID());
if (existing) {
addInstance(obj, existing);
} else {
DataObjectTreeItem *dataTreeItem = new DataObjectTreeItem(obj->getName(), obj, parent);
dataTreeItem->setHighlightManager(m_highlightManager);
parent->insertChild(dataTreeItem);
root->addObjectTreeItem(obj->getObjID(), dataTreeItem);
if (m_showMetadata) {
UAVMetaObject *meta = obj->getMetaObject();
MetaObjectTreeItem *metaTreeItem = addMetaObject(meta, dataTreeItem);
root->addMetaObjectTreeItem(meta->getObjID(), metaTreeItem);
}
addInstance(obj, dataTreeItem);
}
}
TreeItem *UAVObjectTreeModel::createCategoryItems(QStringList categoryPath, TreeItem *root)
{
TreeItem *parent = root;
foreach(QString category, categoryPath) {
TreeItem *existing = parent->findChildByName(category);
if (!existing) {
TreeItem *categoryItem = new TopTreeItem(category, parent);
categoryItem->setHighlightManager(m_highlightManager);
parent->insertChild(categoryItem);
parent = categoryItem;
} else {
parent = existing;
}
}
return parent;
}
MetaObjectTreeItem *UAVObjectTreeModel::addMetaObject(UAVMetaObject *obj, TreeItem *parent)
{
connect(obj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateObject(UAVObject *)));
MetaObjectTreeItem *meta = new MetaObjectTreeItem(obj, tr("Meta Data"), parent);
meta->setHighlightManager(m_highlightManager);
foreach(UAVObjectField * field, obj->getFields()) {
if (field->getNumElements() > 1) {
addArrayField(field, meta);
} else {
addSingleField(0, field, meta);
}
}
parent->appendChild(meta);
return meta;
}
void UAVObjectTreeModel::addInstance(UAVObject *obj, TreeItem *parent)
{
connect(obj, SIGNAL(objectUpdated(UAVObject *)), this, SLOT(updateObject(UAVObject *)));
connect(obj, SIGNAL(isKnownChanged(UAVObject *)), this, SLOT(updateIsKnown(UAVObject *)));
TreeItem *item;
if (obj->isSingleInstance()) {
item = parent;
DataObjectTreeItem *dataObjectItem = createDataObject(obj);
TreeItem *parentItem = getParentItem(obj, showCategories());
insertItem(parentItem, dataObjectItem);
} else {
QString name = tr("Instance") + " " + QString::number(obj->getInstID());
item = new InstanceTreeItem(obj, name, parent);
item->setHighlightManager(m_highlightManager);
parent->appendChild(item);
TreeItem *dataObjectItem;
if (obj->getInstID() == 0) {
dataObjectItem = createDataObject(obj);
TreeItem *parentItem = getParentItem(obj, showCategories());
insertItem(parentItem, dataObjectItem);
} else {
dataObjectItem = findObjectTreeItem(obj->getObjID());
}
InstanceTreeItem *instanceItem = createDataObjectInstance(obj);
appendItem(dataObjectItem, instanceItem);
}
}
DataObjectTreeItem *UAVObjectTreeModel::createDataObject(UAVDataObject *obj)
{
DataObjectTreeItem *item = new DataObjectTreeItem(obj, obj->getName());
addObjectTreeItem(obj->getObjID(), item);
item->setHighlightManager(m_highlightManager);
MetaObjectTreeItem *metaItem = createMetaObject(obj->getMetaObject());
if (showMetadata()) {
appendItem(item, metaItem);
}
if (obj->isSingleInstance()) {
foreach(UAVObjectField * field, obj->getFields()) {
if (field->getNumElements() > 1) {
addArrayField(field, item);
@ -235,25 +243,89 @@ void UAVObjectTreeModel::addInstance(UAVObject *obj, TreeItem *parent)
}
}
void UAVObjectTreeModel::addArrayField(UAVObjectField *field, TreeItem *parent)
return item;
}
InstanceTreeItem *UAVObjectTreeModel::createDataObjectInstance(UAVDataObject *obj)
{
TreeItem *item = new ArrayFieldTreeItem(field, field->getName(), parent);
QString name = tr("Instance") + " " + QString::number((int)obj->getInstID());
InstanceTreeItem *item = new InstanceTreeItem(obj, name);
item->setHighlightManager(m_highlightManager);
parent->appendChild(item);
foreach(UAVObjectField * field, obj->getFields()) {
if (field->getNumElements() > 1) {
addArrayField(field, item);
} else {
addSingleField(0, field, item);
}
}
return item;
}
MetaObjectTreeItem *UAVObjectTreeModel::createMetaObject(UAVMetaObject *obj)
{
MetaObjectTreeItem *item = new MetaObjectTreeItem(obj, tr("Meta Data"));
addObjectTreeItem(obj->getObjID(), item);
item->setHighlightManager(m_highlightManager);
foreach(UAVObjectField * field, obj->getFields()) {
if (field->getNumElements() > 1) {
addArrayField(field, item);
} else {
addSingleField(0, field, item);
}
}
return item;
}
TreeItem *UAVObjectTreeModel::getParentItem(UAVDataObject *obj, bool categorize)
{
TreeItem *parentItem = obj->isSettingsObject() ? m_settingsTree : m_nonSettingsTree;
if (categorize) {
QString category = obj->getCategory();
if (obj->getCategory().isEmpty()) {
category = tr("Uncategorized");
}
QStringList categoryPath = category.split('/');
foreach(QString category, categoryPath) {
TreeItem *categoryItem = parentItem->childByName(category);
if (!categoryItem) {
categoryItem = new TopTreeItem(category);
categoryItem->setHighlightManager(m_highlightManager);
insertItem(parentItem, categoryItem);
}
parentItem = categoryItem;
}
}
return parentItem;
}
void UAVObjectTreeModel::addArrayField(UAVObjectField *field, TreeItem *parent)
{
TreeItem *item = new ArrayFieldTreeItem(field, field->getName());
item->setHighlightManager(m_highlightManager);
appendItem(parent, item);
for (int i = 0; i < (int)field->getNumElements(); ++i) {
addSingleField(i, field, item);
}
}
void UAVObjectTreeModel::addSingleField(int index, UAVObjectField *field, TreeItem *parent)
void UAVObjectTreeModel::addSingleField(int i, UAVObjectField *field, TreeItem *parent)
{
QList<QVariant> data;
if (field->getNumElements() == 1) {
data.append(field->getName());
} else {
data.append(QString("[%1]").arg((field->getElementNames())[index]));
data.append(QString("[%1]").arg((field->getElementNames())[i]));
}
FieldTreeItem *item = NULL;
@ -263,10 +335,10 @@ void UAVObjectTreeModel::addSingleField(int index, UAVObjectField *field, TreeIt
case UAVObjectField::ENUM:
{
QStringList options = field->getOptions();
QVariant value = field->getValue(index);
QVariant value = field->getValue(i);
data.append(options.indexOf(value.toString()));
data.append(field->getUnits());
item = new EnumFieldTreeItem(field, index, data, parent);
item = new EnumFieldTreeItem(field, i, data);
break;
}
case UAVObjectField::INT8:
@ -275,20 +347,20 @@ void UAVObjectTreeModel::addSingleField(int index, UAVObjectField *field, TreeIt
case UAVObjectField::UINT8:
case UAVObjectField::UINT16:
case UAVObjectField::UINT32:
data.append(field->getValue(index));
data.append(field->getValue(i));
data.append(field->getUnits());
if (field->getUnits().toLower() == "hex") {
item = new HexFieldTreeItem(field, index, data, parent);
item = new HexFieldTreeItem(field, i, data);
} else if (field->getUnits().toLower() == "char") {
item = new CharFieldTreeItem(field, index, data, parent);
item = new CharFieldTreeItem(field, i, data);
} else {
item = new IntFieldTreeItem(field, index, data, parent);
item = new IntFieldTreeItem(field, i, data);
}
break;
case UAVObjectField::FLOAT32:
data.append(field->getValue(index));
data.append(field->getValue(i));
data.append(field->getUnits());
item = new FloatFieldTreeItem(field, index, data, m_useScientificFloatNotation, parent);
item = new FloatFieldTreeItem(field, i, data, m_settings);
break;
default:
Q_ASSERT(false);
@ -297,7 +369,91 @@ void UAVObjectTreeModel::addSingleField(int index, UAVObjectField *field, TreeIt
item->setHighlightManager(m_highlightManager);
item->setDescription(field->getDescription());
parent->appendChild(item);
appendItem(parent, item);
}
void UAVObjectTreeModel::appendItem(TreeItem *parentItem, TreeItem *childItem)
{
int row = parentItem->childCount();
beginInsertRows(index(parentItem), row, row);
parentItem->appendChild(childItem);
endInsertRows();
}
void UAVObjectTreeModel::insertItem(TreeItem *parentItem, TreeItem *childItem, int row)
{
if (row < 0) {
row = parentItem->insertionIndex(childItem);
}
beginInsertRows(index(parentItem), row, row);
parentItem->insertChild(childItem, row);
endInsertRows();
}
void UAVObjectTreeModel::removeItem(TreeItem *parentItem, TreeItem *childItem)
{
int row = childItem->row();
beginRemoveRows(index(parentItem), row, row);
parentItem->removeChild(childItem);
endRemoveRows();
}
void UAVObjectTreeModel::moveItem(TreeItem *newParentItem, TreeItem *oldParentItem, TreeItem *childItem)
{
int destinationRow = newParentItem->insertionIndex(childItem);
int sourceRow = childItem->row();
beginMoveRows(index(oldParentItem), sourceRow, sourceRow, index(newParentItem), destinationRow);
oldParentItem->removeChild(childItem);
newParentItem->insertChild(childItem, destinationRow);
endMoveRows();
}
void UAVObjectTreeModel::toggleCategoryItems()
{
foreach(ObjectTreeItem * item, m_objectTreeItems.values()) {
DataObjectTreeItem *dataItem = dynamic_cast<DataObjectTreeItem *>(item);
if (dataItem) {
TreeItem *oldParentItem = dataItem->parentItem();
TreeItem *newParentItem = getParentItem(dataItem->dataObject(), showCategories());
if (oldParentItem == newParentItem) {
// should not happen
continue;
}
moveItem(newParentItem, oldParentItem, dataItem);
if (!showCategories()) {
// remove empty category items
TreeItem *item = oldParentItem;
while (item->childCount() == 0 && item != newParentItem) {
TreeItem *tmp = item;
item = item->parentItem();
removeItem(tmp->parentItem(), tmp);
delete tmp;
}
}
}
}
}
void UAVObjectTreeModel::toggleMetaItems()
{
foreach(ObjectTreeItem * item, m_objectTreeItems.values()) {
MetaObjectTreeItem *metaItem = dynamic_cast<MetaObjectTreeItem *>(item);
if (metaItem) {
DataObjectTreeItem *dataItem = findDataObjectTreeItem(metaItem->object());
if (showMetadata()) {
insertItem(dataItem, metaItem, 0);
} else {
removeItem(dataItem, metaItem);
}
}
}
}
QModelIndex UAVObjectTreeModel::index(int row, int column, const QModelIndex &parent) const
@ -338,6 +494,10 @@ QModelIndex UAVObjectTreeModel::parent(const QModelIndex &index) const
TreeItem *childItem = static_cast<TreeItem *>(index.internalPointer());
TreeItem *parentItem = childItem->parentItem();
if (!parentItem) {
return QModelIndex();
}
if (parentItem == m_rootItem) {
return QModelIndex();
}
@ -405,22 +565,22 @@ QVariant UAVObjectTreeModel::data(const QModelIndex &index, int role) const
case Qt::ForegroundRole:
if (!dynamic_cast<TopTreeItem *>(item) && !item->isKnown()) {
return m_unknownObjectColor;
return unknownObjectColor();
}
return QVariant();
case Qt::BackgroundRole:
if (index.column() == TreeItem::TITLE_COLUMN) {
if (!dynamic_cast<TopTreeItem *>(item) && item->isHighlighted()) {
return m_recentlyUpdatedColor;
return recentlyUpdatedColor();
}
} else if (index.column() == TreeItem::DATA_COLUMN) {
FieldTreeItem *fieldItem = dynamic_cast<FieldTreeItem *>(item);
if (fieldItem && fieldItem->isHighlighted()) {
return m_recentlyUpdatedColor;
return recentlyUpdatedColor();
}
if (fieldItem && fieldItem->changed()) {
return m_manuallyChangedColor;
return manuallyChangedColor();
}
}
return QVariant();
@ -437,13 +597,12 @@ QVariant UAVObjectTreeModel::data(const QModelIndex &index, int role) const
bool UAVObjectTreeModel::setData(const QModelIndex &index, const QVariant & value, int role)
{
Q_UNUSED(role)
Q_UNUSED(role);
TreeItem *item = static_cast<TreeItem *>(index.internalPointer());
item->setData(value, index.column());
return true;
}
Qt::ItemFlags UAVObjectTreeModel::flags(const QModelIndex &index) const
{
if (!index.isValid()) {
@ -472,50 +631,29 @@ QVariant UAVObjectTreeModel::headerData(int section, Qt::Orientation orientation
void UAVObjectTreeModel::updateObject(UAVObject *obj)
{
Q_ASSERT(obj);
ObjectTreeItem *item = findObjectTreeItem(obj);
ObjectTreeItem *item = findObjectTreeItem(obj->getObjID());
Q_ASSERT(item);
// TODO don't update meta object if they are not shown
item->update();
if (!m_onlyHighlightChangedValues) {
if (!onlyHighlightChangedValues()) {
item->setHighlighted(true);
}
}
ObjectTreeItem *UAVObjectTreeModel::findObjectTreeItem(UAVObject *object)
void UAVObjectTreeModel::updateIsKnown(UAVObject *object)
{
UAVDataObject *dataObject = qobject_cast<UAVDataObject *>(object);
UAVMetaObject *metaObject = qobject_cast<UAVMetaObject *>(object);
DataObjectTreeItem *item = findDataObjectTreeItem(object);
Q_ASSERT(dataObject || metaObject);
if (dataObject) {
return findDataObjectTreeItem(dataObject);
} else {
return findMetaObjectTreeItem(metaObject);
if (item) {
refreshIsKnown(item);
}
return 0;
}
DataObjectTreeItem *UAVObjectTreeModel::findDataObjectTreeItem(UAVDataObject *obj)
{
TopTreeItem *root = obj->isSettingsObject() ? m_settingsTree : m_nonSettingsTree;
return root->findDataObjectTreeItemByObjectId(obj->getObjID());
}
MetaObjectTreeItem *UAVObjectTreeModel::findMetaObjectTreeItem(UAVMetaObject *obj)
{
UAVDataObject *dataObject = qobject_cast<UAVDataObject *>(obj->getParentObject());
Q_ASSERT(dataObject);
TopTreeItem *root = dataObject->isSettingsObject() ? m_settingsTree : m_nonSettingsTree;
return root->findMetaObjectTreeItemByObjectId(obj->getObjID());
}
void UAVObjectTreeModel::updateHighlight(TreeItem *item)
void UAVObjectTreeModel::refreshHighlight(TreeItem *item)
{
// performance note: here we emit data changes column by column
// emitting a dataChanged that spans multiple columns kills performance (CPU shoots up)
// this is probably because we configure the sort/filter proxy to be dynamic
// this happens when calling setDynamicSortFilter(true) on it which we do
// this is probably caused by the sort/filter proxy...
QModelIndex itemIndex;
@ -528,16 +666,7 @@ void UAVObjectTreeModel::updateHighlight(TreeItem *item)
emit dataChanged(itemIndex, itemIndex);
}
void UAVObjectTreeModel::updateIsKnown(UAVObject *object)
{
ObjectTreeItem *item = findObjectTreeItem(object);
if (item) {
updateIsKnown(item);
}
}
void UAVObjectTreeModel::updateIsKnown(TreeItem *item)
void UAVObjectTreeModel::refreshIsKnown(TreeItem *item)
{
QModelIndex itemIndex;
@ -546,6 +675,32 @@ void UAVObjectTreeModel::updateIsKnown(TreeItem *item)
emit dataChanged(itemIndex, itemIndex);
foreach(TreeItem * child, item->children()) {
updateIsKnown(child);
refreshIsKnown(child);
}
}
void UAVObjectTreeModel::addObjectTreeItem(quint32 objectId, ObjectTreeItem *oti)
{
m_objectTreeItems[objectId] = oti;
}
ObjectTreeItem *UAVObjectTreeModel::findObjectTreeItem(quint32 objectId)
{
return m_objectTreeItems.value(objectId, 0);
}
DataObjectTreeItem *UAVObjectTreeModel::findDataObjectTreeItem(UAVObject *object)
{
UAVDataObject *dataObject;
UAVMetaObject *metaObject = qobject_cast<UAVMetaObject *>(object);
if (metaObject) {
dataObject = qobject_cast<UAVDataObject *>(metaObject->getParentObject());
} else {
dataObject = qobject_cast<UAVDataObject *>(object);
}
Q_ASSERT(dataObject);
return static_cast<DataObjectTreeItem *>(findObjectTreeItem(dataObject->getObjID()));
}

View File

@ -34,6 +34,7 @@
#include <QMap>
#include <QList>
#include <QColor>
#include <QSettings>
class TopTreeItem;
class ObjectTreeItem;
@ -49,7 +50,7 @@ class QTimer;
class UAVObjectTreeModel : public QAbstractItemModel {
Q_OBJECT
public:
explicit UAVObjectTreeModel(QObject *parent, bool categorize, bool showMetadata, bool useScientificNotation);
explicit UAVObjectTreeModel(QObject *parent);
~UAVObjectTreeModel();
QVariant data(const QModelIndex &index, int role) const;
@ -63,90 +64,74 @@ public:
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
void resetModelData();
bool showCategories() const;
void setShowCategories(bool show);
bool showCategories()
{
return m_categorize;
}
bool showMetadata() const;
void setShowMetadata(bool show);
void setShowCategories(bool showCategories);
bool useScientificNotation();
void setUseScientificNotation(bool useScientificNotation);
bool showMetadata()
{
return m_showMetadata;
}
QColor unknownObjectColor() const;
void setUnknownObjectColor(QColor color);
void setShowMetadata(bool showMetadata);
QColor recentlyUpdatedColor() const;
void setRecentlyUpdatedColor(QColor color);
bool showScientificNotation()
{
return m_useScientificFloatNotation;
}
QColor manuallyChangedColor() const;
void setManuallyChangedColor(QColor color);
void setShowScientificNotation(bool showScientificNotation);
int recentlyUpdatedTimeout() const;
void setRecentlyUpdatedTimeout(int timeout);
void setUnknowObjectColor(QColor color)
{
m_unknownObjectColor = color;
}
void setRecentlyUpdatedColor(QColor color)
{
m_recentlyUpdatedColor = color;
}
void setManuallyChangedColor(QColor color)
{
m_manuallyChangedColor = color;
}
void setRecentlyUpdatedTimeout(int timeout)
{
m_recentlyUpdatedTimeout = timeout;
TreeItem::setHighlightTime(timeout);
}
void setOnlyHighlightChangedValues(bool hilight)
{
m_onlyHighlightChangedValues = hilight;
}
public slots:
void newObject(UAVObject *obj);
bool onlyHighlightChangedValues() const;
void setOnlyHighlightChangedValues(bool highlight);
private slots:
void newObject(UAVObject *obj);
void updateObject(UAVObject *obj);
void updateIsKnown(UAVObject *obj);
void updateHighlight(TreeItem *item);
void updateIsKnown(TreeItem *item);
void refreshHighlight(TreeItem *item);
void refreshIsKnown(TreeItem *item);
private:
QModelIndex index(TreeItem *item, int column = 0);
void setupModelData(UAVObjectManager *objManager);
void addDataObject(UAVDataObject *obj);
MetaObjectTreeItem *addMetaObject(UAVMetaObject *obj, TreeItem *parent);
void addArrayField(UAVObjectField *field, TreeItem *parent);
void addSingleField(int index, UAVObjectField *field, TreeItem *parent);
void addInstance(UAVObject *obj, TreeItem *parent);
QSettings m_settings;
TreeItem *createCategoryItems(QStringList categoryPath, TreeItem *root);
QString updateMode(quint8 updateMode);
ObjectTreeItem *findObjectTreeItem(UAVObject *obj);
DataObjectTreeItem *findDataObjectTreeItem(UAVDataObject *obj);
MetaObjectTreeItem *findMetaObjectTreeItem(UAVMetaObject *obj);
HighlightManager *m_highlightManager;
TreeItem *m_rootItem;
TopTreeItem *m_settingsTree;
TopTreeItem *m_nonSettingsTree;
bool m_categorize;
bool m_showMetadata;
bool m_useScientificFloatNotation;
int m_recentlyUpdatedTimeout;
QColor m_recentlyUpdatedColor;
QColor m_manuallyChangedColor;
QColor m_unknownObjectColor;
bool m_onlyHighlightChangedValues;
// Highlight manager to handle highlighting of tree items.
HighlightManager *m_highlightManager;
QHash<quint32, ObjectTreeItem *> m_objectTreeItems;
QModelIndex index(TreeItem *item, int column = 0);
void setupModelData();
void resetModelData();
void addObject(UAVDataObject *obj);
void addArrayField(UAVObjectField *field, TreeItem *parent);
void addSingleField(int index, UAVObjectField *field, TreeItem *parent);
DataObjectTreeItem *createDataObject(UAVDataObject *obj);
InstanceTreeItem *createDataObjectInstance(UAVDataObject *obj);
MetaObjectTreeItem *createMetaObject(UAVMetaObject *obj);
TreeItem *getParentItem(UAVDataObject *obj, bool categorize);
void appendItem(TreeItem *parentItem, TreeItem *childItem);
void insertItem(TreeItem *parentItem, TreeItem *childItem, int row = -1);
void removeItem(TreeItem *parentItem, TreeItem *childItem);
void moveItem(TreeItem *newParentItem, TreeItem *oldParentItem, TreeItem *childItem);
void toggleCategoryItems();
void toggleMetaItems();
void addObjectTreeItem(quint32 objectId, ObjectTreeItem *oti);
ObjectTreeItem *findObjectTreeItem(quint32 objectId);
DataObjectTreeItem *findDataObjectTreeItem(UAVObject *obj);
};
#endif // UAVOBJECTTREEMODEL_H