mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#1898 Curve Creator: Use tree structure internally in QModel
This commit is contained in:
parent
da9421485e
commit
424c4b18a3
@ -121,6 +121,10 @@ QList<caf::PdmOptionItemInfo> ManyGroups::calculateValueOptions(const caf::PdmFi
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void ManyGroups::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
uiOrdering.add(&m_toggleField);
|
||||
uiOrdering.add(&m_multiSelectList);
|
||||
|
||||
/*
|
||||
{
|
||||
caf::PdmUiGroup* group = uiOrdering.addNewGroup("First");
|
||||
|
||||
@ -156,4 +160,5 @@ void ManyGroups::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOr
|
||||
|
||||
subGroup->add(&m_proxyDoubleField);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -40,8 +40,12 @@
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmUiTreeSelectionQModel.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QCheckBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QTreeView>
|
||||
|
||||
#include <algorithm>
|
||||
@ -99,6 +103,8 @@ CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiTreeSelectionEditor);
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
PdmUiTreeSelectionEditor::PdmUiTreeSelectionEditor()
|
||||
: m_model(nullptr),
|
||||
m_proxyModel(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@ -124,39 +130,89 @@ void PdmUiTreeSelectionEditor::configureAndUpdateUi(const QString& uiConfigName)
|
||||
bool optionsOnly = true;
|
||||
QList<PdmOptionItemInfo> options = field()->valueOptions(&optionsOnly);
|
||||
|
||||
if (!m_treeView->model())
|
||||
if (!m_model)
|
||||
{
|
||||
caf::PdmUiTreeSelectionQModel* model = new caf::PdmUiTreeSelectionQModel(m_treeView);
|
||||
m_treeView->setModel(model);
|
||||
connect(model, SIGNAL(signalSelectionStateForIndexHasChanged(int, bool)), this, SLOT(slotSetSelectionStateForIndex(int, bool)));
|
||||
m_model = new caf::PdmUiTreeSelectionQModel(m_treeView);
|
||||
|
||||
m_proxyModel = new QSortFilterProxyModel;
|
||||
m_proxyModel->setSourceModel(m_model);
|
||||
m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
|
||||
m_treeView->setModel(m_proxyModel);
|
||||
}
|
||||
|
||||
caf::PdmUiTreeSelectionQModel* treeSelectionQModel = dynamic_cast<caf::PdmUiTreeSelectionQModel*>(m_treeView->model());
|
||||
if (treeSelectionQModel)
|
||||
bool itemCountHasChaged = false;
|
||||
if (m_model->optionItemCount() != options.size()) itemCountHasChaged = true;
|
||||
|
||||
// TODO: If the count is different between incoming and current list of items,
|
||||
// use cafQTreeViewStateSerializer to restore collapsed state
|
||||
m_model->setOptions(this, options);
|
||||
|
||||
if (itemCountHasChaged)
|
||||
{
|
||||
bool itemCountHasChaged = false;
|
||||
if (treeSelectionQModel->optionItemCount() != options.size()) itemCountHasChaged = true;
|
||||
m_treeView->expandAll();
|
||||
}
|
||||
|
||||
// TODO: If the count is different between incoming and current list of items,
|
||||
// use cafQTreeViewStateSerializer to restore collapsed state
|
||||
treeSelectionQModel->setOptions(this, options);
|
||||
|
||||
if (itemCountHasChaged)
|
||||
bool allItemsChecked = true;
|
||||
QModelIndexList indices = allVisibleSourceModelIndices();
|
||||
for (auto mi : indices)
|
||||
{
|
||||
if (m_model->data(mi, Qt::CheckStateRole).toBool() == false)
|
||||
{
|
||||
m_treeView->expandAll();
|
||||
allItemsChecked = false;
|
||||
}
|
||||
}
|
||||
|
||||
//m_toggleAllCheckBox->setChecked(allItemsChecked);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeSelectionEditor::slotSetSelectionStateForIndex(int index, bool setSelected)
|
||||
QWidget* PdmUiTreeSelectionEditor::createEditorWidget(QWidget* parent)
|
||||
{
|
||||
std::vector<int> indices;
|
||||
indices.push_back(index);
|
||||
QFrame* frame = new QFrame(parent);
|
||||
QVBoxLayout* layout = new QVBoxLayout;
|
||||
frame->setLayout(layout);
|
||||
|
||||
setSelectionStateForIndices(indices, setSelected);
|
||||
{
|
||||
QHBoxLayout* headerLayout = new QHBoxLayout;
|
||||
layout->addLayout(headerLayout);
|
||||
|
||||
// m_toggleAllCheckBox = new QCheckBox();
|
||||
// headerLayout->addWidget(m_toggleAllCheckBox);
|
||||
//
|
||||
// connect(m_toggleAllCheckBox, SIGNAL(clicked(bool)), this, SLOT(slotToggleAll()));
|
||||
|
||||
// m_textFilterLineEdit = new QLineEdit();
|
||||
// headerLayout->addWidget(m_textFilterLineEdit);
|
||||
//
|
||||
// connect(m_textFilterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotTextFilterChanged()));
|
||||
}
|
||||
|
||||
QTreeViewHeightHint* treeViewHeightHint = new QTreeViewHeightHint(parent);
|
||||
treeViewHeightHint->setHeightHint(2000);
|
||||
|
||||
treeViewHeightHint->setHeaderHidden(true);
|
||||
treeViewHeightHint->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
treeViewHeightHint->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
connect(treeViewHeightHint, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint)));
|
||||
|
||||
m_treeView = treeViewHeightHint;
|
||||
|
||||
layout->addWidget(treeViewHeightHint);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QWidget* PdmUiTreeSelectionEditor::createLabelWidget(QWidget * parent)
|
||||
{
|
||||
m_label = new QLabel(parent);
|
||||
return m_label;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -166,43 +222,48 @@ void PdmUiTreeSelectionEditor::customMenuRequested(const QPoint& pos)
|
||||
{
|
||||
QMenu menu;
|
||||
|
||||
QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes();
|
||||
|
||||
bool onlyHeadersInSelection = true;
|
||||
for (auto mi : selectedIndexes)
|
||||
{
|
||||
std::vector<int> items = selectedCheckableItems();
|
||||
if (items.size() > 0)
|
||||
QVariant v = m_proxyModel->data(mi, PdmUiTreeSelectionQModel::headingRole());
|
||||
if (v.toBool() == false)
|
||||
{
|
||||
{
|
||||
QAction* act = new QAction("Set Selected On", this);
|
||||
connect(act, SIGNAL(triggered()), SLOT(slotSetSelectedOn()));
|
||||
|
||||
menu.addAction(act);
|
||||
}
|
||||
|
||||
{
|
||||
QAction* act = new QAction("Set Selected Off", this);
|
||||
connect(act, SIGNAL(triggered()), SLOT(slotSetSelectedOff()));
|
||||
|
||||
menu.addAction(act);
|
||||
}
|
||||
onlyHeadersInSelection = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (onlyHeadersInSelection)
|
||||
{
|
||||
std::vector<int> items = selectedHeaderItems();
|
||||
if (items.size() > 0)
|
||||
{
|
||||
{
|
||||
QAction* act = new QAction("Set Sub Items On", this);
|
||||
connect(act, SIGNAL(triggered()), SLOT(slotSetSubItemsOn()));
|
||||
QAction* act = new QAction("Sub Items On", this);
|
||||
connect(act, SIGNAL(triggered()), SLOT(slotSetSubItemsOn()));
|
||||
|
||||
menu.addAction(act);
|
||||
}
|
||||
menu.addAction(act);
|
||||
}
|
||||
|
||||
{
|
||||
QAction* act = new QAction("Set Sub Items Off", this);
|
||||
connect(act, SIGNAL(triggered()), SLOT(slotSetSubItemsOff()));
|
||||
{
|
||||
QAction* act = new QAction("Sub Items Off", this);
|
||||
connect(act, SIGNAL(triggered()), SLOT(slotSetSubItemsOff()));
|
||||
|
||||
menu.addAction(act);
|
||||
}
|
||||
menu.addAction(act);
|
||||
}
|
||||
}
|
||||
else if (selectedIndexes.size() > 0)
|
||||
{
|
||||
{
|
||||
QAction* act = new QAction("Set Selected On", this);
|
||||
connect(act, SIGNAL(triggered()), SLOT(slotSetSelectedOn()));
|
||||
|
||||
menu.addAction(act);
|
||||
}
|
||||
|
||||
{
|
||||
QAction* act = new QAction("Set Selected Off", this);
|
||||
connect(act, SIGNAL(triggered()), SLOT(slotSetSelectedOff()));
|
||||
|
||||
menu.addAction(act);
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,10 +281,12 @@ void PdmUiTreeSelectionEditor::customMenuRequested(const QPoint& pos)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeSelectionEditor::slotSetSelectedOn()
|
||||
{
|
||||
std::vector<int> items = selectedCheckableItems();
|
||||
if (items.size() > 0)
|
||||
if (!m_proxyModel) return;
|
||||
|
||||
QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes();
|
||||
for (auto mi : selectedIndexes)
|
||||
{
|
||||
setSelectionStateForIndices(items, true);
|
||||
m_proxyModel->setData(mi, true, Qt::CheckStateRole);
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,10 +295,12 @@ void PdmUiTreeSelectionEditor::slotSetSelectedOn()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeSelectionEditor::slotSetSelectedOff()
|
||||
{
|
||||
std::vector<int> items = selectedCheckableItems();
|
||||
if (items.size() > 0)
|
||||
if (!m_proxyModel) return;
|
||||
|
||||
QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes();
|
||||
for (auto mi : selectedIndexes)
|
||||
{
|
||||
setSelectionStateForIndices(items, false);
|
||||
m_proxyModel->setData(mi, false, Qt::CheckStateRole);
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,14 +309,14 @@ void PdmUiTreeSelectionEditor::slotSetSelectedOff()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeSelectionEditor::slotSetSubItemsOn()
|
||||
{
|
||||
caf::PdmUiTreeSelectionQModel* treeSelectionQModel = dynamic_cast<caf::PdmUiTreeSelectionQModel*>(m_treeView->model());
|
||||
|
||||
std::vector<int> items = selectedHeaderItems();
|
||||
for (auto i : items)
|
||||
QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes();
|
||||
for (auto mi : selectedIndexes)
|
||||
{
|
||||
std::vector<int> children = treeSelectionQModel->allSubItemIndices(i);
|
||||
|
||||
setSelectionStateForIndices(children, true);
|
||||
for (int i = 0; i < m_proxyModel->rowCount(mi); i++)
|
||||
{
|
||||
QModelIndex childIndex = m_proxyModel->index(i, 0, mi);
|
||||
m_proxyModel->setData(childIndex, true, Qt::CheckStateRole);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,145 +325,99 @@ void PdmUiTreeSelectionEditor::slotSetSubItemsOn()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeSelectionEditor::slotSetSubItemsOff()
|
||||
{
|
||||
caf::PdmUiTreeSelectionQModel* treeSelectionQModel = dynamic_cast<caf::PdmUiTreeSelectionQModel*>(m_treeView->model());
|
||||
|
||||
std::vector<int> items = selectedHeaderItems();
|
||||
for (auto i : items)
|
||||
QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes();
|
||||
for (auto mi : selectedIndexes)
|
||||
{
|
||||
std::vector<int> children = treeSelectionQModel->allSubItemIndices(i);
|
||||
|
||||
setSelectionStateForIndices(children, false);
|
||||
for (int i = 0; i < m_proxyModel->rowCount(mi); i++)
|
||||
{
|
||||
QModelIndex childIndex = m_proxyModel->index(i, 0, mi);
|
||||
m_proxyModel->setData(childIndex, false, Qt::CheckStateRole);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<int> PdmUiTreeSelectionEditor::selectedCheckableItems() const
|
||||
void PdmUiTreeSelectionEditor::slotToggleAll()
|
||||
{
|
||||
std::vector<int> items;
|
||||
|
||||
caf::PdmUiTreeSelectionQModel* treeSelectionQModel = dynamic_cast<caf::PdmUiTreeSelectionQModel*>(m_treeView->model());
|
||||
if (treeSelectionQModel)
|
||||
if (m_toggleAllCheckBox->isChecked())
|
||||
{
|
||||
QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes();
|
||||
|
||||
for (auto mi : selectedIndexes)
|
||||
{
|
||||
auto optionItem = treeSelectionQModel->optionItem(mi);
|
||||
if (!optionItem->isHeading())
|
||||
{
|
||||
items.push_back(treeSelectionQModel->optionItemIndex(mi));
|
||||
}
|
||||
}
|
||||
checkAllItems();
|
||||
}
|
||||
else
|
||||
{
|
||||
unCheckAllItems();
|
||||
}
|
||||
|
||||
return items;
|
||||
// Set focus back to the tree view to trigger a redraw
|
||||
m_treeView->setFocus();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<int> PdmUiTreeSelectionEditor::selectedHeaderItems() const
|
||||
void PdmUiTreeSelectionEditor::slotTextFilterChanged()
|
||||
{
|
||||
std::vector<int> items;
|
||||
QString searchString = m_textFilterLineEdit->text();
|
||||
searchString += "*";
|
||||
|
||||
caf::PdmUiTreeSelectionQModel* treeSelectionQModel = dynamic_cast<caf::PdmUiTreeSelectionQModel*>(m_treeView->model());
|
||||
if (treeSelectionQModel)
|
||||
{
|
||||
QModelIndexList selectedIndexes = m_treeView->selectionModel()->selectedIndexes();
|
||||
|
||||
for (auto mi : selectedIndexes)
|
||||
{
|
||||
auto optionItem = treeSelectionQModel->optionItem(mi);
|
||||
if (optionItem->isHeading())
|
||||
{
|
||||
items.push_back(treeSelectionQModel->optionItemIndex(mi));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
m_proxyModel->setFilterWildcard(searchString);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeSelectionEditor::setSelectionStateForIndices(const std::vector<int>& indices, bool setSelected)
|
||||
void PdmUiTreeSelectionEditor::checkAllItems()
|
||||
{
|
||||
std::vector<unsigned int> selectedIndices;
|
||||
QModelIndexList indices = allVisibleSourceModelIndices();
|
||||
|
||||
m_model->setCheckedStateForItems(indices, true);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeSelectionEditor::unCheckAllItems()
|
||||
{
|
||||
QModelIndexList indices = allVisibleSourceModelIndices();
|
||||
|
||||
m_model->setCheckedStateForItems(indices, false);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QModelIndexList PdmUiTreeSelectionEditor::allVisibleSourceModelIndices() const
|
||||
{
|
||||
QModelIndexList indices;
|
||||
|
||||
recursiveAppendVisibleSourceModelIndices(QModelIndex(), &indices);
|
||||
|
||||
return indices;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmUiTreeSelectionEditor::recursiveAppendVisibleSourceModelIndices(const QModelIndex& parent, QModelIndexList* sourceModelIndices) const
|
||||
{
|
||||
for (int row = 0; row < m_proxyModel->rowCount(parent); row++)
|
||||
{
|
||||
QVariant fieldValue = field()->uiValue();
|
||||
QList<QVariant> fieldValueSelection = fieldValue.toList();
|
||||
|
||||
for (auto v : fieldValueSelection)
|
||||
QModelIndex mi = m_proxyModel->index(row, 0, parent);
|
||||
if (mi.isValid())
|
||||
{
|
||||
selectedIndices.push_back(v.toUInt());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto index : indices)
|
||||
{
|
||||
unsigned int unsignedIndex = static_cast<unsigned int>(index);
|
||||
|
||||
if (setSelected)
|
||||
{
|
||||
bool isIndexPresent = false;
|
||||
for (auto indexInField : selectedIndices)
|
||||
QVariant v = m_proxyModel->data(mi, PdmUiTreeSelectionQModel::headingRole());
|
||||
if (v.toBool() == false)
|
||||
{
|
||||
if (indexInField == unsignedIndex)
|
||||
{
|
||||
isIndexPresent = true;
|
||||
}
|
||||
sourceModelIndices->push_back(m_proxyModel->mapToSource(mi));
|
||||
}
|
||||
|
||||
if (!isIndexPresent)
|
||||
{
|
||||
selectedIndices.push_back(unsignedIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedIndices.erase(std::remove(selectedIndices.begin(), selectedIndices.end(), unsignedIndex), selectedIndices.end());
|
||||
recursiveAppendVisibleSourceModelIndices(mi, sourceModelIndices);
|
||||
}
|
||||
}
|
||||
|
||||
QList<QVariant> fieldValueSelection;
|
||||
for (auto v : selectedIndices)
|
||||
{
|
||||
fieldValueSelection.push_back(QVariant(v));
|
||||
}
|
||||
|
||||
this->setValueToField(fieldValueSelection);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QWidget* PdmUiTreeSelectionEditor::createEditorWidget(QWidget * parent)
|
||||
{
|
||||
QTreeViewHeightHint* treeViewHeightHint = new QTreeViewHeightHint(parent);
|
||||
treeViewHeightHint->setHeightHint(2000);
|
||||
|
||||
treeViewHeightHint->setHeaderHidden(true);
|
||||
treeViewHeightHint->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
treeViewHeightHint->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
connect(treeViewHeightHint, SIGNAL(customContextMenuRequested(QPoint)), SLOT(customMenuRequested(QPoint)));
|
||||
|
||||
m_treeView = treeViewHeightHint;
|
||||
|
||||
return treeViewHeightHint;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QWidget* PdmUiTreeSelectionEditor::createLabelWidget(QWidget * parent)
|
||||
{
|
||||
m_label = new QLabel(parent);
|
||||
return m_label;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace caf
|
||||
|
@ -38,12 +38,34 @@
|
||||
|
||||
#include "cafPdmUiFieldEditorHandle.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
class QLabel;
|
||||
class QTreeView;
|
||||
class QAbstractItemModel;
|
||||
class QCheckBox;
|
||||
class QLineEdit;
|
||||
class QSortFilterProxyModel;
|
||||
class QModelIndex;
|
||||
|
||||
namespace caf
|
||||
{
|
||||
class PdmUiTreeSelectionQModel;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class PdmUiTreeSelectionEditorAttribute : public PdmUiEditorAttribute
|
||||
{
|
||||
public:
|
||||
bool showTextFilter;
|
||||
|
||||
public:
|
||||
PdmUiTreeSelectionEditorAttribute()
|
||||
{
|
||||
showTextFilter = false;
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -54,16 +76,15 @@ class PdmUiTreeSelectionEditor : public PdmUiFieldEditorHandle
|
||||
CAF_PDM_UI_FIELD_EDITOR_HEADER_INIT;
|
||||
|
||||
public:
|
||||
PdmUiTreeSelectionEditor();
|
||||
virtual ~PdmUiTreeSelectionEditor();
|
||||
PdmUiTreeSelectionEditor();
|
||||
virtual ~PdmUiTreeSelectionEditor();
|
||||
|
||||
protected:
|
||||
virtual QWidget* createEditorWidget(QWidget * parent);
|
||||
virtual QWidget* createLabelWidget(QWidget * parent);
|
||||
virtual void configureAndUpdateUi(const QString& uiConfigName);
|
||||
virtual QWidget* createEditorWidget(QWidget* parent);
|
||||
virtual QWidget* createLabelWidget(QWidget* parent);
|
||||
|
||||
private slots:
|
||||
void slotSetSelectionStateForIndex(int index, bool setSelected);
|
||||
void customMenuRequested(const QPoint& pos);
|
||||
|
||||
void slotSetSelectedOn();
|
||||
@ -71,14 +92,26 @@ private slots:
|
||||
void slotSetSubItemsOn();
|
||||
void slotSetSubItemsOff();
|
||||
|
||||
private:
|
||||
std::vector<int> selectedCheckableItems() const;
|
||||
std::vector<int> selectedHeaderItems() const;
|
||||
void setSelectionStateForIndices(const std::vector<int>& indices, bool setSelected);
|
||||
void slotToggleAll();
|
||||
|
||||
void slotTextFilterChanged();
|
||||
|
||||
private:
|
||||
QPointer<QTreeView> m_treeView;
|
||||
QPointer<QLabel> m_label;
|
||||
void checkAllItems();
|
||||
void unCheckAllItems();
|
||||
|
||||
QModelIndexList allVisibleSourceModelIndices() const;
|
||||
void recursiveAppendVisibleSourceModelIndices(const QModelIndex& parent,
|
||||
QModelIndexList* sourceModelIndices) const;
|
||||
|
||||
private:
|
||||
QPointer<QTreeView> m_treeView;
|
||||
QPointer<QLabel> m_label;
|
||||
QPointer<QCheckBox> m_toggleAllCheckBox;
|
||||
QPointer<QLineEdit> m_textFilterLineEdit;
|
||||
|
||||
PdmUiTreeSelectionQModel* m_model;
|
||||
QSortFilterProxyModel* m_proxyModel;
|
||||
};
|
||||
|
||||
} // end namespace caf
|
||||
|
@ -36,8 +36,9 @@
|
||||
|
||||
#include "cafPdmUiTreeSelectionQModel.h"
|
||||
|
||||
#include "cafPdmUiTreeViewModel.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmUiCommandSystemProxy.h"
|
||||
#include "cafPdmUiTreeViewModel.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QLabel>
|
||||
@ -50,29 +51,68 @@
|
||||
caf::PdmUiTreeSelectionQModel::PdmUiTreeSelectionQModel(QObject *parent /*= 0*/) : QAbstractItemModel(parent)
|
||||
{
|
||||
m_uiFieldHandle = nullptr;
|
||||
m_zeroLevelRowCount = 0;
|
||||
m_tree = nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void caf::PdmUiTreeSelectionQModel::setOptions(caf::PdmUiFieldEditorHandle* field, const QList<caf::PdmOptionItemInfo>& options)
|
||||
caf::PdmUiTreeSelectionQModel::~PdmUiTreeSelectionQModel()
|
||||
{
|
||||
bool itemCountHasChanged = false;
|
||||
if (optionItemCount() != options.size())
|
||||
m_uiFieldHandle = nullptr;
|
||||
|
||||
delete m_tree;
|
||||
m_tree = nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int caf::PdmUiTreeSelectionQModel::headingRole()
|
||||
{
|
||||
return Qt::UserRole + 1;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void caf::PdmUiTreeSelectionQModel::setCheckedStateForItems(const QModelIndexList& sourceModelIndices, bool checked)
|
||||
{
|
||||
std::set<unsigned int> selectedIndices;
|
||||
{
|
||||
itemCountHasChanged = true;
|
||||
QVariant fieldValue = m_uiFieldHandle->field()->uiValue();
|
||||
QList<QVariant> fieldValueSelection = fieldValue.toList();
|
||||
|
||||
for (auto v : fieldValueSelection)
|
||||
{
|
||||
selectedIndices.insert(v.toUInt());
|
||||
}
|
||||
}
|
||||
|
||||
m_uiFieldHandle = field;
|
||||
m_options = options;
|
||||
|
||||
computeOptionItemTreeData();
|
||||
|
||||
if (itemCountHasChanged)
|
||||
if (checked)
|
||||
{
|
||||
reset();
|
||||
for (auto mi : sourceModelIndices)
|
||||
{
|
||||
selectedIndices.insert(static_cast<unsigned int>(optionIndex(mi)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto mi : sourceModelIndices)
|
||||
{
|
||||
selectedIndices.erase(static_cast<unsigned int>(optionIndex(mi)));
|
||||
}
|
||||
}
|
||||
|
||||
QList<QVariant> fieldValueSelection;
|
||||
for (auto v : selectedIndices)
|
||||
{
|
||||
fieldValueSelection.push_back(QVariant(v));
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
PdmUiCommandSystemProxy::instance()->setUiValueToField(m_uiFieldHandle->field(), fieldValueSelection);
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -83,19 +123,54 @@ int caf::PdmUiTreeSelectionQModel::optionItemCount() const
|
||||
return m_options.size();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void caf::PdmUiTreeSelectionQModel::setOptions(caf::PdmUiFieldEditorHandle* field, const QList<caf::PdmOptionItemInfo>& options)
|
||||
{
|
||||
m_uiFieldHandle = field;
|
||||
|
||||
if (m_options.size() != options.size())
|
||||
{
|
||||
beginResetModel();
|
||||
|
||||
m_options = options;
|
||||
|
||||
if (m_tree)
|
||||
{
|
||||
delete m_tree;
|
||||
m_tree = nullptr;
|
||||
}
|
||||
|
||||
m_tree = new TreeItemType(nullptr, -1, 0);
|
||||
buildOptionItemTree(0, m_tree);
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const caf::PdmOptionItemInfo* caf::PdmUiTreeSelectionQModel::optionItem(const QModelIndex &index) const
|
||||
{
|
||||
if (index.isValid())
|
||||
{
|
||||
int opIndex = optionItemIndex(index);
|
||||
int opIndex = optionIndex(index);
|
||||
|
||||
return &(m_options[opIndex]);
|
||||
}
|
||||
return &m_options[opIndex];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int caf::PdmUiTreeSelectionQModel::optionIndex(const QModelIndex &index) const
|
||||
{
|
||||
CAF_ASSERT(index.isValid());
|
||||
|
||||
TreeItemType* item = static_cast<TreeItemType*>(index.internalPointer());
|
||||
|
||||
int optionIndex = item->dataObject();
|
||||
|
||||
return optionIndex;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -105,13 +180,13 @@ Qt::ItemFlags caf::PdmUiTreeSelectionQModel::flags(const QModelIndex &index) con
|
||||
{
|
||||
if (index.isValid())
|
||||
{
|
||||
int opIndex = optionItemIndex(index);
|
||||
const caf::PdmOptionItemInfo* optionItemInfo = optionItem(index);
|
||||
|
||||
if (m_options[opIndex].isReadOnly())
|
||||
if (optionItemInfo->isReadOnly())
|
||||
{
|
||||
return QAbstractItemModel::flags(index)^Qt::ItemIsEnabled;
|
||||
}
|
||||
else if (!m_options[opIndex].isHeading())
|
||||
else if (!optionItemInfo->isHeading())
|
||||
{
|
||||
return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable;
|
||||
}
|
||||
@ -128,23 +203,18 @@ QModelIndex caf::PdmUiTreeSelectionQModel::index(int row, int column, const QMod
|
||||
if (!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
|
||||
if (m_zeroLevelRowToOptionIndex.size() == 0)
|
||||
return QModelIndex();
|
||||
TreeItemType* parentItem;
|
||||
|
||||
int opIndex = -1;
|
||||
if (parent.isValid())
|
||||
{
|
||||
opIndex = optionItemIndex(parent) + row + 1;
|
||||
}
|
||||
if (!parent.isValid())
|
||||
parentItem = m_tree;
|
||||
else
|
||||
{
|
||||
opIndex = m_zeroLevelRowToOptionIndex.at(row);
|
||||
}
|
||||
parentItem = static_cast<TreeItemType*>(parent.internalPointer());
|
||||
|
||||
CAF_ASSERT(opIndex > -1);
|
||||
CAF_ASSERT(opIndex < m_options.size());
|
||||
|
||||
return createIndex(row, column, opIndex);
|
||||
TreeItemType* childItem = parentItem->child(row);
|
||||
if (childItem)
|
||||
return createIndex(row, column, childItem);
|
||||
else
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -158,12 +228,18 @@ int caf::PdmUiTreeSelectionQModel::columnCount(const QModelIndex &parent /*= QMo
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QModelIndex caf::PdmUiTreeSelectionQModel::parent(const QModelIndex &child) const
|
||||
QModelIndex caf::PdmUiTreeSelectionQModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if (!child.isValid())
|
||||
if (!index.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
return m_optionsTreeData[optionItemIndex(child)].parentModelIndex;
|
||||
TreeItemType* childItem = static_cast<TreeItemType*>(index.internalPointer());
|
||||
TreeItemType* parentItem = childItem->parent();
|
||||
|
||||
if (parentItem == m_tree)
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(parentItem->row(), 0, parentItem);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -171,12 +247,18 @@ QModelIndex caf::PdmUiTreeSelectionQModel::parent(const QModelIndex &child) cons
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int caf::PdmUiTreeSelectionQModel::rowCount(const QModelIndex &parent /*= QModelIndex()*/) const
|
||||
{
|
||||
if (!parent.isValid())
|
||||
{
|
||||
return m_zeroLevelRowCount;
|
||||
}
|
||||
if (!m_tree) return 0;
|
||||
|
||||
return m_optionsTreeData[optionItemIndex(parent)].childCount;
|
||||
if (parent.column() > 0)
|
||||
return 0;
|
||||
|
||||
TreeItemType* parentItem;
|
||||
if (!parent.isValid())
|
||||
parentItem = m_tree;
|
||||
else
|
||||
parentItem = static_cast<TreeItemType*>(parent.internalPointer());
|
||||
|
||||
return parentItem->childCount();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -186,19 +268,17 @@ QVariant caf::PdmUiTreeSelectionQModel::data(const QModelIndex &index, int role
|
||||
{
|
||||
if (index.isValid())
|
||||
{
|
||||
CAF_ASSERT(index.internalId() < m_options.size());
|
||||
|
||||
int opIndex = optionItemIndex(index);
|
||||
const caf::PdmOptionItemInfo* optionItemInfo = optionItem(index);
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
return m_options[opIndex].optionUiText();
|
||||
return optionItemInfo->optionUiText();
|
||||
}
|
||||
else if (role == Qt::DecorationRole)
|
||||
{
|
||||
return m_options[opIndex].icon();
|
||||
return optionItemInfo->icon();
|
||||
}
|
||||
else if (role == Qt::CheckStateRole && !m_options[opIndex].isHeading())
|
||||
else if (role == Qt::CheckStateRole && !optionItemInfo->isHeading())
|
||||
{
|
||||
CAF_ASSERT(m_uiFieldHandle);
|
||||
|
||||
@ -207,6 +287,8 @@ QVariant caf::PdmUiTreeSelectionQModel::data(const QModelIndex &index, int role
|
||||
QVariant fieldValue = m_uiFieldHandle->field()->uiValue();
|
||||
QList<QVariant> valuesSelectedInField = fieldValue.toList();
|
||||
|
||||
int opIndex = optionIndex(index);
|
||||
|
||||
for (QVariant v : valuesSelectedInField)
|
||||
{
|
||||
int indexInField = v.toInt();
|
||||
@ -221,7 +303,7 @@ QVariant caf::PdmUiTreeSelectionQModel::data(const QModelIndex &index, int role
|
||||
}
|
||||
else if (role == Qt::FontRole)
|
||||
{
|
||||
if (m_options[opIndex].isHeading())
|
||||
if (optionItemInfo->isHeading())
|
||||
{
|
||||
QFont font;
|
||||
font.setBold(true);
|
||||
@ -229,6 +311,10 @@ QVariant caf::PdmUiTreeSelectionQModel::data(const QModelIndex &index, int role
|
||||
return font;
|
||||
}
|
||||
}
|
||||
else if (role == headingRole())
|
||||
{
|
||||
return optionItemInfo->isHeading();
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
@ -239,14 +325,54 @@ QVariant caf::PdmUiTreeSelectionQModel::data(const QModelIndex &index, int role
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool caf::PdmUiTreeSelectionQModel::setData(const QModelIndex &index, const QVariant &value, int role /*= Qt::EditRole*/)
|
||||
{
|
||||
if (role == Qt::CheckStateRole)
|
||||
{
|
||||
bool isSelected = value.toBool();
|
||||
if (role == Qt::CheckStateRole)
|
||||
{
|
||||
std::vector<unsigned int> selectedIndices;
|
||||
{
|
||||
QVariant fieldValue = m_uiFieldHandle->field()->uiValue();
|
||||
QList<QVariant> fieldValueSelection = fieldValue.toList();
|
||||
|
||||
emit signalSelectionStateForIndexHasChanged(optionItemIndex(index), isSelected);
|
||||
for (auto v : fieldValueSelection)
|
||||
{
|
||||
selectedIndices.push_back(v.toUInt());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool setSelected = value.toBool();
|
||||
|
||||
unsigned int opIndex = static_cast<unsigned int>(optionIndex(index));
|
||||
|
||||
if (setSelected)
|
||||
{
|
||||
bool isIndexPresent = false;
|
||||
for (auto indexInField : selectedIndices)
|
||||
{
|
||||
if (indexInField == opIndex)
|
||||
{
|
||||
isIndexPresent = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isIndexPresent)
|
||||
{
|
||||
selectedIndices.push_back(opIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedIndices.erase(std::remove(selectedIndices.begin(), selectedIndices.end(), opIndex), selectedIndices.end());
|
||||
}
|
||||
|
||||
QList<QVariant> fieldValueSelection;
|
||||
for (auto v : selectedIndices)
|
||||
{
|
||||
fieldValueSelection.push_back(QVariant(v));
|
||||
}
|
||||
|
||||
PdmUiCommandSystemProxy::instance()->setUiValueToField(m_uiFieldHandle->field(), fieldValueSelection);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -254,106 +380,33 @@ bool caf::PdmUiTreeSelectionQModel::setData(const QModelIndex &index, const QVar
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int caf::PdmUiTreeSelectionQModel::optionItemIndex(const QModelIndex& modelIndex) const
|
||||
void caf::PdmUiTreeSelectionQModel::buildOptionItemTree(int parentOptionIndex, TreeItemType* parentNode)
|
||||
{
|
||||
CAF_ASSERT(modelIndex.isValid());
|
||||
CAF_ASSERT(modelIndex.internalId() < m_options.size());
|
||||
|
||||
return modelIndex.internalId();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<int> caf::PdmUiTreeSelectionQModel::allSubItemIndices(int headingIndex) const
|
||||
{
|
||||
std::vector<int> children;
|
||||
|
||||
int parentLevel = m_options[headingIndex].level();
|
||||
|
||||
int currentIndex = headingIndex + 1;
|
||||
while (currentIndex < m_options.size() && m_options[currentIndex].level() > parentLevel)
|
||||
if (parentNode == m_tree)
|
||||
{
|
||||
children.push_back(currentIndex);
|
||||
currentIndex++;
|
||||
for (int i = 0; i < m_options.size(); i++)
|
||||
{
|
||||
if (m_options[i].level() == 0)
|
||||
{
|
||||
TreeItemType* node = new TreeItemType(parentNode, -1, i);
|
||||
|
||||
buildOptionItemTree(i, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void caf::PdmUiTreeSelectionQModel::computeOptionItemTreeData()
|
||||
{
|
||||
m_optionsTreeData.clear();
|
||||
m_zeroLevelRowToOptionIndex.clear();
|
||||
|
||||
if (m_options.size() == 0) return;
|
||||
|
||||
m_optionsTreeData.resize(m_options.size());
|
||||
|
||||
m_zeroLevelRowCount = 0;
|
||||
|
||||
for (int i = 0; i < m_options.size(); i++)
|
||||
else
|
||||
{
|
||||
if (m_options[i].level() == 0)
|
||||
int currentOptionIndex = parentOptionIndex + 1;
|
||||
while (currentOptionIndex < m_options.size() && m_options[currentOptionIndex].level() > m_options[parentNode->dataObject()].level())
|
||||
{
|
||||
m_zeroLevelRowToOptionIndex[m_zeroLevelRowCount] = i;
|
||||
|
||||
m_zeroLevelRowCount++;
|
||||
|
||||
m_optionsTreeData[i].parentModelIndex = QModelIndex();
|
||||
}
|
||||
else if (m_options[i].level() > 0)
|
||||
{
|
||||
// Compute parent model index
|
||||
|
||||
int childLevel = m_options[i].level();
|
||||
|
||||
int parentOptionIndex = i - 1;
|
||||
while (parentOptionIndex > -1)
|
||||
if (m_options[currentOptionIndex].level() == m_options[parentNode->dataObject()].level() + 1)
|
||||
{
|
||||
if (m_options[parentOptionIndex].level() == childLevel - 1)
|
||||
{
|
||||
int parentRow = 0;
|
||||
TreeItemType* node = new TreeItemType(parentNode, -1, currentOptionIndex);
|
||||
|
||||
int parentLevelOptionIndex = parentOptionIndex - 1;
|
||||
while (parentLevelOptionIndex > -1 && m_options[parentLevelOptionIndex].level() > childLevel - 2)
|
||||
{
|
||||
if (m_options[parentLevelOptionIndex].level() == childLevel - 1)
|
||||
{
|
||||
parentRow++;
|
||||
}
|
||||
|
||||
parentLevelOptionIndex--;
|
||||
}
|
||||
|
||||
m_optionsTreeData[i].parentModelIndex = createIndex(parentRow, 0, parentOptionIndex);
|
||||
break;
|
||||
}
|
||||
|
||||
parentOptionIndex--;
|
||||
buildOptionItemTree(currentOptionIndex, node);
|
||||
}
|
||||
currentOptionIndex++;
|
||||
}
|
||||
|
||||
int childCount = 0;
|
||||
{
|
||||
int parentLevel = m_options[i].level();
|
||||
int currentOptionIndex = i + 1;
|
||||
|
||||
while (currentOptionIndex < m_options.size() && m_options[currentOptionIndex].level() > parentLevel)
|
||||
{
|
||||
if (m_options[currentOptionIndex].level() == parentLevel + 1)
|
||||
{
|
||||
childCount++;
|
||||
}
|
||||
|
||||
currentOptionIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
m_optionsTreeData[i].childCount = childCount;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmUiFieldEditorHandle.h"
|
||||
#include "cafUiTreeItem.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
|
||||
@ -50,16 +51,6 @@ class PdmOptionItemInfo;
|
||||
class PdmUiFieldHandle;
|
||||
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class OptionItemTreeData
|
||||
{
|
||||
public:
|
||||
int childCount;
|
||||
QModelIndex parentModelIndex;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
@ -68,13 +59,14 @@ class PdmUiTreeSelectionQModel : public QAbstractItemModel
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PdmUiTreeSelectionQModel(QObject *parent = 0);
|
||||
~PdmUiTreeSelectionQModel();
|
||||
|
||||
void setOptions(caf::PdmUiFieldEditorHandle* field, const QList<caf::PdmOptionItemInfo>& options);
|
||||
static int headingRole();
|
||||
|
||||
int optionItemCount() const;
|
||||
const caf::PdmOptionItemInfo* optionItem(const QModelIndex &index) const;
|
||||
int optionItemIndex(const QModelIndex& modelIndex) const;
|
||||
std::vector<int> allSubItemIndices(int headingIndex) const;
|
||||
void setCheckedStateForItems(const QModelIndexList& indices, bool checked);
|
||||
|
||||
int optionItemCount() const;
|
||||
void setOptions(caf::PdmUiFieldEditorHandle* field, const QList<caf::PdmOptionItemInfo>& options);
|
||||
|
||||
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
|
||||
@ -84,19 +76,18 @@ public:
|
||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
signals:
|
||||
void signalSelectionStateForIndexHasChanged(int index, bool isSelected);
|
||||
|
||||
private:
|
||||
void computeOptionItemTreeData();
|
||||
typedef caf::UiTreeItem<int> TreeItemType;
|
||||
|
||||
const caf::PdmOptionItemInfo* optionItem(const QModelIndex &index) const;
|
||||
int optionIndex(const QModelIndex &index) const;
|
||||
void buildOptionItemTree(int optionIndex, TreeItemType* parentNode);
|
||||
|
||||
private:
|
||||
QList<caf::PdmOptionItemInfo> m_options;
|
||||
caf::PdmUiFieldEditorHandle* m_uiFieldHandle;
|
||||
|
||||
std::vector<OptionItemTreeData> m_optionsTreeData;
|
||||
int m_zeroLevelRowCount;
|
||||
std::map<int, int> m_zeroLevelRowToOptionIndex;
|
||||
TreeItemType* m_tree;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user