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

Type backward compatibility #5741

Merged
Merged
Show file tree
Hide file tree
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
5 changes: 4 additions & 1 deletion QMLComponents/boundcontrols/boundcontrolbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ std::string BoundControlBase::getName() const
return fq(_control->name());
}

void BoundControlBase::_readTableValue(const Json::Value &value, const std::string& key, bool hasMultipleTerms, Terms& terms, ListModel::RowControlsValues& allControlValues)
void BoundControlBase::_readTableValue(const Json::Value &value, const std::string& key, bool hasMultipleTerms, Terms& terms, ListModel::RowControlsValues& allControlValues, const Terms& sourceTerms)
{
for (const Json::Value& row : value)
{
Expand All @@ -126,6 +126,9 @@ void BoundControlBase::_readTableValue(const Json::Value &value, const std::stri
Term term = Term::readTerm(keyValue);
if (term.size() > 0)
{
int termInd = sourceTerms.indexOf(term);
if (termInd >= 0)
term.setTypes(sourceTerms[termInd].types());
terms.add(term);

QMap<QString, Json::Value> controlMap;
Expand Down
2 changes: 1 addition & 1 deletion QMLComponents/boundcontrols/boundcontrolbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class BoundControlBase : public BoundControl
static Json::Value _getTableValueOption(const Terms& terms, const ListModel::RowControlsValues& componentValuesMap, const std::string& key, bool hasInteraction, bool keyHasVariables);
void _setTableValue(const Terms& terms, const ListModel::RowControlsValues& componentValuesMap, const std::string& key, bool hasInteraction, bool keyHasVariables = false);

void _readTableValue(const Json::Value& value, const std::string& key, bool hasMultipleTerms, Terms& terms, ListModel::RowControlsValues& allControlValues);
void _readTableValue(const Json::Value& value, const std::string& key, bool hasMultipleTerms, Terms& terms, ListModel::RowControlsValues& allControlValues, const Terms& sourceTerms = Terms());
bool _isValueWithTypes(const Json::Value &value) const;

JASPControl* _control = nullptr;
Expand Down
62 changes: 40 additions & 22 deletions QMLComponents/boundcontrols/boundcontrolterms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,43 +127,61 @@ void BoundControlTerms::bindTo(const Json::Value &value)
Log::log() << "Control " << _control->name() << " is bound with a value that is neither an array, an object bor a string :" << valuePart.toStyledString() << std::endl;
}

int i = 0;
int termId = 0;
for (Term& term : terms)
{
if (typesPart.size() > i) // If the type is given, use it
if (typesPart.size() > termId) // If the type is given, use it
{
if (typesPart[i].isArray())
{
columnTypeVec types;
for (const Json::Value& jsonType : typesPart[i])
columnTypeVec types;
if (typesPart[termId].isArray())
for (const Json::Value& jsonType : typesPart[termId])
types.push_back(columnTypeFromString(jsonType.asString(), columnType::unknown));
term.setTypes(types);
}
else
term.setType(columnTypeFromString(typesPart[i].asString(), columnType::unknown));
types.push_back(columnTypeFromString(typesPart[termId].asString(), columnType::unknown));
term.setTypes(types);
}
else
termId++;
}

// For backward compatibility, the types of the terms must be checked.
// Before 0.19.0, the types were not given: in this case the real type of the variable (if it is a variable) is retrieved from the dataset.
// In 0.19.1, the types were not given for terms with interaction: in this case, the variables of the interation term is
// most of the time also in the Variables List: the types of these variables must be stored and used for interaction term. This type might be not the one in the dataset, but a type changed by the user.
QMap<QString, columnType> variableTypeMap;
for (Term& term : terms)
{
if (term.size() == 1 && term.type() != columnType::unknown && _listView->isTypeAllowed(term.type()))
variableTypeMap[term.asQString()] = term.type();
}

for (Term& term : terms)
{
columnTypeVec types = term.types(),
checkedTypes;
int componentId = 0;
for (const QString& component : term.components())
{
if (term.type() == columnType::unknown)
{
// Backward compatibility: the type was not saved before 0.19, so get the real type and check whether it is allowed. If not, take the default
columnType type = _listView->model()->getVariableRealType(term.asQString());
if (type != columnType::unknown && !_listView->isTypeAllowed(type))
type = _listView->defaultType();
term.setType(type);
}
typesPart.append(columnTypeToString(term.type()));
columnType type = types.size() > componentId ? types[componentId] : columnType::unknown;
if (type == columnType::unknown)
type = variableTypeMap.contains(component) ? variableTypeMap[component] : _listView->model()->getVariableRealType(component);

// Ensure that the type is allowed (if it is unknown, this is not a variable, so don't check the type)
if (type != columnType::unknown && !_listView->isTypeAllowed(type))
type = _listView->defaultType();

checkedTypes.push_back(type);
componentId++;
}
i++;

term.setTypes(checkedTypes);
}

Json::Value newValue = Json::objectValue;
newValue["value"] = valuePart;
newValue["types"] = typesPart;
newValue["types"] = terms.types();
BoundControlBase::bindTo(newValue);

_termsModel->initTerms(terms, allControlValues);

}

Json::Value BoundControlTerms::createJson() const
Expand Down
2 changes: 1 addition & 1 deletion QMLComponents/controls/componentslistbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void ComponentsListBase::bindTo(const Json::Value& value)
Terms terms;
ListModel::RowControlsValues allControlValues;

_readTableValue(value, keyName, containsInteractions(), terms, allControlValues);
_readTableValue(value, keyName, containsInteractions(), terms, allControlValues, _termsModel->getSourceTerms());

_termsModel->initTerms(terms, allControlValues);
}
Expand Down
Loading