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

OP-9 GCS/uavobjectbrowser: Individualize highlights. Clean build may be required.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@503 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
ephy 2010-04-15 15:42:47 +00:00 committed by ephy
parent 412fb3abc3
commit 44176370de
4 changed files with 157 additions and 104 deletions

View File

@ -27,20 +27,26 @@
#include "treeitem.h"
int TreeItem::m_highlightTimeMs = 500;
TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parent) :
QObject(0),
m_data(data),
m_parent(parent),
m_highlight(false),
m_changed(false)
{
connect(&m_timer, SIGNAL(timeout()), this, SLOT(removeHighlight()));
}
TreeItem::TreeItem(const QVariant &data, TreeItem *parent) :
QObject(0),
m_parent(parent),
m_highlight(false),
m_changed(false)
{
m_data << data << "" << "";
connect(&m_timer, SIGNAL(timeout()), this, SLOT(removeHighlight()));
}
TreeItem::~TreeItem()
@ -51,13 +57,13 @@ TreeItem::~TreeItem()
void TreeItem::appendChild(TreeItem *child)
{
m_children.append(child);
child->setParent(this);
child->setParentTree(this);
}
void TreeItem::insert(int index, TreeItem *child)
{
m_children.insert(index, child);
child->setParent(this);
child->setParentTree(this);
}
TreeItem *TreeItem::child(int row)
@ -91,3 +97,31 @@ void TreeItem::setData(QVariant value, int column)
{
m_data.replace(column, value);
}
void TreeItem::update() {
foreach(TreeItem *child, treeChildren())
child->update();
}
void TreeItem::apply() {
foreach(TreeItem *child, treeChildren())
child->apply();
}
void TreeItem::setHighlight(bool highlight) {
m_highlight = highlight;
m_changed = false;
if (highlight) {
if (m_timer.isActive()) {
m_timer.stop();
}
m_timer.setSingleShot(true);
m_timer.start(m_highlightTimeMs);
}
}
void TreeItem::removeHighlight() {
m_highlight = false;
update();
emit removeHighlight(this);
}

View File

@ -42,6 +42,8 @@
#include <QtCore/QList>
#include <QtCore/QVariant>
#include <QtCore/QStringList>
#include <QtCore/QTimer>
#include <QtCore/QObject>
#include <limits>
#define QINT8MIN std::numeric_limits<qint8>::min()
@ -55,54 +57,62 @@
#define QINT32MAX std::numeric_limits<qint32>::max()
#define QUINT32MAX std::numeric_limits<qint32>::max()
class TreeItem
{
public:
TreeItem(const QList<QVariant> &data, TreeItem *parent = 0);
TreeItem(const QVariant &data, TreeItem *parent = 0);
virtual ~TreeItem();
class TreeItem : public QObject
{
Q_OBJECT
public:
TreeItem(const QList<QVariant> &data, TreeItem *parent = 0);
TreeItem(const QVariant &data, TreeItem *parent = 0);
virtual ~TreeItem();
void appendChild(TreeItem *child);
void insert(int index, TreeItem *child);
void appendChild(TreeItem *child);
void insert(int index, TreeItem *child);
TreeItem *child(int row);
inline QList<TreeItem*> children() const { return m_children; }
int childCount() const;
int columnCount() const;
QVariant data(int column = 1) const;
// only column 1 is changed with setData currently
// other columns are initialized in constructor
virtual void setData(QVariant value, int column = 1);
int row() const;
TreeItem *parent() { return m_parent; }
void setParent(TreeItem *parent) { m_parent = parent; }
inline virtual bool isEditable() { return false; }
virtual void update() {
foreach(TreeItem *child, children())
child->update();
}
virtual void apply() {
foreach(TreeItem *child, children())
child->apply();
}
inline bool highlighted() { return m_highlight; }
inline void setHighlight(bool highlight) { m_highlight = highlight; m_changed = false; }
inline bool changed() { return m_changed; }
inline void setChanged(bool changed) { m_changed = changed; }
TreeItem *child(int row);
inline QList<TreeItem*> treeChildren() const { return m_children; }
int childCount() const;
int columnCount() const;
QVariant data(int column = 1) const;
// only column 1 is changed with setData currently
// other columns are initialized in constructor
virtual void setData(QVariant value, int column = 1);
int row() const;
TreeItem *parent() { return m_parent; }
void setParentTree(TreeItem *parent) { m_parent = parent; }
inline virtual bool isEditable() { return false; }
virtual void update();
virtual void apply();
private:
QList<TreeItem*> m_children;
// m_data contains: [0] property name, [1] value, and [2] unit
QList<QVariant> m_data;
TreeItem *m_parent;
bool m_highlight;
bool m_changed;
public:
static const int dataColumn = 1;
};
inline bool highlighted() { return m_highlight; }
void setHighlight(bool highlight);
static void setHighlightTime(int time) { m_highlightTimeMs = time; }
inline bool changed() { return m_changed; }
inline void setChanged(bool changed) { m_changed = changed; }
signals:
void removeHighlight(TreeItem*);
private slots:
void removeHighlight();
private:
QList<TreeItem*> m_children;
// m_data contains: [0] property name, [1] value, and [2] unit
QList<QVariant> m_data;
TreeItem *m_parent;
bool m_highlight;
bool m_changed;
QTimer m_timer;
public:
static const int dataColumn = 1;
private:
static int m_highlightTimeMs;
};
class TopTreeItem : public TreeItem
{
Q_OBJECT
public:
TopTreeItem(const QList<QVariant> &data, TreeItem *parent = 0) : TreeItem(data, parent) { }
TopTreeItem(const QVariant &data, TreeItem *parent = 0) : TreeItem(data, parent) { }
@ -124,6 +134,7 @@ private:
class ObjectTreeItem : public TreeItem
{
Q_OBJECT
public:
ObjectTreeItem(const QList<QVariant> &data, TreeItem *parent = 0) :
TreeItem(data, parent), m_obj(0) { }
@ -137,6 +148,7 @@ private:
class MetaObjectTreeItem : public ObjectTreeItem
{
Q_OBJECT
public:
MetaObjectTreeItem(UAVObject *obj, const QList<QVariant> &data, TreeItem *parent = 0) :
ObjectTreeItem(data, parent) { setObject(obj); }
@ -146,20 +158,21 @@ public:
class DataObjectTreeItem : public ObjectTreeItem
{
Q_OBJECT
public:
DataObjectTreeItem(const QList<QVariant> &data, TreeItem *parent = 0) :
ObjectTreeItem(data, parent) { }
DataObjectTreeItem(const QVariant &data, TreeItem *parent = 0) :
ObjectTreeItem(data, parent) { }
virtual void apply() {
foreach(TreeItem *child, children()) {
foreach(TreeItem *child, treeChildren()) {
MetaObjectTreeItem *metaChild = dynamic_cast<MetaObjectTreeItem*>(child);
if (!metaChild)
child->apply();
}
}
virtual void update() {
foreach(TreeItem *child, children()) {
foreach(TreeItem *child, treeChildren()) {
MetaObjectTreeItem *metaChild = dynamic_cast<MetaObjectTreeItem*>(child);
if (!metaChild)
child->update();
@ -169,6 +182,7 @@ public:
class InstanceTreeItem : public DataObjectTreeItem
{
Q_OBJECT
public:
InstanceTreeItem(UAVObject *obj, const QList<QVariant> &data, TreeItem *parent = 0) :
DataObjectTreeItem(data, parent) { setObject(obj); }
@ -180,6 +194,7 @@ public:
class ArrayFieldTreeItem : public TreeItem
{
Q_OBJECT
public:
ArrayFieldTreeItem(const QList<QVariant> &data, TreeItem *parent = 0) : TreeItem(data, parent) { }
ArrayFieldTreeItem(const QVariant &data, TreeItem *parent = 0) : TreeItem(data, parent) { }
@ -187,6 +202,7 @@ public:
class FieldTreeItem : public TreeItem
{
Q_OBJECT
public:
FieldTreeItem(int index, const QList<QVariant> &data, TreeItem *parent = 0) :
TreeItem(data, parent), m_index(index) { }
@ -203,13 +219,14 @@ protected:
class EnumFieldTreeItem : public FieldTreeItem
{
Q_OBJECT
public:
EnumFieldTreeItem(UAVObjectFieldEnum *field, int index, const QList<QVariant> &data,
TreeItem *parent = 0) :
FieldTreeItem(index, data, parent), enumOptions(field->getOptions()), m_field(field) { }
FieldTreeItem(index, data, parent), enumOptions(field->getOptions()), m_field(field) { }
EnumFieldTreeItem(UAVObjectFieldEnum *field, int index, const QVariant &data,
TreeItem *parent = 0) :
FieldTreeItem(index, data, parent), enumOptions(field->getOptions()), m_field(field) { }
FieldTreeItem(index, data, parent), enumOptions(field->getOptions()), m_field(field) { }
void setData(QVariant value, int column) {
setChanged(m_field->getSelectedIndex(m_index) != value);
TreeItem::setData(value, column);
@ -224,8 +241,6 @@ public:
if (data() != value || changed()) {
setHighlight(true);
TreeItem::setData(value);
} else {
setHighlight(false);
}
}
@ -237,6 +252,7 @@ private:
class IntFieldTreeItem : public FieldTreeItem
{
Q_OBJECT
public:
IntFieldTreeItem(int index, const QList<QVariant> &data, int min, int max, TreeItem *parent = 0) :
FieldTreeItem(index, data, parent), MIN(min), MAX(max) { }
@ -249,6 +265,7 @@ public:
class Int8FieldTreeItem : public IntFieldTreeItem
{
Q_OBJECT
public:
Int8FieldTreeItem(UAVObjectFieldInt8 *field, int index, const QList<QVariant> &data, TreeItem *parent = 0) :
IntFieldTreeItem(index, data, QINT8MIN, QINT8MAX, parent), m_field(field) { }
@ -267,8 +284,6 @@ public:
if (data() != value || changed()) {
setHighlight(true);
TreeItem::setData(value);
} else {
setHighlight(false);
}
}
private:
@ -277,6 +292,7 @@ private:
class Int16FieldTreeItem : public IntFieldTreeItem
{
Q_OBJECT
public:
Int16FieldTreeItem(UAVObjectFieldInt16 *field, int index, const QList<QVariant> &data, TreeItem *parent = 0) :
IntFieldTreeItem(index, data, QINT16MIN, QINT16MAX, parent), m_field(field) { }
@ -295,8 +311,6 @@ public:
if (data() != value || changed()) {
setHighlight(true);
TreeItem::setData(value);
} else {
setHighlight(false);
}
}
private:
@ -305,6 +319,7 @@ private:
class Int32FieldTreeItem : public IntFieldTreeItem
{
Q_OBJECT
public:
Int32FieldTreeItem(UAVObjectFieldInt32 *field, int index, const QList<QVariant> &data, TreeItem *parent = 0) :
IntFieldTreeItem(index, data, QINT32MIN, QINT32MAX, parent), m_field(field) { }
@ -323,8 +338,6 @@ public:
if (data() != value || changed()) {
setHighlight(true);
TreeItem::setData(value);
} else {
setHighlight(false);
}
}
private:
@ -333,6 +346,7 @@ private:
class UInt8FieldTreeItem : public IntFieldTreeItem
{
Q_OBJECT
public:
UInt8FieldTreeItem(UAVObjectFieldUInt8 *field, int index, const QList<QVariant> &data, TreeItem *parent = 0) :
IntFieldTreeItem(index, data, QUINTMIN, QUINT8MAX, parent), m_field(field) { }
@ -351,8 +365,6 @@ public:
if (data() != value || changed()) {
setHighlight(true);
TreeItem::setData(value);
} else {
setHighlight(false);
}
}
private:
@ -361,6 +373,7 @@ private:
class UInt16FieldTreeItem : public IntFieldTreeItem
{
Q_OBJECT
public:
UInt16FieldTreeItem(UAVObjectFieldUInt16 *field, int index, const QList<QVariant> &data, TreeItem *parent = 0) :
IntFieldTreeItem(index, data, QUINTMIN, QUINT16MAX, parent), m_field(field) { }
@ -379,8 +392,6 @@ public:
if (data() != value || changed()) {
setHighlight(true);
TreeItem::setData(value);
} else {
setHighlight(false);
}
}
private:
@ -389,6 +400,7 @@ private:
class UInt32FieldTreeItem : public IntFieldTreeItem
{
Q_OBJECT
public:
UInt32FieldTreeItem(UAVObjectFieldUInt32 *field, int index, const QList<QVariant> &data, TreeItem *parent = 0) :
IntFieldTreeItem(index, data, QUINTMIN, QUINT32MAX, parent), m_field(field) { }
@ -407,8 +419,6 @@ public:
if (data() != value || changed()) {
setHighlight(true);
TreeItem::setData(value);
} else {
setHighlight(false);
}
}
private:
@ -418,6 +428,7 @@ private:
class FloatFieldTreeItem : public FieldTreeItem
{
Q_OBJECT
public:
FloatFieldTreeItem(UAVObjectFieldFloat *field, int index, const QList<QVariant> &data, TreeItem *parent = 0) :
FieldTreeItem(index, data, parent), m_field(field) { }
@ -437,8 +448,6 @@ public:
if (data() != value || changed()) {
setHighlight(true);
TreeItem::setData(value);
} else {
setHighlight(false);
}
}
private:

View File

@ -47,14 +47,18 @@ UAVObjectTreeModel::UAVObjectTreeModel(QObject *parent) :
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
UAVObjectManager *objManager = pm->getObject<UAVObjectManager>();
m_signalMapper = new QSignalMapper();
connect(m_signalMapper, SIGNAL(mapped(QObject*)), this, SLOT(resetHighlightObject(QObject*)));
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()
{
delete m_rootItem;
}
void UAVObjectTreeModel::setupModelData(UAVObjectManager *objManager)
{
// root
@ -66,6 +70,8 @@ void UAVObjectTreeModel::setupModelData(UAVObjectManager *objManager)
m_rootItem->appendChild(m_settingsTree);
m_nonSettingsTree = new TopTreeItem(tr("Data Objects"), m_rootItem);
m_rootItem->appendChild(m_nonSettingsTree);
connect(m_settingsTree, SIGNAL(removeHighlight(TreeItem*)), this, SLOT(removeHighlight(TreeItem*)));
connect(m_nonSettingsTree, SIGNAL(removeHighlight(TreeItem*)), this, SLOT(removeHighlight(TreeItem*)));
QList< QList<UAVDataObject*> > objList = objManager->getDataObjects();
foreach (QList<UAVDataObject*> list, objList) {
@ -90,6 +96,7 @@ void UAVObjectTreeModel::addDataObject(UAVDataObject *obj)
addInstance(obj, root->child(index));
} else {
DataObjectTreeItem *data = new DataObjectTreeItem(obj->getName());
connect(data, SIGNAL(removeHighlight(TreeItem*)), this, SLOT(removeHighlight(TreeItem*)));
int index = root->nameIndex(obj->getName());
root->insert(index, data);
root->insertObjId(index, obj->getObjID());
@ -103,6 +110,7 @@ void UAVObjectTreeModel::addMetaObject(UAVMetaObject *obj, TreeItem *parent)
{
connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(highlightUpdatedObject(UAVObject*)));
MetaObjectTreeItem *meta = new MetaObjectTreeItem(obj, tr("Meta Data"));
connect(meta, SIGNAL(removeHighlight(TreeItem*)), this, SLOT(removeHighlight(TreeItem*)));
foreach (UAVObjectField *field, obj->getFields()) {
if (field->getNumElements() > 1) {
addArrayField(field, meta);
@ -124,6 +132,7 @@ void UAVObjectTreeModel::addInstance(UAVObject *obj, TreeItem *parent)
} else {
QString name = tr("Instance") + " " + QString::number(obj->getInstID());
item = new InstanceTreeItem(obj, name);
connect(item, SIGNAL(removeHighlight(TreeItem*)), this, SLOT(removeHighlight(TreeItem*)));
parent->appendChild(item);
}
foreach (UAVObjectField *field, obj->getFields()) {
@ -139,6 +148,7 @@ void UAVObjectTreeModel::addInstance(UAVObject *obj, TreeItem *parent)
void UAVObjectTreeModel::addArrayField(UAVObjectField *field, TreeItem *parent)
{
TreeItem *item = new ArrayFieldTreeItem(field->getName());
connect(item, SIGNAL(removeHighlight(TreeItem*)), this, SLOT(removeHighlight(TreeItem*)));
for (uint i = 0; i < field->getNumElements(); ++i) {
addSingleField(i, field, item);
}
@ -199,6 +209,7 @@ void UAVObjectTreeModel::addSingleField(int index, UAVObjectField *field, TreeIt
data.append(field->getUnits());
item = new FieldTreeItem(index, data);
}
connect(item, SIGNAL(removeHighlight(TreeItem*)), this, SLOT(removeHighlight(TreeItem*)));
parent->appendChild(item);
}
@ -222,6 +233,22 @@ QModelIndex UAVObjectTreeModel::index(int row, int column, const QModelIndex &pa
return QModelIndex();
}
QModelIndex UAVObjectTreeModel::index(TreeItem *item)
{
QModelIndex root;
if (item->parent() == 0)
root = QModelIndex();
else
root = index(item->parent());
for (int i = 0; i < rowCount(root); ++i) {
TreeItem *parentItem = static_cast<TreeItem*>(root.child(i, 0).internalPointer());
if (parentItem == item)
return createIndex(i, 0, item);
}
return QModelIndex();
}
QModelIndex UAVObjectTreeModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
@ -337,35 +364,8 @@ void UAVObjectTreeModel::highlightUpdatedObject(UAVObject *obj)
Q_ASSERT(item);
item->setHighlight(true);
item->update();
emit dataChanged(QModelIndex(), QModelIndex());
// any updates while highlighted will not reset timer
if (m_timerMap.contains(obj))
return;
QTimer *timer = new QTimer(this);
timer->setSingleShot(true);
m_timerMap.insert(obj, timer);
connect(timer, SIGNAL(timeout()), m_signalMapper, SLOT(map()));
m_signalMapper->setMapping(timer, obj);
timer->start(m_recentlyUpdatedTimeout);
}
void UAVObjectTreeModel::resetHighlightObject(QObject *object)
{
UAVObject *obj = qobject_cast<UAVObject*>(object);
Q_ASSERT(obj);
QTimer *timer = m_timerMap.value(obj);
Q_ASSERT(timer);
delete timer;
m_timerMap.remove(obj);
ObjectTreeItem *item = findObjectTreeItem(obj);
Q_ASSERT(item);
item->setHighlight(false);
item->update();
emit dataChanged(QModelIndex(), QModelIndex());
QModelIndex itemIndex = index(item);
emit dataChanged(itemIndex, itemIndex);
}
ObjectTreeItem *UAVObjectTreeModel::findObjectTreeItem(UAVObject *object)
@ -378,8 +378,12 @@ ObjectTreeItem *UAVObjectTreeModel::findObjectTreeItem(UAVObject *object)
} else {
dobj = qobject_cast<UAVDataObject*>(mobj->getParentObject());
Q_ASSERT(dobj);
DataObjectTreeItem *dItem = findDataObjectTreeItem(dobj);
foreach (TreeItem *child, dItem->children()) {
ObjectTreeItem *dItem = findDataObjectTreeItem(dobj);
Q_ASSERT(dItem);
Q_ASSERT(dItem->object());
if (!dItem->object()->isSingleInstance())
dItem = dynamic_cast<ObjectTreeItem*>(dItem->parent());
foreach (TreeItem *child, dItem->treeChildren()) {
MetaObjectTreeItem *mItem = dynamic_cast<MetaObjectTreeItem*>(child);
if (mItem && mItem->object()) {
Q_ASSERT(mItem->object() == mobj);
@ -395,20 +399,27 @@ DataObjectTreeItem *UAVObjectTreeModel::findDataObjectTreeItem(UAVDataObject *ob
{
Q_ASSERT(object);
TopTreeItem *root = object->isSettings() ? m_settingsTree : m_nonSettingsTree;
foreach (TreeItem *child, root->children()) {
foreach (TreeItem *child, root->treeChildren()) {
DataObjectTreeItem *dItem = dynamic_cast<DataObjectTreeItem*>(child);
if (dItem && dItem->object() && dItem->object()->isSingleInstance()) {
if(dItem->object() == object) {
return dItem;
}
} else {
foreach (TreeItem *c, dItem->children()) {
foreach (TreeItem *c, dItem->treeChildren()) {
DataObjectTreeItem *d = dynamic_cast<DataObjectTreeItem*>(c);
if (d && d->object() == object)
return dItem;
return d;
}
}
}
return 0;
}
void UAVObjectTreeModel::removeHighlight(TreeItem *item)
{
QModelIndex itemIndex = index(item);
emit dataChanged(itemIndex, itemIndex.sibling(itemIndex.row(), item->dataColumn));
}

View File

@ -49,6 +49,7 @@ class UAVObjectTreeModel : public QAbstractItemModel
Q_OBJECT
public:
explicit UAVObjectTreeModel(QObject *parent = 0);
~UAVObjectTreeModel();
QVariant data(const QModelIndex &index, int role) const;
bool setData(const QModelIndex &index, const QVariant & value, int role);
@ -69,10 +70,10 @@ public slots:
private slots:
void highlightUpdatedObject(UAVObject *obj);
void resetHighlightObject(QObject *obj);
void removeHighlight(TreeItem*);
private:
QModelIndex index(TreeItem *item);
void addDataObject(UAVDataObject *obj);
void addMetaObject(UAVMetaObject *obj, TreeItem *parent);
void addArrayField(UAVObjectField *field, TreeItem *parent);
@ -87,8 +88,6 @@ private:
TreeItem *m_rootItem;
TopTreeItem *m_settingsTree;
TopTreeItem *m_nonSettingsTree;
QSignalMapper *m_signalMapper;
QMap<UAVObject*,QTimer*> m_timerMap;
int m_recentlyUpdatedTimeout;
QColor m_recentlyUpdatedColor;
QColor m_manuallyChangedColor;