From 44176370deec299e66b09f02a60dca7e9e39c0a7 Mon Sep 17 00:00:00 2001 From: ephy Date: Thu, 15 Apr 2010 15:42:47 +0000 Subject: [PATCH] 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 --- .../src/plugins/uavobjectbrowser/treeitem.cpp | 38 ++++- .../src/plugins/uavobjectbrowser/treeitem.h | 133 ++++++++++-------- .../uavobjectbrowser/uavobjecttreemodel.cpp | 83 ++++++----- .../uavobjectbrowser/uavobjecttreemodel.h | 7 +- 4 files changed, 157 insertions(+), 104 deletions(-) diff --git a/ground/src/plugins/uavobjectbrowser/treeitem.cpp b/ground/src/plugins/uavobjectbrowser/treeitem.cpp index 06a0a4108..bf814023c 100644 --- a/ground/src/plugins/uavobjectbrowser/treeitem.cpp +++ b/ground/src/plugins/uavobjectbrowser/treeitem.cpp @@ -27,20 +27,26 @@ #include "treeitem.h" +int TreeItem::m_highlightTimeMs = 500; + TreeItem::TreeItem(const QList &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); +} diff --git a/ground/src/plugins/uavobjectbrowser/treeitem.h b/ground/src/plugins/uavobjectbrowser/treeitem.h index 7228a8adc..069def514 100644 --- a/ground/src/plugins/uavobjectbrowser/treeitem.h +++ b/ground/src/plugins/uavobjectbrowser/treeitem.h @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include #define QINT8MIN std::numeric_limits::min() @@ -55,54 +57,62 @@ #define QINT32MAX std::numeric_limits::max() #define QUINT32MAX std::numeric_limits::max() -class TreeItem - { - public: - TreeItem(const QList &data, TreeItem *parent = 0); - TreeItem(const QVariant &data, TreeItem *parent = 0); - virtual ~TreeItem(); +class TreeItem : public QObject +{ +Q_OBJECT +public: + TreeItem(const QList &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 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 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 m_children; - // m_data contains: [0] property name, [1] value, and [2] unit - QList 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 m_children; + // m_data contains: [0] property name, [1] value, and [2] unit + QList 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 &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 &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 &data, TreeItem *parent = 0) : ObjectTreeItem(data, parent) { setObject(obj); } @@ -146,20 +158,21 @@ public: class DataObjectTreeItem : public ObjectTreeItem { +Q_OBJECT public: DataObjectTreeItem(const QList &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(child); if (!metaChild) child->apply(); } } virtual void update() { - foreach(TreeItem *child, children()) { + foreach(TreeItem *child, treeChildren()) { MetaObjectTreeItem *metaChild = dynamic_cast(child); if (!metaChild) child->update(); @@ -169,6 +182,7 @@ public: class InstanceTreeItem : public DataObjectTreeItem { +Q_OBJECT public: InstanceTreeItem(UAVObject *obj, const QList &data, TreeItem *parent = 0) : DataObjectTreeItem(data, parent) { setObject(obj); } @@ -180,6 +194,7 @@ public: class ArrayFieldTreeItem : public TreeItem { +Q_OBJECT public: ArrayFieldTreeItem(const QList &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 &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 &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 &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 &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 &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 &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 &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 &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 &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 &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: diff --git a/ground/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp b/ground/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp index ef76f2ad6..7013d8146 100644 --- a/ground/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp +++ b/ground/src/plugins/uavobjectbrowser/uavobjecttreemodel.cpp @@ -47,14 +47,18 @@ UAVObjectTreeModel::UAVObjectTreeModel(QObject *parent) : ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectManager *objManager = pm->getObject(); - 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 > objList = objManager->getDataObjects(); foreach (QList 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(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(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(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(dItem->parent()); + foreach (TreeItem *child, dItem->treeChildren()) { MetaObjectTreeItem *mItem = dynamic_cast(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(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(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)); +} + + diff --git a/ground/src/plugins/uavobjectbrowser/uavobjecttreemodel.h b/ground/src/plugins/uavobjectbrowser/uavobjecttreemodel.h index 55986a477..6308f6d79 100644 --- a/ground/src/plugins/uavobjectbrowser/uavobjecttreemodel.h +++ b/ground/src/plugins/uavobjectbrowser/uavobjecttreemodel.h @@ -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 m_timerMap; int m_recentlyUpdatedTimeout; QColor m_recentlyUpdatedColor; QColor m_manuallyChangedColor;