Skip to content

Commit

Permalink
Resize is back
Browse files Browse the repository at this point in the history
  • Loading branch information
boutinb authored and JorisGoosen committed Jun 7, 2024
1 parent e6d1b25 commit 3212d63
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 13 deletions.
1 change: 1 addition & 0 deletions Desktop/components/JASP/Widgets/MainWindow.qml
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ Window

CreateComputeColumnDialog { id: createComputeDialog }
ModuleInstaller { id: moduleInstallerDialog }
ResizeDataDialog { id: resizeDataDialog }
RenameColumnDialog { id: renameColumnDialog }
PlotEditor { id: plotEditingDialog }

Expand Down
217 changes: 217 additions & 0 deletions Desktop/components/JASP/Widgets/ResizeDataDialog.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
//
// Copyright (C) 2013-2024 University of Amsterdam
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see
// <http://www.gnu.org/licenses/>.
//

import QtQuick
import QtQuick.Controls
import JASP.Controls

Popup
{
id: popupResizeData;
modal: true;

y: (parent.height / 2) - (height / 2)
x: (parent.width / 2) - (width / 2)
width: popupLoader.width
height: popupLoader.height+1

background: Rectangle
{
color: jaspTheme.uiBackground
border.color: jaspTheme.uiBorder
border.width: 1
radius: jaspTheme.borderRadius
}
padding: 0

Connections
{
target: ribbonModel
function onResizeData() { popupResizeData.open() }
}

Loader
{
id: popupLoader
sourceComponent: visible ? resizeComp : null
visible: popupResizeData.opened
}

Component
{
id: resizeComp

Item
{
height: inputs.height + jaspTheme.generalAnchorMargin + (30 * jaspTheme.uiScale)
width: 250 * jaspTheme.uiScale

Component.onCompleted: cols.forceActiveFocus();

Text
{
id: title
text: qsTr("Resize Data")
font: jaspTheme.fontGroupTitle
color: jaspTheme.textEnabled
verticalAlignment: Text.AlignVCenter
anchors
{
top: parent.top
topMargin: jaspTheme.generalAnchorMargin
horizontalCenter: parent.horizontalCenter
}
}

Item
{
id: inputs
height: 95 * jaspTheme.uiScale + 2 * jaspTheme.generalAnchorMargin

anchors
{
top: title.bottom
left: parent.left
right: parent.right
margins: jaspTheme.generalAnchorMargin
}

Label
{
id: colsLabel
text: qsTr("Columns")
focus: true
anchors
{
top: inputs.top
horizontalCenter: cols.horizontalCenter
}
}

Label
{
id: rowsLabel
text: qsTr("Rows")
anchors
{
top: inputs.top
horizontalCenter: rows.horizontalCenter
}
}

Label
{
id: x
text: "X"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
anchors
{
top: colsLabel.bottom
horizontalCenter: parent.horizontalCenter
topMargin: jaspTheme.generalAnchorMargin * 0.5
}
}

IntegerField
{
id: cols
defaultValue: dataSetModel.columnCount()
fieldWidth: width
selectValueOnFocus: true
anchors
{
top: x.bottom
left: parent.left
right: x.left
margins: jaspTheme.generalAnchorMargin
topMargin: jaspTheme.generalAnchorMargin * 0.5
}
onEditingFinished: rows.forceActiveFocus();

KeyNavigation.tab: rows
KeyNavigation.right: rows
KeyNavigation.down: resizeButton
}

IntegerField
{
id: rows
defaultValue: dataSetModel.rowCount()
fieldWidth: width
selectValueOnFocus: true
anchors
{
top: x.bottom
left: x.right
right: parent.right
margins: jaspTheme.generalAnchorMargin
topMargin: jaspTheme.generalAnchorMargin * 0.5
}

onEditingFinished: resizeButton.forceActiveFocus();
KeyNavigation.down: closeButtonCross
KeyNavigation.tab: resizeButton
}
}

RoundedButton
{
id: resizeButton
activeFocusOnTab: true
text: qsTr("Resize")
onClicked:
{
mainWindow.resizeData(rows.displayValue, cols.displayValue);
popupResizeData.close();
}

toolTip: qsTr("Resize data to set values")

KeyNavigation.tab: closeButtonCross

anchors
{
bottom: inputs.bottom
margins: jaspTheme.generalAnchorMargin
left: parent.left
right: closeButtonCross.left
}
}

RoundedButton
{
id: closeButtonCross
activeFocusOnTab: true
iconSource: jaspTheme.iconPath + "cross.png"
width: height
height: resizeButton.height
onClicked: popupResizeData.close()
toolTip: qsTr("Close without resizing data")
KeyNavigation.tab: cols

anchors
{
right: parent.right
bottom: inputs.bottom
margins: jaspTheme.generalAnchorMargin
}
}
}
}
}
32 changes: 22 additions & 10 deletions Desktop/data/expanddataproxymodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,15 +245,21 @@ void ExpandDataProxyModel::insertColumn(int col, bool computed, bool R)
_undoStack->pushCommand(new InsertColumnCommand(_sourceModel, col, props));
}

void ExpandDataProxyModel::_expandIfNecessary(int row, int col)
void ExpandDataProxyModel::resize(int row, int col, bool onlyExpand, const QString& undoText)
{
QUndoCommand* parentCommand = nullptr;

if (!_sourceModel || row < 0 || col < 0)
return;

if (col >= _sourceModel->columnCount() || row >= _sourceModel->rowCount())
_undoStack->startMacro();
if (onlyExpand)
{
if (col < _sourceModel->columnCount() && row < _sourceModel->rowCount()) return;
}
else
{
if (col == (_sourceModel->columnCount() - 1) && row == (_sourceModel->rowCount() - 1)) return;
}

_undoStack->startMacro(undoText);

if(col >= _sourceModel->columnCount())
{
Expand All @@ -263,8 +269,9 @@ void ExpandDataProxyModel::_expandIfNecessary(int row, int col)
if(colC > 0)
insertColumns(colNr, colC);
}


else if (!onlyExpand && col < (_sourceModel->columnCount() - 1))
removeColumns(col + 1, _sourceModel->columnCount() - col - 1);

if(row >= _sourceModel->rowCount())
{
int rowNr = _sourceModel->rowCount(),
Expand All @@ -273,14 +280,19 @@ void ExpandDataProxyModel::_expandIfNecessary(int row, int col)
if(rowC > 0)
insertRows(rowNr, rowC);
}
else if (!onlyExpand && row < (_sourceModel->rowCount() - 1))
removeRows(row + 1, _sourceModel->rowCount() - row - 1);

if (!undoText.isEmpty())
_undoStack->endMacro();
}

void ExpandDataProxyModel::setData(int row, int col, const QVariant &value, int role)
{
if (!_sourceModel || row < 0 || col < 0)
return;

_expandIfNecessary(row, col);
resize(row, col);
_undoStack->endMacro(new SetDataCommand(_sourceModel, row, col, value, role));
}

Expand All @@ -289,7 +301,7 @@ void ExpandDataProxyModel::pasteSpreadsheet(int row, int col, const std::vector<
if (!_sourceModel || row < 0 || col < 0 || values.size() == 0 || values[0].size() == 0 )
return;

_expandIfNecessary(row + values[0].size() - 1, col + values.size() - 1);
resize(row + values[0].size() - 1, col + values.size() - 1);
_undoStack->endMacro(new PasteSpreadsheetCommand(_sourceModel, row, col, values, labels, selected, colNames));
}

Expand All @@ -315,7 +327,7 @@ void ExpandDataProxyModel::copyColumns(int startCol, const std::vector<Json::Val
if (!_sourceModel || startCol < 0 || copiedColumns.size() == 0)
return;

_expandIfNecessary(0, startCol + copiedColumns.size() - 1);
resize(0, startCol + copiedColumns.size() - 1);
_undoStack->endMacro(new CopyColumnsCommand(_sourceModel, startCol, copiedColumns));
}

Expand Down
2 changes: 1 addition & 1 deletion Desktop/data/expanddataproxymodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ class ExpandDataProxyModel : public QObject
void redo() { _undoStack->redo(); }
QString undoText() { return _undoStack->undoText(); }
QString redoText() { return _undoStack->redoText(); }
void resize(int row, int col, bool onlyExpand = true, const QString& undoText = QString());

signals:
void undoChanged();

protected:
void _setRolenames();
void _expandIfNecessary(int row, int col);

QAbstractItemModel* _sourceModel = nullptr;
bool _expandDataSet = false;
Expand Down
3 changes: 2 additions & 1 deletion Desktop/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,8 @@ void MainWindow::loadQML()
connect(_ribbonModel, &RibbonModel::cellsClear, DataSetView::mainDataViewer(), &DataSetView::cellsClear);
connect(_ribbonModel, &RibbonModel::dataUndo, DataSetView::mainDataViewer(), &DataSetView::undo);
connect(_ribbonModel, &RibbonModel::dataRedo, DataSetView::mainDataViewer(), &DataSetView::redo);

connect(this, &MainWindow::resizeData, DataSetView::mainDataViewer(), &DataSetView::resizeData);


//connect(DataSetView::lastInstancedDataSetView(), &DataSetView::selectionStartChanged, _columnModel, &ColumnModel::changeSelectedColumn);

Expand Down
1 change: 1 addition & 0 deletions Desktop/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ public slots:
void contactVisibleChanged();
void communityVisibleChanged();
void contactTextChanged();
void resizeData(int row, int col);

private slots:
void resultsPageLoaded();
Expand Down
4 changes: 3 additions & 1 deletion Desktop/modules/ribbonmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ void RibbonModel::addSpecialRibbonButtonsEarly()
_analysesButton = new RibbonButton(this, "Analyses", fq(tr("Analyses")), "JASP_logo_green.svg", false, [&](){ emit finishCurrentEdit(); emit showStatistics(); }, fq(tr("Switch JASP to analyses mode")), true);
_dataSwitchButton = new RibbonButton(this, "Data", fq(tr("Edit Data")), "data-button.svg", false, [&](){ emit showData(); }, fq(tr("Switch JASP to data editing mode")), false, false, false);
_dataNewButton = new RibbonButton(this, "Data-New", fq(tr("New Data")), "data-button-new.svg", false, [&](){ emit genShowEmptyData(); }, fq(tr("Open a workspace without data")), true, false, false);
_dataResizeButton = new RibbonButton(this, "Data-Resize", fq(tr("Resize Data")), "data-button-resize.svg", false, [&](){ emit resizeData(); }, fq(tr("Resize your dataset")), false);
_insertButton = new RibbonButton(this, "Data-Insert", fq(tr("Insert")), "data-button-insert.svg", _entriesInsert, fq(tr("Insert empty columns or rows")));
_removeButton = new RibbonButton(this, "Data-Remove", fq(tr("Remove")), "data-button-erase.svg", _entriesDelete, fq(tr("Remove columns or rows")));
_synchroniseOnButton = new RibbonButton(this, "Data-Synch-On", fq(tr("Synchronisation")), "data-button-sync-off.svg", true, [&](){ emit setDataSynchronisation(true); }, fq(tr("Turn external data synchronisation on")), false);
Expand All @@ -163,7 +164,7 @@ void RibbonModel::addSpecialRibbonButtonsEarly()

connect(this, &RibbonModel::dataLoadedChanged, _insertButton, &RibbonButton::setEnabled);
connect(this, &RibbonModel::dataLoadedChanged, _removeButton, &RibbonButton::setEnabled);

connect(this, &RibbonModel::dataLoadedChanged, _dataResizeButton, &RibbonButton::setEnabled);
connect(this, &RibbonModel::synchronisationChanged, _synchroniseOnButton, [=](bool synching){ _synchroniseOnButton->setEnabled(!synching); });
connect(this, &RibbonModel::synchronisationChanged, _synchroniseOffButton, [=](bool synching){ _synchroniseOffButton->setEnabled(synching); });

Expand Down Expand Up @@ -197,6 +198,7 @@ void RibbonModel::addSpecialRibbonButtonsEarly()
addRibbonButtonModel(new RibbonButton(this), size_t(RowType::Data));
addRibbonButtonModel(_synchroniseOnButton, size_t(RowType::Data));
addRibbonButtonModel(_synchroniseOffButton, size_t(RowType::Data));
addRibbonButtonModel(_dataResizeButton, size_t(RowType::Data));
addRibbonButtonModel(_insertButton, size_t(RowType::Data));
addRibbonButtonModel(_removeButton, size_t(RowType::Data));
addRibbonButtonModel(_undoButton, size_t(RowType::Data));
Expand Down
2 changes: 2 additions & 0 deletions Desktop/modules/ribbonmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ class RibbonModel : public QAbstractListModel
void dataModeChanged(bool dataMode);
void startExternalEdit();
void stopExternalEdit();
void resizeData();
void finishCurrentEdit();
void dataInsertComputedColumnBefore(int, bool);
void dataInsertComputedColumnAfter(int, bool);
Expand Down Expand Up @@ -152,6 +153,7 @@ private slots:
RibbonButton * _analysesButton = nullptr,
* _dataSwitchButton = nullptr,
* _dataNewButton = nullptr,
* _dataResizeButton = nullptr,
* _insertButton = nullptr,
* _removeButton = nullptr,
* _synchroniseOnButton = nullptr,
Expand Down
6 changes: 6 additions & 0 deletions Desktop/qquick/datasetview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1455,6 +1455,12 @@ void DataSetView::setColumnType(int columnIndex, int newColumnType)
columnIndexSelectedApply(columnIndex, [&](intset col) { _model->setColumnType(col, newColumnType); });
}

void DataSetView::resizeData(int rows, int columns)
{
// Argument row and column of the resize method are indices
_model->resize(rows - 1, columns - 1, false, tr("Resize data to %1 rows and %2 columns").arg(rows).arg(columns));
}

void DataSetView::columnReverseValues(int columnIndex)
{
columnIndexSelectedApply(columnIndex, [&](intset col) { _model->columnReverseValues(col); });
Expand Down
2 changes: 2 additions & 0 deletions Desktop/qquick/datasetview.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ public slots:
void commitLastEdit();

void setColumnType(int columnIndex, int newColumnType);
void resizeData(int rows, int columns);

protected:
void _copy(QPoint where, bool clear);
void calculateCellSizesAndClear(bool clearStorage);
Expand Down

0 comments on commit 3212d63

Please sign in to comment.