#1830 AppFwk : Cache data to speed up model queries

This commit is contained in:
Magne Sjaastad
2017-09-06 10:54:51 +02:00
parent e7351179c3
commit 55bdf4701e
2 changed files with 134 additions and 108 deletions

View File

@@ -43,13 +43,14 @@
#include <QLabel> #include <QLabel>
#include <QTreeView> #include <QTreeView>
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
caf::PdmUiTreeSelectionQModel::PdmUiTreeSelectionQModel(QObject *parent /*= 0*/) : QAbstractItemModel(parent) caf::PdmUiTreeSelectionQModel::PdmUiTreeSelectionQModel(QObject *parent /*= 0*/) : QAbstractItemModel(parent)
{ {
m_uiFieldHandle = nullptr;
m_zeroLevelRowCount = 0;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -59,6 +60,8 @@ void caf::PdmUiTreeSelectionQModel::setOptions(caf::PdmUiFieldEditorHandle* fiel
{ {
m_uiFieldHandle = field; m_uiFieldHandle = field;
m_options = options; m_options = options;
computeOptionItemTreeData();
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -77,32 +80,20 @@ QModelIndex caf::PdmUiTreeSelectionQModel::index(int row, int column, const QMod
if (!hasIndex(row, column, parent)) if (!hasIndex(row, column, parent))
return QModelIndex(); return QModelIndex();
int optionItemIndex = -1;
if (parent.isValid()) if (parent.isValid())
{ {
int optionItemIndex = parent.internalId() + 1 + row; optionItemIndex = toOptionItemIndex(parent) + row + 1;
return createIndex(row, column, optionItemIndex);
} }
else else
{ {
int optionItemIndex = 0; optionItemIndex = m_zeroLevelRowToOptionIndex.at(row);
int zeroLevelItemCount = 0;
while (optionItemIndex < m_options.size())
{
if (m_options[optionItemIndex].level() == 0)
{
zeroLevelItemCount++;
if (zeroLevelItemCount == row + 1)
{
return createIndex(row, column, optionItemIndex);
}
}
optionItemIndex++;
}
} }
return QModelIndex(); CAF_ASSERT(optionItemIndex > -1);
CAF_ASSERT(optionItemIndex < m_options.size());
return createIndex(row, column, optionItemIndex);
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -121,40 +112,7 @@ QModelIndex caf::PdmUiTreeSelectionQModel::parent(const QModelIndex &child) cons
if (!child.isValid()) if (!child.isValid())
return QModelIndex(); return QModelIndex();
int childOptionIndex = toOptionItemIndex(child); return m_optionsTreeData[toOptionItemIndex(child)].parentModelIndex;
int childLevel = m_options[childOptionIndex].level();
if (childLevel < 1)
{
return QModelIndex();
}
int parentOptionIndex = childOptionIndex - 1;
while (parentOptionIndex > -1)
{
if (m_options[parentOptionIndex].level() == childLevel - 1)
{
int parentRow = 0;
int parentLevelOptionIndex = parentOptionIndex - 1;
while (parentLevelOptionIndex > -1 && m_options[parentLevelOptionIndex].level() > childLevel - 2)
{
if (m_options[parentLevelOptionIndex].level() == childLevel - 1)
{
parentRow++;
}
parentLevelOptionIndex--;
}
return createIndex(parentRow, 0, parentOptionIndex);
}
parentOptionIndex--;
}
CAF_ASSERT(false);
return QModelIndex();
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -164,41 +122,10 @@ int caf::PdmUiTreeSelectionQModel::rowCount(const QModelIndex &parent /*= QModel
{ {
if (!parent.isValid()) if (!parent.isValid())
{ {
int childCount = 0; return m_zeroLevelRowCount;
for (auto o : m_options)
{
if (o.level() == 0)
{
childCount++;
}
}
return childCount;
}
else
{
int childCount = 0;
int parentOptionIndex = toOptionItemIndex(parent);
int parentLevel = m_options[parentOptionIndex].level();
int currentOptionIndex = parentOptionIndex + 1;
while (currentOptionIndex < m_options.size() && m_options[currentOptionIndex].level() > parentLevel)
{
if (m_options[currentOptionIndex].level() == parentLevel + 1)
{
childCount++;
}
currentOptionIndex++;
}
return childCount;
} }
CAF_ASSERT(false); return m_optionsTreeData[toOptionItemIndex(parent)].childCount;
return 0;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@@ -206,29 +133,32 @@ int caf::PdmUiTreeSelectionQModel::rowCount(const QModelIndex &parent /*= QModel
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QVariant caf::PdmUiTreeSelectionQModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole*/) const QVariant caf::PdmUiTreeSelectionQModel::data(const QModelIndex &index, int role /*= Qt::DisplayRole*/) const
{ {
CAF_ASSERT(index.internalId() < m_options.size()); if (index.isValid())
if (role == Qt::DisplayRole)
{ {
return m_options[toOptionItemIndex(index)].optionUiText(); CAF_ASSERT(index.internalId() < m_options.size());
}
else if (role == Qt::CheckStateRole)
{
CAF_ASSERT(m_uiFieldHandle);
QVariant fieldValue = m_uiFieldHandle->field()->uiValue(); if (role == Qt::DisplayRole)
QList<QVariant> valuesSelectedInField = fieldValue.toList();
for (QVariant v : valuesSelectedInField)
{ {
int indexInField = v.toInt(); return m_options[toOptionItemIndex(index)].optionUiText();
if (indexInField == toOptionItemIndex(index))
{
return Qt::Checked;
}
} }
else if (role == Qt::CheckStateRole)
{
CAF_ASSERT(m_uiFieldHandle);
return Qt::Unchecked; QVariant fieldValue = m_uiFieldHandle->field()->uiValue();
QList<QVariant> valuesSelectedInField = fieldValue.toList();
for (QVariant v : valuesSelectedInField)
{
int indexInField = v.toInt();
if (indexInField == toOptionItemIndex(index))
{
return Qt::Checked;
}
}
return Qt::Unchecked;
}
} }
return QVariant(); return QVariant();
@@ -254,9 +184,86 @@ bool caf::PdmUiTreeSelectionQModel::setData(const QModelIndex &index, const QVar
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
int caf::PdmUiTreeSelectionQModel::toOptionItemIndex(const QModelIndex& modelIndex) 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++)
{
if (m_options[i].level() == 0)
{
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[parentOptionIndex].level() == childLevel - 1)
{
int parentRow = 0;
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--;
}
}
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;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int caf::PdmUiTreeSelectionQModel::toOptionItemIndex(const QModelIndex& modelIndex) const
{ {
CAF_ASSERT(modelIndex.isValid()); CAF_ASSERT(modelIndex.isValid());
CAF_ASSERT(modelIndex.internalId() < m_options.size());
return modelIndex.internalId(); return modelIndex.internalId();
} }

View File

@@ -40,6 +40,9 @@
#include <QAbstractItemModel> #include <QAbstractItemModel>
#include <vector>
#include <map>
namespace caf namespace caf
{ {
@@ -47,6 +50,17 @@ class PdmOptionItemInfo;
class PdmUiFieldHandle; class PdmUiFieldHandle;
//==================================================================================================
///
//==================================================================================================
class OptionItemTreeData
{
public:
int zeroLevelIndex;
int childCount;
QModelIndex parentModelIndex;
};
//================================================================================================== //==================================================================================================
/// ///
//================================================================================================== //==================================================================================================
@@ -70,11 +84,16 @@ signals:
void signalSelectionStateForIndexHasChanged(int index, bool isSelected); void signalSelectionStateForIndexHasChanged(int index, bool isSelected);
private: private:
static int toOptionItemIndex(const QModelIndex& modelIndex); void computeOptionItemTreeData();
int toOptionItemIndex(const QModelIndex& modelIndex) const;
private: private:
QList<caf::PdmOptionItemInfo> m_options; QList<caf::PdmOptionItemInfo> m_options;
caf::PdmUiFieldEditorHandle* m_uiFieldHandle; caf::PdmUiFieldEditorHandle* m_uiFieldHandle;
std::vector<OptionItemTreeData> m_optionsTreeData;
int m_zeroLevelRowCount;
std::map<int, int> m_zeroLevelRowToOptionIndex;
}; };