mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-01-19 04:52:12 +01:00
Merged in mkaduk/librepilot/LP-286_taulabs_uavbrowser_filter (pull request #226)
LP-286 Port TauLabs filter in UAVobjectbrowser
This commit is contained in:
commit
4ada670272
@ -2,7 +2,8 @@
|
||||
******************************************************************************
|
||||
*
|
||||
* @file browseritemdelegate.cpp
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @addtogroup GCSPlugins GCS Plugins
|
||||
* @{
|
||||
* @addtogroup UAVObjectBrowserPlugin UAVObject Browser Plugin
|
||||
@ -34,20 +35,19 @@ BrowserItemDelegate::BrowserItemDelegate(QObject *parent) :
|
||||
|
||||
QWidget *BrowserItemDelegate::createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem & option,
|
||||
const QModelIndex & index) const
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(option)
|
||||
FieldTreeItem * item = static_cast<FieldTreeItem *>(index.internalPointer());
|
||||
FieldTreeItem * item = static_cast<FieldTreeItem *>(index.data(Qt::UserRole).value<void *>());
|
||||
QWidget *editor = item->createEditor(parent);
|
||||
Q_ASSERT(editor);
|
||||
return editor;
|
||||
}
|
||||
|
||||
|
||||
void BrowserItemDelegate::setEditorData(QWidget *editor,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
FieldTreeItem *item = static_cast<FieldTreeItem *>(index.internalPointer());
|
||||
FieldTreeItem *item = static_cast<FieldTreeItem *>(index.data(Qt::UserRole).value<void *>());
|
||||
QVariant value = index.model()->data(index, Qt::EditRole);
|
||||
|
||||
item->setEditorValue(editor, value);
|
||||
@ -56,15 +56,18 @@ void BrowserItemDelegate::setEditorData(QWidget *editor,
|
||||
void BrowserItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
FieldTreeItem *item = static_cast<FieldTreeItem *>(index.internalPointer());
|
||||
FieldTreeItem *item = static_cast<FieldTreeItem *>(index.data(Qt::UserRole).value<void *>());
|
||||
QVariant value = item->getEditorValue(editor);
|
||||
|
||||
model->setData(index, value, Qt::EditRole);
|
||||
bool ret = model->setData(index, value, Qt::EditRole);
|
||||
|
||||
Q_ASSERT(ret);
|
||||
}
|
||||
|
||||
void BrowserItemDelegate::updateEditorGeometry(QWidget *editor,
|
||||
const QStyleOptionViewItem &option, const QModelIndex & /* index */) const
|
||||
const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
editor->setGeometry(option.rect);
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,8 @@
|
||||
******************************************************************************
|
||||
*
|
||||
* @file browseritemdelegate.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @addtogroup GCSPlugins GCS Plugins
|
||||
* @{
|
||||
* @addtogroup UAVObjectBrowserPlugin UAVObject Browser Plugin
|
||||
@ -46,11 +47,6 @@ public:
|
||||
const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
QSize sizeHint(const QStyleOptionViewItem & option,
|
||||
const QModelIndex &index) const;
|
||||
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
};
|
||||
|
||||
#endif // BROWSERITEMDELEGATE_H
|
||||
|
@ -259,7 +259,7 @@ public:
|
||||
|
||||
DataObjectTreeItem *findDataObjectTreeItemByObjectId(quint32 objectId)
|
||||
{
|
||||
return m_objectTreeItemsPerObjectIds.contains(objectId) ? m_objectTreeItemsPerObjectIds[objectId] : 0;
|
||||
return m_objectTreeItemsPerObjectIds.value(objectId, 0);
|
||||
}
|
||||
|
||||
void addMetaObjectTreeItem(quint32 objectId, MetaObjectTreeItem *oti)
|
||||
@ -269,7 +269,7 @@ public:
|
||||
|
||||
MetaObjectTreeItem *findMetaObjectTreeItemByObjectId(quint32 objectId)
|
||||
{
|
||||
return m_metaObjectTreeItemsPerObjectIds.contains(objectId) ? m_metaObjectTreeItemsPerObjectIds[objectId] : 0;
|
||||
return m_metaObjectTreeItemsPerObjectIds.value(objectId, 0);
|
||||
}
|
||||
|
||||
QList<MetaObjectTreeItem *> getMetaObjectItems();
|
||||
|
@ -204,6 +204,40 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="searchLine">
|
||||
<property name="placeholderText">
|
||||
<string>type filter text</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="searchClearButton">
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="fileclose">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
@ -273,6 +307,7 @@
|
||||
<string>This space shows a description of the selected UAVObject.</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="lineEdit"/>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -2,7 +2,9 @@
|
||||
******************************************************************************
|
||||
*
|
||||
* @file uavobjectbrowserwidget.cpp
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||
* Tau Labs, http://taulabs.org, Copyright (C) 2013
|
||||
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @addtogroup GCSPlugins GCS Plugins
|
||||
* @{
|
||||
* @addtogroup UAVObjectBrowserPlugin UAVObject Browser Plugin
|
||||
@ -43,39 +45,54 @@
|
||||
|
||||
UAVObjectBrowserWidget::UAVObjectBrowserWidget(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
m_browser = new Ui_UAVObjectBrowser();
|
||||
m_viewoptions = new Ui_viewoptions();
|
||||
m_viewoptionsDialog = new QDialog(this);
|
||||
|
||||
m_viewoptions = new Ui_viewoptions();
|
||||
m_viewoptions->setupUi(m_viewoptionsDialog);
|
||||
|
||||
m_model = new UAVObjectTreeModel(this);
|
||||
|
||||
m_modelProxy = new TreeSortFilterProxyModel(this);
|
||||
m_modelProxy->setSourceModel(m_model);
|
||||
m_modelProxy->setDynamicSortFilter(true);
|
||||
|
||||
m_browser = new Ui_UAVObjectBrowser();
|
||||
m_browser->setupUi(this);
|
||||
m_model = new UAVObjectTreeModel();
|
||||
m_browser->treeView->setModel(m_model);
|
||||
m_browser->treeView->setModel(m_modelProxy);
|
||||
m_browser->treeView->setColumnWidth(0, 300);
|
||||
|
||||
BrowserItemDelegate *m_delegate = new BrowserItemDelegate();
|
||||
m_browser->treeView->setItemDelegate(m_delegate);
|
||||
m_browser->treeView->setItemDelegate(new BrowserItemDelegate());
|
||||
m_browser->treeView->setEditTriggers(QAbstractItemView::AllEditTriggers);
|
||||
m_browser->treeView->setSelectionBehavior(QAbstractItemView::SelectItems);
|
||||
|
||||
m_mustacheTemplate = loadFileIntoString(QString(":/uavobjectbrowser/resources/uavodescription.mustache"));
|
||||
|
||||
showMetaData(m_viewoptions->cbMetaData->isChecked());
|
||||
showDescription(m_viewoptions->cbDescription->isChecked());
|
||||
|
||||
connect(m_browser->treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)),
|
||||
this, SLOT(currentChanged(QModelIndex, QModelIndex)), Qt::UniqueConnection);
|
||||
connect(m_viewoptions->cbMetaData, SIGNAL(toggled(bool)), this, SLOT(showMetaData(bool)));
|
||||
connect(m_viewoptions->cbCategorized, SIGNAL(toggled(bool)), this, SLOT(categorize(bool)));
|
||||
connect(m_viewoptions->cbDescription, SIGNAL(toggled(bool)), this, SLOT(showDescription(bool)));
|
||||
connect(m_browser->saveSDButton, SIGNAL(clicked()), this, SLOT(saveObject()));
|
||||
connect(m_browser->readSDButton, SIGNAL(clicked()), this, SLOT(loadObject()));
|
||||
connect(m_browser->eraseSDButton, SIGNAL(clicked()), this, SLOT(eraseObject()));
|
||||
connect(m_browser->sendButton, SIGNAL(clicked()), this, SLOT(sendUpdate()));
|
||||
connect(m_browser->requestButton, SIGNAL(clicked()), this, SLOT(requestUpdate()));
|
||||
connect(m_browser->eraseSDButton, SIGNAL(clicked()), this, SLOT(eraseObject()));
|
||||
connect(m_browser->tbView, SIGNAL(clicked()), this, SLOT(viewSlot()));
|
||||
connect(m_browser->splitter, SIGNAL(splitterMoved(int, int)), this, SLOT(splitterMoved()));
|
||||
|
||||
connect(m_viewoptions->cbMetaData, SIGNAL(toggled(bool)), this, SLOT(showMetaData(bool)));
|
||||
connect(m_viewoptions->cbMetaData, SIGNAL(toggled(bool)), this, SLOT(viewOptionsChangedSlot()));
|
||||
connect(m_viewoptions->cbCategorized, SIGNAL(toggled(bool)), this, SLOT(categorize(bool)));
|
||||
connect(m_viewoptions->cbCategorized, SIGNAL(toggled(bool)), this, SLOT(viewOptionsChangedSlot()));
|
||||
connect(m_viewoptions->cbDescription, SIGNAL(toggled(bool)), this, SLOT(showDescription(bool)));
|
||||
connect(m_viewoptions->cbDescription, SIGNAL(toggled(bool)), this, SLOT(viewOptionsChangedSlot()));
|
||||
connect(m_viewoptions->cbScientific, SIGNAL(toggled(bool)), this, SLOT(useScientificNotation(bool)));
|
||||
connect(m_viewoptions->cbScientific, SIGNAL(toggled(bool)), this, SLOT(viewOptionsChangedSlot()));
|
||||
connect(m_viewoptions->cbMetaData, SIGNAL(toggled(bool)), this, SLOT(viewOptionsChangedSlot()));
|
||||
connect(m_viewoptions->cbCategorized, SIGNAL(toggled(bool)), this, SLOT(viewOptionsChangedSlot()));
|
||||
connect(m_viewoptions->cbDescription, SIGNAL(toggled(bool)), this, SLOT(viewOptionsChangedSlot()));
|
||||
connect(m_browser->splitter, SIGNAL(splitterMoved(int, int)), this, SLOT(splitterMoved()));
|
||||
|
||||
// search field and button
|
||||
connect(m_browser->searchLine, SIGNAL(textChanged(QString)), this, SLOT(searchLineChanged(QString)));
|
||||
connect(m_browser->searchClearButton, SIGNAL(clicked(bool)), this, SLOT(searchTextCleared()));
|
||||
|
||||
enableSendRequest(false);
|
||||
}
|
||||
|
||||
@ -99,9 +116,12 @@ void UAVObjectBrowserWidget::setSplitterState(QByteArray state)
|
||||
|
||||
void UAVObjectBrowserWidget::showMetaData(bool show)
|
||||
{
|
||||
// TODO update the model directly instead of hiding rows...
|
||||
QList<QModelIndex> metaIndexes = m_model->getMetaDataIndexes();
|
||||
foreach(QModelIndex index, metaIndexes) {
|
||||
m_browser->treeView->setRowHidden(index.row(), index.parent(), !show);
|
||||
foreach(QModelIndex modelIndex, metaIndexes) {
|
||||
QModelIndex proxyModelIndex = m_modelProxy->mapFromSource(modelIndex);
|
||||
|
||||
m_browser->treeView->setRowHidden(proxyModelIndex.row(), proxyModelIndex.parent(), !show);
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,62 +132,82 @@ void UAVObjectBrowserWidget::showDescription(bool show)
|
||||
|
||||
void UAVObjectBrowserWidget::categorize(bool categorize)
|
||||
{
|
||||
// TODO we should update the model instead of rebuilding it
|
||||
// a side effect of rebuilding is that some state is lost (expand state, ...)
|
||||
UAVObjectTreeModel *model = new UAVObjectTreeModel(0, categorize, m_viewoptions->cbScientific->isChecked());
|
||||
|
||||
model->setRecentlyUpdatedColor(m_recentlyUpdatedColor);
|
||||
model->setManuallyChangedColor(m_manuallyChangedColor);
|
||||
model->setRecentlyUpdatedTimeout(m_recentlyUpdatedTimeout);
|
||||
model->setOnlyHilightChangedValues(m_onlyHilightChangedValues);
|
||||
model->setUnknowObjectColor(m_unknownObjectColor);
|
||||
|
||||
UAVObjectTreeModel *tmpModel = m_model;
|
||||
|
||||
m_model = new UAVObjectTreeModel(0, categorize, m_viewoptions->cbScientific->isChecked());
|
||||
m_model->setRecentlyUpdatedColor(m_recentlyUpdatedColor);
|
||||
m_model->setManuallyChangedColor(m_manuallyChangedColor);
|
||||
m_model->setRecentlyUpdatedTimeout(m_recentlyUpdatedTimeout);
|
||||
m_model->setOnlyHilightChangedValues(m_onlyHilightChangedValues);
|
||||
m_model->setUnknowObjectColor(m_unknownObjectColor);
|
||||
m_browser->treeView->setModel(m_model);
|
||||
showMetaData(m_viewoptions->cbMetaData->isChecked());
|
||||
connect(m_browser->treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(currentChanged(QModelIndex, QModelIndex)), Qt::UniqueConnection);
|
||||
|
||||
m_model = model;
|
||||
m_modelProxy->setSourceModel(m_model);
|
||||
delete tmpModel;
|
||||
|
||||
showMetaData(m_viewoptions->cbMetaData->isChecked());
|
||||
|
||||
// force an expand all if search text is not empty
|
||||
if (!m_browser->searchLine->text().isEmpty()) {
|
||||
searchLineChanged(m_browser->searchLine->text());
|
||||
}
|
||||
}
|
||||
|
||||
void UAVObjectBrowserWidget::useScientificNotation(bool scientific)
|
||||
{
|
||||
// TODO we should update the model instead of rebuilding it
|
||||
// a side effect of rebuilding is that some state is lost (expand state, ...)
|
||||
UAVObjectTreeModel *model = new UAVObjectTreeModel(0, m_viewoptions->cbCategorized->isChecked(), scientific);
|
||||
|
||||
model->setManuallyChangedColor(m_manuallyChangedColor);
|
||||
model->setRecentlyUpdatedTimeout(m_recentlyUpdatedTimeout);
|
||||
model->setUnknowObjectColor(m_unknownObjectColor);
|
||||
|
||||
UAVObjectTreeModel *tmpModel = m_model;
|
||||
|
||||
m_model = new UAVObjectTreeModel(0, m_viewoptions->cbCategorized->isChecked(), scientific);
|
||||
m_model->setRecentlyUpdatedColor(m_recentlyUpdatedColor);
|
||||
m_model->setManuallyChangedColor(m_manuallyChangedColor);
|
||||
m_model->setRecentlyUpdatedTimeout(m_recentlyUpdatedTimeout);
|
||||
m_model->setUnknowObjectColor(m_unknownObjectColor);
|
||||
m_browser->treeView->setModel(m_model);
|
||||
showMetaData(m_viewoptions->cbMetaData->isChecked());
|
||||
connect(m_browser->treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex, QModelIndex)), this, SLOT(currentChanged(QModelIndex, QModelIndex)), Qt::UniqueConnection);
|
||||
|
||||
m_model = model;
|
||||
m_modelProxy->setSourceModel(m_model);
|
||||
delete tmpModel;
|
||||
|
||||
showMetaData(m_viewoptions->cbMetaData->isChecked());
|
||||
|
||||
// force an expand all if search text is not empty
|
||||
if (!m_browser->searchLine->text().isEmpty()) {
|
||||
searchLineChanged(m_browser->searchLine->text());
|
||||
}
|
||||
}
|
||||
|
||||
void UAVObjectBrowserWidget::sendUpdate()
|
||||
{
|
||||
// TODO why steal focus ?
|
||||
this->setFocus();
|
||||
|
||||
ObjectTreeItem *objItem = findCurrentObjectTreeItem();
|
||||
Q_ASSERT(objItem);
|
||||
objItem->apply();
|
||||
UAVObject *obj = objItem->object();
|
||||
Q_ASSERT(obj);
|
||||
obj->updated();
|
||||
|
||||
if (objItem != NULL) {
|
||||
objItem->apply();
|
||||
UAVObject *obj = objItem->object();
|
||||
Q_ASSERT(obj);
|
||||
obj->updated();
|
||||
}
|
||||
}
|
||||
|
||||
void UAVObjectBrowserWidget::requestUpdate()
|
||||
{
|
||||
ObjectTreeItem *objItem = findCurrentObjectTreeItem();
|
||||
|
||||
Q_ASSERT(objItem);
|
||||
UAVObject *obj = objItem->object();
|
||||
Q_ASSERT(obj);
|
||||
obj->requestUpdate();
|
||||
if (objItem != NULL) {
|
||||
UAVObject *obj = objItem->object();
|
||||
Q_ASSERT(obj);
|
||||
obj->requestUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
ObjectTreeItem *UAVObjectBrowserWidget::findCurrentObjectTreeItem()
|
||||
{
|
||||
QModelIndex current = m_browser->treeView->currentIndex();
|
||||
TreeItem *item = static_cast<TreeItem *>(current.internalPointer());
|
||||
TreeItem *item = static_cast<TreeItem *>(current.data(Qt::UserRole).value<void *>());
|
||||
ObjectTreeItem *objItem = 0;
|
||||
|
||||
while (item) {
|
||||
@ -193,15 +233,20 @@ QString UAVObjectBrowserWidget::loadFileIntoString(QString fileName)
|
||||
|
||||
void UAVObjectBrowserWidget::saveObject()
|
||||
{
|
||||
// TODO why steal focus ?
|
||||
this->setFocus();
|
||||
|
||||
// Send update so that the latest value is saved
|
||||
sendUpdate();
|
||||
|
||||
// Save object
|
||||
ObjectTreeItem *objItem = findCurrentObjectTreeItem();
|
||||
Q_ASSERT(objItem);
|
||||
UAVObject *obj = objItem->object();
|
||||
Q_ASSERT(obj);
|
||||
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj);
|
||||
|
||||
if (objItem != NULL) {
|
||||
UAVObject *obj = objItem->object();
|
||||
Q_ASSERT(obj);
|
||||
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj);
|
||||
}
|
||||
}
|
||||
|
||||
void UAVObjectBrowserWidget::loadObject()
|
||||
@ -209,22 +254,24 @@ void UAVObjectBrowserWidget::loadObject()
|
||||
// Load object
|
||||
ObjectTreeItem *objItem = findCurrentObjectTreeItem();
|
||||
|
||||
Q_ASSERT(objItem);
|
||||
UAVObject *obj = objItem->object();
|
||||
Q_ASSERT(obj);
|
||||
updateObjectPersistance(ObjectPersistence::OPERATION_LOAD, obj);
|
||||
// Retrieve object so that latest value is displayed
|
||||
requestUpdate();
|
||||
if (objItem != NULL) {
|
||||
UAVObject *obj = objItem->object();
|
||||
Q_ASSERT(obj);
|
||||
updateObjectPersistance(ObjectPersistence::OPERATION_LOAD, obj);
|
||||
// Retrieve object so that latest value is displayed
|
||||
requestUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void UAVObjectBrowserWidget::eraseObject()
|
||||
{
|
||||
ObjectTreeItem *objItem = findCurrentObjectTreeItem();
|
||||
|
||||
Q_ASSERT(objItem);
|
||||
UAVObject *obj = objItem->object();
|
||||
Q_ASSERT(obj);
|
||||
updateObjectPersistance(ObjectPersistence::OPERATION_DELETE, obj);
|
||||
if (objItem != NULL) {
|
||||
UAVObject *obj = objItem->object();
|
||||
Q_ASSERT(obj);
|
||||
updateObjectPersistance(ObjectPersistence::OPERATION_DELETE, obj);
|
||||
}
|
||||
}
|
||||
|
||||
void UAVObjectBrowserWidget::updateObjectPersistance(ObjectPersistence::OperationOptions op, UAVObject *obj)
|
||||
@ -248,9 +295,9 @@ void UAVObjectBrowserWidget::currentChanged(const QModelIndex ¤t, const QM
|
||||
{
|
||||
Q_UNUSED(previous);
|
||||
|
||||
TreeItem *item = static_cast<TreeItem *>(current.internalPointer());
|
||||
TreeItem *item = static_cast<TreeItem *>(current.data(Qt::UserRole).value<void *>());
|
||||
bool enable = true;
|
||||
if (current == QModelIndex()) {
|
||||
if (!current.isValid()) {
|
||||
enable = false;
|
||||
}
|
||||
TopTreeItem *top = dynamic_cast<TopTreeItem *>(item);
|
||||
@ -388,3 +435,94 @@ void UAVObjectBrowserWidget::updateDescription()
|
||||
}
|
||||
m_browser->descriptionText->setText("");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UAVObjectBrowserWidget::searchTextChanged Looks for matching text in the UAVO fields
|
||||
*/
|
||||
|
||||
void UAVObjectBrowserWidget::searchLineChanged(QString searchText)
|
||||
{
|
||||
m_modelProxy->setFilterRegExp(QRegExp(searchText, Qt::CaseInsensitive, QRegExp::FixedString));
|
||||
if (!searchText.isEmpty()) {
|
||||
m_browser->treeView->expandAll();
|
||||
} else {
|
||||
m_browser->treeView->collapseAll();
|
||||
}
|
||||
}
|
||||
|
||||
void UAVObjectBrowserWidget::searchTextCleared()
|
||||
{
|
||||
m_browser->searchLine->clear();
|
||||
}
|
||||
|
||||
TreeSortFilterProxyModel::TreeSortFilterProxyModel(QObject *p) :
|
||||
QSortFilterProxyModel(p)
|
||||
{
|
||||
Q_ASSERT(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TreeSortFilterProxyModel::filterAcceptsRow Taken from
|
||||
* http://qt-project.org/forums/viewthread/7782. This proxy model
|
||||
* will accept rows:
|
||||
* - That match themselves, or
|
||||
* - That have a parent that matches (on its own), or
|
||||
* - That have a child that matches.
|
||||
* @param sourceRow
|
||||
* @param sourceParent
|
||||
* @return
|
||||
*/
|
||||
bool TreeSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||
{
|
||||
if (filterAcceptsRowItself(source_row, source_parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// accept if any of the parents is accepted on it's own merits
|
||||
QModelIndex parent = source_parent;
|
||||
while (parent.isValid()) {
|
||||
if (filterAcceptsRowItself(parent.row(), parent.parent())) {
|
||||
return true;
|
||||
}
|
||||
parent = parent.parent();
|
||||
}
|
||||
|
||||
// accept if any of the children is accepted on it's own merits
|
||||
if (hasAcceptedChildren(source_row, source_parent)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TreeSortFilterProxyModel::filterAcceptsRowItself(int source_row, const QModelIndex &source_parent) const
|
||||
{
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
}
|
||||
|
||||
bool TreeSortFilterProxyModel::hasAcceptedChildren(int source_row, const QModelIndex &source_parent) const
|
||||
{
|
||||
QModelIndex item = sourceModel()->index(source_row, 0, source_parent);
|
||||
|
||||
if (!item.isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if there are children
|
||||
int childCount = item.model()->rowCount(item);
|
||||
if (childCount == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < childCount; ++i) {
|
||||
if (filterAcceptsRowItself(i, item)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hasAcceptedChildren(i, item)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -2,7 +2,9 @@
|
||||
******************************************************************************
|
||||
*
|
||||
* @file uavobjectbrowserwidget.h
|
||||
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2016.
|
||||
* Tau Labs, http://taulabs.org, Copyright (C) 2013
|
||||
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
||||
* @addtogroup GCSPlugins GCS Plugins
|
||||
* @{
|
||||
* @addtogroup UAVObjectBrowserPlugin UAVObject Browser Plugin
|
||||
@ -28,16 +30,30 @@
|
||||
#ifndef UAVOBJECTBROWSERWIDGET_H_
|
||||
#define UAVOBJECTBROWSERWIDGET_H_
|
||||
|
||||
#include "uavobjecttreemodel.h"
|
||||
|
||||
#include "objectpersistence.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTreeView>
|
||||
#include "objectpersistence.h"
|
||||
#include "uavobjecttreemodel.h"
|
||||
#include <QKeyEvent>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class QPushButton;
|
||||
class ObjectTreeItem;
|
||||
class Ui_UAVObjectBrowser;
|
||||
class Ui_viewoptions;
|
||||
|
||||
class TreeSortFilterProxyModel : public QSortFilterProxyModel {
|
||||
public:
|
||||
TreeSortFilterProxyModel(QObject *parent);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
|
||||
bool filterAcceptsRowItself(int source_row, const QModelIndex &source_parent) const;
|
||||
bool hasAcceptedChildren(int source_row, const QModelIndex &source_parent) const;
|
||||
};
|
||||
|
||||
class UAVObjectBrowserWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
@ -72,6 +88,7 @@ public:
|
||||
}
|
||||
void setViewOptions(bool categorized, bool scientific, bool metadata, bool description);
|
||||
void setSplitterState(QByteArray state);
|
||||
|
||||
public slots:
|
||||
void showMetaData(bool show);
|
||||
void showDescription(bool show);
|
||||
@ -87,18 +104,21 @@ private slots:
|
||||
void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void viewSlot();
|
||||
void viewOptionsChangedSlot();
|
||||
void searchLineChanged(QString searchText);
|
||||
void searchTextCleared();
|
||||
void splitterMoved();
|
||||
QString createObjectDescription(UAVObject *object);
|
||||
|
||||
signals:
|
||||
void viewOptionsChanged(bool categorized, bool scientific, bool metadata, bool description);
|
||||
void splitterChanged(QByteArray state);
|
||||
|
||||
private:
|
||||
QPushButton *m_requestUpdate;
|
||||
QPushButton *m_sendUpdate;
|
||||
Ui_UAVObjectBrowser *m_browser;
|
||||
Ui_viewoptions *m_viewoptions;
|
||||
QDialog *m_viewoptionsDialog;
|
||||
UAVObjectTreeModel *m_model;
|
||||
TreeSortFilterProxyModel *m_modelProxy;
|
||||
|
||||
int m_recentlyUpdatedTimeout;
|
||||
QColor m_unknownObjectColor;
|
||||
|
@ -68,20 +68,23 @@ UAVObjectTreeModel::~UAVObjectTreeModel()
|
||||
|
||||
void UAVObjectTreeModel::setupModelData(UAVObjectManager *objManager)
|
||||
{
|
||||
m_settingsTree = new TopTreeItem(tr("Settings"));
|
||||
m_settingsTree->setHighlightManager(m_highlightManager);
|
||||
connect(m_settingsTree, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *)));
|
||||
|
||||
m_nonSettingsTree = new TopTreeItem(tr("Data Objects"));
|
||||
m_nonSettingsTree->setHighlightManager(m_highlightManager);
|
||||
connect(m_nonSettingsTree, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *)));
|
||||
|
||||
// root
|
||||
QList<QVariant> rootData;
|
||||
rootData << tr("Property") << tr("Value") << tr("Unit");
|
||||
m_rootItem = new TreeItem(rootData);
|
||||
|
||||
m_settingsTree = new TopTreeItem(tr("Settings"), m_rootItem);
|
||||
m_settingsTree->setHighlightManager(m_highlightManager);
|
||||
m_rootItem->appendChild(m_settingsTree);
|
||||
m_nonSettingsTree = new TopTreeItem(tr("Data Objects"), m_rootItem);
|
||||
m_nonSettingsTree->setHighlightManager(m_highlightManager);
|
||||
m_rootItem->appendChild(m_nonSettingsTree);
|
||||
m_rootItem = new TreeItem(rootData);
|
||||
m_rootItem->setHighlightManager(m_highlightManager);
|
||||
connect(m_settingsTree, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *)));
|
||||
connect(m_nonSettingsTree, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *)));
|
||||
|
||||
// tree item takes ownership of its children
|
||||
m_rootItem->appendChild(m_settingsTree);
|
||||
m_rootItem->appendChild(m_nonSettingsTree);
|
||||
|
||||
QList< QList<UAVDataObject *> > objList = objManager->getDataObjects();
|
||||
foreach(QList<UAVDataObject *> list, objList) {
|
||||
@ -258,8 +261,7 @@ void UAVObjectTreeModel::addSingleField(int index, UAVObjectField *field, TreeIt
|
||||
parent->appendChild(item);
|
||||
}
|
||||
|
||||
QModelIndex UAVObjectTreeModel::index(int row, int column, const QModelIndex &parent)
|
||||
const
|
||||
QModelIndex UAVObjectTreeModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (!hasIndex(row, column, parent)) {
|
||||
return QModelIndex();
|
||||
@ -306,10 +308,11 @@ QModelIndex UAVObjectTreeModel::parent(const QModelIndex &index) const
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
TreeItem *childItem = static_cast<TreeItem *>(index.internalPointer());
|
||||
TreeItem *parentItem = childItem->parent();
|
||||
TreeItem *item = static_cast<TreeItem *>(index.internalPointer());
|
||||
|
||||
if (parentItem == m_rootItem) {
|
||||
TreeItem *parentItem = item->parent();
|
||||
if (!parentItem) {
|
||||
// item is root has no parent...
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
@ -363,50 +366,56 @@ QVariant UAVObjectTreeModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
TreeItem *item = static_cast<TreeItem *>(index.internalPointer());
|
||||
|
||||
if (index.column() == TreeItem::DATA_COLUMN && role == Qt::EditRole) {
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
if (index.column() == TreeItem::DATA_COLUMN) {
|
||||
EnumFieldTreeItem *fieldItem = dynamic_cast<EnumFieldTreeItem *>(item);
|
||||
if (fieldItem) {
|
||||
int enumIndex = fieldItem->data(index.column()).toInt();
|
||||
return fieldItem->enumOptions(enumIndex);
|
||||
}
|
||||
}
|
||||
return item->data(index.column());
|
||||
}
|
||||
|
||||
if (role == Qt::ToolTipRole) {
|
||||
case Qt::EditRole:
|
||||
if (index.column() == TreeItem::DATA_COLUMN) {
|
||||
return item->data(index.column());
|
||||
}
|
||||
return QVariant();
|
||||
|
||||
case Qt::ToolTipRole:
|
||||
return item->description();
|
||||
}
|
||||
|
||||
if (role == Qt::ForegroundRole) {
|
||||
case Qt::ForegroundRole:
|
||||
if (!dynamic_cast<TopTreeItem *>(item) && !item->isKnown()) {
|
||||
return QVariant(m_unknownObjectColor);
|
||||
return m_unknownObjectColor;
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
|
||||
if (index.column() == 0 && role == Qt::BackgroundRole) {
|
||||
if (!dynamic_cast<TopTreeItem *>(item) && item->highlighted()) {
|
||||
return QVariant(m_recentlyUpdatedColor);
|
||||
case Qt::BackgroundRole:
|
||||
if (index.column() == TreeItem::TITLE_COLUMN) {
|
||||
if (!dynamic_cast<TopTreeItem *>(item) && item->highlighted()) {
|
||||
return m_recentlyUpdatedColor;
|
||||
}
|
||||
} else if (index.column() == TreeItem::DATA_COLUMN) {
|
||||
FieldTreeItem *fieldItem = dynamic_cast<FieldTreeItem *>(item);
|
||||
if (fieldItem && fieldItem->highlighted()) {
|
||||
return m_recentlyUpdatedColor;
|
||||
}
|
||||
if (fieldItem && fieldItem->changed()) {
|
||||
return m_manuallyChangedColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
|
||||
if (index.column() == TreeItem::DATA_COLUMN && role == Qt::BackgroundRole) {
|
||||
FieldTreeItem *fieldItem = dynamic_cast<FieldTreeItem *>(item);
|
||||
if (fieldItem && fieldItem->highlighted()) {
|
||||
return QVariant(m_recentlyUpdatedColor);
|
||||
}
|
||||
case Qt::UserRole:
|
||||
// UserRole gives access to TreeItem
|
||||
// cast to void* is necessary
|
||||
return qVariantFromValue((void *)item);
|
||||
|
||||
if (fieldItem && fieldItem->changed()) {
|
||||
return QVariant(m_manuallyChangedColor);
|
||||
}
|
||||
}
|
||||
|
||||
if (role != Qt::DisplayRole) {
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if (index.column() == TreeItem::DATA_COLUMN) {
|
||||
EnumFieldTreeItem *fieldItem = dynamic_cast<EnumFieldTreeItem *>(item);
|
||||
if (fieldItem) {
|
||||
int enumIndex = fieldItem->data(index.column()).toInt();
|
||||
return fieldItem->enumOptions(enumIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return item->data(index.column());
|
||||
}
|
||||
|
||||
bool UAVObjectTreeModel::setData(const QModelIndex &index, const QVariant & value, int role)
|
||||
|
Loading…
x
Reference in New Issue
Block a user