Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add levels property to VariablesList #5677

Merged
merged 4 commits into from
Oct 14, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 15 additions & 20 deletions CommonData/column.cpp
Original file line number Diff line number Diff line change
@@ -537,7 +537,7 @@ columnType Column::setValues(const stringvec & values, const stringvec & labels,
if(label && !label->isEmptyValue())
labelsNonNA.insert(label);
}
else if(!std::isnan(_dbls[i]))
else if(!isEmptyValue(_dbls[i]))
doublesNonNA.insert(_dbls[i]);
}

@@ -833,7 +833,7 @@ int Column::labelsTempCount()
_labelByNonEmptyIndex[nonEmptyIndex] = _labels[r];
_labelNonEmptyIndexByLabel[_labels[r]] = nonEmptyIndex;

if(!std::isnan(*_labelsTempDbls.rbegin()))
if(!isEmptyValue(*_labelsTempDbls.rbegin()))
_labelsTempNumerics++;

nonEmptyIndex++;
@@ -843,7 +843,7 @@ int Column::labelsTempCount()

for(size_t r=0; r<rowCount(); r++)
{
if(!std::isnan(_dbls[r]) && _ints[r] == Label::DOUBLE_LABEL_VALUE)
if(!isEmptyValue(_dbls[r]) && _ints[r] == Label::DOUBLE_LABEL_VALUE)
dblset.insert(_dbls[r]);
}

@@ -873,14 +873,14 @@ int Column::labelsTempCount()
return _labelsTemp.size();
}

int Column::nonFilteredTotalNumerics()
int Column::nonFilteredNumericsCount()
{
if (_nonFilteredNumericsCount == -1)
{
doubleset numerics;

for(size_t r=0; r<_data->rowCount(); r++)
if(_data->filter()->filtered()[r] && !std::isnan(_dbls[r]))
if(_data->filter()->filtered()[r] && !isEmptyValue(_dbls[r]))
numerics.insert(_dbls[r]);

_nonFilteredNumericsCount = numerics.size();
@@ -889,36 +889,31 @@ int Column::nonFilteredTotalNumerics()
return _nonFilteredNumericsCount;
}

int Column::nonFilteredTotalLevels()
stringset Column::nonFilteredLevels()
{
if (_nonFilteredLevelsCount == -1)
if (_nonFilteredLevels.empty())
{
Labelset labels;
doubleset numerics;

for(size_t r=0; r<_data->rowCount(); r++)
if(_data->filter()->filtered()[r])
{
if(_ints[r] != Label::DOUBLE_LABEL_VALUE)
{
Label * label = labelByIntsId(_ints[r]);
if(label && !label->isEmptyValue())
labels.insert(label);
_nonFilteredLevels.insert(label->label());
}
else if(!std::isnan(_dbls[r]))
numerics.insert(_dbls[r]);
else if(!isEmptyValue(_dbls[r]))
_nonFilteredLevels.insert(ColumnUtils::doubleToString(_dbls[r]));
}

_nonFilteredLevelsCount = numerics.size() + labels.size();
}

return _nonFilteredLevelsCount;
return _nonFilteredLevels;
}

void Column::nonFilteredCountersReset()
{
_nonFilteredLevelsCount = -1;
_nonFilteredNumericsCount = -1;
_nonFilteredLevels.clear();
_nonFilteredNumericsCount = -1;
}

int Column::labelsTempNumerics()
@@ -1773,7 +1768,7 @@ doublevec Column::valuesNumericOrdered()
else
ColumnUtils::getDoubleValue(label->originalValueAsString(), aValue);

if(!std::isnan(aValue))
if(!std::isnan(aValue)) //not isEmptyValue because we want to use the output to rewrite the data again
values.insert(aValue);
}

@@ -1806,7 +1801,7 @@ void Column::valuesReverse()
else
ColumnUtils::getDoubleValue(label->originalValueAsString(), aValue);

if(!std::isnan(aValue))
if(!std::isnan(aValue)) //not isEmptyValue because we want to use the output to rewrite the data again
label->setOriginalValue(flipIt[aValue]);
}

8 changes: 4 additions & 4 deletions CommonData/column.h
Original file line number Diff line number Diff line change
@@ -128,8 +128,8 @@ class Column : public DataSetBaseNode
int labelsDoubleValueIsTempLabelRow(double dbl);
Label * labelDoubleDummy() { return _doubleDummy; }

int nonFilteredTotalNumerics();
int nonFilteredTotalLevels();
int nonFilteredNumericsCount();
stringset nonFilteredLevels();
void nonFilteredCountersReset();

std::set<size_t> labelsMoveRows(std::vector<qsizetype> rows, bool up);
@@ -259,8 +259,8 @@ class Column : public DataSetBaseNode
stringvec _labelsTemp; ///< Contains displaystring for labels. Used to allow people to edit "double" labels. Initialized when necessary
doublevec _labelsTempDbls;
strintmap _labelsTempToIndex;
int _nonFilteredLevelsCount = -1,
_nonFilteredNumericsCount = -1;
stringset _nonFilteredLevels;
int _nonFilteredNumericsCount = -1;
bool _invalidated = false,
_autoSortByValue;
computedColumnType _codeType = computedColumnType::notComputed;
2 changes: 2 additions & 0 deletions CommonData/dataset.cpp
Original file line number Diff line number Diff line change
@@ -563,6 +563,8 @@ void DataSet::setEmptyValuesJson(const Json::Value &emptyValues, bool updateDB)
void DataSet::setWorkspaceEmptyValues(const stringset &values)
{
_emptyValues->setEmptyValues(values);
for(Column * column : _columns)
column->labelsTempReset();
dbUpdate();
}

27 changes: 5 additions & 22 deletions Desktop/data/columnsmodel.cpp
Original file line number Diff line number Diff line change
@@ -16,9 +16,11 @@ ColumnsModel::ColumnsModel(DataSetTableModel *tableModel)
connect(_tableModel, &DataSetTableModel::columnTypeChanged, this, [&](QString col, int) { emit columnTypeChanged(col); });
connect(_tableModel, &DataSetTableModel::labelChanged, this, [&](QString col, QString orgLabel, QString newLabel) { emit labelsChanged(col, {std::make_pair(orgLabel, newLabel) }); } );
connect(_tableModel, &DataSetTableModel::labelsReordered, this, &ColumnsModel::labelsReordered );
connect(_tableModel, &DataSetTableModel::emptyValuesChanged, this, &ColumnsModel::dataSetChanged );

auto * info = new VariableInfo(_singleton);


connect(this, &ColumnsModel::namesChanged, info, &VariableInfo::namesChanged );
connect(this, &ColumnsModel::columnsChanged, info, &VariableInfo::columnsChanged );
connect(this, &ColumnsModel::columnTypeChanged, info, &VariableInfo::columnTypeChanged );
@@ -151,10 +153,10 @@ QVariant ColumnsModel::provideInfo(VariableInfo::InfoType info, const QString& c
switch(info)
{
case VariableInfo::VariableType: return colTypeInt;
case VariableInfo::Labels: return _getLabels(colIndex);
case VariableInfo::DoubleValues: return QTransposeProxyModel::data(qColIndex, int(DataSetPackage::specialRoles::valuesDblList));
case VariableInfo::TotalNumericValues: return QTransposeProxyModel::data(qColIndex, int(DataSetPackage::specialRoles::totalNumericValues));
case VariableInfo::TotalLevels: return QTransposeProxyModel::data(qColIndex, int(DataSetPackage::specialRoles::totalLevels));
case VariableInfo::TotalNumericValues: return QTransposeProxyModel::data(qColIndex, int(DataSetPackage::specialRoles::nonFilteredNumericValuesCount));
case VariableInfo::TotalLevels: return QTransposeProxyModel::data(qColIndex, int(DataSetPackage::specialRoles::nonFilteredLevels)).toStringList().length();
case VariableInfo::Labels: return QTransposeProxyModel::data(qColIndex, int(DataSetPackage::specialRoles::nonFilteredLevels));
case VariableInfo::NameRole: return data(qColIndex, ColumnsModel::NameRole);
case VariableInfo::DataSetRowCount: return QTransposeProxyModel::columnCount();
case VariableInfo::DataSetValue: return QTransposeProxyModel::data(qValIndex, int(DataSetPackage::specialRoles::value));
@@ -276,22 +278,3 @@ void ColumnsModel::datasetChanged( QStringList chan
emit dataSetChanged(); //For VariableInfoProvider and listeners
}

QVariant ColumnsModel::_getLabels(int colId) const
{
QStringList labels = QTransposeProxyModel::data(index(colId, 0), int(DataSetPackage::specialRoles::labelsStrList)).toStringList();
QStringList unusedLabels = labels;

int count = _tableModel->rowCount();
for (int i = 0; i < count; i++)
{
unusedLabels.removeAll(_tableModel->data(_tableModel->index(i, colId)).toString());
if (unusedLabels.isEmpty())
break;
}

// Warning: the order of the labels must be kept.
for (const QString& unusedLabel : unusedLabels)
labels.removeAll(unusedLabel);

return labels;
}
2 changes: 0 additions & 2 deletions Desktop/data/columnsmodel.h
Original file line number Diff line number Diff line change
@@ -58,8 +58,6 @@ public slots:
void dataSetChanged();

private:
QVariant _getLabels(int colId) const;

DataSetTableModel * _tableModel = nullptr;
static ColumnsModel * _singleton;
};
60 changes: 25 additions & 35 deletions Desktop/data/datasetpackage.cpp
Original file line number Diff line number Diff line change
@@ -506,22 +506,21 @@ QVariant DataSetPackage::data(const QModelIndex &index, int role) const

switch(role)
{
case Qt::DisplayRole: return tq(column->getDisplay(index.row()));
case int(specialRoles::label): return tq(column->getLabel(index.row(), false, true));
case int(specialRoles::description): return tq(column->description());
case int(specialRoles::shadowDisplay): return tq(column->getShadow(index.row()));
case int(specialRoles::labelsStrList): return getColumnLabelsAsStringList(column->name());
case int(specialRoles::valuesDblList): return getColumnValuesAsDoubleList(getColumnIndex(column->name()));
case int(specialRoles::inEasyFilter): return isColumnUsedInEasyFilter(column->name());
case int(specialRoles::value): return tq(column->getValue(index.row()));
case int(specialRoles::name): return tq(column->name());
case int(specialRoles::title): return tq(column->title());
case int(specialRoles::filter): return getRowFilter(index.row());
case int(specialRoles::columnType): return int(column->type());
case int(specialRoles::totalNumericValues): return column->nonFilteredTotalNumerics();
case int(specialRoles::totalLevels): return column->nonFilteredTotalLevels();
case int(specialRoles::computedColumnType): return int(column->codeType());
case int(specialRoles::columnPkgIndex): return index.column();
case Qt::DisplayRole: return tq(column->getDisplay(index.row()));
case int(specialRoles::label): return tq(column->getLabel(index.row(), false, true));
case int(specialRoles::value): return tq(column->getValue(index.row()));
case int(specialRoles::name): return tq(column->name());
case int(specialRoles::title): return tq(column->title());
case int(specialRoles::filter): return getRowFilter(index.row());
case int(specialRoles::columnType): return int(column->type());
case int(specialRoles::description): return tq(column->description());
case int(specialRoles::inEasyFilter): return isColumnUsedInEasyFilter(column->name());
case int(specialRoles::shadowDisplay): return tq(column->getShadow(index.row()));
case int(specialRoles::valuesDblList): return getColumnValuesAsDoubleList(getColumnIndex(column->name()));
case int(specialRoles::nonFilteredNumericValuesCount): return column->nonFilteredNumericsCount();
case int(specialRoles::nonFilteredLevels): return tql(column->nonFilteredLevels());
case int(specialRoles::computedColumnType): return int(column->codeType());
case int(specialRoles::columnPkgIndex): return index.column();
case int(specialRoles::lines):
{
bool iAmActive = getRowFilter(index.row()),
@@ -551,17 +550,16 @@ QVariant DataSetPackage::data(const QModelIndex &index, int role) const

switch(role)
{
case int(specialRoles::filter): return index.row() >= labels.size() || labels[index.row()]->filterAllows();
case int(specialRoles::value): return tq(column->labelsTempValue(index.row()));
case int(specialRoles::description): return index.row() >= labels.size() ? "" : tq(labels[index.row()]->description());
case int(specialRoles::labelsStrList): return getColumnLabelsAsStringList(column->name());
case int(specialRoles::totalNumericValues): return column->labelsTempNumerics();
case int(specialRoles::totalLevels): return int(column->labelsTemp().size());
case int(specialRoles::valuesDblList): return getColumnValuesAsDoubleList(getColumnIndex(column->name()));
case int(specialRoles::lines): return getDataSetViewLines(index.row() == 0, index.column() == 0, true, true);
case int(specialRoles::label): [[fallthrough]];
case Qt::DisplayRole: return tq(column->labelsTempDisplay(index.row()));
default: return QVariant();
case int(specialRoles::nonFilteredNumericValuesCount): return column->nonFilteredNumericsCount();
case int(specialRoles::nonFilteredLevels): return tql(column->nonFilteredLevels());
case int(specialRoles::valuesDblList): return getColumnValuesAsDoubleList(getColumnIndex(column->name()));
case int(specialRoles::description): return index.row() >= labels.size() ? "" : tq(labels[index.row()]->description());
case int(specialRoles::filter): return index.row() >= labels.size() || labels[index.row()]->filterAllows();
case int(specialRoles::value): return tq(column->labelsTempValue(index.row()));
case int(specialRoles::lines): return getDataSetViewLines(index.row() == 0, index.column() == 0, true, true);
case int(specialRoles::label): [[fallthrough]];
case Qt::DisplayRole: return tq(column->labelsTempDisplay(index.row()));
default: return QVariant();
}
}
}
@@ -1806,14 +1804,6 @@ std::string DataSetPackage::getColumnName(size_t columnIndex) const
return _dataSet && _dataSet->column(columnIndex) ? _dataSet->column(columnIndex)->name() : "";
}

QStringList DataSetPackage::getColumnLabelsAsStringList(const std::string & columnName) const
{
int colIndex = getColumnIndex(columnName);

if(colIndex > -1) return getColumnLabelsAsStringList(colIndex);
else return QStringList();;
}

QStringList DataSetPackage::getColumnLabelsAsStringList(size_t columnIndex) const
{
return tq(getColumnLabelsAsStrVec(columnIndex));
1 change: 0 additions & 1 deletion Desktop/data/datasetpackage.h
Original file line number Diff line number Diff line change
@@ -241,7 +241,6 @@ class DataSetPackage : public QAbstractItemModel //Not QAbstractTableModel becau
void columnsReverseValues( intset columnIndex);
void columnsSetAutoSortForColumns( std::map<int,bool> columnutoSort);
qsizetype getMaximumColumnWidthInCharacters( int columnIndex) const;
QStringList getColumnLabelsAsStringList( const std::string & columnName) const;
QStringList getColumnLabelsAsStringList( size_t columnIndex) const;
stringvec getColumnLabelsAsStrVec( size_t columnIndex) const;
boolvec getColumnFilterAllows( size_t columnIndex) const;
6 changes: 3 additions & 3 deletions Desktop/data/datasetpackageenums.h
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@

///Special roles for the different submodels of DataSetPackage. If both maxColString and columnWidthFallback are defined by a model DataSetView will only use maxColString. selected is now only used in ColumnModel, but defined here for convenience.
DECLARE_ENUM(
dataPkgRoles,
dataPkgRoles,
filter = Qt::UserRole,
name,
title,
@@ -24,11 +24,11 @@ DECLARE_ENUM(
maxColumnHeaderString,
columnWidthFallback,
computedColumnType,
totalNumericValues,
nonFilteredNumericValuesCount,
nonFilteredLevels,
columnIsComputed,
labelsHasFilter,
columnPkgIndex,
labelsStrList,
valuesStrList,
valuesDblList,
inEasyFilter,
1 change: 1 addition & 0 deletions Desktop/data/datasettablemodel.cpp
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ DataSetTableModel::DataSetTableModel(bool showInactive)
connect(DataSetPackage::pkg(), &DataSetPackage::columnDataTypeChanged, this, [&](QString colName) { emit columnTypeChanged(colName, int(DataSetPackage::pkg()->getColumnType(colName))); }, Qt::QueuedConnection);
connect(DataSetPackage::pkg(), &DataSetPackage::labelChanged, this, &DataSetTableModel::labelChanged );
connect(DataSetPackage::pkg(), &DataSetPackage::labelsReordered, this, &DataSetTableModel::labelsReordered );
connect(DataSetPackage::pkg(), &DataSetPackage::workspaceEmptyValuesChanged, this, &DataSetTableModel::emptyValuesChanged );
//connect(this, &DataSetTableModel::dataChanged, this, &DataSetTableModel::onDataChanged, Qt::QueuedConnection);

setFilterRole(int(DataSetPackage::specialRoles::filter));
1 change: 1 addition & 0 deletions Desktop/data/datasettablemodel.h
Original file line number Diff line number Diff line change
@@ -57,6 +57,7 @@ class DataSetTableModel : public DataSetTableProxy
void columnTypeChanged(QString colName, int colType);
void labelChanged(QString columnName, QString originalLabel, QString newLabel);
void labelsReordered(QString columnName);
void emptyValuesChanged();

void renameColumnDialog(int columnIndex);

9 changes: 9 additions & 0 deletions QMLComponents/controls/variableslistbase.cpp
Original file line number Diff line number Diff line change
@@ -45,6 +45,8 @@ VariablesListBase::VariablesListBase(QQuickItem* parent)
_controlType = ControlType::VariablesListView;
_useControlMouseArea = false;
_allowedTypesModel = new ColumnTypesModel(this);

connect(VariableInfo::info(), &VariableInfo::dataSetChanged, this, &VariablesListBase::levelsChanged);
}

void VariablesListBase::setUp()
@@ -89,6 +91,8 @@ void VariablesListBase::setUp()
QQuickItem::connect(this, SIGNAL(itemDoubleClicked(int)), this, SLOT(itemDoubleClickedHandler(int)));
QQuickItem::connect(this, SIGNAL(itemsDropped(QVariant, QVariant, int)), this, SLOT(itemsDroppedHandler(QVariant, QVariant, int)));
connect(this, &VariablesListBase::allowedColumnsChanged, this, &VariablesListBase::_setAllowedVariables );
connect(_draggableModel, &ListModelDraggable::termsChanged, this, &VariablesListBase::levelsChanged );
connect(_draggableModel, &ListModelDraggable::filterChanged, this, &VariablesListBase::levelsChanged );
connect(_draggableModel, &ListModelDraggable::filterChanged, this, &VariablesListBase::checkLevelsConstraints );
connect(this, &VariablesListBase::maxLevelsChanged, this, &VariablesListBase::checkLevelsConstraints );
connect(this, &VariablesListBase::minLevelsChanged, this, &VariablesListBase::checkLevelsConstraints );
@@ -296,6 +300,11 @@ columnType VariablesListBase::defaultType() const
return _allowedTypesModel->defaultType();
}

QStringList VariablesListBase::levels() const
{
return initialized() ? model()->allLevels(model()->terms()) : QStringList();
}

void VariablesListBase::setDropKeys(const QStringList &dropKeys)
{
Log::log() << "LOG setDropKeys " << name() << ": " << dropKeys.join('/') << std::endl;
3 changes: 3 additions & 0 deletions QMLComponents/controls/variableslistbase.h
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@ class VariablesListBase : public JASPListControl, public BoundControl
Q_PROPERTY( QStringList allowedColumns READ allowedColumns WRITE setAllowedColumns NOTIFY allowedColumnsChanged )
Q_PROPERTY( QStringList allowedColumnsIcons READ allowedColumnsIcons NOTIFY allowedColumnsIconsChanged )
Q_PROPERTY( QStringList dropKeys READ dropKeys WRITE setDropKeys NOTIFY dropKeysChanged )
Q_PROPERTY( QStringList levels READ levels NOTIFY levelsChanged )
Q_PROPERTY( QString interactionHighOrderCheckBox READ interactionHighOrderCheckBox WRITE setInteractionHighOrderCheckBox NOTIFY interactionHighOrderCheckBoxChanged )
Q_PROPERTY( QAbstractListModel* allowedTypesModel READ allowedTypesModel NOTIFY allowedTypesModelChanged )
Q_PROPERTY( int minNumericLevels READ minNumericLevels WRITE setMinNumericLevels NOTIFY minNumericLevelsChanged )
@@ -75,6 +76,7 @@ class VariablesListBase : public JASPListControl, public BoundControl
QAbstractListModel * allowedTypesModel();
bool isTypeAllowed(columnType type) const override;
columnType defaultType() const override;
QStringList levels() const;
int minLevels() const { return _minLevels; }
int maxLevels() const { return _maxLevels; }
int minNumericLevels() const { return _minNumericLevels; }
@@ -89,6 +91,7 @@ class VariablesListBase : public JASPListControl, public BoundControl
void dropKeysChanged();
void interactionHighOrderCheckBoxChanged();
void allowedTypesModelChanged();
void levelsChanged();
void minLevelsChanged();
void maxLevelsChanged();
void minNumericLevelsChanged();
19 changes: 9 additions & 10 deletions QMLComponents/models/listmodel.cpp
Original file line number Diff line number Diff line change
@@ -566,17 +566,16 @@ Terms ListModel::filterTerms(const Terms& terms, const QStringList& filters)
}

if (filters.contains("levels"))
{
Terms allLabels;
for (const Term& term : result)
{
Terms labels = requestInfo(VariableInfo::Labels, term.asQString()).toStringList();
if (labels.size() > 0) allLabels.add(labels);
else allLabels.add(term);
}
result = allLevels(result);

result = allLabels;
}
return result;
}

QStringList ListModel::allLevels(const Terms& terms) const
{
QStringList result;
for (const Term& term : terms)
result.append(requestInfo(VariableInfo::Labels, term.asQString()).toStringList());

return result;
}
1 change: 1 addition & 0 deletions QMLComponents/models/listmodel.h
Original file line number Diff line number Diff line change
@@ -88,6 +88,7 @@ class ListModel : public QAbstractTableModel, public VariableInfoConsumer
virtual JASPControl * getRowControl(const QString& key, const QString& name) const;
virtual bool addRowControl(const QString& key, JASPControl* control);
QStringList termsTypes();
QStringList allLevels(const Terms& terms) const;
void setVariableType(int index, columnType type);
columnType getVariableType( const QString& name) const;
columnType getVariableRealType(const QString& name) const;