Skip to content

Commit

Permalink
Add possibility to reset column types when changing the ordinal thres…
Browse files Browse the repository at this point in the history
…hold

Fixes jasp-stats/jasp-issues#2426

If you change the threshold between Categorical and Scale, it might be handy to reset the variable types with this new value.

I have also redesigned a bit the Preferences/Data to have the same look as the other preferences memus.
  • Loading branch information
boutinb committed Jan 15, 2024
1 parent b41342d commit ed19af9
Show file tree
Hide file tree
Showing 13 changed files with 128 additions and 101 deletions.
18 changes: 17 additions & 1 deletion Desktop/components/JASP/Widgets/DataTableView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,22 @@ FocusScope
property real iconTextPadding: 10
readonly property int __iconDim: baseBlockDim * preferencesModel.uiScale

function getColumnTypeIcon(type)
{
return String(dataSetModel.getColumnTypesWithIcons()[type]) === "" ? "" : jaspTheme.iconPath + dataSetModel.getColumnTypesWithIcons()[type]
}

Connections
{
target: dataSetModel
function onColumnTypeChanged(colName, colType)
{
if (headerText === colName)
colIcon.source = getColumnTypeIcon(colType)
}
}


Keys.onPressed: (event) =>
{
var controlPressed = Boolean(event.modifiers & Qt.ControlModifier)
Expand Down Expand Up @@ -547,7 +563,7 @@ FocusScope
anchors.margins: 4


source: String(dataSetModel.getColumnTypesWithIcons()[columnType]) === "" ? "" : jaspTheme.iconPath + dataSetModel.getColumnTypesWithIcons()[columnType]
source: getColumnTypeIcon(columnType)
width: source == "" ? 0 : headerRoot.__iconDim
height: headerRoot.__iconDim

Expand Down
154 changes: 72 additions & 82 deletions Desktop/components/JASP/Widgets/FileMenu/PrefsData.qml
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import QtQuick 2.11
import QtQuick.Controls 2.4
import JASP.Widgets 1.0
import QtQuick
import QtQuick.Controls as QTC
import JASP.Widgets
import JASP.Controls

import JASP.Controls 1.0


ScrollView
QTC.ScrollView
{
id: scrollPrefs
focus: true
Expand All @@ -30,14 +29,13 @@ ScrollView

PrefsGroupRect
{
spacing: jaspTheme.rowSpacing
implicitWidth: scrollPrefs.width - (jaspTheme.generalAnchorMargin * 2)
id: spreadSheetEditor
title: qsTr("External spreadsheet editor (for data synchronization)")

Item //Use default spreadsheet editor
Item
{

height: useDefaultEditor.height + (editCustomEditor.visible ? editCustomEditor.height : linuxInfo.visible ? linuxInfo.height : 0)
width: parent.width - jaspTheme.generalAnchorMargin
height: editCustomEditor.y + editCustomEditor.height
width: parent.width

CheckBox
{
Expand Down Expand Up @@ -68,7 +66,6 @@ ScrollView
Item
{
id: editCustomEditor
// visible: !LINUX && !preferencesModel.useDefaultEditor
enabled: !LINUX && !preferencesModel.useDefaultEditor
width: parent.width
height: browseEditorButton.height
Expand Down Expand Up @@ -110,7 +107,7 @@ ScrollView
onTextChanged: preferencesModel.customEditor = text
color: jaspTheme.textEnabled

KeyNavigation.tab: customThreshold
KeyNavigation.tab: thresholdScale

anchors
{
Expand All @@ -129,55 +126,48 @@ ScrollView
}
}
}
}

PrefsGroupRect
{
id: thresholdScaleSetting
title: qsTr("Import threshold between Categorical or Scale")

Item //Scale threshold
SpinBox
{
height: customThreshold.height + thresholdScale.height
width: customThreshold.width
id: thresholdScale
value: preferencesModel.thresholdScale
onValueChanged: preferencesModel.thresholdScale = value

CheckBox
{
id: customThreshold
label: qsTr("Import threshold between Categorical or Scale") + ":"
checked: preferencesModel.customThresholdScale
onCheckedChanged: preferencesModel.customThresholdScale = checked
ToolTip.delay: 500
ToolTip.timeout: 6000 //Some longer to read carefully
toolTip: qsTr("Threshold number of unique integers before classifying a variable as 'scale'.\nYou need to reload your data to take effect! Check help for more info.")
KeyNavigation.tab: resetDataWithThresholdButton

KeyNavigation.tab: thresholdScale

}

SpinBox
Button
{
id: thresholdScale
value: preferencesModel.thresholdScale
onValueChanged: preferencesModel.thresholdScale = value
enabled: preferencesModel.customThresholdScale

KeyNavigation.tab: missingValueDataLabelInput

id: resetDataWithThresholdButton
label: qsTr("Reset variable types")
visible: mainWindow.dataAvailable
onClicked: mainWindow.resetVariableTypes()
anchors
{
top: customThreshold.bottom
left: customThreshold.left
leftMargin: jaspTheme.subOptionOffset
top: thresholdScale.top
left: thresholdScale.right
leftMargin: jaspTheme.generalAnchorMargin
}

KeyNavigation.tab: missingValueDataLabelInput
}
}
}

PrefsGroupRect
{
id: missingValuesSettings
title: qsTr("Missing values setting")

Item
{
id: missingValueDataLabelItem
height: missingValueDataLabelInput.height
anchors
{
left: parent.left
right: parent.right
margins: jaspTheme.generalAnchorMargin
}

Label
{
Expand Down Expand Up @@ -219,48 +209,48 @@ ScrollView
showResetWorkspaceButton: true
resetButtonLabel: qsTr("Reset with standard values")
resetButtonTooltip: qsTr("Reset missing values with the standard JASP missing values")
KeyNavigation.tab: noBomNative
KeyNavigation.tab: WINDOWS ? noBomNative : useDefaultEditor
}
}
}

PrefsGroupRect
PrefsGroupRect
{
visible: WINDOWS
enabled: WINDOWS
title: qsTr("Windows workaround")

CheckBox
{
visible: WINDOWS
enabled: WINDOWS
title: qsTr("Windows workaround")

CheckBox
{
id: noBomNative
label: qsTr("Assume CSV is the selected codepage, when no BOM is specified.")
checked: preferencesModel.windowsNoBomNative
onCheckedChanged: preferencesModel.windowsNoBomNative = checked
toolTip: qsTr("See documentation for more information ")
id: noBomNative
label: qsTr("Assume CSV is the selected codepage, when no BOM is specified.")
checked: preferencesModel.windowsNoBomNative
onCheckedChanged: preferencesModel.windowsNoBomNative = checked
toolTip: qsTr("See documentation for more information ")

KeyNavigation.tab: codePageSelection
}

/*ErrorMessage
{
text: WINDOWS && windowsCodePagesHelper.error ? qsTr("Some problem occured loading the available codepages...") : ""
}*/
KeyNavigation.tab: codePageSelection
}

/*ErrorMessage
{
text: WINDOWS && windowsCodePagesHelper.error ? qsTr("Some problem occured loading the available codepages...") : ""
}*/

DropDown
{
id: codePageSelection
enabled: preferencesModel.windowsNoBomNative && WINDOWS //&& !windowsCodePagesHelper.error
toolTip: qsTr("See documentation for more information ")
values: WINDOWS ? windowsCodePagesHelper.codePageIDs : []
addEmptyValue: true
showEmptyValueAsNormal: true
addLineAfterEmptyValue: true
placeholderText: qsTr("Choose codepage here")
startValue: WINDOWS ? windowsCodePagesHelper.codePageID : ""
onValueChanged: if(WINDOWS) windowsCodePagesHelper.codePageID = value

KeyNavigation.tab: useDefaultEditor
}

DropDown
{
id: codePageSelection
enabled: preferencesModel.windowsNoBomNative && WINDOWS //&& !windowsCodePagesHelper.error
toolTip: qsTr("See documentation for more information ")
values: WINDOWS ? windowsCodePagesHelper.codePageIDs : []
addEmptyValue: true
showEmptyValueAsNormal: true
addLineAfterEmptyValue: true
placeholderText: qsTr("Choose codepage here")
startValue: WINDOWS ? windowsCodePagesHelper.codePageID : ""
onValueChanged: if(WINDOWS) windowsCodePagesHelper.codePageID = value

KeyNavigation.tab: useDefaultEditor
}
}
}
Expand Down
1 change: 1 addition & 0 deletions Desktop/data/columnmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ void ColumnModel::columnDataTypeChanged(const QString & colName)

if(colIndex == chosenColumn())
{
emit columnTypeChanged();
// if(DataSetPackage::pkg()->dataSet()->column(colIndex)->type() == columnType::scale)
// setChosenColumn(-1);
emit tabsChanged();
Expand Down
2 changes: 1 addition & 1 deletion Desktop/data/columnsmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ ColumnsModel::ColumnsModel(DataSetTableModel *tableModel)

setSourceModel(tableModel);

connect(_tableModel, &DataSetTableModel::columnTypeChanged, this, &ColumnsModel::columnTypeChanged );
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 );

Expand Down
35 changes: 27 additions & 8 deletions Desktop/data/datasetpackage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ bool DataSetPackage::setData(const QModelIndex &index, const QVariant &value, in
if(value.toInt() >= int(columnType::unknown) && value.toInt() <= int(columnType::scale))
{
columnType converted = static_cast<columnType>(value.toInt());
if(setColumnType(index.column(), converted))
if(converted != column->type() && setColumnType(index.column(), converted))
{
aChange = true;
emit columnDataTypeChanged(tq(column->name()));
Expand Down Expand Up @@ -1129,16 +1129,17 @@ bool DataSetPackage::setColumnType(int columnIndex, columnType newColumnType)
if (_dataSet == nullptr)
return true;

Column *col = _dataSet->column(columnIndex);

if (col->type() == newColumnType)
return true;

columnTypeChangeResult feedback;

feedback = _dataSet->column(columnIndex)->changeType(newColumnType);
feedback = col->changeType(newColumnType);

if (feedback == columnTypeChangeResult::changed) //Everything went splendidly
{
beginResetModel();
endResetModel();
emit columnDataTypeChanged(tq(_dataSet->column(columnIndex)->name()));
}
else
{
QString informUser = tr("Something went wrong converting columntype, but it is unclear what.");
Expand Down Expand Up @@ -1262,6 +1263,19 @@ void DataSetPackage::dbDelete()
_dataSet->dbDelete();
}

void DataSetPackage::resetVariableTypes()
{
for (int i = 0; i < _dataSet->columnCount(); i++)
{
Column* col = _dataSet->column(i);
columnType orgType = col->type();
stringvec values = getColumnDataStrs(i);
initColumnWithStrings(i, col->name(), values);
if (col->type() != orgType)
emit columnDataTypeChanged(tq(col->name()));
}
}

void DataSetPackage::createDataSet()
{
JASPTIMER_SCOPE(DataSetPackage::createDataSet);
Expand Down Expand Up @@ -1437,8 +1451,7 @@ void DataSetPackage::initColumnWithStrings(QVariant colId, const std::string & n
int colIndex = getColIndex(colId);

//If less unique integers than the thresholdScale then we think it must be ordinal: https://github.com/jasp-stats/INTERNAL-jasp/issues/270
bool useCustomThreshold = Settings::value(Settings::USE_CUSTOM_THRESHOLD_SCALE).toBool();
size_t thresholdScale = (useCustomThreshold ? Settings::value(Settings::THRESHOLD_SCALE) : Settings::defaultValue(Settings::THRESHOLD_SCALE)).toUInt();
size_t thresholdScale = Settings::value(Settings::THRESHOLD_SCALE).toUInt();

JASPTIMER_RESUME(DataSetPackage::initColumnWithStrings preamble);
bool valuesAreIntegers = convertVecToInt(colIndex, values, intValues, uniqueValues, emptyValuesMap);
Expand Down Expand Up @@ -1904,6 +1917,12 @@ columnType DataSetPackage::getColumnType(size_t columnIndex) const
return _dataSet && _dataSet->column(columnIndex) ? _dataSet->column(columnIndex)->type() : columnType::unknown;
}

columnType DataSetPackage::getColumnType(const QString& name) const
{
return _dataSet ? getColumnType(_dataSet->getColumnIndex(fq(name))) : columnType::unknown;
}


std::string DataSetPackage::getColumnName(size_t columnIndex) const
{
return _dataSet && _dataSet->column(columnIndex) ? _dataSet->column(columnIndex)->name() : "";
Expand Down
2 changes: 2 additions & 0 deletions Desktop/data/datasetpackage.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ class DataSetPackage : public QAbstractItemModel //Not QAbstractTableModel becau
int getColumnIndex( const QString & name) const { return getColumnIndex(name.toStdString()); }
Column* getColumn( const std::string & name) { return _dataSet->column(name); }
enum columnType getColumnType( size_t columnIndex) const;
enum columnType getColumnType( const QString & name) const;
std::string getColumnName( size_t columnIndex) const;
intvec getColumnDataInts( size_t columnIndex);
doublevec getColumnDataDbls( size_t columnIndex);
Expand Down Expand Up @@ -285,6 +286,7 @@ class DataSetPackage : public QAbstractItemModel //Not QAbstractTableModel becau
stringset columnsCreatedByAnalysis( Analysis * analysis);
std::string freeNewColumnName(size_t startHere);
void dbDelete();
void resetVariableTypes();


signals:
Expand Down
2 changes: 1 addition & 1 deletion Desktop/data/datasettablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ DataSetTableModel::DataSetTableModel(bool showInactive)
{

connect(DataSetPackage::pkg(), &DataSetPackage::columnsFilteredCountChanged, this, &DataSetTableModel::columnsFilteredCountChanged );
connect(DataSetPackage::pkg(), &DataSetPackage::columnDataTypeChanged, this, &DataSetTableModel::columnTypeChanged );
connect(DataSetPackage::pkg(), &DataSetPackage::columnDataTypeChanged, this, [&](QString colName) { emit columnTypeChanged(colName, int(DataSetPackage::pkg()->getColumnType(colName))); });
connect(DataSetPackage::pkg(), &DataSetPackage::labelChanged, this, &DataSetTableModel::labelChanged );
connect(DataSetPackage::pkg(), &DataSetPackage::labelsReordered, this, &DataSetTableModel::labelsReordered );
//connect(this, &DataSetTableModel::dataChanged, this, &DataSetTableModel::onDataChanged, Qt::QueuedConnection);
Expand Down
2 changes: 1 addition & 1 deletion Desktop/data/datasettablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class DataSetTableModel : public DataSetTableProxy
signals:
void columnsFilteredCountChanged();
void showInactiveChanged(bool showInactive);
void columnTypeChanged(QString colName);
void columnTypeChanged(QString colName, int colType);
void labelChanged(QString columnName, QString originalLabel, QString newLabel);
void labelsReordered(QString columnName);

Expand Down
Loading

0 comments on commit ed19af9

Please sign in to comment.