blob: 376de1cf083030ddf89ee20b3987922ee3ddcd54 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2012, 2019 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.r.ui.dataeditor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.ecommons.waltable.data.IDataProvider;
import org.eclipse.statet.ecommons.waltable.data.ISpanningDataProvider;
import org.eclipse.statet.ecommons.waltable.layer.cell.DataCell;
import org.eclipse.statet.ecommons.waltable.sort.ISortModel;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.r.ui.dataeditor.IRDataTableInput;
import org.eclipse.statet.r.ui.dataeditor.IRDataTableVariable;
import org.eclipse.statet.r.ui.dataeditor.RDataTableColumn;
import org.eclipse.statet.rj.data.RArray;
import org.eclipse.statet.rj.data.RDataUtils;
import org.eclipse.statet.rj.data.RList;
import org.eclipse.statet.rj.data.RStore;
import org.eclipse.statet.rj.data.UnexpectedRDataException;
import org.eclipse.statet.rj.services.FunctionCall;
import org.eclipse.statet.rj.ts.core.RToolService;
public class FTableDataProvider extends RMatrixDataProvider {
protected abstract class FTableHeaderDataProvider implements ISpanningDataProvider {
public FTableHeaderDataProvider() {
}
protected DataCell getCell(final RList vars, final long varIdx, long valueIdx) {
int span= 1;
for (long idx= vars.getLength() - 1; idx > varIdx; idx--) {
span *= vars.get(idx).getLength();
}
valueIdx -= valueIdx % span; // to origin
return createCell(varIdx, valueIdx, span);
}
protected abstract DataCell createCell(long varPosition, long valuePosition, int valueSpan);
protected Object getDataValue(final RList vars, final long varIdx, long valueIdx) {
if (vars.getLength() == 0) {
return DUMMY;
}
int span= 1;
for (long idx= vars.getLength() - 1; idx > varIdx; idx--) {
span *= vars.get(idx).getLength();
}
final RStore<?> values= vars.get(varIdx).getData();
valueIdx %= span * values.getLength(); // remove iteration
valueIdx /= span; // remove span
return values.get(valueIdx);
}
@Override
public void setDataValue(final long columnIndex, final long rowIndex, final Object newValue) {
throw new UnsupportedOperationException();
}
}
protected class FTableColumnDataProvider extends FTableHeaderDataProvider {
public FTableColumnDataProvider() {
}
@Override
public long getColumnCount() {
return FTableDataProvider.this.getColumnCount();
}
@Override
public long getRowCount() {
return FTableDataProvider.this.fColVars.getLength();
}
@Override
public DataCell getCellByPosition(final long columnIndex, final long rowIndex) {
return getCell(FTableDataProvider.this.fColVars, rowIndex, columnIndex);
}
@Override
protected DataCell createCell(final long varIndex, final long valueIndex, final int valueSpan) {
return new DataCell(valueIndex, varIndex, valueSpan, 1);
}
@Override
public Object getDataValue(final long columnIndex, final long rowIndex,
final int flags, final IProgressMonitor monitor) {
return getDataValue(FTableDataProvider.this.fColVars, rowIndex, columnIndex);
}
}
protected class FTableRowDataProvider extends FTableHeaderDataProvider {
public FTableRowDataProvider() {
}
@Override
public long getColumnCount() {
return FTableDataProvider.this.fRowVars.getLength();
}
@Override
public long getRowCount() {
return FTableDataProvider.this.getRowCount();
}
@Override
public DataCell getCellByPosition(final long columnIndex, final long rowIndex) {
return getCell(FTableDataProvider.this.fRowVars, columnIndex, rowIndex);
}
@Override
protected DataCell createCell(final long varPosition, final long valuePosition, final int valueSpan) {
return new DataCell(varPosition, valuePosition, 1, valueSpan);
}
@Override
public Object getDataValue(final long columnIndex, final long rowIndex,
final int flags, final IProgressMonitor monitor) {
return getDataValue(FTableDataProvider.this.fRowVars, columnIndex, rowIndex);
}
}
private RList fColVars;
private RList fRowVars;
public FTableDataProvider(final IRDataTableInput input, final RArray<?> struct) throws CoreException {
super(input, struct);
}
@Override
protected RDataTableContentDescription loadDescription(final RElementName name,
final RArray<?> struct,
final RToolService r, final ProgressMonitor m) throws StatusException, UnexpectedRDataException {
final RDataTableContentDescription description= new RDataTableContentDescription(name, struct, r.getTool());
// description.rowHeaderColumn= createNamesColumn("rownames(" + fInput.getFullName() + ")", getRowCount(struct), r, monitor);
final RDataTableColumn template= createColumn(struct.getData(),
getInput().getFullName(), null, -1, null,
r, m );
{ final FunctionCall call= r.createFunctionCall("attr"); //$NON-NLS-1$
call.add(getInput().getFullName());
call.addChar("col.vars"); //$NON-NLS-1$
this.fColVars= RDataUtils.checkRList(call.evalData(m));
if (checkVars(this.fColVars) != getColumnCount()) {
this.fColVars= null;
throw new UnexpectedRDataException("col.vars"); //$NON-NLS-1$
}
}
{ final FunctionCall call= r.createFunctionCall("attr"); //$NON-NLS-1$
call.add(getInput().getFullName());
call.addChar("row.vars"); //$NON-NLS-1$
this.fRowVars= RDataUtils.checkRList(call.evalData(m));
if (checkVars(this.fRowVars) != getFullRowCount()) {
this.fColVars= null;
this.fRowVars= null;
throw new UnexpectedRDataException("row.vars"); //$NON-NLS-1$
}
}
{ final int cols= (int) this.fColVars.getLength();
final int rows= (int) this.fRowVars.getLength();
final IRDataTableVariable[] variables= new IRDataTableVariable[cols + rows];
int i= 0;
for (int j= 0; j < cols; j++) {
variables[i++]= new FTableVariable(IRDataTableVariable.COLUMN, this.fColVars.getName(j),
this.fColVars.get(j).getData() );
}
for (int j= 0; j < rows; j++) {
variables[i++]= new FTableVariable(IRDataTableVariable.ROW, this.fRowVars.getName(j),
this.fRowVars.get(j).getData() );
}
description.setVariables(variables);
}
description.setDefaultDataFormat(template.getDefaultFormat());
return description;
}
private long checkVars(final RList rList) {
long num= 1;
final int l= (int) rList.getLength();
for (int i= 0; i < l; i++) {
num *= rList.get(i).getLength();
}
return num;
}
@Override
protected ISortModel createSortModel() {
return null;
}
@Override
public boolean hasRealColumns() {
return (this.fColVars.getLength() > 0);
}
@Override
public boolean hasRealRows() {
return (this.fRowVars.getLength() > 0);
}
@Override
protected IDataProvider createColumnDataProvider() {
return new FTableColumnDataProvider();
}
@Override
protected IDataProvider createRowDataProvider() {
return new FTableRowDataProvider();
}
@Override
public IDataProvider createColumnLabelProvider() {
return new IDataProvider() {
@Override
public long getColumnCount() {
return 0;
}
@Override
public long getRowCount() {
return FTableDataProvider.this.fColVars.getLength();
}
@Override
public Object getDataValue(final long columnIndex, final long rowIndex,
final int flags, final IProgressMonitor monitor) {
return FTableDataProvider.this.fColVars.getName(rowIndex);
}
@Override
public void setDataValue(final long columnIndex, final long rowIndex, final Object newValue) {
throw new UnsupportedOperationException();
}
};
}
@Override
public IDataProvider createRowLabelProvider() {
return new IDataProvider() {
@Override
public long getColumnCount() {
return FTableDataProvider.this.fRowVars.getLength();
}
@Override
public long getRowCount() {
return 0;
}
@Override
public Object getDataValue(final long columnIndex, final long rowIndex,
final int flags, final IProgressMonitor monitor) {
return FTableDataProvider.this.fRowVars.getName(columnIndex);
}
@Override
public void setDataValue(final long columnIndex, final long rowIndex, final Object newValue) {
throw new UnsupportedOperationException();
}
};
}
}