mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-06 21:54:15 +01:00
Merged in filnet/librepilot/LP-567_uavobjectbrowser_highlight_handling (pull request #486)
LP-567 uavobjectbrowser highlight handling Approved-by: Philippe Renon <philippe_renon@yahoo.fr> Approved-by: Lalanne Laurent <f5soh@free.fr>
This commit is contained in:
commit
53bd0da106
@ -31,7 +31,9 @@
|
|||||||
|
|
||||||
BrowserItemDelegate::BrowserItemDelegate(QObject *parent) :
|
BrowserItemDelegate::BrowserItemDelegate(QObject *parent) :
|
||||||
QStyledItemDelegate(parent)
|
QStyledItemDelegate(parent)
|
||||||
{}
|
{
|
||||||
|
_sizeHint = QSpinBox().sizeHint();
|
||||||
|
}
|
||||||
|
|
||||||
QWidget *BrowserItemDelegate::createEditor(QWidget *parent,
|
QWidget *BrowserItemDelegate::createEditor(QWidget *parent,
|
||||||
const QStyleOptionViewItem & option,
|
const QStyleOptionViewItem & option,
|
||||||
@ -75,5 +77,5 @@ QSize BrowserItemDelegate::sizeHint(const QStyleOptionViewItem & option, const Q
|
|||||||
{
|
{
|
||||||
Q_UNUSED(option);
|
Q_UNUSED(option);
|
||||||
Q_UNUSED(index);
|
Q_UNUSED(index);
|
||||||
return QSpinBox().sizeHint();
|
return _sizeHint;
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,9 @@ public:
|
|||||||
const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
QSize sizeHint(const QStyleOptionViewItem & option,
|
QSize sizeHint(const QStyleOptionViewItem & option,
|
||||||
const QModelIndex &index) const;
|
const QModelIndex &index) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSize _sizeHint;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BROWSERITEMDELEGATE_H
|
#endif // BROWSERITEMDELEGATE_H
|
||||||
|
@ -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"
|
|
@ -29,12 +29,15 @@
|
|||||||
#define FIELDTREEITEM_H
|
#define FIELDTREEITEM_H
|
||||||
|
|
||||||
#include "treeitem.h"
|
#include "treeitem.h"
|
||||||
#include <QtCore/QStringList>
|
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QSettings>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
#include <QDoubleSpinBox>
|
#include <QDoubleSpinBox>
|
||||||
#include <qscispinbox/QScienceSpinBox.h>
|
#include <qscispinbox/QScienceSpinBox.h>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#define QINT8MIN std::numeric_limits<qint8>::min()
|
#define QINT8MIN std::numeric_limits<qint8>::min()
|
||||||
@ -49,58 +52,72 @@
|
|||||||
#define QUINT32MAX std::numeric_limits<qint32>::max()
|
#define QUINT32MAX std::numeric_limits<qint32>::max()
|
||||||
|
|
||||||
class FieldTreeItem : public TreeItem {
|
class FieldTreeItem : public TreeItem {
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FieldTreeItem(int index, const QList<QVariant> &data, UAVObjectField *field, TreeItem *parent = 0) :
|
FieldTreeItem(int index, const QList<QVariant> &data, UAVObjectField *field) :
|
||||||
TreeItem(data, parent), m_index(index), m_field(field)
|
TreeItem(data), m_index(index), m_field(field)
|
||||||
|
{}
|
||||||
|
FieldTreeItem(int index, const QVariant &data, UAVObjectField *field) :
|
||||||
|
TreeItem(data), m_index(index), m_field(field)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
FieldTreeItem(int index, const QVariant &data, UAVObjectField *field, TreeItem *parent = 0) :
|
bool isEditable() const
|
||||||
TreeItem(data, parent), m_index(index), m_field(field)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool isEditable()
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual QWidget *createEditor(QWidget *parent) = 0;
|
virtual QWidget *createEditor(QWidget *parent) const = 0;
|
||||||
virtual QVariant getEditorValue(QWidget *editor) = 0;
|
virtual QVariant getEditorValue(QWidget *editor) const = 0;
|
||||||
virtual void setEditorValue(QWidget *editor, QVariant value) = 0;
|
virtual void setEditorValue(QWidget *editor, QVariant value) const = 0;
|
||||||
virtual void apply() {}
|
|
||||||
virtual bool isKnown()
|
void setData(QVariant value, int column)
|
||||||
{
|
{
|
||||||
return parent()->isKnown();
|
QVariant currentValue = fieldToData();
|
||||||
|
|
||||||
|
setChanged(currentValue != value);
|
||||||
|
TreeItem::setData(value, column);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update(const QTime &ts)
|
||||||
|
{
|
||||||
|
bool updated = false;
|
||||||
|
|
||||||
|
if (!changed()) {
|
||||||
|
QVariant currentValue = fieldToData();
|
||||||
|
if (data() != currentValue) {
|
||||||
|
updated = true;
|
||||||
|
TreeItem::setData(currentValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (changed() || updated) {
|
||||||
|
setHighlighted(true, ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply()
|
||||||
|
{
|
||||||
|
m_field->setValue(dataToField(), m_index);
|
||||||
|
setChanged(false);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual QVariant fieldToData() const = 0;
|
||||||
|
virtual QVariant dataToField() const = 0;
|
||||||
|
|
||||||
int m_index;
|
int m_index;
|
||||||
UAVObjectField *m_field;
|
UAVObjectField *m_field;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EnumFieldTreeItem : public FieldTreeItem {
|
class EnumFieldTreeItem : public FieldTreeItem {
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
EnumFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data, TreeItem *parent = 0) :
|
EnumFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data) :
|
||||||
FieldTreeItem(index, data, field, parent), m_enumOptions(field->getOptions())
|
FieldTreeItem(index, data, field), m_enumOptions(field->getOptions())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
EnumFieldTreeItem(UAVObjectField *field, int index, const QVariant &data, TreeItem *parent = 0) :
|
EnumFieldTreeItem(UAVObjectField *field, int index, const QVariant &data) :
|
||||||
FieldTreeItem(index, data, field, parent), m_enumOptions(field->getOptions())
|
FieldTreeItem(index, data, field), m_enumOptions(field->getOptions())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void setData(QVariant value, int column)
|
|
||||||
{
|
|
||||||
QStringList options = m_field->getOptions();
|
|
||||||
QVariant tmpValue = m_field->getValue(m_index);
|
|
||||||
int tmpValIndex = options.indexOf(tmpValue.toString());
|
|
||||||
|
|
||||||
setChanged(tmpValIndex != value);
|
|
||||||
TreeItem::setData(value, column);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString enumOptions(int index)
|
QString enumOptions(int index)
|
||||||
{
|
{
|
||||||
if ((index < 0) || (index >= m_enumOptions.length())) {
|
if ((index < 0) || (index >= m_enumOptions.length())) {
|
||||||
@ -109,28 +126,24 @@ public:
|
|||||||
return m_enumOptions.at(index);
|
return m_enumOptions.at(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply()
|
QVariant fieldToData() const
|
||||||
{
|
|
||||||
int value = data().toInt();
|
|
||||||
QStringList options = m_field->getOptions();
|
|
||||||
|
|
||||||
m_field->setValue(options[value], m_index);
|
|
||||||
setChanged(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update()
|
|
||||||
{
|
{
|
||||||
QStringList options = m_field->getOptions();
|
QStringList options = m_field->getOptions();
|
||||||
QVariant value = m_field->getValue(m_index);
|
QVariant value = m_field->getValue(m_index);
|
||||||
int valIndex = options.indexOf(value.toString());
|
int valIndex = options.indexOf(value.toString());
|
||||||
|
|
||||||
if (data() != valIndex || changed()) {
|
return valIndex;
|
||||||
TreeItem::setData(valIndex);
|
|
||||||
setHighlight(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *createEditor(QWidget *parent)
|
QVariant dataToField() const
|
||||||
|
{
|
||||||
|
int value = data().toInt();
|
||||||
|
QStringList options = m_field->getOptions();
|
||||||
|
|
||||||
|
return options[value];
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *createEditor(QWidget *parent) const
|
||||||
{
|
{
|
||||||
QComboBox *editor = new QComboBox(parent);
|
QComboBox *editor = new QComboBox(parent);
|
||||||
|
|
||||||
@ -142,14 +155,14 @@ public:
|
|||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant getEditorValue(QWidget *editor)
|
QVariant getEditorValue(QWidget *editor) const
|
||||||
{
|
{
|
||||||
QComboBox *comboBox = static_cast<QComboBox *>(editor);
|
QComboBox *comboBox = static_cast<QComboBox *>(editor);
|
||||||
|
|
||||||
return comboBox->currentIndex();
|
return comboBox->currentIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEditorValue(QWidget *editor, QVariant value)
|
void setEditorValue(QWidget *editor, QVariant value) const
|
||||||
{
|
{
|
||||||
QComboBox *comboBox = static_cast<QComboBox *>(editor);
|
QComboBox *comboBox = static_cast<QComboBox *>(editor);
|
||||||
|
|
||||||
@ -161,16 +174,14 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class IntFieldTreeItem : public FieldTreeItem {
|
class IntFieldTreeItem : public FieldTreeItem {
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
IntFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data, TreeItem *parent = 0) :
|
IntFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data) :
|
||||||
FieldTreeItem(index, data, field, parent)
|
FieldTreeItem(index, data, field)
|
||||||
{
|
{
|
||||||
setMinMaxValues();
|
setMinMaxValues();
|
||||||
}
|
}
|
||||||
|
IntFieldTreeItem(UAVObjectField *field, int index, const QVariant &data) :
|
||||||
IntFieldTreeItem(UAVObjectField *field, int index, const QVariant &data, TreeItem *parent = 0) :
|
FieldTreeItem(index, data, field)
|
||||||
FieldTreeItem(index, data, field, parent)
|
|
||||||
{
|
{
|
||||||
setMinMaxValues();
|
setMinMaxValues();
|
||||||
}
|
}
|
||||||
@ -208,7 +219,17 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *createEditor(QWidget *parent)
|
QVariant fieldToData() const
|
||||||
|
{
|
||||||
|
return m_field->getValue(m_index).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant dataToField() const
|
||||||
|
{
|
||||||
|
return data().toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *createEditor(QWidget *parent) const
|
||||||
{
|
{
|
||||||
QSpinBox *editor = new QSpinBox(parent);
|
QSpinBox *editor = new QSpinBox(parent);
|
||||||
|
|
||||||
@ -217,7 +238,7 @@ public:
|
|||||||
return editor;
|
return editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant getEditorValue(QWidget *editor)
|
QVariant getEditorValue(QWidget *editor) const
|
||||||
{
|
{
|
||||||
QSpinBox *spinBox = static_cast<QSpinBox *>(editor);
|
QSpinBox *spinBox = static_cast<QSpinBox *>(editor);
|
||||||
|
|
||||||
@ -225,74 +246,41 @@ public:
|
|||||||
return spinBox->value();
|
return spinBox->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEditorValue(QWidget *editor, QVariant value)
|
void setEditorValue(QWidget *editor, QVariant value) const
|
||||||
{
|
{
|
||||||
QSpinBox *spinBox = static_cast<QSpinBox *>(editor);
|
QSpinBox *spinBox = static_cast<QSpinBox *>(editor);
|
||||||
|
|
||||||
spinBox->setValue(value.toInt());
|
spinBox->setValue(value.toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
void setData(QVariant value, int column)
|
|
||||||
{
|
|
||||||
setChanged(m_field->getValue(m_index) != value);
|
|
||||||
TreeItem::setData(value, column);
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply()
|
|
||||||
{
|
|
||||||
m_field->setValue(data().toInt(), m_index);
|
|
||||||
setChanged(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update()
|
|
||||||
{
|
|
||||||
int value = m_field->getValue(m_index).toInt();
|
|
||||||
|
|
||||||
if (data() != value || changed()) {
|
|
||||||
TreeItem::setData(value);
|
|
||||||
setHighlight(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_minValue;
|
int m_minValue;
|
||||||
int m_maxValue;
|
int m_maxValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FloatFieldTreeItem : public FieldTreeItem {
|
class FloatFieldTreeItem : public FieldTreeItem {
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
FloatFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data, bool scientific = false, TreeItem *parent = 0) :
|
FloatFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data, const QSettings &settings) :
|
||||||
FieldTreeItem(index, data, field, parent), m_useScientificNotation(scientific) {}
|
FieldTreeItem(index, data, field), m_settings(settings) {}
|
||||||
|
|
||||||
FloatFieldTreeItem(UAVObjectField *field, int index, const QVariant &data, bool scientific = false, TreeItem *parent = 0) :
|
FloatFieldTreeItem(UAVObjectField *field, int index, const QVariant &data, const QSettings &settings) :
|
||||||
FieldTreeItem(index, data, field, parent), m_useScientificNotation(scientific) {}
|
FieldTreeItem(index, data, field), m_settings(settings) {}
|
||||||
|
|
||||||
void setData(QVariant value, int column)
|
QVariant fieldToData() const
|
||||||
{
|
{
|
||||||
setChanged(m_field->getValue(m_index) != value);
|
return m_field->getValue(m_index).toDouble();
|
||||||
TreeItem::setData(value, column);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void apply()
|
QVariant dataToField() const
|
||||||
{
|
{
|
||||||
m_field->setValue(data().toDouble(), m_index);
|
return data().toDouble();
|
||||||
setChanged(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void update()
|
QWidget *createEditor(QWidget *parent) const
|
||||||
{
|
{
|
||||||
double value = m_field->getValue(m_index).toDouble();
|
bool useScientificNotation = m_settings.value("useScientificNotation", false).toBool();
|
||||||
|
|
||||||
if (data() != value || changed()) {
|
if (useScientificNotation) {
|
||||||
TreeItem::setData(value);
|
|
||||||
setHighlight(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget *createEditor(QWidget *parent)
|
|
||||||
{
|
|
||||||
if (m_useScientificNotation) {
|
|
||||||
QScienceSpinBox *editor = new QScienceSpinBox(parent);
|
QScienceSpinBox *editor = new QScienceSpinBox(parent);
|
||||||
editor->setDecimals(6);
|
editor->setDecimals(6);
|
||||||
editor->setMinimum(-std::numeric_limits<float>::max());
|
editor->setMinimum(-std::numeric_limits<float>::max());
|
||||||
@ -307,9 +295,11 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant getEditorValue(QWidget *editor)
|
QVariant getEditorValue(QWidget *editor) const
|
||||||
{
|
{
|
||||||
if (m_useScientificNotation) {
|
bool useScientificNotation = m_settings.value("useScientificNotation", false).toBool();
|
||||||
|
|
||||||
|
if (useScientificNotation) {
|
||||||
QScienceSpinBox *spinBox = static_cast<QScienceSpinBox *>(editor);
|
QScienceSpinBox *spinBox = static_cast<QScienceSpinBox *>(editor);
|
||||||
spinBox->interpretText();
|
spinBox->interpretText();
|
||||||
return spinBox->value();
|
return spinBox->value();
|
||||||
@ -320,9 +310,11 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEditorValue(QWidget *editor, QVariant value)
|
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);
|
QScienceSpinBox *spinBox = static_cast<QScienceSpinBox *>(editor);
|
||||||
spinBox->setValue(value.toDouble());
|
spinBox->setValue(value.toDouble());
|
||||||
} else {
|
} else {
|
||||||
@ -332,21 +324,30 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_useScientificNotation;
|
const QSettings &m_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
class HexFieldTreeItem : public FieldTreeItem {
|
class HexFieldTreeItem : public FieldTreeItem {
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
HexFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data, TreeItem *parent = 0) :
|
HexFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data) :
|
||||||
FieldTreeItem(index, data, field, parent)
|
FieldTreeItem(index, data, field)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
HexFieldTreeItem(UAVObjectField *field, int index, const QVariant &data, TreeItem *parent = 0) :
|
HexFieldTreeItem(UAVObjectField *field, int index, const QVariant &data) :
|
||||||
FieldTreeItem(index, data, field, parent)
|
FieldTreeItem(index, data, field)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
QWidget *createEditor(QWidget *parent)
|
QVariant fieldToData() const
|
||||||
|
{
|
||||||
|
return toHexString(m_field->getValue(m_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant dataToField() const
|
||||||
|
{
|
||||||
|
return toUInt(data());
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *createEditor(QWidget *parent) const
|
||||||
{
|
{
|
||||||
QLineEdit *lineEdit = new QLineEdit(parent);
|
QLineEdit *lineEdit = new QLineEdit(parent);
|
||||||
|
|
||||||
@ -355,44 +356,22 @@ public:
|
|||||||
return lineEdit;
|
return lineEdit;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant getEditorValue(QWidget *editor)
|
QVariant getEditorValue(QWidget *editor) const
|
||||||
{
|
{
|
||||||
QLineEdit *lineEdit = static_cast<QLineEdit *>(editor);
|
QLineEdit *lineEdit = static_cast<QLineEdit *>(editor);
|
||||||
|
|
||||||
return lineEdit->text();
|
return lineEdit->text();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEditorValue(QWidget *editor, QVariant value)
|
void setEditorValue(QWidget *editor, QVariant value) const
|
||||||
{
|
{
|
||||||
QLineEdit *lineEdit = static_cast<QLineEdit *>(editor);
|
QLineEdit *lineEdit = static_cast<QLineEdit *>(editor);
|
||||||
|
|
||||||
lineEdit->setText(value.toString());
|
lineEdit->setText(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void setData(QVariant value, int column)
|
|
||||||
{
|
|
||||||
setChanged(m_field->getValue(m_index) != toUInt(value));
|
|
||||||
TreeItem::setData(value, column);
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply()
|
|
||||||
{
|
|
||||||
m_field->setValue(toUInt(data()), m_index);
|
|
||||||
setChanged(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update()
|
|
||||||
{
|
|
||||||
QVariant value = toHexString(m_field->getValue(m_index));
|
|
||||||
|
|
||||||
if (data() != value || changed()) {
|
|
||||||
TreeItem::setData(value);
|
|
||||||
setHighlight(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVariant toHexString(QVariant value)
|
QVariant toHexString(QVariant value) const
|
||||||
{
|
{
|
||||||
QString str;
|
QString str;
|
||||||
bool ok;
|
bool ok;
|
||||||
@ -400,7 +379,7 @@ private:
|
|||||||
return str.setNum(value.toUInt(&ok), 16).toUpper();
|
return str.setNum(value.toUInt(&ok), 16).toUpper();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant toUInt(QVariant str)
|
QVariant toUInt(QVariant str) const
|
||||||
{
|
{
|
||||||
bool ok;
|
bool ok;
|
||||||
|
|
||||||
@ -409,17 +388,26 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class CharFieldTreeItem : public FieldTreeItem {
|
class CharFieldTreeItem : public FieldTreeItem {
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
CharFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data, TreeItem *parent = 0) :
|
CharFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data) :
|
||||||
FieldTreeItem(index, data, field, parent)
|
FieldTreeItem(index, data, field)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CharFieldTreeItem(UAVObjectField *field, int index, const QVariant &data, TreeItem *parent = 0) :
|
CharFieldTreeItem(UAVObjectField *field, int index, const QVariant &data) :
|
||||||
FieldTreeItem(index, data, field, parent)
|
FieldTreeItem(index, data, field)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
QWidget *createEditor(QWidget *parent)
|
QVariant fieldToData() const
|
||||||
|
{
|
||||||
|
return toChar(m_field->getValue(m_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant dataToField() const
|
||||||
|
{
|
||||||
|
return toUInt(data());
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *createEditor(QWidget *parent) const
|
||||||
{
|
{
|
||||||
QLineEdit *lineEdit = new QLineEdit(parent);
|
QLineEdit *lineEdit = new QLineEdit(parent);
|
||||||
|
|
||||||
@ -428,49 +416,27 @@ public:
|
|||||||
return lineEdit;
|
return lineEdit;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant getEditorValue(QWidget *editor)
|
QVariant getEditorValue(QWidget *editor) const
|
||||||
{
|
{
|
||||||
QLineEdit *lineEdit = static_cast<QLineEdit *>(editor);
|
QLineEdit *lineEdit = static_cast<QLineEdit *>(editor);
|
||||||
|
|
||||||
return lineEdit->text();
|
return lineEdit->text();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setEditorValue(QWidget *editor, QVariant value)
|
void setEditorValue(QWidget *editor, QVariant value) const
|
||||||
{
|
{
|
||||||
QLineEdit *lineEdit = static_cast<QLineEdit *>(editor);
|
QLineEdit *lineEdit = static_cast<QLineEdit *>(editor);
|
||||||
|
|
||||||
lineEdit->setText(value.toString());
|
lineEdit->setText(value.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void setData(QVariant value, int column)
|
|
||||||
{
|
|
||||||
setChanged(m_field->getValue(m_index) != toUInt(value));
|
|
||||||
TreeItem::setData(value, column);
|
|
||||||
}
|
|
||||||
|
|
||||||
void apply()
|
|
||||||
{
|
|
||||||
m_field->setValue(toUInt(data()), m_index);
|
|
||||||
setChanged(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update()
|
|
||||||
{
|
|
||||||
QVariant value = toChar(m_field->getValue(m_index));
|
|
||||||
|
|
||||||
if (data() != value || changed()) {
|
|
||||||
TreeItem::setData(value);
|
|
||||||
setHighlight(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVariant toChar(QVariant value)
|
QVariant toChar(QVariant value) const
|
||||||
{
|
{
|
||||||
return value.toChar();
|
return value.toChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant toUInt(QVariant str)
|
QVariant toUInt(QVariant str) const
|
||||||
{
|
{
|
||||||
return QVariant(str.toString().at(0).toLatin1());
|
return QVariant(str.toString().at(0).toLatin1());
|
||||||
}
|
}
|
||||||
|
@ -27,26 +27,30 @@
|
|||||||
|
|
||||||
#include "treeitem.h"
|
#include "treeitem.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
/* Constructor */
|
/* Constructor */
|
||||||
HighLightManager::HighLightManager(long checkingInterval)
|
HighlightManager::HighlightManager()
|
||||||
{
|
{
|
||||||
// Start the timer and connect it to the callback
|
// Initialize the timer and connect it to the callback
|
||||||
m_expirationTimer.start(checkingInterval);
|
m_expirationTimer.setTimerType(Qt::PreciseTimer);
|
||||||
connect(&m_expirationTimer, SIGNAL(timeout()), this, SLOT(checkItemsExpired()));
|
m_expirationTimer.setSingleShot(true);
|
||||||
|
connect(&m_expirationTimer, &QTimer::timeout, this, &HighlightManager::checkItemsExpired);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called to add item to list. Item is only added if absent.
|
* Called to add item to list. Item is only added if absent.
|
||||||
* Returns true if item was added, otherwise false.
|
* Returns true if item was added, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool HighLightManager::add(TreeItem *itemToAdd)
|
bool HighlightManager::add(TreeItem *item)
|
||||||
{
|
{
|
||||||
// Lock to ensure thread safety
|
// Lock to ensure thread safety
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
|
|
||||||
// Check so that the item isn't already in the list
|
// Check so that the item isn't already in the list
|
||||||
if (!m_items.contains(itemToAdd)) {
|
if (!m_items.contains(item)) {
|
||||||
m_items.insert(itemToAdd);
|
m_items.insert(item);
|
||||||
|
emit updateHighlight(item);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -56,13 +60,57 @@ bool HighLightManager::add(TreeItem *itemToAdd)
|
|||||||
* Called to remove item from list.
|
* Called to remove item from list.
|
||||||
* Returns true if item was removed, otherwise false.
|
* Returns true if item was removed, otherwise false.
|
||||||
*/
|
*/
|
||||||
bool HighLightManager::remove(TreeItem *itemToRemove)
|
bool HighlightManager::remove(TreeItem *item)
|
||||||
{
|
{
|
||||||
// Lock to ensure thread safety
|
// Lock to ensure thread safety
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
|
|
||||||
// Remove item and return result
|
// Remove item and return result
|
||||||
return m_items.remove(itemToRemove);
|
const bool removed = m_items.remove(item);
|
||||||
|
|
||||||
|
if (removed) {
|
||||||
|
emit updateHighlight(item);
|
||||||
|
}
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called to remove item from list.
|
||||||
|
* Will not emit a signal. Called when destroying an item
|
||||||
|
* Returns true if item was removed, otherwise false.
|
||||||
|
*/
|
||||||
|
bool HighlightManager::reset(TreeItem *item)
|
||||||
|
{
|
||||||
|
// Lock to ensure thread safety
|
||||||
|
QMutexLocker locker(&m_mutex);
|
||||||
|
|
||||||
|
// Remove item and return result
|
||||||
|
return m_items.remove(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HighlightManager::startTimer(QTime expirationTime)
|
||||||
|
{
|
||||||
|
// Lock to ensure thread safety
|
||||||
|
QMutexLocker locker(&m_mutex);
|
||||||
|
|
||||||
|
if (!m_expirationTimer.isActive()) {
|
||||||
|
int msec = QTime::currentTime().msecsTo(expirationTime);
|
||||||
|
// qDebug() << "start" << msec;
|
||||||
|
m_expirationTimer.start((msec < 10) ? 10 : msec);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HighlightManager::reset()
|
||||||
|
{
|
||||||
|
// Lock to ensure thread safety
|
||||||
|
QMutexLocker locker(&m_mutex);
|
||||||
|
|
||||||
|
m_expirationTimer.stop();
|
||||||
|
|
||||||
|
m_items.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -71,7 +119,7 @@ bool HighLightManager::remove(TreeItem *itemToRemove)
|
|||||||
* removes them if they are expired.
|
* removes them if they are expired.
|
||||||
* Expired highlights are restored.
|
* Expired highlights are restored.
|
||||||
*/
|
*/
|
||||||
void HighLightManager::checkItemsExpired()
|
void HighlightManager::checkItemsExpired()
|
||||||
{
|
{
|
||||||
// Lock to ensure thread safety
|
// Lock to ensure thread safety
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
@ -81,72 +129,102 @@ void HighLightManager::checkItemsExpired()
|
|||||||
|
|
||||||
// This is the timestamp to compare with
|
// This is the timestamp to compare with
|
||||||
QTime now = QTime::currentTime();
|
QTime now = QTime::currentTime();
|
||||||
|
QTime next;
|
||||||
|
|
||||||
// Loop over all items, check if they expired.
|
// Loop over all items, check if they expired.
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
TreeItem *item = iter.next();
|
TreeItem *item = iter.next();
|
||||||
if (item->getHiglightExpires() < now) {
|
if (item->getHighlightExpires() <= now) {
|
||||||
// If expired, call removeHighlight
|
// expired, call removeHighlight
|
||||||
item->removeHighlight();
|
item->resetHighlight();
|
||||||
|
|
||||||
// Remove from list since it is restored.
|
// Remove from list since it is restored.
|
||||||
iter.remove();
|
iter.remove();
|
||||||
|
|
||||||
|
emit updateHighlight(item);
|
||||||
|
} else {
|
||||||
|
// not expired, check if next to expire
|
||||||
|
if (!next.isValid() || (next > item->getHighlightExpires())) {
|
||||||
|
next = item->getHighlightExpires();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (next.isValid()) {
|
||||||
|
int msec = QTime::currentTime().msecsTo(next);
|
||||||
|
// qDebug() << "restart" << msec;
|
||||||
|
m_expirationTimer.start((msec < 10) ? 10 : msec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int TreeItem::m_highlightTimeMs = 500;
|
int TreeItem::m_highlightTimeMs = 300;
|
||||||
|
|
||||||
TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parent) :
|
TreeItem::TreeItem(const QList<QVariant> &data) :
|
||||||
QObject(0),
|
m_itemData(data),
|
||||||
m_data(data),
|
m_parentItem(0),
|
||||||
m_parent(parent),
|
m_changed(false),
|
||||||
m_highlight(false),
|
m_highlighted(false),
|
||||||
m_changed(false)
|
m_highlightManager(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
TreeItem::TreeItem(const QVariant &data, TreeItem *parent) :
|
TreeItem::TreeItem(const QVariant &data) :
|
||||||
QObject(0),
|
m_parentItem(0),
|
||||||
m_parent(parent),
|
m_changed(false),
|
||||||
m_highlight(false),
|
m_highlighted(false),
|
||||||
m_changed(false)
|
m_highlightManager(0)
|
||||||
{
|
{
|
||||||
m_data << data << "" << "";
|
m_itemData << data << "" << "";
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeItem::~TreeItem()
|
TreeItem::~TreeItem()
|
||||||
{
|
{
|
||||||
qDeleteAll(m_children);
|
if (m_highlightManager) {
|
||||||
|
m_highlightManager->reset(this);
|
||||||
|
}
|
||||||
|
qDeleteAll(m_childItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeItem::appendChild(TreeItem *child)
|
void TreeItem::setParentItem(TreeItem *parentItem)
|
||||||
{
|
{
|
||||||
m_children.append(child);
|
if (m_parentItem) {
|
||||||
child->setParentTree(this);
|
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_children.insert(index, child);
|
|
||||||
child->setParentTree(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeItem *TreeItem::getChild(int index)
|
void TreeItem::insertChild(TreeItem *childItem, int index)
|
||||||
{
|
{
|
||||||
return m_children.value(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
|
||||||
|
{
|
||||||
|
return m_childItems.value(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TreeItem::childCount() const
|
int TreeItem::childCount() const
|
||||||
{
|
{
|
||||||
return m_children.count();
|
return m_childItems.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
int TreeItem::row() const
|
int TreeItem::row() const
|
||||||
{
|
{
|
||||||
if (m_parent) {
|
if (m_parentItem) {
|
||||||
return m_parent->m_children.indexOf(const_cast<TreeItem *>(this));
|
return m_parentItem->m_childItems.indexOf(const_cast<TreeItem *>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -154,79 +232,140 @@ int TreeItem::row() const
|
|||||||
|
|
||||||
int TreeItem::columnCount() const
|
int TreeItem::columnCount() const
|
||||||
{
|
{
|
||||||
return m_data.count();
|
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
|
QVariant TreeItem::data(int column) const
|
||||||
{
|
{
|
||||||
return m_data.value(column);
|
return m_itemData.value(column);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeItem::setData(QVariant value, int column)
|
void TreeItem::setData(QVariant value, int column)
|
||||||
{
|
{
|
||||||
m_data.replace(column, value);
|
m_itemData.replace(column, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeItem::update()
|
void TreeItem::update(const QTime &ts)
|
||||||
{
|
{
|
||||||
foreach(TreeItem * child, treeChildren())
|
foreach(TreeItem * child, children()) {
|
||||||
child->update();
|
child->update(ts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeItem::apply()
|
void TreeItem::apply()
|
||||||
{
|
{
|
||||||
foreach(TreeItem * child, treeChildren())
|
foreach(TreeItem * child, children()) {
|
||||||
child->apply();
|
child->apply();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called after a value has changed to trigger highlightning of tree item.
|
* Called after a value has changed to trigger highlighting of tree item.
|
||||||
*/
|
*/
|
||||||
void TreeItem::setHighlight(bool highlight)
|
void TreeItem::setHighlighted(bool highlighted, const QTime &ts)
|
||||||
{
|
{
|
||||||
m_highlight = highlight;
|
|
||||||
m_changed = false;
|
m_changed = false;
|
||||||
if (highlight) {
|
if (m_highlighted != highlighted) {
|
||||||
// Update the expires timestamp
|
m_highlighted = highlighted;
|
||||||
m_highlightExpires = QTime::currentTime().addMSecs(m_highlightTimeMs);
|
if (highlighted) {
|
||||||
|
// Add to highlight manager
|
||||||
// Add to highlightmanager
|
m_highlightManager->add(this);
|
||||||
if (m_highlightManager->add(this)) {
|
// Update expiration timeout
|
||||||
// Only emit signal if it was added
|
m_highlightExpires = ts.addMSecs(m_highlightTimeMs);
|
||||||
emit updateHighlight(this);
|
// start expiration timer if necessary
|
||||||
|
m_highlightManager->startTimer(m_highlightExpires);
|
||||||
|
} else {
|
||||||
|
m_highlightManager->remove(this);
|
||||||
}
|
}
|
||||||
} else if (m_highlightManager->remove(this)) {
|
|
||||||
// Only emit signal if it was removed
|
|
||||||
emit updateHighlight(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a parent, call recursively to update highlight status of parents.
|
// If we have a parent, call recursively to update highlight status of parents.
|
||||||
// This will ensure that the root of a leaf that is changed also is highlighted.
|
// This will ensure that the root of a leaf that is changed is also highlighted.
|
||||||
// Only updates that really changes values will trigger highlight of parents.
|
// Only updates that really changes values will trigger highlight of parents.
|
||||||
if (m_parent) {
|
if (m_parentItem) {
|
||||||
m_parent->setHighlight(highlight);
|
m_parentItem->setHighlighted(highlighted, ts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeItem::removeHighlight()
|
void TreeItem::resetHighlight()
|
||||||
{
|
{
|
||||||
m_highlight = false;
|
m_highlighted = false;
|
||||||
emit updateHighlight(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeItem::setHighlightManager(HighLightManager *mgr)
|
void TreeItem::setHighlightManager(HighlightManager *mgr)
|
||||||
{
|
{
|
||||||
m_highlightManager = mgr;
|
m_highlightManager = mgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTime TreeItem::getHiglightExpires()
|
QTime TreeItem::getHighlightExpires() const
|
||||||
{
|
{
|
||||||
return m_highlightExpires;
|
return m_highlightExpires;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<MetaObjectTreeItem *> TopTreeItem::getMetaObjectItems()
|
int TreeItem::childIndex(QString name) const
|
||||||
{
|
{
|
||||||
return m_metaObjectTreeItemsPerObjectIds.values();
|
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
|
QVariant ArrayFieldTreeItem::data(int column) const
|
||||||
@ -234,28 +373,32 @@ QVariant ArrayFieldTreeItem::data(int column) const
|
|||||||
if (column == 1) {
|
if (column == 1) {
|
||||||
if (m_field->getType() == UAVObjectField::UINT8 && m_field->getUnits().toLower() == "char") {
|
if (m_field->getType() == UAVObjectField::UINT8 && m_field->getUnits().toLower() == "char") {
|
||||||
QString dataString;
|
QString dataString;
|
||||||
|
dataString.reserve(2 + m_field->getNumElements());
|
||||||
|
dataString.append("'");
|
||||||
for (uint i = 0; i < m_field->getNumElements(); ++i) {
|
for (uint i = 0; i < m_field->getNumElements(); ++i) {
|
||||||
dataString.append(m_field->getValue(i).toChar());
|
dataString.append(m_field->getValue(i).toChar());
|
||||||
}
|
}
|
||||||
QString data = QString("'%1'").arg(dataString);
|
dataString.append("'");
|
||||||
return data;
|
return dataString;
|
||||||
} else if (m_field->getUnits().toLower() == "hex") {
|
} else if (m_field->getUnits().toLower() == "hex") {
|
||||||
QString dataString;
|
QString dataString;
|
||||||
|
int len = TreeItem::maxHexStringLength(m_field->getType());
|
||||||
|
QChar fillChar('0');
|
||||||
|
dataString.reserve(2 + (len + 1) * m_field->getNumElements());
|
||||||
|
dataString.append("{");
|
||||||
for (uint i = 0; i < m_field->getNumElements(); ++i) {
|
for (uint i = 0; i < m_field->getNumElements(); ++i) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
dataString.append(' ');
|
dataString.append(' ');
|
||||||
}
|
}
|
||||||
bool ok;
|
bool ok;
|
||||||
dataString.append(QString("%1")
|
uint value = m_field->getValue(i).toUInt(&ok);
|
||||||
.arg(m_field->getValue(i).toUInt(&ok), TreeItem::maxHexStringLength(m_field->getType()),
|
QString str = QString("%1").arg(value, len, 16, fillChar);
|
||||||
16, QChar('0')).toUpper());
|
str = str.toUpper();
|
||||||
|
dataString.append(str);
|
||||||
|
}
|
||||||
|
dataString.append("}");
|
||||||
|
return dataString;
|
||||||
}
|
}
|
||||||
QString data = QString("{%1}").arg(dataString);
|
|
||||||
return data;
|
|
||||||
} else {
|
|
||||||
return QVariant();
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return TreeItem::data(column);
|
return TreeItem::data(column);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -29,16 +29,16 @@
|
|||||||
#define TREEITEM_H
|
#define TREEITEM_H
|
||||||
|
|
||||||
#include "uavobject.h"
|
#include "uavobject.h"
|
||||||
|
#include "uavdataobject.h"
|
||||||
#include "uavmetaobject.h"
|
#include "uavmetaobject.h"
|
||||||
#include "uavobjectfield.h"
|
#include "uavobjectfield.h"
|
||||||
#include <QtCore/QList>
|
|
||||||
#include <QtCore/QLinkedList>
|
#include <QList>
|
||||||
#include <QtCore/QMap>
|
#include <QMap>
|
||||||
#include <QtCore/QVariant>
|
#include <QVariant>
|
||||||
#include <QtCore/QTime>
|
#include <QTime>
|
||||||
#include <QtCore/QTimer>
|
#include <QTimer>
|
||||||
#include <QtCore/QObject>
|
#include <QObject>
|
||||||
#include <QtCore/QDebug>
|
|
||||||
|
|
||||||
class TreeItem;
|
class TreeItem;
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ class TreeItem;
|
|||||||
* non highlighted state in a linked list.
|
* non highlighted state in a linked list.
|
||||||
* A timer traverses this list periodically to find out
|
* A timer traverses this list periodically to find out
|
||||||
* if any of the items should be restored. All items are
|
* if any of the items should be restored. All items are
|
||||||
* updated withan expiration timestamp when they expires.
|
* updated with an expiration timestamp when they expires.
|
||||||
* An item that is beeing restored is removed from the
|
* An item that is beeing restored is removed from the
|
||||||
* list and its removeHighlight() method is called. Items
|
* list and its removeHighlight() method is called. Items
|
||||||
* that are not expired are left in the list til next time.
|
* that are not expired are left in the list til next time.
|
||||||
@ -57,18 +57,26 @@ class TreeItem;
|
|||||||
* left untouched in the list. This reduces unwanted emits
|
* left untouched in the list. This reduces unwanted emits
|
||||||
* of signals to the repaint/update function.
|
* of signals to the repaint/update function.
|
||||||
*/
|
*/
|
||||||
class HighLightManager : public QObject {
|
class HighlightManager : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
// Constructor taking the checking interval in ms.
|
HighlightManager();
|
||||||
HighLightManager(long checkingInterval);
|
|
||||||
|
|
||||||
// This is called when an item has been set to
|
// This is called when an item is set to highlighted = true.
|
||||||
// highlighted = true.
|
bool add(TreeItem *item);
|
||||||
bool add(TreeItem *itemToAdd);
|
|
||||||
|
|
||||||
// This is called when an item is set to highlighted = false;
|
// This is called when an item is set to highlighted = false;
|
||||||
bool remove(TreeItem *itemToRemove);
|
bool remove(TreeItem *item);
|
||||||
|
|
||||||
|
// This is called when an item is destroyed
|
||||||
|
bool reset(TreeItem *item);
|
||||||
|
|
||||||
|
bool startTimer(QTime time);
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void updateHighlight(TreeItem *item);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
// Timer callback method.
|
// Timer callback method.
|
||||||
@ -85,252 +93,182 @@ private:
|
|||||||
QMutex m_mutex;
|
QMutex m_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TreeItem : public QObject {
|
class TreeItem {
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
static const int TITLE_COLUMN = 0;
|
static const int TITLE_COLUMN = 0;
|
||||||
static const int DATA_COLUMN = 1;
|
static const int DATA_COLUMN = 1;
|
||||||
|
|
||||||
TreeItem(const QList<QVariant> &data, TreeItem *parent = 0);
|
TreeItem(const QList<QVariant> &data);
|
||||||
TreeItem(const QVariant &data, TreeItem *parent = 0);
|
TreeItem(const QVariant &data);
|
||||||
virtual ~TreeItem();
|
virtual ~TreeItem();
|
||||||
|
|
||||||
void appendChild(TreeItem *child);
|
TreeItem *parentItem() const
|
||||||
void insertChild(TreeItem *child);
|
|
||||||
|
|
||||||
TreeItem *getChild(int index);
|
|
||||||
inline QList<TreeItem *> treeChildren() const
|
|
||||||
{
|
{
|
||||||
return m_children;
|
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 childCount() const;
|
||||||
|
|
||||||
int columnCount() const;
|
int columnCount() const;
|
||||||
virtual QVariant data(int column = 1) const;
|
|
||||||
QString description()
|
QString description() const
|
||||||
{
|
{
|
||||||
return m_description;
|
return m_description;
|
||||||
}
|
}
|
||||||
void setDescription(QString d) // Split around 40 characters
|
|
||||||
{
|
|
||||||
int idx = d.indexOf(" ", 40);
|
|
||||||
|
|
||||||
d.insert(idx, QString("<br>"));
|
void setDescription(QString desc);
|
||||||
d.remove("@Ref", Qt::CaseInsensitive);
|
|
||||||
m_description = d;
|
virtual QVariant data(int column = 1) const;
|
||||||
}
|
|
||||||
// only column 1 (TreeItem::dataColumn) is changed with setData currently
|
|
||||||
// other columns are initialized in constructor
|
|
||||||
virtual void setData(QVariant value, int column = 1);
|
virtual void setData(QVariant value, int column = 1);
|
||||||
|
|
||||||
int row() const;
|
int row() const;
|
||||||
TreeItem *parent()
|
|
||||||
{
|
virtual bool isEditable() const
|
||||||
return m_parent;
|
|
||||||
}
|
|
||||||
void setParentTree(TreeItem *parent)
|
|
||||||
{
|
|
||||||
m_parent = parent;
|
|
||||||
}
|
|
||||||
inline virtual bool isEditable()
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
virtual void update();
|
|
||||||
|
virtual void update(const QTime &ts);
|
||||||
virtual void apply();
|
virtual void apply();
|
||||||
|
|
||||||
inline bool highlighted()
|
bool changed() const
|
||||||
{
|
{
|
||||||
return m_highlight;
|
return m_changed;
|
||||||
}
|
}
|
||||||
void setHighlight(bool highlight);
|
|
||||||
|
void setChanged(bool changed)
|
||||||
|
{
|
||||||
|
m_changed = changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isHighlighted() const
|
||||||
|
{
|
||||||
|
return m_highlighted;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setHighlighted(bool highlighted, const QTime &ts);
|
||||||
|
|
||||||
static void setHighlightTime(int time)
|
static void setHighlightTime(int time)
|
||||||
{
|
{
|
||||||
m_highlightTimeMs = time;
|
m_highlightTimeMs = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool changed()
|
QTime getHighlightExpires() const;
|
||||||
|
|
||||||
|
void resetHighlight();
|
||||||
|
|
||||||
|
void setHighlightManager(HighlightManager *mgr);
|
||||||
|
|
||||||
|
virtual bool isKnown() const
|
||||||
{
|
{
|
||||||
return m_changed;
|
if (m_parentItem) {
|
||||||
|
return m_parentItem->isKnown();
|
||||||
}
|
}
|
||||||
inline void setChanged(bool changed)
|
|
||||||
{
|
|
||||||
m_changed = changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void setHighlightManager(HighLightManager *mgr);
|
|
||||||
|
|
||||||
QTime getHiglightExpires();
|
|
||||||
|
|
||||||
virtual void removeHighlight();
|
|
||||||
|
|
||||||
int nameIndex(QString name)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < childCount(); ++i) {
|
|
||||||
if (name < getChild(i)->data(0).toString()) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return childCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
TreeItem *findChildByName(QString name)
|
|
||||||
{
|
|
||||||
foreach(TreeItem * child, m_children) {
|
|
||||||
if (name == child->data(0).toString()) {
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int 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;
|
|
||||||
}
|
|
||||||
void updateIsKnown(bool isKnown)
|
|
||||||
{
|
|
||||||
if (isKnown != this->isKnown()) {
|
|
||||||
m_changed = false;
|
|
||||||
foreach(TreeItem * child, m_children) {
|
|
||||||
child->updateIsKnown(isKnown);
|
|
||||||
}
|
|
||||||
emit updateIsKnown(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
virtual bool isKnown()
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
signals:
|
int childIndex(QString name) const;
|
||||||
void updateHighlight(TreeItem *item);
|
|
||||||
void updateIsKnown(TreeItem *item);
|
|
||||||
|
|
||||||
private slots:
|
TreeItem *childByName(QString name) const;
|
||||||
|
|
||||||
|
int insertionIndex(TreeItem *item) const;
|
||||||
|
|
||||||
|
static int maxHexStringLength(UAVObjectField::FieldType type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int m_highlightTimeMs;
|
static int m_highlightTimeMs;
|
||||||
QList<TreeItem *> m_children;
|
|
||||||
|
|
||||||
|
QList<TreeItem *> m_childItems;
|
||||||
// m_data contains: [0] property name, [1] value, [2] unit
|
// m_data contains: [0] property name, [1] value, [2] unit
|
||||||
QList<QVariant> m_data;
|
QList<QVariant> m_itemData;
|
||||||
|
TreeItem *m_parentItem;
|
||||||
|
|
||||||
QString m_description;
|
QString m_description;
|
||||||
TreeItem *m_parent;
|
|
||||||
bool m_highlight;
|
|
||||||
bool m_changed;
|
bool m_changed;
|
||||||
|
|
||||||
|
bool m_highlighted;
|
||||||
QTime m_highlightExpires;
|
QTime m_highlightExpires;
|
||||||
HighLightManager *m_highlightManager;
|
HighlightManager *m_highlightManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DataObjectTreeItem;
|
|
||||||
class MetaObjectTreeItem;
|
|
||||||
|
|
||||||
class TopTreeItem : public TreeItem {
|
class TopTreeItem : public TreeItem {
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
TopTreeItem(const QList<QVariant> &data, TreeItem *parent = 0) : TreeItem(data, parent) {}
|
TopTreeItem(const QList<QVariant> &data) :
|
||||||
TopTreeItem(const QVariant &data, TreeItem *parent = 0) : TreeItem(data, parent) {}
|
TreeItem(data)
|
||||||
|
{}
|
||||||
void addObjectTreeItem(quint32 objectId, DataObjectTreeItem *oti)
|
TopTreeItem(const QVariant &data) :
|
||||||
{
|
TreeItem(data)
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<MetaObjectTreeItem *> getMetaObjectItems();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QHash<quint32, DataObjectTreeItem *> m_objectTreeItemsPerObjectIds;
|
|
||||||
QHash<quint32, MetaObjectTreeItem *> m_metaObjectTreeItemsPerObjectIds;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ObjectTreeItem : public TreeItem {
|
class ObjectTreeItem : public TreeItem {
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
ObjectTreeItem(const QList<QVariant> &data, UAVObject *object, TreeItem *parent = 0) :
|
ObjectTreeItem(UAVObject *object, const QList<QVariant> &data) :
|
||||||
TreeItem(data, parent), m_obj(object)
|
TreeItem(data), m_obj(object)
|
||||||
{
|
{
|
||||||
setDescription(m_obj->getDescription());
|
setDescription(m_obj->getDescription());
|
||||||
}
|
}
|
||||||
ObjectTreeItem(const QVariant &data, UAVObject *object, TreeItem *parent = 0) :
|
ObjectTreeItem(UAVObject *object, const QVariant &data) :
|
||||||
TreeItem(data, parent), m_obj(object)
|
TreeItem(data), m_obj(object)
|
||||||
{
|
{
|
||||||
setDescription(m_obj->getDescription());
|
setDescription(m_obj->getDescription());
|
||||||
}
|
}
|
||||||
inline UAVObject *object()
|
|
||||||
|
UAVObject *object() const
|
||||||
{
|
{
|
||||||
return m_obj;
|
return m_obj;
|
||||||
}
|
}
|
||||||
bool isKnown()
|
|
||||||
{
|
|
||||||
return !m_obj->isSettingsObject() || m_obj->isKnown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UAVObject *m_obj;
|
UAVObject *m_obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
class MetaObjectTreeItem : public ObjectTreeItem {
|
class MetaObjectTreeItem : public ObjectTreeItem {
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
MetaObjectTreeItem(UAVObject *object, const QList<QVariant> &data, TreeItem *parent = 0) :
|
MetaObjectTreeItem(UAVMetaObject *object, const QList<QVariant> &data) :
|
||||||
ObjectTreeItem(data, object, parent)
|
ObjectTreeItem(object, data)
|
||||||
{}
|
{}
|
||||||
MetaObjectTreeItem(UAVObject *object, const QVariant &data, TreeItem *parent = 0) :
|
MetaObjectTreeItem(UAVMetaObject *object, const QVariant &data) :
|
||||||
ObjectTreeItem(data, object, parent)
|
ObjectTreeItem(object, data)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool isKnown()
|
UAVMetaObject *metaObject() const
|
||||||
{
|
{
|
||||||
return parent()->isKnown();
|
return static_cast<UAVMetaObject *>(object());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DataObjectTreeItem : public ObjectTreeItem {
|
class DataObjectTreeItem : public ObjectTreeItem {
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
DataObjectTreeItem(const QList<QVariant> &data, UAVObject *object, TreeItem *parent = 0) :
|
DataObjectTreeItem(UAVDataObject *object, const QList<QVariant> &data) :
|
||||||
ObjectTreeItem(data, object, parent) {}
|
ObjectTreeItem(object, data)
|
||||||
DataObjectTreeItem(const QVariant &data, UAVObject *object, TreeItem *parent = 0) :
|
{}
|
||||||
ObjectTreeItem(data, object, parent) {}
|
DataObjectTreeItem(UAVDataObject *object, const QVariant &data) :
|
||||||
|
ObjectTreeItem(object, data)
|
||||||
|
{}
|
||||||
|
|
||||||
|
UAVDataObject *dataObject() const
|
||||||
|
{
|
||||||
|
return static_cast<UAVDataObject *>(object());
|
||||||
|
}
|
||||||
|
|
||||||
virtual void apply()
|
virtual void apply()
|
||||||
{
|
{
|
||||||
foreach(TreeItem * child, treeChildren()) {
|
foreach(TreeItem * child, children()) {
|
||||||
MetaObjectTreeItem *metaChild = dynamic_cast<MetaObjectTreeItem *>(child);
|
MetaObjectTreeItem *metaChild = dynamic_cast<MetaObjectTreeItem *>(child);
|
||||||
|
|
||||||
if (!metaChild) {
|
if (!metaChild) {
|
||||||
@ -338,49 +276,54 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void update()
|
|
||||||
|
virtual void update(const QTime &ts)
|
||||||
{
|
{
|
||||||
foreach(TreeItem * child, treeChildren()) {
|
foreach(TreeItem * child, children()) {
|
||||||
MetaObjectTreeItem *metaChild = dynamic_cast<MetaObjectTreeItem *>(child);
|
MetaObjectTreeItem *metaChild = dynamic_cast<MetaObjectTreeItem *>(child);
|
||||||
|
|
||||||
if (!metaChild) {
|
if (!metaChild) {
|
||||||
child->update();
|
child->update(ts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool isKnown() const
|
||||||
|
{
|
||||||
|
return !object()->isSettingsObject() || object()->isKnown();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class InstanceTreeItem : public DataObjectTreeItem {
|
class InstanceTreeItem : public DataObjectTreeItem {
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
InstanceTreeItem(UAVObject *object, const QList<QVariant> &data, TreeItem *parent = 0) :
|
InstanceTreeItem(UAVDataObject *object, const QList<QVariant> &data) :
|
||||||
DataObjectTreeItem(data, object, parent)
|
DataObjectTreeItem(object, data)
|
||||||
{}
|
{}
|
||||||
InstanceTreeItem(UAVObject *object, const QVariant &data, TreeItem *parent = 0) :
|
InstanceTreeItem(UAVDataObject *object, const QVariant &data) :
|
||||||
DataObjectTreeItem(data, object, parent)
|
DataObjectTreeItem(object, data)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
virtual void update(const QTime &ts)
|
||||||
|
{
|
||||||
|
TreeItem::update(ts);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void apply()
|
virtual void apply()
|
||||||
{
|
{
|
||||||
TreeItem::apply();
|
TreeItem::apply();
|
||||||
}
|
}
|
||||||
virtual void update()
|
|
||||||
{
|
|
||||||
TreeItem::update();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArrayFieldTreeItem : public TreeItem {
|
class ArrayFieldTreeItem : public TreeItem {
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
ArrayFieldTreeItem(UAVObjectField *field, const QList<QVariant> &data, TreeItem *parent = 0) : TreeItem(data, parent), m_field(field)
|
ArrayFieldTreeItem(UAVObjectField *field, const QList<QVariant> &data) :
|
||||||
|
TreeItem(data), m_field(field)
|
||||||
{}
|
{}
|
||||||
ArrayFieldTreeItem(UAVObjectField *field, const QVariant &data, TreeItem *parent = 0) : TreeItem(data, parent), m_field(field)
|
ArrayFieldTreeItem(UAVObjectField *field, const QVariant &data) :
|
||||||
|
TreeItem(data), m_field(field)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
QVariant data(int column) const;
|
QVariant data(int column) const;
|
||||||
bool isKnown()
|
|
||||||
{
|
|
||||||
return parent()->isKnown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UAVObjectField *m_field;
|
UAVObjectField *m_field;
|
||||||
|
@ -50,11 +50,22 @@ void UAVObjectBrowser::loadConfiguration(IUAVGadgetConfiguration *config)
|
|||||||
m_widget->setRecentlyUpdatedColor(m->recentlyUpdatedColor());
|
m_widget->setRecentlyUpdatedColor(m->recentlyUpdatedColor());
|
||||||
m_widget->setManuallyChangedColor(m->manuallyChangedColor());
|
m_widget->setManuallyChangedColor(m->manuallyChangedColor());
|
||||||
m_widget->setRecentlyUpdatedTimeout(m->recentlyUpdatedTimeout());
|
m_widget->setRecentlyUpdatedTimeout(m->recentlyUpdatedTimeout());
|
||||||
m_widget->setOnlyHilightChangedValues(m->onlyHighlightChangedValues());
|
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());
|
m_widget->setSplitterState(m->splitterState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UAVObjectBrowser::saveState(QSettings &settings) const
|
||||||
|
{
|
||||||
|
m_widget->saveState(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UAVObjectBrowser::restoreState(QSettings &settings)
|
||||||
|
{
|
||||||
|
m_widget->restoreState(settings);
|
||||||
|
}
|
||||||
|
|
||||||
void UAVObjectBrowser::viewOptionsChangedSlot(bool categorized, bool scientific, bool metadata, bool description)
|
void UAVObjectBrowser::viewOptionsChangedSlot(bool categorized, bool scientific, bool metadata, bool description)
|
||||||
{
|
{
|
||||||
if (m_config) {
|
if (m_config) {
|
||||||
|
@ -51,6 +51,9 @@ public:
|
|||||||
}
|
}
|
||||||
void loadConfiguration(IUAVGadgetConfiguration *config);
|
void loadConfiguration(IUAVGadgetConfiguration *config);
|
||||||
|
|
||||||
|
void saveState(QSettings &settings) const;
|
||||||
|
void restoreState(QSettings &settings);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void viewOptionsChangedSlot(bool categorized, bool scientific, bool metadata, bool description);
|
void viewOptionsChangedSlot(bool categorized, bool scientific, bool metadata, bool description);
|
||||||
void splitterChanged(QByteArray state);
|
void splitterChanged(QByteArray state);
|
||||||
|
@ -7,28 +7,27 @@ include(../../plugin.pri)
|
|||||||
include(uavobjectbrowser_dependencies.pri)
|
include(uavobjectbrowser_dependencies.pri)
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
browserplugin.h \
|
treeitem.h \
|
||||||
|
fieldtreeitem.h \
|
||||||
|
browseritemdelegate.h \
|
||||||
|
uavobjecttreemodel.h \
|
||||||
uavobjectbrowserconfiguration.h \
|
uavobjectbrowserconfiguration.h \
|
||||||
|
uavobjectbrowseroptionspage.h \
|
||||||
uavobjectbrowser.h \
|
uavobjectbrowser.h \
|
||||||
uavobjectbrowserwidget.h \
|
uavobjectbrowserwidget.h \
|
||||||
uavobjectbrowserfactory.h \
|
uavobjectbrowserfactory.h \
|
||||||
uavobjectbrowseroptionspage.h \
|
browserplugin.h
|
||||||
uavobjecttreemodel.h \
|
|
||||||
treeitem.h \
|
|
||||||
browseritemdelegate.h \
|
|
||||||
fieldtreeitem.h
|
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
browserplugin.cpp \
|
treeitem.cpp \
|
||||||
|
browseritemdelegate.cpp \
|
||||||
|
uavobjecttreemodel.cpp \
|
||||||
uavobjectbrowserconfiguration.cpp \
|
uavobjectbrowserconfiguration.cpp \
|
||||||
|
uavobjectbrowseroptionspage.cpp \
|
||||||
uavobjectbrowser.cpp \
|
uavobjectbrowser.cpp \
|
||||||
uavobjectbrowserfactory.cpp \
|
uavobjectbrowserfactory.cpp \
|
||||||
uavobjectbrowserwidget.cpp \
|
uavobjectbrowserwidget.cpp \
|
||||||
uavobjectbrowseroptionspage.cpp \
|
browserplugin.cpp
|
||||||
uavobjecttreemodel.cpp \
|
|
||||||
treeitem.cpp \
|
|
||||||
browseritemdelegate.cpp \
|
|
||||||
fieldtreeitem.cpp
|
|
||||||
|
|
||||||
OTHER_FILES += UAVObjectBrowser.pluginspec
|
OTHER_FILES += UAVObjectBrowser.pluginspec
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "extensionsystem/pluginmanager.h"
|
#include "extensionsystem/pluginmanager.h"
|
||||||
#include "utils/mustache.h"
|
#include "utils/mustache.h"
|
||||||
|
|
||||||
|
#include <QTextStream>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
UAVObjectBrowserWidget::UAVObjectBrowserWidget(QWidget *parent) : QWidget(parent)
|
UAVObjectBrowserWidget::UAVObjectBrowserWidget(QWidget *parent) : QWidget(parent)
|
||||||
@ -47,10 +48,7 @@ UAVObjectBrowserWidget::UAVObjectBrowserWidget(QWidget *parent) : QWidget(parent
|
|||||||
m_viewoptions = new Ui_viewoptions();
|
m_viewoptions = new Ui_viewoptions();
|
||||||
m_viewoptions->setupUi(m_viewoptionsDialog);
|
m_viewoptions->setupUi(m_viewoptionsDialog);
|
||||||
|
|
||||||
m_model = new UAVObjectTreeModel(this,
|
m_model = createTreeModel();
|
||||||
m_viewoptions->cbCategorized->isChecked(),
|
|
||||||
m_viewoptions->cbMetaData->isChecked(),
|
|
||||||
m_viewoptions->cbScientific->isChecked());
|
|
||||||
|
|
||||||
m_modelProxy = new TreeSortFilterProxyModel(this);
|
m_modelProxy = new TreeSortFilterProxyModel(this);
|
||||||
m_modelProxy->setSourceModel(m_model);
|
m_modelProxy->setSourceModel(m_model);
|
||||||
@ -97,12 +95,12 @@ UAVObjectBrowserWidget::~UAVObjectBrowserWidget()
|
|||||||
delete m_browser;
|
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->cbCategorized->setChecked(showCategories);
|
||||||
m_viewoptions->cbMetaData->setChecked(metadata);
|
m_viewoptions->cbMetaData->setChecked(showMetadata);
|
||||||
m_viewoptions->cbScientific->setChecked(scientific);
|
m_viewoptions->cbScientific->setChecked(useScientificNotation);
|
||||||
m_viewoptions->cbDescription->setChecked(description);
|
m_viewoptions->cbDescription->setChecked(showDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UAVObjectBrowserWidget::setSplitterState(QByteArray state)
|
void UAVObjectBrowserWidget::setSplitterState(QByteArray state)
|
||||||
@ -156,7 +154,7 @@ ObjectTreeItem *UAVObjectBrowserWidget::findCurrentObjectTreeItem()
|
|||||||
if (objItem) {
|
if (objItem) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
item = item->parent();
|
item = item->parentItem();
|
||||||
}
|
}
|
||||||
return objItem;
|
return objItem;
|
||||||
}
|
}
|
||||||
@ -186,7 +184,7 @@ void UAVObjectBrowserWidget::saveObject()
|
|||||||
if (objItem != NULL) {
|
if (objItem != NULL) {
|
||||||
UAVObject *obj = objItem->object();
|
UAVObject *obj = objItem->object();
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(obj);
|
||||||
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj);
|
updateObjectPersistence(ObjectPersistence::OPERATION_SAVE, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +196,7 @@ void UAVObjectBrowserWidget::loadObject()
|
|||||||
if (objItem != NULL) {
|
if (objItem != NULL) {
|
||||||
UAVObject *obj = objItem->object();
|
UAVObject *obj = objItem->object();
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(obj);
|
||||||
updateObjectPersistance(ObjectPersistence::OPERATION_LOAD, obj);
|
updateObjectPersistence(ObjectPersistence::OPERATION_LOAD, obj);
|
||||||
// Retrieve object so that latest value is displayed
|
// Retrieve object so that latest value is displayed
|
||||||
requestUpdate();
|
requestUpdate();
|
||||||
}
|
}
|
||||||
@ -211,13 +209,13 @@ void UAVObjectBrowserWidget::eraseObject()
|
|||||||
if (objItem != NULL) {
|
if (objItem != NULL) {
|
||||||
UAVObject *obj = objItem->object();
|
UAVObject *obj = objItem->object();
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(obj);
|
||||||
updateObjectPersistance(ObjectPersistence::OPERATION_DELETE, obj);
|
updateObjectPersistence(ObjectPersistence::OPERATION_DELETE, obj);
|
||||||
// Retrieve object so that correct default value is displayed
|
// Retrieve object so that correct default value is displayed
|
||||||
requestUpdate();
|
requestUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UAVObjectBrowserWidget::updateObjectPersistance(ObjectPersistence::OperationOptions op, UAVObject *obj)
|
void UAVObjectBrowserWidget::updateObjectPersistence(ObjectPersistence::OperationOptions op, UAVObject *obj)
|
||||||
{
|
{
|
||||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||||
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
|
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
|
||||||
@ -238,11 +236,11 @@ void UAVObjectBrowserWidget::currentChanged(const QModelIndex ¤t, const QM
|
|||||||
{
|
{
|
||||||
Q_UNUSED(previous);
|
Q_UNUSED(previous);
|
||||||
|
|
||||||
TreeItem *item = static_cast<TreeItem *>(current.data(Qt::UserRole).value<void *>());
|
|
||||||
bool enable = true;
|
bool enable = true;
|
||||||
if (!current.isValid()) {
|
if (!current.isValid()) {
|
||||||
enable = false;
|
enable = false;
|
||||||
}
|
}
|
||||||
|
TreeItem *item = static_cast<TreeItem *>(current.data(Qt::UserRole).value<void *>());
|
||||||
TopTreeItem *top = dynamic_cast<TopTreeItem *>(item);
|
TopTreeItem *top = dynamic_cast<TopTreeItem *>(item);
|
||||||
ObjectTreeItem *data = dynamic_cast<ObjectTreeItem *>(item);
|
ObjectTreeItem *data = dynamic_cast<ObjectTreeItem *>(item);
|
||||||
if (top || (data && !data->object())) {
|
if (top || (data && !data->object())) {
|
||||||
@ -264,25 +262,33 @@ void UAVObjectBrowserWidget::viewSlot()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UAVObjectBrowserWidget::updateViewOptions()
|
UAVObjectTreeModel *UAVObjectBrowserWidget::createTreeModel()
|
||||||
{
|
{
|
||||||
// TODO we should update the model instead of rebuilding it
|
UAVObjectTreeModel *model = new UAVObjectTreeModel(this);
|
||||||
// a side effect of rebuilding is that some state is lost (expand state, ...)
|
|
||||||
UAVObjectTreeModel *model = new UAVObjectTreeModel(this,
|
model->setShowCategories(m_viewoptions->cbCategorized->isChecked());
|
||||||
m_viewoptions->cbCategorized->isChecked(),
|
model->setShowMetadata(m_viewoptions->cbMetaData->isChecked());
|
||||||
m_viewoptions->cbMetaData->isChecked(),
|
model->setUseScientificNotation(m_viewoptions->cbScientific->isChecked());
|
||||||
m_viewoptions->cbScientific->isChecked());
|
|
||||||
|
|
||||||
model->setUnknowObjectColor(m_unknownObjectColor);
|
|
||||||
model->setRecentlyUpdatedColor(m_recentlyUpdatedColor);
|
model->setRecentlyUpdatedColor(m_recentlyUpdatedColor);
|
||||||
model->setManuallyChangedColor(m_manuallyChangedColor);
|
model->setManuallyChangedColor(m_manuallyChangedColor);
|
||||||
model->setRecentlyUpdatedTimeout(m_recentlyUpdatedTimeout);
|
model->setRecentlyUpdatedTimeout(m_recentlyUpdatedTimeout);
|
||||||
model->setOnlyHilightChangedValues(m_onlyHilightChangedValues);
|
model->setUnknownObjectColor(m_unknownObjectColor);
|
||||||
|
model->setOnlyHighlightChangedValues(m_onlyHighlightChangedValues);
|
||||||
|
|
||||||
UAVObjectTreeModel *tmpModel = m_model;
|
return model;
|
||||||
m_model = model;
|
}
|
||||||
m_modelProxy->setSourceModel(m_model);
|
|
||||||
delete tmpModel;
|
void UAVObjectBrowserWidget::updateViewOptions()
|
||||||
|
{
|
||||||
|
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(showCategories);
|
||||||
|
m_model->setShowMetadata(showMetadata);
|
||||||
|
m_model->setUseScientificNotation(useScientificNotation);
|
||||||
|
|
||||||
// force an expand all if search text is not empty
|
// force an expand all if search text is not empty
|
||||||
if (!m_browser->searchLine->text().isEmpty()) {
|
if (!m_browser->searchLine->text().isEmpty()) {
|
||||||
@ -290,8 +296,7 @@ void UAVObjectBrowserWidget::updateViewOptions()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// persist options
|
// persist options
|
||||||
emit viewOptionsChanged(m_viewoptions->cbCategorized->isChecked(), m_viewoptions->cbScientific->isChecked(),
|
emit viewOptionsChanged(showCategories, useScientificNotation, showMetadata, showDesc);
|
||||||
m_viewoptions->cbMetaData->isChecked(), m_viewoptions->cbDescription->isChecked());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UAVObjectBrowserWidget::splitterMoved()
|
void UAVObjectBrowserWidget::splitterMoved()
|
||||||
@ -417,6 +422,68 @@ void UAVObjectBrowserWidget::searchLineChanged(QString searchText)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString UAVObjectBrowserWidget::indexToPath(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
QString path = index.data(Qt::DisplayRole).toString();
|
||||||
|
|
||||||
|
QModelIndex parent = index.parent();
|
||||||
|
|
||||||
|
while (parent.isValid()) {
|
||||||
|
path = parent.data(Qt::DisplayRole).toString() + "/" + path;
|
||||||
|
parent = parent.parent();
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex UAVObjectBrowserWidget::indexFromPath(const QString &path) const
|
||||||
|
{
|
||||||
|
QStringList list = path.split("/");
|
||||||
|
|
||||||
|
QModelIndex index = m_modelProxy->index(0, 0);
|
||||||
|
|
||||||
|
foreach(QString name, list) {
|
||||||
|
QModelIndexList items = m_modelProxy->match(index, Qt::DisplayRole, name, 1, Qt::MatchFlags(Qt::MatchExactly | Qt::MatchRecursive));
|
||||||
|
|
||||||
|
if (!items.isEmpty()) {
|
||||||
|
index = items.first();
|
||||||
|
} else {
|
||||||
|
// bail out
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAVObjectBrowserWidget::saveState(QSettings &settings) const
|
||||||
|
{
|
||||||
|
QStringList list;
|
||||||
|
|
||||||
|
// prepare list
|
||||||
|
foreach(QModelIndex index, m_modelProxy->getPersistentIndexList()) {
|
||||||
|
if (m_browser->treeView->isExpanded(index)) {
|
||||||
|
QString path = indexToPath(index);
|
||||||
|
list << path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// save list
|
||||||
|
settings.setValue("expandedItems", QVariant::fromValue(list));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAVObjectBrowserWidget::restoreState(QSettings &settings)
|
||||||
|
{
|
||||||
|
// get list
|
||||||
|
QStringList list = settings.value("expandedItems").toStringList();
|
||||||
|
|
||||||
|
foreach(QString path, list) {
|
||||||
|
QModelIndex index = indexFromPath(path);
|
||||||
|
|
||||||
|
if (index.isValid()) {
|
||||||
|
m_browser->treeView->setExpanded(index, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UAVObjectBrowserWidget::searchTextCleared()
|
void UAVObjectBrowserWidget::searchTextCleared()
|
||||||
{
|
{
|
||||||
m_browser->searchLine->clear();
|
m_browser->searchLine->clear();
|
||||||
|
@ -46,6 +46,12 @@ class TreeSortFilterProxyModel : public QSortFilterProxyModel {
|
|||||||
public:
|
public:
|
||||||
TreeSortFilterProxyModel(QObject *parent);
|
TreeSortFilterProxyModel(QObject *parent);
|
||||||
|
|
||||||
|
public:
|
||||||
|
QModelIndexList getPersistentIndexList() const
|
||||||
|
{
|
||||||
|
return persistentIndexList();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
|
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
|
||||||
bool filterAcceptsRowItself(int source_row, const QModelIndex &source_parent) const;
|
bool filterAcceptsRowItself(int source_row, const QModelIndex &source_parent) const;
|
||||||
@ -62,7 +68,7 @@ public:
|
|||||||
void setUnknownObjectColor(QColor color)
|
void setUnknownObjectColor(QColor color)
|
||||||
{
|
{
|
||||||
m_unknownObjectColor = color;
|
m_unknownObjectColor = color;
|
||||||
m_model->setUnknowObjectColor(color);
|
m_model->setUnknownObjectColor(color);
|
||||||
}
|
}
|
||||||
void setRecentlyUpdatedColor(QColor color)
|
void setRecentlyUpdatedColor(QColor color)
|
||||||
{
|
{
|
||||||
@ -79,14 +85,20 @@ public:
|
|||||||
m_recentlyUpdatedTimeout = timeout;
|
m_recentlyUpdatedTimeout = timeout;
|
||||||
m_model->setRecentlyUpdatedTimeout(timeout);
|
m_model->setRecentlyUpdatedTimeout(timeout);
|
||||||
}
|
}
|
||||||
void setOnlyHilightChangedValues(bool hilight)
|
void setOnlyHighlightChangedValues(bool highlight)
|
||||||
{
|
{
|
||||||
m_onlyHilightChangedValues = hilight;
|
m_onlyHighlightChangedValues = highlight;
|
||||||
m_model->setOnlyHilightChangedValues(hilight);
|
m_model->setOnlyHighlightChangedValues(highlight);
|
||||||
}
|
}
|
||||||
void setViewOptions(bool categorized, bool scientific, bool metadata, bool description);
|
void setViewOptions(bool showCategories, bool showMetadata, bool useScientificNotation, bool showDescription);
|
||||||
void setSplitterState(QByteArray state);
|
void setSplitterState(QByteArray state);
|
||||||
|
|
||||||
|
void saveState(QSettings &settings) const;
|
||||||
|
void restoreState(QSettings &settings);
|
||||||
|
|
||||||
|
QString indexToPath(const QModelIndex &index) const;
|
||||||
|
QModelIndex indexFromPath(const QString &path) const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void showDescription(bool show);
|
void showDescription(bool show);
|
||||||
|
|
||||||
@ -119,10 +131,12 @@ private:
|
|||||||
QColor m_unknownObjectColor;
|
QColor m_unknownObjectColor;
|
||||||
QColor m_recentlyUpdatedColor;
|
QColor m_recentlyUpdatedColor;
|
||||||
QColor m_manuallyChangedColor;
|
QColor m_manuallyChangedColor;
|
||||||
bool m_onlyHilightChangedValues;
|
bool m_onlyHighlightChangedValues;
|
||||||
QString m_mustacheTemplate;
|
QString m_mustacheTemplate;
|
||||||
|
|
||||||
void updateObjectPersistance(ObjectPersistence::OperationOptions op, UAVObject *obj);
|
UAVObjectTreeModel *createTreeModel();
|
||||||
|
|
||||||
|
void updateObjectPersistence(ObjectPersistence::OperationOptions op, UAVObject *obj);
|
||||||
void enableSendRequest(bool enable);
|
void enableSendRequest(bool enable);
|
||||||
void updateDescription();
|
void updateDescription();
|
||||||
ObjectTreeItem *findCurrentObjectTreeItem();
|
ObjectTreeItem *findCurrentObjectTreeItem();
|
||||||
|
@ -26,169 +26,226 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "uavobjecttreemodel.h"
|
#include "uavobjecttreemodel.h"
|
||||||
|
|
||||||
#include "fieldtreeitem.h"
|
#include "fieldtreeitem.h"
|
||||||
#include "uavobjectmanager.h"
|
#include "uavobjectmanager.h"
|
||||||
#include "uavdataobject.h"
|
#include "uavdataobject.h"
|
||||||
#include "uavmetaobject.h"
|
#include "uavmetaobject.h"
|
||||||
#include "uavobjectfield.h"
|
#include "uavobjectfield.h"
|
||||||
#include "extensionsystem/pluginmanager.h"
|
#include "extensionsystem/pluginmanager.h"
|
||||||
|
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QtCore/QTimer>
|
|
||||||
#include <QtCore/QSignalMapper>
|
|
||||||
#include <QtCore/QDebug>
|
|
||||||
|
|
||||||
UAVObjectTreeModel::UAVObjectTreeModel(QObject *parent, bool categorize, bool showMetadata, bool useScientificNotation) :
|
UAVObjectTreeModel::UAVObjectTreeModel(QObject *parent) : QAbstractItemModel(parent)
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
m_highlightManager = new HighlightManager();
|
||||||
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
|
connect(m_highlightManager, &HighlightManager::updateHighlight, this, &UAVObjectTreeModel::refreshHighlight);
|
||||||
|
|
||||||
Q_ASSERT(objManager);
|
TreeItem::setHighlightTime(recentlyUpdatedTimeout());
|
||||||
|
|
||||||
// Create highlight manager, let it run every 300 ms.
|
setupModelData();
|
||||||
m_highlightManager = new HighLightManager(300);
|
|
||||||
connect(objManager, SIGNAL(newObject(UAVObject *)), this, SLOT(newObject(UAVObject *)));
|
|
||||||
connect(objManager, SIGNAL(newInstance(UAVObject *)), this, SLOT(newObject(UAVObject *)));
|
|
||||||
|
|
||||||
TreeItem::setHighlightTime(m_recentlyUpdatedTimeout);
|
|
||||||
setupModelData(objManager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UAVObjectTreeModel::~UAVObjectTreeModel()
|
UAVObjectTreeModel::~UAVObjectTreeModel()
|
||||||
{
|
{
|
||||||
delete m_highlightManager;
|
|
||||||
delete m_rootItem;
|
delete m_rootItem;
|
||||||
|
delete m_highlightManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UAVObjectTreeModel::setupModelData(UAVObjectManager *objManager)
|
bool UAVObjectTreeModel::showCategories() const
|
||||||
{
|
{
|
||||||
m_settingsTree = new TopTreeItem(tr("Settings"));
|
return m_settings.value("showCategories", false).toBool();
|
||||||
m_settingsTree->setHighlightManager(m_highlightManager);
|
}
|
||||||
connect(m_settingsTree, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *)));
|
|
||||||
|
|
||||||
m_nonSettingsTree = new TopTreeItem(tr("Data Objects"));
|
void UAVObjectTreeModel::setShowCategories(bool show)
|
||||||
m_nonSettingsTree->setHighlightManager(m_highlightManager);
|
{
|
||||||
connect(m_nonSettingsTree, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *)));
|
if (show == showCategories()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_settings.setValue("showCategories", show);
|
||||||
|
toggleCategoryItems();
|
||||||
|
}
|
||||||
|
|
||||||
// root
|
bool UAVObjectTreeModel::showMetadata() const
|
||||||
|
{
|
||||||
|
return m_settings.value("showMetadata", false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAVObjectTreeModel::setShowMetadata(bool show)
|
||||||
|
{
|
||||||
|
if (show == showMetadata()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_settings.setValue("showMetadata", show);
|
||||||
|
toggleMetaItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAVObjectTreeModel::useScientificNotation()
|
||||||
|
{
|
||||||
|
return m_settings.value("useScientificNotation", false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
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", 300).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);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UAVObjectTreeModel::highlightTopTreeItems() const
|
||||||
|
{
|
||||||
|
return m_settings.value("highlightTopTreeItems", false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAVObjectTreeModel::setHighlightTopTreeItems(bool highlight)
|
||||||
|
{
|
||||||
|
m_settings.setValue("highlightTopTreeItems", highlight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAVObjectTreeModel::setupModelData()
|
||||||
|
{
|
||||||
QList<QVariant> rootData;
|
QList<QVariant> rootData;
|
||||||
rootData << tr("Property") << tr("Value") << tr("Unit");
|
rootData << tr("Property") << tr("Value") << tr("Unit");
|
||||||
m_rootItem = new TreeItem(rootData);
|
m_rootItem = new TreeItem(rootData);
|
||||||
m_rootItem->setHighlightManager(m_highlightManager);
|
m_rootItem->setHighlightManager(m_highlightManager);
|
||||||
|
|
||||||
// tree item takes ownership of its children
|
m_settingsTree = new TopTreeItem(tr("Settings"));
|
||||||
m_rootItem->appendChild(m_settingsTree);
|
m_settingsTree->setHighlightManager(m_highlightManager);
|
||||||
m_rootItem->appendChild(m_nonSettingsTree);
|
|
||||||
|
m_nonSettingsTree = new TopTreeItem(tr("Data Objects"));
|
||||||
|
m_nonSettingsTree->setHighlightManager(m_highlightManager);
|
||||||
|
|
||||||
|
// 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, &UAVObjectTreeModel::newObject, Qt::UniqueConnection);
|
||||||
|
connect(objManager, &UAVObjectManager::newInstance, this, &UAVObjectTreeModel::newObject, Qt::UniqueConnection);
|
||||||
|
|
||||||
QList< QList<UAVDataObject *> > objList = objManager->getDataObjects();
|
QList< QList<UAVDataObject *> > objList = objManager->getDataObjects();
|
||||||
foreach(QList<UAVDataObject *> list, objList) {
|
foreach(QList<UAVDataObject *> list, objList) {
|
||||||
foreach(UAVDataObject * obj, list) {
|
foreach(UAVDataObject * obj, list) {
|
||||||
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)
|
void UAVObjectTreeModel::newObject(UAVObject *obj)
|
||||||
{
|
{
|
||||||
UAVDataObject *dobj = qobject_cast<UAVDataObject *>(obj);
|
UAVDataObject *dataObj = qobject_cast<UAVDataObject *>(obj);
|
||||||
|
|
||||||
if (dobj) {
|
if (dataObj) {
|
||||||
addDataObject(dobj);
|
addObject(dataObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UAVObjectTreeModel::addDataObject(UAVDataObject *obj)
|
void UAVObjectTreeModel::addObject(UAVDataObject *obj)
|
||||||
{
|
{
|
||||||
TopTreeItem *root = obj->isSettingsObject() ? m_settingsTree : m_nonSettingsTree;
|
connect(obj, &UAVDataObject::objectUpdated, this, &UAVObjectTreeModel::updateObject, Qt::UniqueConnection);
|
||||||
|
connect(obj, &UAVDataObject::isKnownChanged, this, &UAVObjectTreeModel::updateIsKnown, Qt::UniqueConnection);
|
||||||
TreeItem *parent = root;
|
if (obj->getInstID() == 0) {
|
||||||
|
UAVMetaObject *metaObj = obj->getMetaObject();
|
||||||
if (m_categorize && obj->getCategory() != 0 && !obj->getCategory().isEmpty()) {
|
connect(metaObj, &UAVDataObject::objectUpdated, this, &UAVObjectTreeModel::updateObject, Qt::UniqueConnection);
|
||||||
QStringList categoryPath = obj->getCategory().split('/');
|
|
||||||
parent = createCategoryItems(categoryPath, root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectTreeItem *existing = root->findDataObjectTreeItemByObjectId(obj->getObjID());
|
|
||||||
if (existing) {
|
|
||||||
addInstance(obj, existing);
|
|
||||||
} else {
|
|
||||||
DataObjectTreeItem *dataTreeItem = new DataObjectTreeItem(obj->getName(), obj);
|
|
||||||
dataTreeItem->setHighlightManager(m_highlightManager);
|
|
||||||
connect(dataTreeItem, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *)));
|
|
||||||
connect(dataTreeItem, SIGNAL(updateIsKnown(TreeItem *)), this, SLOT(updateIsKnown(TreeItem *)));
|
|
||||||
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);
|
|
||||||
connect(categoryItem, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *)));
|
|
||||||
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(highlightUpdatedObject(UAVObject *)));
|
|
||||||
MetaObjectTreeItem *meta = new MetaObjectTreeItem(obj, tr("Meta Data"));
|
|
||||||
|
|
||||||
meta->setHighlightManager(m_highlightManager);
|
|
||||||
connect(meta, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *)));
|
|
||||||
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(highlightUpdatedObject(UAVObject *)));
|
|
||||||
connect(obj, SIGNAL(isKnownChanged(UAVObject *, bool)), this, SLOT(isKnownChanged(UAVObject *, bool)));
|
|
||||||
TreeItem *item;
|
|
||||||
if (obj->isSingleInstance()) {
|
if (obj->isSingleInstance()) {
|
||||||
item = parent;
|
DataObjectTreeItem *dataObjectItem = createDataObject(obj);
|
||||||
DataObjectTreeItem *objectItem = static_cast<DataObjectTreeItem *>(parent);
|
TreeItem *parentItem = getParentItem(obj, showCategories());
|
||||||
connect(objectItem, SIGNAL(updateIsKnown(TreeItem *)), this, SLOT(updateIsKnown(TreeItem *)));
|
insertItem(parentItem, dataObjectItem);
|
||||||
} else {
|
} else {
|
||||||
QString name = tr("Instance") + " " + QString::number(obj->getInstID());
|
TreeItem *dataObjectItem;
|
||||||
item = new InstanceTreeItem(obj, name);
|
if (obj->getInstID() == 0) {
|
||||||
item->setHighlightManager(m_highlightManager);
|
dataObjectItem = createDataObject(obj);
|
||||||
connect(item, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *)));
|
TreeItem *parentItem = getParentItem(obj, showCategories());
|
||||||
connect(item, SIGNAL(updateIsKnown(TreeItem *)), this, SLOT(updateIsKnown(TreeItem *)));
|
insertItem(parentItem, dataObjectItem);
|
||||||
parent->appendChild(item);
|
} 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);
|
||||||
|
|
||||||
|
// metadata items are created up front and are added/removed as needed
|
||||||
|
// see toggleMetaItems()
|
||||||
|
MetaObjectTreeItem *metaItem = createMetaObject(obj->getMetaObject());
|
||||||
|
if (showMetadata()) {
|
||||||
|
appendItem(item, metaItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->isSingleInstance()) {
|
||||||
foreach(UAVObjectField * field, obj->getFields()) {
|
foreach(UAVObjectField * field, obj->getFields()) {
|
||||||
if (field->getNumElements() > 1) {
|
if (field->getNumElements() > 1) {
|
||||||
addArrayField(field, item);
|
addArrayField(field, item);
|
||||||
@ -196,6 +253,71 @@ void UAVObjectTreeModel::addInstance(UAVObject *obj, TreeItem *parent)
|
|||||||
addSingleField(0, field, item);
|
addSingleField(0, field, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstanceTreeItem *UAVObjectTreeModel::createDataObjectInstance(UAVDataObject *obj)
|
||||||
|
{
|
||||||
|
QString name = obj->getName() + " " + QString::number((int)obj->getInstID());
|
||||||
|
InstanceTreeItem *item = new InstanceTreeItem(obj, name);
|
||||||
|
|
||||||
|
item->setHighlightManager(m_highlightManager);
|
||||||
|
|
||||||
|
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) {
|
||||||
|
// metadata items are created and destroyed as needed
|
||||||
|
// see toggleCategoryItems()
|
||||||
|
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)
|
void UAVObjectTreeModel::addArrayField(UAVObjectField *field, TreeItem *parent)
|
||||||
@ -203,21 +325,21 @@ void UAVObjectTreeModel::addArrayField(UAVObjectField *field, TreeItem *parent)
|
|||||||
TreeItem *item = new ArrayFieldTreeItem(field, field->getName());
|
TreeItem *item = new ArrayFieldTreeItem(field, field->getName());
|
||||||
|
|
||||||
item->setHighlightManager(m_highlightManager);
|
item->setHighlightManager(m_highlightManager);
|
||||||
connect(item, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *)));
|
|
||||||
connect(item, SIGNAL(updateIsKnown(TreeItem *)), this, SLOT(updateIsKnown(TreeItem *)));
|
appendItem(parent, item);
|
||||||
for (uint i = 0; i < field->getNumElements(); ++i) {
|
|
||||||
|
for (int i = 0; i < (int)field->getNumElements(); ++i) {
|
||||||
addSingleField(i, field, item);
|
addSingleField(i, field, item);
|
||||||
}
|
}
|
||||||
parent->appendChild(item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UAVObjectTreeModel::addSingleField(int index, UAVObjectField *field, TreeItem *parent)
|
void UAVObjectTreeModel::addSingleField(int i, UAVObjectField *field, TreeItem *parent)
|
||||||
{
|
{
|
||||||
QList<QVariant> data;
|
QList<QVariant> data;
|
||||||
if (field->getNumElements() == 1) {
|
if (field->getNumElements() == 1) {
|
||||||
data.append(field->getName());
|
data.append(field->getName());
|
||||||
} else {
|
} else {
|
||||||
data.append(QString("[%1]").arg((field->getElementNames())[index]));
|
data.append(QString("[%1]").arg((field->getElementNames())[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldTreeItem *item = NULL;
|
FieldTreeItem *item = NULL;
|
||||||
@ -227,10 +349,10 @@ void UAVObjectTreeModel::addSingleField(int index, UAVObjectField *field, TreeIt
|
|||||||
case UAVObjectField::ENUM:
|
case UAVObjectField::ENUM:
|
||||||
{
|
{
|
||||||
QStringList options = field->getOptions();
|
QStringList options = field->getOptions();
|
||||||
QVariant value = field->getValue(index);
|
QVariant value = field->getValue(i);
|
||||||
data.append(options.indexOf(value.toString()));
|
data.append(options.indexOf(value.toString()));
|
||||||
data.append(field->getUnits());
|
data.append(field->getUnits());
|
||||||
item = new EnumFieldTreeItem(field, index, data);
|
item = new EnumFieldTreeItem(field, i, data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UAVObjectField::INT8:
|
case UAVObjectField::INT8:
|
||||||
@ -239,29 +361,113 @@ void UAVObjectTreeModel::addSingleField(int index, UAVObjectField *field, TreeIt
|
|||||||
case UAVObjectField::UINT8:
|
case UAVObjectField::UINT8:
|
||||||
case UAVObjectField::UINT16:
|
case UAVObjectField::UINT16:
|
||||||
case UAVObjectField::UINT32:
|
case UAVObjectField::UINT32:
|
||||||
data.append(field->getValue(index));
|
data.append(field->getValue(i));
|
||||||
data.append(field->getUnits());
|
data.append(field->getUnits());
|
||||||
if (field->getUnits().toLower() == "hex") {
|
if (field->getUnits().toLower() == "hex") {
|
||||||
item = new HexFieldTreeItem(field, index, data);
|
item = new HexFieldTreeItem(field, i, data);
|
||||||
} else if (field->getUnits().toLower() == "char") {
|
} else if (field->getUnits().toLower() == "char") {
|
||||||
item = new CharFieldTreeItem(field, index, data);
|
item = new CharFieldTreeItem(field, i, data);
|
||||||
} else {
|
} else {
|
||||||
item = new IntFieldTreeItem(field, index, data);
|
item = new IntFieldTreeItem(field, i, data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UAVObjectField::FLOAT32:
|
case UAVObjectField::FLOAT32:
|
||||||
data.append(field->getValue(index));
|
data.append(field->getValue(i));
|
||||||
data.append(field->getUnits());
|
data.append(field->getUnits());
|
||||||
item = new FloatFieldTreeItem(field, index, data, m_useScientificFloatNotation);
|
item = new FloatFieldTreeItem(field, i, data, m_settings);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
item->setHighlightManager(m_highlightManager);
|
item->setHighlightManager(m_highlightManager);
|
||||||
item->setDescription(field->getDescription());
|
item->setDescription(field->getDescription());
|
||||||
connect(item, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *)));
|
|
||||||
connect(item, SIGNAL(updateIsKnown(TreeItem *)), this, SLOT(updateIsKnown(TreeItem *)));
|
appendItem(parent, item);
|
||||||
parent->appendChild(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
|
QModelIndex UAVObjectTreeModel::index(int row, int column, const QModelIndex &parent) const
|
||||||
@ -271,38 +477,26 @@ QModelIndex UAVObjectTreeModel::index(int row, int column, const QModelIndex &pa
|
|||||||
}
|
}
|
||||||
|
|
||||||
TreeItem *parentItem;
|
TreeItem *parentItem;
|
||||||
|
|
||||||
if (!parent.isValid()) {
|
if (!parent.isValid()) {
|
||||||
parentItem = m_rootItem;
|
parentItem = m_rootItem;
|
||||||
} else {
|
} else {
|
||||||
parentItem = static_cast<TreeItem *>(parent.internalPointer());
|
parentItem = static_cast<TreeItem *>(parent.internalPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeItem *childItem = parentItem->getChild(row);
|
TreeItem *childItem = parentItem->child(row);
|
||||||
if (childItem) {
|
if (childItem) {
|
||||||
return createIndex(row, column, childItem);
|
return createIndex(row, column, childItem);
|
||||||
} else {
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
}
|
||||||
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex UAVObjectTreeModel::index(TreeItem *item)
|
QModelIndex UAVObjectTreeModel::index(TreeItem *item, int column) const
|
||||||
{
|
{
|
||||||
if (item->parent() == 0) {
|
if (item == m_rootItem) {
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex root = index(item->parent());
|
return createIndex(item->row(), column, item);
|
||||||
|
|
||||||
for (int i = 0; i < rowCount(root); ++i) {
|
|
||||||
QModelIndex childIndex = index(i, 0, root);
|
|
||||||
TreeItem *child = static_cast<TreeItem *>(childIndex.internalPointer());
|
|
||||||
if (child == item) {
|
|
||||||
return childIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Q_ASSERT(false);
|
|
||||||
return QModelIndex();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex UAVObjectTreeModel::parent(const QModelIndex &index) const
|
QModelIndex UAVObjectTreeModel::parent(const QModelIndex &index) const
|
||||||
@ -311,11 +505,14 @@ QModelIndex UAVObjectTreeModel::parent(const QModelIndex &index) const
|
|||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeItem *item = static_cast<TreeItem *>(index.internalPointer());
|
TreeItem *childItem = static_cast<TreeItem *>(index.internalPointer());
|
||||||
|
TreeItem *parentItem = childItem->parentItem();
|
||||||
|
|
||||||
TreeItem *parentItem = item->parent();
|
|
||||||
if (!parentItem) {
|
if (!parentItem) {
|
||||||
// item is root has no parent...
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parentItem == m_rootItem) {
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,24 +538,15 @@ int UAVObjectTreeModel::rowCount(const QModelIndex &parent) const
|
|||||||
|
|
||||||
int UAVObjectTreeModel::columnCount(const QModelIndex &parent) const
|
int UAVObjectTreeModel::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
|
TreeItem *parentItem;
|
||||||
|
|
||||||
if (parent.isValid()) {
|
if (parent.isValid()) {
|
||||||
return static_cast<TreeItem *>(parent.internalPointer())->columnCount();
|
parentItem = static_cast<TreeItem *>(parent.internalPointer());
|
||||||
} else {
|
} else {
|
||||||
return m_rootItem->columnCount();
|
parentItem = m_rootItem;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QModelIndex> UAVObjectTreeModel::getMetaDataIndexes()
|
|
||||||
{
|
|
||||||
QList<QModelIndex> metaIndexes;
|
|
||||||
foreach(MetaObjectTreeItem * metaItem, m_settingsTree->getMetaObjectItems()) {
|
|
||||||
metaIndexes.append(index(metaItem));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(MetaObjectTreeItem * metaItem, m_nonSettingsTree->getMetaObjectItems()) {
|
return parentItem->columnCount();
|
||||||
metaIndexes.append(index(metaItem));
|
|
||||||
}
|
|
||||||
return metaIndexes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant UAVObjectTreeModel::data(const QModelIndex &index, int role) const
|
QVariant UAVObjectTreeModel::data(const QModelIndex &index, int role) const
|
||||||
@ -391,22 +579,26 @@ QVariant UAVObjectTreeModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
case Qt::ForegroundRole:
|
case Qt::ForegroundRole:
|
||||||
if (!dynamic_cast<TopTreeItem *>(item) && !item->isKnown()) {
|
if (!dynamic_cast<TopTreeItem *>(item) && !item->isKnown()) {
|
||||||
return m_unknownObjectColor;
|
return unknownObjectColor();
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
case Qt::BackgroundRole:
|
case Qt::BackgroundRole:
|
||||||
if (index.column() == TreeItem::TITLE_COLUMN) {
|
if (index.column() == TreeItem::TITLE_COLUMN) {
|
||||||
if (!dynamic_cast<TopTreeItem *>(item) && item->highlighted()) {
|
// TODO filtering here on highlightTopTreeItems() should not be necessary
|
||||||
return m_recentlyUpdatedColor;
|
// top tree items should not be highlighted at all in the first place
|
||||||
|
// when highlightTopTreeItems() is false
|
||||||
|
bool highlight = (highlightTopTreeItems() || !dynamic_cast<TopTreeItem *>(item));
|
||||||
|
if (highlight && item->isHighlighted()) {
|
||||||
|
return recentlyUpdatedColor();
|
||||||
}
|
}
|
||||||
} else if (index.column() == TreeItem::DATA_COLUMN) {
|
} else if (index.column() == TreeItem::DATA_COLUMN) {
|
||||||
FieldTreeItem *fieldItem = dynamic_cast<FieldTreeItem *>(item);
|
FieldTreeItem *fieldItem = dynamic_cast<FieldTreeItem *>(item);
|
||||||
if (fieldItem && fieldItem->highlighted()) {
|
if (fieldItem && fieldItem->isHighlighted()) {
|
||||||
return m_recentlyUpdatedColor;
|
return recentlyUpdatedColor();
|
||||||
}
|
}
|
||||||
if (fieldItem && fieldItem->changed()) {
|
if (fieldItem && fieldItem->changed()) {
|
||||||
return m_manuallyChangedColor;
|
return manuallyChangedColor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@ -423,13 +615,12 @@ QVariant UAVObjectTreeModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
bool UAVObjectTreeModel::setData(const QModelIndex &index, const QVariant & value, int role)
|
bool UAVObjectTreeModel::setData(const QModelIndex &index, const QVariant & value, int role)
|
||||||
{
|
{
|
||||||
Q_UNUSED(role)
|
Q_UNUSED(role);
|
||||||
TreeItem * item = static_cast<TreeItem *>(index.internalPointer());
|
TreeItem *item = static_cast<TreeItem *>(index.internalPointer());
|
||||||
item->setData(value, index.column());
|
item->setData(value, index.column());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Qt::ItemFlags UAVObjectTreeModel::flags(const QModelIndex &index) const
|
Qt::ItemFlags UAVObjectTreeModel::flags(const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
if (!index.isValid()) {
|
if (!index.isValid()) {
|
||||||
@ -452,77 +643,83 @@ QVariant UAVObjectTreeModel::headerData(int section, Qt::Orientation orientation
|
|||||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||||
return m_rootItem->data(section);
|
return m_rootItem->data(section);
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UAVObjectTreeModel::highlightUpdatedObject(UAVObject *obj)
|
void UAVObjectTreeModel::updateObject(UAVObject *obj)
|
||||||
{
|
{
|
||||||
Q_ASSERT(obj);
|
Q_ASSERT(obj);
|
||||||
ObjectTreeItem *item = findObjectTreeItem(obj);
|
ObjectTreeItem *item = findObjectTreeItem(obj->getObjID());
|
||||||
Q_ASSERT(item);
|
Q_ASSERT(item);
|
||||||
if (!m_onlyHilightChangedValues) {
|
// TODO don't update meta object if they are not shown
|
||||||
item->setHighlight(true);
|
QTime ts = QTime::currentTime();
|
||||||
|
item->update(ts);
|
||||||
|
if (!onlyHighlightChangedValues()) {
|
||||||
|
item->setHighlighted(true, ts);
|
||||||
}
|
}
|
||||||
item->update();
|
}
|
||||||
if (!m_onlyHilightChangedValues) {
|
|
||||||
QModelIndex itemIndex = index(item);
|
void UAVObjectTreeModel::updateIsKnown(UAVObject *object)
|
||||||
|
{
|
||||||
|
DataObjectTreeItem *item = findDataObjectTreeItem(object);
|
||||||
|
|
||||||
|
if (item) {
|
||||||
|
refreshIsKnown(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 caused by the sort/filter proxy...
|
||||||
|
|
||||||
|
QModelIndex itemIndex;
|
||||||
|
|
||||||
|
itemIndex = index(item, TreeItem::TITLE_COLUMN);
|
||||||
Q_ASSERT(itemIndex != QModelIndex());
|
Q_ASSERT(itemIndex != QModelIndex());
|
||||||
emit dataChanged(itemIndex, itemIndex);
|
emit dataChanged(itemIndex, itemIndex);
|
||||||
|
|
||||||
|
itemIndex = index(item, TreeItem::DATA_COLUMN);
|
||||||
|
Q_ASSERT(itemIndex != QModelIndex());
|
||||||
|
emit dataChanged(itemIndex, itemIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UAVObjectTreeModel::refreshIsKnown(TreeItem *item)
|
||||||
|
{
|
||||||
|
QModelIndex itemIndex;
|
||||||
|
|
||||||
|
itemIndex = index(item, TreeItem::TITLE_COLUMN);
|
||||||
|
Q_ASSERT(itemIndex != QModelIndex());
|
||||||
|
emit dataChanged(itemIndex, itemIndex);
|
||||||
|
|
||||||
|
foreach(TreeItem * child, item->children()) {
|
||||||
|
refreshIsKnown(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectTreeItem *UAVObjectTreeModel::findObjectTreeItem(UAVObject *object)
|
void UAVObjectTreeModel::addObjectTreeItem(quint32 objectId, ObjectTreeItem *oti)
|
||||||
{
|
{
|
||||||
UAVDataObject *dataObject = qobject_cast<UAVDataObject *>(object);
|
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);
|
UAVMetaObject *metaObject = qobject_cast<UAVMetaObject *>(object);
|
||||||
|
|
||||||
Q_ASSERT(dataObject || metaObject);
|
if (metaObject) {
|
||||||
if (dataObject) {
|
dataObject = qobject_cast<UAVDataObject *>(metaObject->getParentObject());
|
||||||
return findDataObjectTreeItem(dataObject);
|
|
||||||
} else {
|
} else {
|
||||||
return findMetaObjectTreeItem(metaObject);
|
dataObject = qobject_cast<UAVDataObject *>(object);
|
||||||
}
|
}
|
||||||
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);
|
Q_ASSERT(dataObject);
|
||||||
TopTreeItem *root = dataObject->isSettingsObject() ? m_settingsTree : m_nonSettingsTree;
|
return static_cast<DataObjectTreeItem *>(findObjectTreeItem(dataObject->getObjID()));
|
||||||
return root->findMetaObjectTreeItemByObjectId(obj->getObjID());
|
|
||||||
}
|
|
||||||
|
|
||||||
void UAVObjectTreeModel::updateHighlight(TreeItem *item)
|
|
||||||
{
|
|
||||||
QModelIndex itemIndex = index(item);
|
|
||||||
|
|
||||||
Q_ASSERT(itemIndex != QModelIndex());
|
|
||||||
emit dataChanged(itemIndex, itemIndex.sibling(itemIndex.row(), TreeItem::DATA_COLUMN));
|
|
||||||
}
|
|
||||||
|
|
||||||
void UAVObjectTreeModel::updateIsKnown(TreeItem *item)
|
|
||||||
{
|
|
||||||
QModelIndex itemIndex = index(item);
|
|
||||||
|
|
||||||
Q_ASSERT(itemIndex != QModelIndex());
|
|
||||||
emit dataChanged(itemIndex, itemIndex.sibling(itemIndex.row(), TreeItem::TITLE_COLUMN));
|
|
||||||
}
|
|
||||||
|
|
||||||
void UAVObjectTreeModel::isKnownChanged(UAVObject *object, bool isKnown)
|
|
||||||
{
|
|
||||||
Q_UNUSED(isKnown);
|
|
||||||
ObjectTreeItem *item = findObjectTreeItem(object);
|
|
||||||
if (item) {
|
|
||||||
item->updateIsKnown(isKnown);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,12 @@
|
|||||||
#define UAVOBJECTTREEMODEL_H
|
#define UAVOBJECTTREEMODEL_H
|
||||||
|
|
||||||
#include "treeitem.h"
|
#include "treeitem.h"
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
#include <QtCore/QMap>
|
#include <QMap>
|
||||||
#include <QtCore/QList>
|
#include <QList>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
class TopTreeItem;
|
class TopTreeItem;
|
||||||
class ObjectTreeItem;
|
class ObjectTreeItem;
|
||||||
@ -48,8 +50,7 @@ class QTimer;
|
|||||||
class UAVObjectTreeModel : public QAbstractItemModel {
|
class UAVObjectTreeModel : public QAbstractItemModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit UAVObjectTreeModel(QObject *parent, bool categorize, bool showMetadata, bool useScientificNotation);
|
explicit UAVObjectTreeModel(QObject *parent);
|
||||||
explicit UAVObjectTreeModel(bool categorize, bool showMetadata, bool useScientificNotation);
|
|
||||||
~UAVObjectTreeModel();
|
~UAVObjectTreeModel();
|
||||||
|
|
||||||
QVariant data(const QModelIndex &index, int role) const;
|
QVariant data(const QModelIndex &index, int role) const;
|
||||||
@ -63,71 +64,77 @@ public:
|
|||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
|
||||||
void setUnknowObjectColor(QColor color)
|
bool showCategories() const;
|
||||||
{
|
void setShowCategories(bool show);
|
||||||
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 setOnlyHilightChangedValues(bool hilight)
|
|
||||||
{
|
|
||||||
m_onlyHilightChangedValues = hilight;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QModelIndex> getMetaDataIndexes();
|
bool showMetadata() const;
|
||||||
|
void setShowMetadata(bool show);
|
||||||
|
|
||||||
signals:
|
bool useScientificNotation();
|
||||||
|
void setUseScientificNotation(bool useScientificNotation);
|
||||||
|
|
||||||
public slots:
|
QColor unknownObjectColor() const;
|
||||||
void newObject(UAVObject *obj);
|
void setUnknownObjectColor(QColor color);
|
||||||
|
|
||||||
|
QColor recentlyUpdatedColor() const;
|
||||||
|
void setRecentlyUpdatedColor(QColor color);
|
||||||
|
|
||||||
|
QColor manuallyChangedColor() const;
|
||||||
|
void setManuallyChangedColor(QColor color);
|
||||||
|
|
||||||
|
int recentlyUpdatedTimeout() const;
|
||||||
|
void setRecentlyUpdatedTimeout(int timeout);
|
||||||
|
|
||||||
|
bool onlyHighlightChangedValues() const;
|
||||||
|
void setOnlyHighlightChangedValues(bool highlight);
|
||||||
|
|
||||||
|
bool highlightTopTreeItems() const;
|
||||||
|
void setHighlightTopTreeItems(bool highlight);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void updateHighlight(TreeItem *item);
|
void newObject(UAVObject *obj);
|
||||||
void updateIsKnown(TreeItem *item);
|
void updateObject(UAVObject *obj);
|
||||||
void highlightUpdatedObject(UAVObject *obj);
|
void updateIsKnown(UAVObject *obj);
|
||||||
void isKnownChanged(UAVObject *object, bool isKnown);
|
void refreshHighlight(TreeItem *item);
|
||||||
|
void refreshIsKnown(TreeItem *item);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupModelData(UAVObjectManager *objManager);
|
QSettings m_settings;
|
||||||
QModelIndex index(TreeItem *item);
|
|
||||||
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);
|
|
||||||
|
|
||||||
TreeItem *createCategoryItems(QStringList categoryPath, TreeItem *root);
|
HighlightManager *m_highlightManager;
|
||||||
|
|
||||||
QString updateMode(quint8 updateMode);
|
|
||||||
ObjectTreeItem *findObjectTreeItem(UAVObject *obj);
|
|
||||||
DataObjectTreeItem *findDataObjectTreeItem(UAVDataObject *obj);
|
|
||||||
MetaObjectTreeItem *findMetaObjectTreeItem(UAVMetaObject *obj);
|
|
||||||
|
|
||||||
TreeItem *m_rootItem;
|
TreeItem *m_rootItem;
|
||||||
TopTreeItem *m_settingsTree;
|
TopTreeItem *m_settingsTree;
|
||||||
TopTreeItem *m_nonSettingsTree;
|
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_onlyHilightChangedValues;
|
|
||||||
|
|
||||||
// Highlight manager to handle highlighting of tree items.
|
QHash<quint32, ObjectTreeItem *> m_objectTreeItems;
|
||||||
HighLightManager *m_highlightManager;
|
|
||||||
|
QModelIndex index(TreeItem *item, int column = 0) const;
|
||||||
|
|
||||||
|
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
|
#endif // UAVOBJECTTREEMODEL_H
|
||||||
|
@ -622,7 +622,7 @@ void UAVObject::setIsKnown(bool isKnown)
|
|||||||
unlock();
|
unlock();
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
emit isKnownChanged(this, isKnown);
|
emit isKnownChanged(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ signals:
|
|||||||
void updateRequested(UAVObject *obj, bool all = false);
|
void updateRequested(UAVObject *obj, bool all = false);
|
||||||
void transactionCompleted(UAVObject *obj, bool success);
|
void transactionCompleted(UAVObject *obj, bool success);
|
||||||
void newInstance(UAVObject *obj);
|
void newInstance(UAVObject *obj);
|
||||||
void isKnownChanged(UAVObject *obj, bool isKnown);
|
void isKnownChanged(UAVObject *obj);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
quint32 objID;
|
quint32 objID;
|
||||||
|
@ -79,7 +79,7 @@ Telemetry::~Telemetry()
|
|||||||
closeAllTransactions();
|
closeAllTransactions();
|
||||||
foreach(QList<UAVObject *> instances, objMngr->getObjects()) {
|
foreach(QList<UAVObject *> instances, objMngr->getObjects()) {
|
||||||
foreach(UAVObject * object, instances) {
|
foreach(UAVObject * object, instances) {
|
||||||
// make sure we 'forget' all objects before we request it from the flight side
|
// 'forget' all objects
|
||||||
object->setIsKnown(false);
|
object->setIsKnown(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,9 +244,8 @@ void Telemetry::transactionCompleted(UAVObject *obj, bool success)
|
|||||||
|
|
||||||
if (transInfo) {
|
if (transInfo) {
|
||||||
if (success) {
|
if (success) {
|
||||||
// We now know tat the flight side knows of this object.
|
// We now know that the flight side knows of this object.
|
||||||
obj->setIsKnown(true);
|
obj->setIsKnown(true);
|
||||||
|
|
||||||
#ifdef VERBOSE_TELEMETRY
|
#ifdef VERBOSE_TELEMETRY
|
||||||
qDebug() << "Telemetry - transaction successful for object" << obj->toStringBrief();
|
qDebug() << "Telemetry - transaction successful for object" << obj->toStringBrief();
|
||||||
#endif
|
#endif
|
||||||
|
@ -365,7 +365,7 @@ bool UAVTalk::processInputByte(quint8 rxbyte)
|
|||||||
{
|
{
|
||||||
UAVObject *rxObj = objMngr->getObject(rxObjId);
|
UAVObject *rxObj = objMngr->getObject(rxObjId);
|
||||||
if (rxObj == NULL && rxType != TYPE_OBJ_REQ) {
|
if (rxObj == NULL && rxType != TYPE_OBJ_REQ) {
|
||||||
qWarning() << "UAVTalk - error : unknown object" << rxObjId;
|
qWarning().noquote() << "UAVTalk - error : unknown object" << QString::number(rxObjId, 16).toUpper();
|
||||||
stats.rxErrors++;
|
stats.rxErrors++;
|
||||||
rxState = STATE_ERROR;
|
rxState = STATE_ERROR;
|
||||||
break;
|
break;
|
||||||
@ -385,7 +385,7 @@ bool UAVTalk::processInputByte(quint8 rxbyte)
|
|||||||
// Check length and determine next state
|
// Check length and determine next state
|
||||||
if (rxLength >= MAX_PAYLOAD_LENGTH) {
|
if (rxLength >= MAX_PAYLOAD_LENGTH) {
|
||||||
// packet error - exceeded payload max length
|
// packet error - exceeded payload max length
|
||||||
qWarning() << "UAVTalk - error : exceeded payload max length" << rxObjId;
|
qWarning().noquote() << "UAVTalk - error : exceeded payload max length" << QString::number(rxObjId, 16).toUpper();
|
||||||
stats.rxErrors++;
|
stats.rxErrors++;
|
||||||
rxState = STATE_ERROR;
|
rxState = STATE_ERROR;
|
||||||
break;
|
break;
|
||||||
@ -394,7 +394,7 @@ bool UAVTalk::processInputByte(quint8 rxbyte)
|
|||||||
// Check the lengths match
|
// Check the lengths match
|
||||||
if ((rxPacketLength + rxLength) != packetSize) {
|
if ((rxPacketLength + rxLength) != packetSize) {
|
||||||
// packet error - mismatched packet size
|
// packet error - mismatched packet size
|
||||||
qWarning() << "UAVTalk - error : mismatched packet size" << rxObjId;
|
qWarning().noquote() << "UAVTalk - error : mismatched packet size" << QString::number(rxObjId, 16).toUpper();
|
||||||
stats.rxErrors++;
|
stats.rxErrors++;
|
||||||
rxState = STATE_ERROR;
|
rxState = STATE_ERROR;
|
||||||
break;
|
break;
|
||||||
@ -430,7 +430,7 @@ bool UAVTalk::processInputByte(quint8 rxbyte)
|
|||||||
|
|
||||||
if (rxCS != rxCSPacket) {
|
if (rxCS != rxCSPacket) {
|
||||||
// packet error - faulty CRC
|
// packet error - faulty CRC
|
||||||
qWarning() << "UAVTalk - error : failed CRC check" << rxObjId;
|
qWarning().noquote() << "UAVTalk - error : failed CRC check" << QString::number(rxObjId, 16).toUpper();
|
||||||
stats.rxCrcErrors++;
|
stats.rxCrcErrors++;
|
||||||
rxState = STATE_ERROR;
|
rxState = STATE_ERROR;
|
||||||
break;
|
break;
|
||||||
@ -438,7 +438,7 @@ bool UAVTalk::processInputByte(quint8 rxbyte)
|
|||||||
|
|
||||||
if (rxPacketLength != packetSize + CHECKSUM_LENGTH) {
|
if (rxPacketLength != packetSize + CHECKSUM_LENGTH) {
|
||||||
// packet error - mismatched packet size
|
// packet error - mismatched packet size
|
||||||
qWarning() << "UAVTalk - error : mismatched packet size" << rxObjId;
|
qWarning().noquote() << "UAVTalk - error : mismatched packet size" << QString::number(rxObjId, 16).toUpper();
|
||||||
stats.rxErrors++;
|
stats.rxErrors++;
|
||||||
rxState = STATE_ERROR;
|
rxState = STATE_ERROR;
|
||||||
break;
|
break;
|
||||||
|
@ -2780,7 +2780,7 @@
|
|||||||
<manuallyChangedColor>#5baa56</manuallyChangedColor>
|
<manuallyChangedColor>#5baa56</manuallyChangedColor>
|
||||||
<onlyHilightChangedValues>false</onlyHilightChangedValues>
|
<onlyHilightChangedValues>false</onlyHilightChangedValues>
|
||||||
<recentlyUpdatedColor>#ff7957</recentlyUpdatedColor>
|
<recentlyUpdatedColor>#ff7957</recentlyUpdatedColor>
|
||||||
<recentlyUpdatedTimeout>500</recentlyUpdatedTimeout>
|
<recentlyUpdatedTimeout>300</recentlyUpdatedTimeout>
|
||||||
<showMetaData>false</showMetaData>
|
<showMetaData>false</showMetaData>
|
||||||
</data>
|
</data>
|
||||||
</default>
|
</default>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user