1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-12-01 09:24:10 +01:00

LP-286 Port TauLabs filter in UAVobjectbrowser

This commit is contained in:
Mateusz Kaduk 2016-04-10 18:46:40 +02:00
parent d3f150f5a8
commit e550317fdf
7 changed files with 243 additions and 50 deletions

View File

@ -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
@ -25,19 +26,24 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "uavobjectbrowserwidget.h"
#include "browseritemdelegate.h"
#include "fieldtreeitem.h"
BrowserItemDelegate::BrowserItemDelegate(QObject *parent) :
BrowserItemDelegate::BrowserItemDelegate(TreeSortFilterProxyModel *proxyModel, QObject *parent) :
QStyledItemDelegate(parent)
{}
{
this->proxyModel = proxyModel;
}
QWidget *BrowserItemDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem & option,
const QModelIndex & index) const
const QModelIndex & proxyIndex) const
{
Q_UNUSED(option)
FieldTreeItem * item = static_cast<FieldTreeItem *>(index.internalPointer());
QModelIndex index = proxyModel->mapToSource(proxyIndex);
FieldTreeItem *item = static_cast<FieldTreeItem *>(index.internalPointer());
QWidget *editor = item->createEditor(parent);
Q_ASSERT(editor);
return editor;
@ -45,21 +51,27 @@ QWidget *BrowserItemDelegate::createEditor(QWidget *parent,
void BrowserItemDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
const QModelIndex & proxyIndex) const
{
QModelIndex index = proxyModel->mapToSource(proxyIndex);
FieldTreeItem *item = static_cast<FieldTreeItem *>(index.internalPointer());
QVariant value = index.model()->data(index, Qt::EditRole);
QVariant value = proxyIndex.model()->data(proxyIndex, Qt::EditRole);
item->setEditorValue(editor, value);
}
void BrowserItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
const QModelIndex &proxyIndex) const
{
QModelIndex index = proxyModel->mapToSource(proxyIndex);
FieldTreeItem *item = static_cast<FieldTreeItem *>(index.internalPointer());
QVariant value = item->getEditorValue(editor);
model->setData(index, value, Qt::EditRole);
bool ret = model->setData(proxyIndex, value, Qt::EditRole);
Q_ASSERT(ret);
}
void BrowserItemDelegate::updateEditorGeometry(QWidget *editor,

View File

@ -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
@ -30,10 +31,12 @@
#include <QStyledItemDelegate>
class TreeSortFilterProxyModel;
class BrowserItemDelegate : public QStyledItemDelegate {
Q_OBJECT
public:
explicit BrowserItemDelegate(QObject *parent = 0);
explicit BrowserItemDelegate(TreeSortFilterProxyModel *proxyModel, QObject *parent = 0);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
@ -51,6 +54,9 @@ public:
signals:
public slots:
private:
TreeSortFilterProxyModel *proxyModel;
};
#endif // BROWSERITEMDELEGATE_H

View File

@ -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>Search for UAVObject...</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>

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @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.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup UAVObjectBrowserPlugin UAVObject Browser Plugin
@ -49,10 +50,13 @@ UAVObjectBrowserWidget::UAVObjectBrowserWidget(QWidget *parent) : QWidget(parent
m_viewoptions->setupUi(m_viewoptionsDialog);
m_browser->setupUi(this);
m_model = new UAVObjectTreeModel();
m_browser->treeView->setModel(m_model);
m_modelProxy = new TreeSortFilterProxyModel(this);
m_modelProxy->setSourceModel(m_model);
m_modelProxy->setDynamicSortFilter(true);
m_browser->treeView->setModel(m_modelProxy);
m_browser->treeView->setColumnWidth(0, 300);
BrowserItemDelegate *m_delegate = new BrowserItemDelegate();
BrowserItemDelegate *m_delegate = new BrowserItemDelegate(m_modelProxy);
m_browser->treeView->setItemDelegate(m_delegate);
m_browser->treeView->setEditTriggers(QAbstractItemView::AllEditTriggers);
m_browser->treeView->setSelectionBehavior(QAbstractItemView::SelectItems);
@ -76,6 +80,8 @@ UAVObjectBrowserWidget::UAVObjectBrowserWidget(QWidget *parent) : QWidget(parent
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()));
connect(m_browser->searchLine, SIGNAL(textChanged(QString)), this, SLOT(searchLineChanged(QString)));
connect(m_browser->searchClearButton, SIGNAL(clicked(bool)), this, SLOT(searchTextCleared()));
enableSendRequest(false);
}
@ -97,11 +103,29 @@ void UAVObjectBrowserWidget::setSplitterState(QByteArray state)
m_browser->splitter->restoreState(state);
}
void UAVObjectBrowserWidget::resetProxyModel(UAVObjectTreeModel *currentModel)
{
m_modelProxy = new TreeSortFilterProxyModel(this);
m_modelProxy->setSourceModel(currentModel);
m_modelProxy->setDynamicSortFilter(true);
m_browser->treeView->setModel(m_modelProxy);
BrowserItemDelegate *m_delegate = new BrowserItemDelegate(m_modelProxy);
m_browser->treeView->setItemDelegate(m_delegate);
if (!m_browser->searchLine->text().isEmpty()) {
emit searchLineChanged(m_browser->searchLine->text());
}
}
void UAVObjectBrowserWidget::showMetaData(bool show)
{
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);
}
}
@ -115,12 +139,12 @@ void UAVObjectBrowserWidget::categorize(bool categorize)
UAVObjectTreeModel *tmpModel = m_model;
m_model = new UAVObjectTreeModel(0, categorize, m_viewoptions->cbScientific->isChecked());
resetProxyModel(m_model);
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);
@ -132,11 +156,10 @@ void UAVObjectBrowserWidget::useScientificNotation(bool scientific)
UAVObjectTreeModel *tmpModel = m_model;
m_model = new UAVObjectTreeModel(0, m_viewoptions->cbCategorized->isChecked(), scientific);
m_model->setRecentlyUpdatedColor(m_recentlyUpdatedColor);
resetProxyModel(m_model);
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);
@ -147,26 +170,28 @@ void UAVObjectBrowserWidget::sendUpdate()
{
this->setFocus();
ObjectTreeItem *objItem = findCurrentObjectTreeItem();
Q_ASSERT(objItem);
if (objItem != NULL) {
objItem->apply();
UAVObject *obj = objItem->object();
Q_ASSERT(obj);
obj->updated();
}
}
void UAVObjectBrowserWidget::requestUpdate()
{
ObjectTreeItem *objItem = findCurrentObjectTreeItem();
Q_ASSERT(objItem);
if (objItem != NULL) {
UAVObject *obj = objItem->object();
Q_ASSERT(obj);
obj->requestUpdate();
}
}
ObjectTreeItem *UAVObjectBrowserWidget::findCurrentObjectTreeItem()
{
QModelIndex current = m_browser->treeView->currentIndex();
QModelIndex current = m_modelProxy->mapToSource(m_browser->treeView->currentIndex());
TreeItem *item = static_cast<TreeItem *>(current.internalPointer());
ObjectTreeItem *objItem = 0;
@ -196,12 +221,14 @@ void UAVObjectBrowserWidget::saveObject()
this->setFocus();
// Send update so that the latest value is saved
sendUpdate();
// Save object
ObjectTreeItem *objItem = findCurrentObjectTreeItem();
Q_ASSERT(objItem);
if (objItem != NULL) {
UAVObject *obj = objItem->object();
Q_ASSERT(obj);
updateObjectPersistance(ObjectPersistence::OPERATION_SAVE, obj);
}
}
void UAVObjectBrowserWidget::loadObject()
@ -209,22 +236,24 @@ void UAVObjectBrowserWidget::loadObject()
// Load object
ObjectTreeItem *objItem = findCurrentObjectTreeItem();
Q_ASSERT(objItem);
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);
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 +277,11 @@ void UAVObjectBrowserWidget::currentChanged(const QModelIndex &current, const QM
{
Q_UNUSED(previous);
TreeItem *item = static_cast<TreeItem *>(current.internalPointer());
QModelIndex cindex = m_modelProxy->mapToSource(current);
TreeItem *item = static_cast<TreeItem *>(cindex.internalPointer());
bool enable = true;
if (current == QModelIndex()) {
if (cindex == QModelIndex()) {
enable = false;
}
TopTreeItem *top = dynamic_cast<TopTreeItem *>(item);
@ -388,3 +419,95 @@ 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));
showMetaData(m_viewoptions->cbMetaData->isChecked());
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;
}

View File

@ -2,7 +2,8 @@
******************************************************************************
*
* @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.
* The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup UAVObjectBrowserPlugin UAVObject Browser Plugin
@ -30,6 +31,8 @@
#include <QWidget>
#include <QTreeView>
#include <QKeyEvent>
#include <QSortFilterProxyModel>
#include "objectpersistence.h"
#include "uavobjecttreemodel.h"
@ -38,6 +41,16 @@ 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
@ -87,6 +100,8 @@ private slots:
void currentChanged(const QModelIndex &current, const QModelIndex &previous);
void viewSlot();
void viewOptionsChangedSlot();
void searchLineChanged(QString searchText);
void searchTextCleared();
void splitterMoved();
QString createObjectDescription(UAVObject *object);
signals:
@ -99,6 +114,7 @@ private:
Ui_viewoptions *m_viewoptions;
QDialog *m_viewoptionsDialog;
UAVObjectTreeModel *m_model;
TreeSortFilterProxyModel *m_modelProxy;
int m_recentlyUpdatedTimeout;
QColor m_unknownObjectColor;
@ -110,6 +126,7 @@ private:
void updateObjectPersistance(ObjectPersistence::OperationOptions op, UAVObject *obj);
void enableSendRequest(bool enable);
void updateDescription();
void resetProxyModel(UAVObjectTreeModel *currentModel);
ObjectTreeItem *findCurrentObjectTreeItem();
QString loadFileIntoString(QString fileName);
};

View File

@ -30,6 +30,7 @@
#include "treeitem.h"
#include <QAbstractItemModel>
#include <QSortFilterProxyModel>
#include <QtCore/QMap>
#include <QtCore/QList>
#include <QColor>
@ -127,5 +128,4 @@ private:
// Highlight manager to handle highlighting of tree items.
HighLightManager *m_highlightManager;
};
#endif // UAVOBJECTTREEMODEL_H