/
insertColumn.js
75 lines (63 loc) · 2.62 KB
/
insertColumn.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { arrayEach } from '../../../helpers/array';
import { cellCoordFactory, isFormulaExpression } from '../utils';
import CellValue from '../cell/value';
import ExpressionModifier from '../expressionModifier';
/**
* When "inser_column" is triggered the following operations must be performed:
*
* - All formulas which contain cell coordinates must be updated and saved into source data - Column must be increased
* by "amount" of times (eq: D4 to E4, $F$5 to $G$5);
* - Mark all formulas which need update with "STATE_OUT_OFF_DATE" flag, so they can be recalculated after the operation.
*/
export const OPERATION_NAME = 'insert_column';
/**
* Execute changes.
*
* @param {Number} start Index column from which the operation starts.
* @param {Number} amount Count of columns to be inserted.
* @param {Boolean} [modifyFormula=true] If `true` all formula expressions will be modified according to the changes.
* `false` value is used by UndoRedo plugin which saves snapshoots before alter
* operation so it doesn't have to modify formulas if "undo" action was triggered.
*/
export function operate(start, amount, modifyFormula = true) {
const { matrix, dataProvider } = this;
const translate = [0, amount];
arrayEach(matrix.cellReferences, (cell) => {
if (cell.column >= start) {
cell.translateTo(...translate);
}
});
arrayEach(matrix.data, (cell) => {
const { row: origRow, column: origColumn } = cell;
if (cell.column >= start) {
cell.translateTo(...translate);
cell.setState(CellValue.STATE_OUT_OFF_DATE);
}
if (modifyFormula) {
const { row, column } = cell;
const value = dataProvider.getSourceDataAtCell(row, column);
if (isFormulaExpression(value)) {
const startCoord = cellCoordFactory('column', start);
const expModifier = new ExpressionModifier(value);
expModifier.useCustomModifier(customTranslateModifier);
expModifier.translate({ column: amount }, startCoord({ row: origRow, column: origColumn }));
dataProvider.updateSourceData(row, column, expModifier.toString());
}
}
});
}
function customTranslateModifier(cell, axis, delta, startFromIndex) {
const { start, end } = cell;
const startIndex = start[axis].index;
const endIndex = end[axis].index;
let deltaStart = delta;
let deltaEnd = delta;
// Do not translate cells above inserted row or on the left of inserted column
if (startFromIndex > startIndex) {
deltaStart = 0;
}
if (startFromIndex > endIndex) {
deltaEnd = 0;
}
return [deltaStart, deltaEnd, false];
}