@odoo/o-spreadsheet 17.1.0-alpha.3 → 17.1.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/o-spreadsheet.cjs.js +655 -420
- package/dist/o-spreadsheet.d.ts +148 -138
- package/dist/o-spreadsheet.esm.js +655 -420
- package/dist/o-spreadsheet.iife.js +655 -420
- package/dist/o-spreadsheet.iife.min.js +294 -320
- package/dist/o_spreadsheet.xml +99 -61
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 17.1.0-alpha.
|
|
6
|
-
* @date 2023-11-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.1.0-alpha.4
|
|
6
|
+
* @date 2023-11-24T13:12:24.882Z
|
|
7
|
+
* @hash 255821b
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -228,7 +228,6 @@
|
|
|
228
228
|
const SCROLLBAR_WIDTH = 15;
|
|
229
229
|
const AUTOFILL_EDGE_LENGTH = 8;
|
|
230
230
|
const ICON_EDGE_LENGTH = 18;
|
|
231
|
-
const UNHIDE_ICON_EDGE_LENGTH = 14;
|
|
232
231
|
const MIN_CF_ICON_MARGIN = 4;
|
|
233
232
|
const MIN_CELL_TEXT_MARGIN = 4;
|
|
234
233
|
const CF_ICON_EDGE_LENGTH = 15;
|
|
@@ -692,8 +691,7 @@
|
|
|
692
691
|
*
|
|
693
692
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
|
|
694
693
|
*/
|
|
695
|
-
const
|
|
696
|
-
" ",
|
|
694
|
+
const whiteSpaceSpecialCharacters = [
|
|
697
695
|
"\t",
|
|
698
696
|
"\f",
|
|
699
697
|
"\v",
|
|
@@ -708,8 +706,7 @@
|
|
|
708
706
|
String.fromCharCode(parseInt("3000", 16)),
|
|
709
707
|
String.fromCharCode(parseInt("feff", 16)),
|
|
710
708
|
];
|
|
711
|
-
const whiteSpaceRegexp = new RegExp(
|
|
712
|
-
const newLineRegex = /\r\n|\r|\n/g;
|
|
709
|
+
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|") + "|(\r\n|\r|\n)", "g");
|
|
713
710
|
/**
|
|
714
711
|
* Replace all the special spaces in a string (non-breaking, tabs, ...) by normal spaces, and all the
|
|
715
712
|
* different newlines types by \n.
|
|
@@ -717,9 +714,9 @@
|
|
|
717
714
|
function replaceSpecialSpaces(text) {
|
|
718
715
|
if (!text)
|
|
719
716
|
return "";
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
return text;
|
|
717
|
+
if (!whiteSpaceRegexp.test(text))
|
|
718
|
+
return text;
|
|
719
|
+
return text.replace(whiteSpaceRegexp, (match, newLine) => (newLine ? NEWLINE : " "));
|
|
723
720
|
}
|
|
724
721
|
/**
|
|
725
722
|
* Determine if the numbers are consecutive.
|
|
@@ -2061,6 +2058,7 @@
|
|
|
2061
2058
|
CommandResult["InvalidNumberOfCriterionValues"] = "InvalidNumberOfCriterionValues";
|
|
2062
2059
|
CommandResult["BlockingValidationRule"] = "BlockingValidationRule";
|
|
2063
2060
|
CommandResult["InvalidCopyPasteSelection"] = "InvalidCopyPasteSelection";
|
|
2061
|
+
CommandResult["NoChanges"] = "NoChanges";
|
|
2064
2062
|
})(exports.CommandResult || (exports.CommandResult = {}));
|
|
2065
2063
|
|
|
2066
2064
|
const DEFAULT_LOCALES = [
|
|
@@ -2190,12 +2188,12 @@
|
|
|
2190
2188
|
}
|
|
2191
2189
|
}
|
|
2192
2190
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
2193
|
-
function normalizeString(str) {
|
|
2191
|
+
const normalizeString = memoize(function normalizeString(str) {
|
|
2194
2192
|
return str
|
|
2195
2193
|
.toLowerCase()
|
|
2196
2194
|
.normalize("NFD")
|
|
2197
2195
|
.replace(/[\u0300-\u036f]/g, "");
|
|
2198
|
-
}
|
|
2196
|
+
});
|
|
2199
2197
|
const expectBooleanValueError = (value) => _t("The function [[FUNCTION_NAME]] expects a boolean value, but '%s' is a text, and cannot be coerced to a number.", value);
|
|
2200
2198
|
function toBoolean(value) {
|
|
2201
2199
|
switch (typeof value) {
|
|
@@ -3428,11 +3426,18 @@
|
|
|
3428
3426
|
return singleCellReference.test(xc);
|
|
3429
3427
|
}
|
|
3430
3428
|
function splitReference(ref) {
|
|
3429
|
+
if (!ref.includes("!")) {
|
|
3430
|
+
return { xc: ref };
|
|
3431
|
+
}
|
|
3431
3432
|
const parts = ref.split("!");
|
|
3432
3433
|
const xc = parts.pop();
|
|
3433
3434
|
const sheetName = getUnquotedSheetName(parts.join("!")) || undefined;
|
|
3434
3435
|
return { sheetName, xc };
|
|
3435
3436
|
}
|
|
3437
|
+
/** Return a reference SheetName!xc from the given arguments */
|
|
3438
|
+
function getFullReference(sheetName, xc) {
|
|
3439
|
+
return sheetName !== undefined ? `${getCanonicalSheetName(sheetName)}!${xc}` : xc;
|
|
3440
|
+
}
|
|
3436
3441
|
|
|
3437
3442
|
/**
|
|
3438
3443
|
* Convert from a cartesian reference to a Zone
|
|
@@ -4541,14 +4546,14 @@
|
|
|
4541
4546
|
switch (context.textBaseline) {
|
|
4542
4547
|
case "top":
|
|
4543
4548
|
underlineY += boxHeight - 2 * strokeWidth;
|
|
4544
|
-
strikeY += boxHeight -
|
|
4549
|
+
strikeY += boxHeight / 2 - strokeWidth;
|
|
4545
4550
|
break;
|
|
4546
4551
|
case "middle":
|
|
4547
4552
|
underlineY += boxHeight / 2 - strokeWidth;
|
|
4548
4553
|
break;
|
|
4549
4554
|
case "alphabetic":
|
|
4550
4555
|
underlineY += 2 * strokeWidth;
|
|
4551
|
-
strikeY -=
|
|
4556
|
+
strikeY -= 3 * strokeWidth;
|
|
4552
4557
|
break;
|
|
4553
4558
|
case "bottom":
|
|
4554
4559
|
underlineY = y;
|
|
@@ -4611,6 +4616,7 @@
|
|
|
4611
4616
|
const children = item.children;
|
|
4612
4617
|
const description = item.description;
|
|
4613
4618
|
const icon = item.icon;
|
|
4619
|
+
const secondaryIcon = item.secondaryIcon;
|
|
4614
4620
|
return {
|
|
4615
4621
|
id: item.id || uuidGenerator$2.uuidv4(),
|
|
4616
4622
|
name: typeof name === "function" ? name : () => name,
|
|
@@ -4629,6 +4635,7 @@
|
|
|
4629
4635
|
isReadonlyAllowed: item.isReadonlyAllowed || false,
|
|
4630
4636
|
separator: item.separator || false,
|
|
4631
4637
|
icon: typeof icon === "function" ? icon : () => icon || "",
|
|
4638
|
+
secondaryIcon: typeof secondaryIcon === "function" ? secondaryIcon : () => secondaryIcon || "",
|
|
4632
4639
|
description: typeof description === "function" ? description : () => description || "",
|
|
4633
4640
|
textColor: item.textColor,
|
|
4634
4641
|
sequence: item.sequence || 0,
|
|
@@ -6984,11 +6991,9 @@
|
|
|
6984
6991
|
padding: ${MENU_VERTICAL_PADDING}px 0px;
|
|
6985
6992
|
width: ${MENU_WIDTH}px;
|
|
6986
6993
|
box-sizing: border-box !important;
|
|
6994
|
+
user-select: none;
|
|
6987
6995
|
|
|
6988
6996
|
.o-menu-item {
|
|
6989
|
-
display: flex;
|
|
6990
|
-
justify-content: space-between;
|
|
6991
|
-
align-items: center;
|
|
6992
6997
|
box-sizing: border-box;
|
|
6993
6998
|
height: ${MENU_ITEM_HEIGHT}px;
|
|
6994
6999
|
padding: ${MENU_ITEM_PADDING_VERTICAL}px ${MENU_ITEM_PADDING_HORIZONTAL}px;
|
|
@@ -6999,20 +7004,12 @@
|
|
|
6999
7004
|
min-width: 40%;
|
|
7000
7005
|
}
|
|
7001
7006
|
|
|
7002
|
-
&.o-menu-root {
|
|
7003
|
-
display: flex;
|
|
7004
|
-
justify-content: space-between;
|
|
7005
|
-
}
|
|
7006
|
-
|
|
7007
7007
|
.o-menu-item-icon {
|
|
7008
7008
|
display: inline-block;
|
|
7009
7009
|
margin: 0px 8px 0px 0px;
|
|
7010
7010
|
width: ${MENU_ITEM_HEIGHT - 2 * MENU_ITEM_PADDING_VERTICAL}px;
|
|
7011
7011
|
line-height: ${MENU_ITEM_HEIGHT - 2 * MENU_ITEM_PADDING_VERTICAL}px;
|
|
7012
7012
|
}
|
|
7013
|
-
.o-menu-item-root {
|
|
7014
|
-
width: 10px;
|
|
7015
|
-
}
|
|
7016
7013
|
|
|
7017
7014
|
&:not(.disabled) {
|
|
7018
7015
|
&:hover,
|
|
@@ -7355,7 +7352,7 @@
|
|
|
7355
7352
|
return result;
|
|
7356
7353
|
}
|
|
7357
7354
|
function tokenizeDebugger(chars) {
|
|
7358
|
-
if (chars.current
|
|
7355
|
+
if (chars.current === "?") {
|
|
7359
7356
|
chars.shift();
|
|
7360
7357
|
return { type: "DEBUGGER", value: "?" };
|
|
7361
7358
|
}
|
|
@@ -7366,7 +7363,7 @@
|
|
|
7366
7363
|
")": "RIGHT_PAREN",
|
|
7367
7364
|
};
|
|
7368
7365
|
function tokenizeMisc(chars) {
|
|
7369
|
-
if (chars.current
|
|
7366
|
+
if (chars.current in misc$1) {
|
|
7370
7367
|
const value = chars.shift();
|
|
7371
7368
|
const type = misc$1[value];
|
|
7372
7369
|
return { type, value };
|
|
@@ -7374,7 +7371,7 @@
|
|
|
7374
7371
|
return null;
|
|
7375
7372
|
}
|
|
7376
7373
|
function tokenizeArgsSeparator(chars, locale) {
|
|
7377
|
-
if (chars.current
|
|
7374
|
+
if (chars.current === locale.formulaArgSeparator) {
|
|
7378
7375
|
const value = chars.shift();
|
|
7379
7376
|
const type = "ARG_SEPARATOR";
|
|
7380
7377
|
return { type, value };
|
|
@@ -7399,14 +7396,13 @@
|
|
|
7399
7396
|
return null;
|
|
7400
7397
|
}
|
|
7401
7398
|
function tokenizeString(chars) {
|
|
7402
|
-
if (chars.current
|
|
7399
|
+
if (chars.current === '"') {
|
|
7403
7400
|
const startChar = chars.shift();
|
|
7404
7401
|
let letters = startChar;
|
|
7405
|
-
while (chars.current()
|
|
7406
|
-
(chars.current() !== startChar || letters[letters.length - 1] === "\\")) {
|
|
7402
|
+
while (chars.current && (chars.current !== startChar || letters[letters.length - 1] === "\\")) {
|
|
7407
7403
|
letters += chars.shift();
|
|
7408
7404
|
}
|
|
7409
|
-
if (chars.current
|
|
7405
|
+
if (chars.current === '"') {
|
|
7410
7406
|
letters += chars.shift();
|
|
7411
7407
|
}
|
|
7412
7408
|
return {
|
|
@@ -7433,14 +7429,14 @@
|
|
|
7433
7429
|
let result = "";
|
|
7434
7430
|
// there are two main cases to manage: either something which starts with
|
|
7435
7431
|
// a ', like 'Sheet 2'A2, or a word-like element.
|
|
7436
|
-
if (chars.current
|
|
7432
|
+
if (chars.current === "'") {
|
|
7437
7433
|
let lastChar = chars.shift();
|
|
7438
7434
|
result += lastChar;
|
|
7439
|
-
while (chars.current
|
|
7435
|
+
while (chars.current) {
|
|
7440
7436
|
lastChar = chars.shift();
|
|
7441
7437
|
result += lastChar;
|
|
7442
7438
|
if (lastChar === "'") {
|
|
7443
|
-
if (chars.current
|
|
7439
|
+
if (chars.current && chars.current === "'") {
|
|
7444
7440
|
lastChar = chars.shift();
|
|
7445
7441
|
result += lastChar;
|
|
7446
7442
|
}
|
|
@@ -7456,7 +7452,7 @@
|
|
|
7456
7452
|
};
|
|
7457
7453
|
}
|
|
7458
7454
|
}
|
|
7459
|
-
while (chars.current
|
|
7455
|
+
while (chars.current && separatorRegexp.test(chars.current)) {
|
|
7460
7456
|
result += chars.shift();
|
|
7461
7457
|
}
|
|
7462
7458
|
if (result.length) {
|
|
@@ -7471,14 +7467,14 @@
|
|
|
7471
7467
|
}
|
|
7472
7468
|
function tokenizeSpace(chars) {
|
|
7473
7469
|
let length = 0;
|
|
7474
|
-
while (chars.current
|
|
7470
|
+
while (chars.current === NEWLINE) {
|
|
7475
7471
|
length++;
|
|
7476
7472
|
chars.shift();
|
|
7477
7473
|
}
|
|
7478
7474
|
if (length) {
|
|
7479
7475
|
return { type: "SPACE", value: NEWLINE.repeat(length) };
|
|
7480
7476
|
}
|
|
7481
|
-
while (chars.current
|
|
7477
|
+
while (chars.current === " ") {
|
|
7482
7478
|
length++;
|
|
7483
7479
|
chars.shift();
|
|
7484
7480
|
}
|
|
@@ -7497,17 +7493,20 @@
|
|
|
7497
7493
|
class TokenizingChars {
|
|
7498
7494
|
text;
|
|
7499
7495
|
currentIndex = 0;
|
|
7496
|
+
current;
|
|
7500
7497
|
constructor(text) {
|
|
7501
7498
|
this.text = text;
|
|
7502
|
-
|
|
7503
|
-
current() {
|
|
7504
|
-
return this.text[this.currentIndex];
|
|
7499
|
+
this.current = text[0];
|
|
7505
7500
|
}
|
|
7506
7501
|
shift() {
|
|
7507
|
-
|
|
7502
|
+
const current = this.current;
|
|
7503
|
+
const next = this.text[++this.currentIndex];
|
|
7504
|
+
this.current = next;
|
|
7505
|
+
return current;
|
|
7508
7506
|
}
|
|
7509
7507
|
advanceBy(length) {
|
|
7510
7508
|
this.currentIndex += length;
|
|
7509
|
+
this.current = this.text[this.currentIndex];
|
|
7511
7510
|
}
|
|
7512
7511
|
isOver() {
|
|
7513
7512
|
return this.currentIndex >= this.text.length;
|
|
@@ -11311,7 +11310,7 @@
|
|
|
11311
11310
|
) {
|
|
11312
11311
|
const _array = toMatrix(arg);
|
|
11313
11312
|
const _nbRows = toInteger(rows?.value, this.locale);
|
|
11314
|
-
const _nbColumns = columns !== undefined ? toInteger(columns.value, this.
|
|
11313
|
+
const _nbColumns = columns !== undefined ? toInteger(columns.value, this.locale) : _array.length;
|
|
11315
11314
|
assert(() => _nbRows >= _array[0].length, _t("The rows arguments (%s) must be greater or equal than the number of rows of the array.", _nbRows.toString()));
|
|
11316
11315
|
assert(() => _nbColumns >= _array.length, _t("The columns arguments (%s) must be greater or equal than the number of columns of the array.", _nbColumns.toString()));
|
|
11317
11316
|
return generateMatrix(_nbColumns, _nbRows, (col, row) => col >= _array.length || row >= _array[col].length ? padWith : _array[col][row]);
|
|
@@ -11800,6 +11799,10 @@
|
|
|
11800
11799
|
FORMAT_LARGE_NUMBER: FORMAT_LARGE_NUMBER
|
|
11801
11800
|
});
|
|
11802
11801
|
|
|
11802
|
+
function sum(values, locale) {
|
|
11803
|
+
return reduceNumbers(values, (acc, a) => acc + a, 0, locale);
|
|
11804
|
+
}
|
|
11805
|
+
|
|
11803
11806
|
const DEFAULT_FACTOR = 1;
|
|
11804
11807
|
const DEFAULT_MODE = 0;
|
|
11805
11808
|
const DEFAULT_PLACES = 0;
|
|
@@ -12751,7 +12754,7 @@
|
|
|
12751
12754
|
return isMatrix(value1) ? value1[0][0]?.format : value1?.format;
|
|
12752
12755
|
},
|
|
12753
12756
|
compute: function (...values) {
|
|
12754
|
-
return
|
|
12757
|
+
return sum(values, this.locale);
|
|
12755
12758
|
},
|
|
12756
12759
|
isExported: true,
|
|
12757
12760
|
};
|
|
@@ -12920,6 +12923,44 @@
|
|
|
12920
12923
|
const dims = args[0].length;
|
|
12921
12924
|
args.forEach((arg, i) => assert(() => arg.length === dims, _t("[[FUNCTION_NAME]] has mismatched dimensions for argument %s (%s vs %s).", i.toString(), dims.toString(), arg.length.toString())));
|
|
12922
12925
|
}
|
|
12926
|
+
function average(values, locale) {
|
|
12927
|
+
let count = 0;
|
|
12928
|
+
const sum = reduceNumbers(values, (acc, a) => {
|
|
12929
|
+
count += 1;
|
|
12930
|
+
return acc + a;
|
|
12931
|
+
}, 0, locale);
|
|
12932
|
+
assert(() => count !== 0, _t("Evaluation of function [[FUNCTION_NAME]] caused a divide by zero error."));
|
|
12933
|
+
return sum / count;
|
|
12934
|
+
}
|
|
12935
|
+
function countNumbers(values, locale) {
|
|
12936
|
+
let count = 0;
|
|
12937
|
+
for (let n of values) {
|
|
12938
|
+
if (isMatrix(n)) {
|
|
12939
|
+
for (let i of n) {
|
|
12940
|
+
for (let j of i) {
|
|
12941
|
+
if (typeof j === "number") {
|
|
12942
|
+
count += 1;
|
|
12943
|
+
}
|
|
12944
|
+
}
|
|
12945
|
+
}
|
|
12946
|
+
}
|
|
12947
|
+
else if (typeof n !== "string" || isNumber(n, locale) || parseDateTime(n, locale)) {
|
|
12948
|
+
count += 1;
|
|
12949
|
+
}
|
|
12950
|
+
}
|
|
12951
|
+
return count;
|
|
12952
|
+
}
|
|
12953
|
+
function countAny(values) {
|
|
12954
|
+
return reduceAny(values, (acc, a) => (a !== undefined && a !== null ? acc + 1 : acc), 0);
|
|
12955
|
+
}
|
|
12956
|
+
function max(values, locale) {
|
|
12957
|
+
const result = reduceNumbers(values, (acc, a) => (acc < a ? a : acc), -Infinity, locale);
|
|
12958
|
+
return result === -Infinity ? 0 : result;
|
|
12959
|
+
}
|
|
12960
|
+
function min(values, locale) {
|
|
12961
|
+
const result = reduceNumbers(values, (acc, a) => (a < acc ? a : acc), Infinity, locale);
|
|
12962
|
+
return result === Infinity ? 0 : result;
|
|
12963
|
+
}
|
|
12923
12964
|
|
|
12924
12965
|
function filterAndFlatData(dataY, dataX) {
|
|
12925
12966
|
const _flatDataY = [];
|
|
@@ -13190,13 +13231,7 @@
|
|
|
13190
13231
|
return isMatrix(value1) ? value1[0][0]?.format : value1?.format;
|
|
13191
13232
|
},
|
|
13192
13233
|
compute: function (...values) {
|
|
13193
|
-
|
|
13194
|
-
const sum = reduceNumbers(values, (acc, a) => {
|
|
13195
|
-
count += 1;
|
|
13196
|
-
return acc + a;
|
|
13197
|
-
}, 0, this.locale);
|
|
13198
|
-
assert(() => count !== 0, _t("Evaluation of function [[FUNCTION_NAME]] caused a divide by zero error."));
|
|
13199
|
-
return sum / count;
|
|
13234
|
+
return average(values, this.locale);
|
|
13200
13235
|
},
|
|
13201
13236
|
isExported: true,
|
|
13202
13237
|
};
|
|
@@ -13354,24 +13389,7 @@
|
|
|
13354
13389
|
],
|
|
13355
13390
|
returns: ["NUMBER"],
|
|
13356
13391
|
compute: function (...values) {
|
|
13357
|
-
|
|
13358
|
-
for (let n of values) {
|
|
13359
|
-
if (isMatrix(n)) {
|
|
13360
|
-
for (let i of n) {
|
|
13361
|
-
for (let j of i) {
|
|
13362
|
-
if (typeof j === "number") {
|
|
13363
|
-
count += 1;
|
|
13364
|
-
}
|
|
13365
|
-
}
|
|
13366
|
-
}
|
|
13367
|
-
}
|
|
13368
|
-
else if (typeof n !== "string" ||
|
|
13369
|
-
isNumber(n, this.locale) ||
|
|
13370
|
-
parseDateTime(n, this.locale)) {
|
|
13371
|
-
count += 1;
|
|
13372
|
-
}
|
|
13373
|
-
}
|
|
13374
|
-
return count;
|
|
13392
|
+
return countNumbers(values, this.locale);
|
|
13375
13393
|
},
|
|
13376
13394
|
isExported: true,
|
|
13377
13395
|
};
|
|
@@ -13386,7 +13404,7 @@
|
|
|
13386
13404
|
],
|
|
13387
13405
|
returns: ["NUMBER"],
|
|
13388
13406
|
compute: function (...values) {
|
|
13389
|
-
return
|
|
13407
|
+
return countAny(values);
|
|
13390
13408
|
},
|
|
13391
13409
|
isExported: true,
|
|
13392
13410
|
};
|
|
@@ -13616,8 +13634,7 @@
|
|
|
13616
13634
|
return isMatrix(value1) ? value1[0][0]?.format : value1?.format;
|
|
13617
13635
|
},
|
|
13618
13636
|
compute: function (...values) {
|
|
13619
|
-
|
|
13620
|
-
return result === -Infinity ? 0 : result;
|
|
13637
|
+
return max(values, this.locale);
|
|
13621
13638
|
},
|
|
13622
13639
|
isExported: true,
|
|
13623
13640
|
};
|
|
@@ -13704,8 +13721,7 @@
|
|
|
13704
13721
|
return isMatrix(value1) ? value1[0][0]?.format : value1?.format;
|
|
13705
13722
|
},
|
|
13706
13723
|
compute: function (...values) {
|
|
13707
|
-
|
|
13708
|
-
return result === Infinity ? 0 : result;
|
|
13724
|
+
return min(values, this.locale);
|
|
13709
13725
|
},
|
|
13710
13726
|
isExported: true,
|
|
13711
13727
|
};
|
|
@@ -17876,6 +17892,149 @@
|
|
|
17876
17892
|
YIELDMAT: YIELDMAT
|
|
17877
17893
|
});
|
|
17878
17894
|
|
|
17895
|
+
/**
|
|
17896
|
+
* Change the reference types inside the given token, if the token represent a range or a cell
|
|
17897
|
+
*
|
|
17898
|
+
* Eg. :
|
|
17899
|
+
* A1 => $A$1 => A$1 => $A1 => A1
|
|
17900
|
+
* A1:$B$1 => $A$1:B$1 => A$1:$B1 => $A1:B1 => A1:$B$1
|
|
17901
|
+
*/
|
|
17902
|
+
function loopThroughReferenceType(token) {
|
|
17903
|
+
if (token.type !== "REFERENCE")
|
|
17904
|
+
return token;
|
|
17905
|
+
const { xc, sheetName } = splitReference(token.value);
|
|
17906
|
+
const [left, right] = xc.split(":");
|
|
17907
|
+
const updatedLeft = getTokenNextReferenceType(left);
|
|
17908
|
+
const updatedRight = right ? `:${getTokenNextReferenceType(right)}` : "";
|
|
17909
|
+
return { ...token, value: getFullReference(sheetName, updatedLeft + updatedRight) };
|
|
17910
|
+
}
|
|
17911
|
+
/**
|
|
17912
|
+
* Get a new token with a changed type of reference from the given cell token symbol.
|
|
17913
|
+
* Undefined behavior if given a token other than a cell or if the Xc contains a sheet reference
|
|
17914
|
+
*
|
|
17915
|
+
* A1 => $A$1 => A$1 => $A1 => A1
|
|
17916
|
+
*/
|
|
17917
|
+
function getTokenNextReferenceType(xc) {
|
|
17918
|
+
switch (getReferenceType(xc)) {
|
|
17919
|
+
case "none":
|
|
17920
|
+
xc = setXcToFixedReferenceType(xc, "colrow");
|
|
17921
|
+
break;
|
|
17922
|
+
case "colrow":
|
|
17923
|
+
xc = setXcToFixedReferenceType(xc, "row");
|
|
17924
|
+
break;
|
|
17925
|
+
case "row":
|
|
17926
|
+
xc = setXcToFixedReferenceType(xc, "col");
|
|
17927
|
+
break;
|
|
17928
|
+
case "col":
|
|
17929
|
+
xc = setXcToFixedReferenceType(xc, "none");
|
|
17930
|
+
break;
|
|
17931
|
+
}
|
|
17932
|
+
return xc;
|
|
17933
|
+
}
|
|
17934
|
+
/**
|
|
17935
|
+
* Returns the given XC with the given reference type. The XC string should not contain a sheet name.
|
|
17936
|
+
*/
|
|
17937
|
+
function setXcToFixedReferenceType(xc, referenceType) {
|
|
17938
|
+
if (xc.includes("!")) {
|
|
17939
|
+
throw new Error("The given XC should not contain a sheet name");
|
|
17940
|
+
}
|
|
17941
|
+
xc = xc.replace(/\$/g, "");
|
|
17942
|
+
let indexOfNumber;
|
|
17943
|
+
switch (referenceType) {
|
|
17944
|
+
case "col":
|
|
17945
|
+
return "$" + xc;
|
|
17946
|
+
case "row":
|
|
17947
|
+
indexOfNumber = xc.search(/[0-9]/);
|
|
17948
|
+
return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
17949
|
+
case "colrow":
|
|
17950
|
+
indexOfNumber = xc.search(/[0-9]/);
|
|
17951
|
+
xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
17952
|
+
return "$" + xc;
|
|
17953
|
+
case "none":
|
|
17954
|
+
return xc;
|
|
17955
|
+
}
|
|
17956
|
+
}
|
|
17957
|
+
/**
|
|
17958
|
+
* Return the type of reference used in the given XC of a cell.
|
|
17959
|
+
* Undefined behavior if the XC have a sheet reference
|
|
17960
|
+
*/
|
|
17961
|
+
function getReferenceType(xcCell) {
|
|
17962
|
+
if (isColAndRowFixed(xcCell)) {
|
|
17963
|
+
return "colrow";
|
|
17964
|
+
}
|
|
17965
|
+
else if (isColFixed(xcCell)) {
|
|
17966
|
+
return "col";
|
|
17967
|
+
}
|
|
17968
|
+
else if (isRowFixed(xcCell)) {
|
|
17969
|
+
return "row";
|
|
17970
|
+
}
|
|
17971
|
+
return "none";
|
|
17972
|
+
}
|
|
17973
|
+
function isColFixed(xc) {
|
|
17974
|
+
return xc.startsWith("$");
|
|
17975
|
+
}
|
|
17976
|
+
function isRowFixed(xc) {
|
|
17977
|
+
return xc.includes("$", 1);
|
|
17978
|
+
}
|
|
17979
|
+
function isColAndRowFixed(xc) {
|
|
17980
|
+
return xc.startsWith("$") && xc.length > 1 && xc.slice(1).includes("$");
|
|
17981
|
+
}
|
|
17982
|
+
|
|
17983
|
+
// -----------------------------------------------------------------------------
|
|
17984
|
+
// CELL
|
|
17985
|
+
// -----------------------------------------------------------------------------
|
|
17986
|
+
// NOTE: missing from Excel: "color", "filename", "parentheses", "prefix", "protect" and "width"
|
|
17987
|
+
const CELL_INFO_TYPES = ["address", "col", "contents", "format", "row", "type"];
|
|
17988
|
+
const CELL = {
|
|
17989
|
+
description: _t("Gets information about a cell."),
|
|
17990
|
+
args: [
|
|
17991
|
+
arg("info_type (string)", _t("The type of information requested. Can be one of %s", CELL_INFO_TYPES.join(", "))),
|
|
17992
|
+
arg("reference (meta)", _t("The reference to the cell.")),
|
|
17993
|
+
],
|
|
17994
|
+
returns: ["ANY"],
|
|
17995
|
+
compute: function (info, reference) {
|
|
17996
|
+
const _info = toString(info).toLowerCase();
|
|
17997
|
+
assert(() => CELL_INFO_TYPES.includes(_info), _t("The info_type should be one of %s.", CELL_INFO_TYPES.join(", ")));
|
|
17998
|
+
const sheetId = this.__originSheetId;
|
|
17999
|
+
const topLeftReference = reference.includes(":") ? reference.split(":")[0] : reference;
|
|
18000
|
+
let { sheetName, xc } = splitReference(topLeftReference);
|
|
18001
|
+
// only put the sheet name if the referenced range is in another sheet than the cell the formula is on
|
|
18002
|
+
sheetName = sheetName === this.getters.getSheetName(sheetId) ? undefined : sheetName;
|
|
18003
|
+
const fixedRef = getFullReference(sheetName, setXcToFixedReferenceType(xc, "colrow"));
|
|
18004
|
+
const range = this.getters.getRangeFromSheetXC(sheetId, fixedRef);
|
|
18005
|
+
switch (_info) {
|
|
18006
|
+
case "address":
|
|
18007
|
+
return this.getters.getRangeString(range, sheetId);
|
|
18008
|
+
case "col":
|
|
18009
|
+
return range.zone.left + 1;
|
|
18010
|
+
case "contents": {
|
|
18011
|
+
const position = { sheetId: range.sheetId, col: range.zone.left, row: range.zone.top };
|
|
18012
|
+
return this.getters.getEvaluatedCell(position).value;
|
|
18013
|
+
}
|
|
18014
|
+
case "format": {
|
|
18015
|
+
const position = { sheetId: range.sheetId, col: range.zone.left, row: range.zone.top };
|
|
18016
|
+
return this.getters.getEvaluatedCell(position).format || "";
|
|
18017
|
+
}
|
|
18018
|
+
case "row":
|
|
18019
|
+
return range.zone.top + 1;
|
|
18020
|
+
case "type": {
|
|
18021
|
+
const position = { sheetId: range.sheetId, col: range.zone.left, row: range.zone.top };
|
|
18022
|
+
const type = this.getters.getEvaluatedCell(position).type;
|
|
18023
|
+
if (type === CellValueType.empty) {
|
|
18024
|
+
return "b"; // blank
|
|
18025
|
+
}
|
|
18026
|
+
else if (type === CellValueType.text) {
|
|
18027
|
+
return "l"; // label
|
|
18028
|
+
}
|
|
18029
|
+
else {
|
|
18030
|
+
return "v"; // value
|
|
18031
|
+
}
|
|
18032
|
+
}
|
|
18033
|
+
}
|
|
18034
|
+
return "";
|
|
18035
|
+
},
|
|
18036
|
+
isExported: true,
|
|
18037
|
+
};
|
|
17879
18038
|
// -----------------------------------------------------------------------------
|
|
17880
18039
|
// ISERR
|
|
17881
18040
|
// -----------------------------------------------------------------------------
|
|
@@ -18031,6 +18190,7 @@
|
|
|
18031
18190
|
|
|
18032
18191
|
var info = /*#__PURE__*/Object.freeze({
|
|
18033
18192
|
__proto__: null,
|
|
18193
|
+
CELL: CELL,
|
|
18034
18194
|
ISBLANK: ISBLANK,
|
|
18035
18195
|
ISERR: ISERR,
|
|
18036
18196
|
ISERROR: ISERROR,
|
|
@@ -18322,7 +18482,7 @@
|
|
|
18322
18482
|
cellReference = rowPart + colPart;
|
|
18323
18483
|
}
|
|
18324
18484
|
if (sheet !== undefined) {
|
|
18325
|
-
return
|
|
18485
|
+
return getFullReference(toString(sheet), cellReference);
|
|
18326
18486
|
}
|
|
18327
18487
|
return cellReference;
|
|
18328
18488
|
},
|
|
@@ -18338,7 +18498,7 @@
|
|
|
18338
18498
|
],
|
|
18339
18499
|
returns: ["NUMBER"],
|
|
18340
18500
|
compute: function (cellReference) {
|
|
18341
|
-
const _cellReference = cellReference || this.__originCellXC
|
|
18501
|
+
const _cellReference = cellReference || this.__originCellXC();
|
|
18342
18502
|
assert(() => !!_cellReference, "In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter.");
|
|
18343
18503
|
const zone = toZone(_cellReference);
|
|
18344
18504
|
return zone.left + 1;
|
|
@@ -18505,7 +18665,7 @@
|
|
|
18505
18665
|
],
|
|
18506
18666
|
returns: ["NUMBER"],
|
|
18507
18667
|
compute: function (cellReference) {
|
|
18508
|
-
cellReference = cellReference || this.__originCellXC
|
|
18668
|
+
cellReference = cellReference || this.__originCellXC();
|
|
18509
18669
|
assert(() => !!cellReference, "In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter.");
|
|
18510
18670
|
const zone = toZone(cellReference);
|
|
18511
18671
|
return zone.top + 1;
|
|
@@ -23857,31 +24017,65 @@
|
|
|
23857
24017
|
`;
|
|
23858
24018
|
class FindAndReplacePanel extends owl.Component {
|
|
23859
24019
|
static template = "o-spreadsheet-FindAndReplacePanel";
|
|
23860
|
-
|
|
24020
|
+
static components = { SelectionInput };
|
|
23861
24021
|
debounceTimeoutId;
|
|
23862
|
-
|
|
24022
|
+
initialShowFormulaState = false;
|
|
24023
|
+
dataRange = "";
|
|
23863
24024
|
searchInput = owl.useRef("searchInput");
|
|
24025
|
+
replaceInput = owl.useRef("replaceInput");
|
|
23864
24026
|
get hasSearchResult() {
|
|
23865
24027
|
return this.env.model.getters.getCurrentSelectedMatchIndex() !== null;
|
|
23866
24028
|
}
|
|
23867
24029
|
get pendingSearch() {
|
|
23868
24030
|
return this.debounceTimeoutId !== undefined;
|
|
23869
24031
|
}
|
|
24032
|
+
get searchOptions() {
|
|
24033
|
+
return this.env.model.getters.getSearchOptions();
|
|
24034
|
+
}
|
|
24035
|
+
get toSearch() {
|
|
24036
|
+
return this.searchInput.el?.value || "";
|
|
24037
|
+
}
|
|
24038
|
+
get toReplace() {
|
|
24039
|
+
return this.replaceInput.el?.value || "";
|
|
24040
|
+
}
|
|
24041
|
+
get allSheetsMatchesCount() {
|
|
24042
|
+
return _t("%s in all sheets", this.env.model.getters.getAllSheetMatchesCount());
|
|
24043
|
+
}
|
|
24044
|
+
get currentSheetMatchesCount() {
|
|
24045
|
+
return _t("%(matches)s in sheet %(sheetName)s", {
|
|
24046
|
+
matches: this.env.model.getters.getActiveSheetMatchesCount(),
|
|
24047
|
+
sheetName: this.env.model.getters.getSheetName(this.env.model.getters.getActiveSheetId()),
|
|
24048
|
+
});
|
|
24049
|
+
}
|
|
24050
|
+
get specificRangeMatchesCount() {
|
|
24051
|
+
const range = this.searchOptions.specificRange;
|
|
24052
|
+
if (!range) {
|
|
24053
|
+
return "";
|
|
24054
|
+
}
|
|
24055
|
+
const { _sheetId, _zone } = range;
|
|
24056
|
+
return _t("%(matches)s in range %(range)s of sheet %(sheetName)s", {
|
|
24057
|
+
matches: this.env.model.getters.getSpecificRangeMatchesCount().toString(),
|
|
24058
|
+
range: zoneToXc(_zone),
|
|
24059
|
+
sheetName: this.env.model.getters.getSheetName(_sheetId),
|
|
24060
|
+
});
|
|
24061
|
+
}
|
|
23870
24062
|
setup() {
|
|
23871
|
-
this.
|
|
24063
|
+
this.initialShowFormulaState = this.env.model.getters.shouldShowFormulas();
|
|
23872
24064
|
owl.onMounted(() => this.searchInput.el?.focus());
|
|
23873
24065
|
owl.onWillUnmount(() => {
|
|
23874
24066
|
clearTimeout(this.debounceTimeoutId);
|
|
23875
24067
|
this.env.model.dispatch("CLEAR_SEARCH");
|
|
23876
|
-
this.env.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.
|
|
24068
|
+
this.env.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.initialShowFormulaState });
|
|
23877
24069
|
});
|
|
23878
24070
|
owl.useEffect(() => {
|
|
23879
|
-
|
|
23880
|
-
this.searchFormulas
|
|
24071
|
+
const showFormula = this.env.model.getters.shouldShowFormulas();
|
|
24072
|
+
this.updateSearch({ searchFormulas: showFormula });
|
|
23881
24073
|
}, () => [this.env.model.getters.shouldShowFormulas()]);
|
|
23882
24074
|
}
|
|
23883
|
-
|
|
23884
|
-
this.
|
|
24075
|
+
onFocusSearch() {
|
|
24076
|
+
this.updateDataRange();
|
|
24077
|
+
}
|
|
24078
|
+
onInput() {
|
|
23885
24079
|
this.debouncedUpdateSearch();
|
|
23886
24080
|
}
|
|
23887
24081
|
onKeydownSearch(ev) {
|
|
@@ -23898,11 +24092,36 @@
|
|
|
23898
24092
|
this.replace();
|
|
23899
24093
|
}
|
|
23900
24094
|
}
|
|
23901
|
-
searchFormulas() {
|
|
24095
|
+
searchFormulas(ev) {
|
|
24096
|
+
const showFormula = ev.target.checked;
|
|
23902
24097
|
this.env.model.dispatch("SET_FORMULA_VISIBILITY", {
|
|
23903
|
-
show:
|
|
24098
|
+
show: showFormula,
|
|
23904
24099
|
});
|
|
23905
|
-
this.updateSearch();
|
|
24100
|
+
this.updateSearch({ searchFormulas: showFormula });
|
|
24101
|
+
}
|
|
24102
|
+
searchExactMatch(ev) {
|
|
24103
|
+
const exactMatch = ev.target.checked;
|
|
24104
|
+
this.updateSearch({ exactMatch });
|
|
24105
|
+
}
|
|
24106
|
+
searchMatchCase(ev) {
|
|
24107
|
+
const matchCase = ev.target.checked;
|
|
24108
|
+
this.updateSearch({ matchCase });
|
|
24109
|
+
}
|
|
24110
|
+
changeSearchScope(ev) {
|
|
24111
|
+
const searchScope = ev.target.value;
|
|
24112
|
+
this.updateSearch({ searchScope });
|
|
24113
|
+
}
|
|
24114
|
+
onSearchRangeChanged(ranges) {
|
|
24115
|
+
this.dataRange = ranges[0];
|
|
24116
|
+
}
|
|
24117
|
+
updateDataRange() {
|
|
24118
|
+
if (!this.dataRange) {
|
|
24119
|
+
return;
|
|
24120
|
+
}
|
|
24121
|
+
if (this.searchOptions.searchScope === "specificRange") {
|
|
24122
|
+
const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.dataRange).rangeData;
|
|
24123
|
+
this.updateSearch({ specificRange });
|
|
24124
|
+
}
|
|
23906
24125
|
}
|
|
23907
24126
|
onSelectPreviousCell() {
|
|
23908
24127
|
this.env.model.dispatch("SELECT_SEARCH_PREVIOUS_MATCH");
|
|
@@ -23910,10 +24129,14 @@
|
|
|
23910
24129
|
onSelectNextCell() {
|
|
23911
24130
|
this.env.model.dispatch("SELECT_SEARCH_NEXT_MATCH");
|
|
23912
24131
|
}
|
|
23913
|
-
updateSearch() {
|
|
24132
|
+
updateSearch(updateSearchOptions) {
|
|
24133
|
+
const searchOptions = {
|
|
24134
|
+
...this.env.model.getters.getSearchOptions(),
|
|
24135
|
+
...updateSearchOptions,
|
|
24136
|
+
};
|
|
23914
24137
|
this.env.model.dispatch("UPDATE_SEARCH", {
|
|
23915
|
-
toSearch: this.
|
|
23916
|
-
searchOptions
|
|
24138
|
+
toSearch: this.toSearch,
|
|
24139
|
+
searchOptions,
|
|
23917
24140
|
});
|
|
23918
24141
|
}
|
|
23919
24142
|
debouncedUpdateSearch() {
|
|
@@ -23925,28 +24148,14 @@
|
|
|
23925
24148
|
}
|
|
23926
24149
|
replace() {
|
|
23927
24150
|
this.env.model.dispatch("REPLACE_SEARCH", {
|
|
23928
|
-
replaceWith: this.
|
|
24151
|
+
replaceWith: this.toReplace,
|
|
23929
24152
|
});
|
|
23930
24153
|
}
|
|
23931
24154
|
replaceAll() {
|
|
23932
24155
|
this.env.model.dispatch("REPLACE_ALL_SEARCH", {
|
|
23933
|
-
replaceWith: this.
|
|
24156
|
+
replaceWith: this.toReplace,
|
|
23934
24157
|
});
|
|
23935
24158
|
}
|
|
23936
|
-
// ---------------------------------------------------------------------------
|
|
23937
|
-
// Private
|
|
23938
|
-
// ---------------------------------------------------------------------------
|
|
23939
|
-
initialState() {
|
|
23940
|
-
return {
|
|
23941
|
-
toSearch: "",
|
|
23942
|
-
replaceWith: "",
|
|
23943
|
-
searchOptions: {
|
|
23944
|
-
matchCase: false,
|
|
23945
|
-
exactMatch: false,
|
|
23946
|
-
searchFormulas: false,
|
|
23947
|
-
},
|
|
23948
|
-
};
|
|
23949
|
-
}
|
|
23950
24159
|
}
|
|
23951
24160
|
FindAndReplacePanel.props = {
|
|
23952
24161
|
onCloseSidePanel: Function,
|
|
@@ -27092,7 +27301,7 @@
|
|
|
27092
27301
|
get cellReference() {
|
|
27093
27302
|
const { col, row, sheetId } = this.env.model.getters.getCurrentEditedCell();
|
|
27094
27303
|
const prefixSheet = sheetId !== this.env.model.getters.getActiveSheetId();
|
|
27095
|
-
return
|
|
27304
|
+
return getFullReference(prefixSheet ? this.env.model.getters.getSheetName(sheetId) : undefined, toXC(col, row));
|
|
27096
27305
|
}
|
|
27097
27306
|
get cellReferenceStyle() {
|
|
27098
27307
|
const { x: left, y: top } = this.rect;
|
|
@@ -28535,22 +28744,15 @@
|
|
|
28535
28744
|
height: 10000px;
|
|
28536
28745
|
background-color: ${SELECTION_BORDER_COLOR};
|
|
28537
28746
|
}
|
|
28538
|
-
.o-unhide {
|
|
28539
|
-
width:
|
|
28540
|
-
|
|
28541
|
-
|
|
28542
|
-
overflow: hidden;
|
|
28543
|
-
border-radius: 2px;
|
|
28544
|
-
top: calc(${HEADER_HEIGHT}px / 2 - ${UNHIDE_ICON_EDGE_LENGTH}px / 2);
|
|
28747
|
+
.o-unhide-buttons {
|
|
28748
|
+
width: fit-content;
|
|
28749
|
+
gap: 5px;
|
|
28750
|
+
transform: translate(-50%, 0);
|
|
28545
28751
|
}
|
|
28546
28752
|
.o-unhide:hover {
|
|
28547
28753
|
z-index: ${ComponentsImportance.Grid + 1};
|
|
28548
28754
|
background-color: lightgrey;
|
|
28549
28755
|
}
|
|
28550
|
-
.o-unhide > svg {
|
|
28551
|
-
position: relative;
|
|
28552
|
-
top: calc(${UNHIDE_ICON_EDGE_LENGTH}px / 2 - ${ICON_EDGE_LENGTH}px / 2);
|
|
28553
|
-
}
|
|
28554
28756
|
}
|
|
28555
28757
|
`;
|
|
28556
28758
|
AbstractResizer.props = {
|
|
@@ -28660,8 +28862,8 @@
|
|
|
28660
28862
|
dimension: "COL",
|
|
28661
28863
|
});
|
|
28662
28864
|
}
|
|
28663
|
-
|
|
28664
|
-
return this._getDimensionsInViewport(hiddenIndex).start;
|
|
28865
|
+
getUnhideButtonStyle(hiddenIndex) {
|
|
28866
|
+
return cssPropertiesToCss({ left: this._getDimensionsInViewport(hiddenIndex).start + "px" });
|
|
28665
28867
|
}
|
|
28666
28868
|
}
|
|
28667
28869
|
css /* scss */ `
|
|
@@ -28707,18 +28909,9 @@
|
|
|
28707
28909
|
height: 1px;
|
|
28708
28910
|
background-color: ${SELECTION_BORDER_COLOR};
|
|
28709
28911
|
}
|
|
28710
|
-
.o-unhide {
|
|
28711
|
-
|
|
28712
|
-
|
|
28713
|
-
position: absolute;
|
|
28714
|
-
overflow: hidden;
|
|
28715
|
-
border-radius: 2px;
|
|
28716
|
-
left: calc(${HEADER_WIDTH}px - ${UNHIDE_ICON_EDGE_LENGTH}px - 2px);
|
|
28717
|
-
}
|
|
28718
|
-
.o-unhide > svg {
|
|
28719
|
-
position: relative;
|
|
28720
|
-
left: calc(${UNHIDE_ICON_EDGE_LENGTH}px / 2 - ${ICON_EDGE_LENGTH}px / 2);
|
|
28721
|
-
top: calc(${UNHIDE_ICON_EDGE_LENGTH}px / 2 - ${ICON_EDGE_LENGTH}px / 2);
|
|
28912
|
+
.o-unhide-buttons {
|
|
28913
|
+
height: fit-content;
|
|
28914
|
+
transform: translate(0, -50%);
|
|
28722
28915
|
}
|
|
28723
28916
|
.o-unhide:hover {
|
|
28724
28917
|
z-index: ${ComponentsImportance.Grid + 1};
|
|
@@ -28833,8 +29026,8 @@
|
|
|
28833
29026
|
elements: hiddenElements,
|
|
28834
29027
|
});
|
|
28835
29028
|
}
|
|
28836
|
-
|
|
28837
|
-
return this._getDimensionsInViewport(hiddenIndex).start;
|
|
29029
|
+
getUnhideButtonStyle(hiddenIndex) {
|
|
29030
|
+
return cssPropertiesToCss({ top: this._getDimensionsInViewport(hiddenIndex).start + "px" });
|
|
28838
29031
|
}
|
|
28839
29032
|
}
|
|
28840
29033
|
css /* scss */ `
|
|
@@ -29341,7 +29534,6 @@
|
|
|
29341
29534
|
owl.onMounted(() => this.focus());
|
|
29342
29535
|
this.props.exposeFocus(() => this.focus());
|
|
29343
29536
|
useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimensionWithHeaders());
|
|
29344
|
-
owl.useEffect(() => this.focus(), () => [this.env.model.getters.getActiveSheetId()]);
|
|
29345
29537
|
this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
|
|
29346
29538
|
this.moveCanvas(deltaX, deltaY);
|
|
29347
29539
|
this.hoveredCell.col = undefined;
|
|
@@ -29778,6 +29970,7 @@
|
|
|
29778
29970
|
const content = clipboardData.getData(ClipboardMIMEType.PlainText);
|
|
29779
29971
|
const target = this.env.model.getters.getSelectedZones();
|
|
29780
29972
|
const clipboardString = this.env.model.getters.getClipboardTextContent();
|
|
29973
|
+
const isCutOperation = this.env.model.getters.isCutOperation();
|
|
29781
29974
|
if (clipboardString === content) {
|
|
29782
29975
|
// the paste actually comes from o-spreadsheet itself
|
|
29783
29976
|
interactivePaste(this.env, target);
|
|
@@ -29785,7 +29978,7 @@
|
|
|
29785
29978
|
else {
|
|
29786
29979
|
interactivePasteFromOS(this.env, target, content);
|
|
29787
29980
|
}
|
|
29788
|
-
if (
|
|
29981
|
+
if (isCutOperation) {
|
|
29789
29982
|
await this.env.clipboard.write({ [ClipboardMIMEType.PlainText]: "" });
|
|
29790
29983
|
}
|
|
29791
29984
|
}
|
|
@@ -31398,12 +31591,6 @@
|
|
|
31398
31591
|
}
|
|
31399
31592
|
function convertExcelRangeToSheetXC(range, dataSetsHaveTitle) {
|
|
31400
31593
|
let { sheetName, xc } = splitReference(range);
|
|
31401
|
-
if (sheetName) {
|
|
31402
|
-
sheetName = getCanonicalSheetName(sheetName) + "!";
|
|
31403
|
-
}
|
|
31404
|
-
else {
|
|
31405
|
-
sheetName = "";
|
|
31406
|
-
}
|
|
31407
31594
|
let zone = toUnboundedZone(xc);
|
|
31408
31595
|
if (dataSetsHaveTitle && zone.bottom !== undefined && zone.right !== undefined) {
|
|
31409
31596
|
const height = zone.bottom - zone.top + 1;
|
|
@@ -31416,7 +31603,7 @@
|
|
|
31416
31603
|
}
|
|
31417
31604
|
}
|
|
31418
31605
|
const dataXC = zoneToXc(zone);
|
|
31419
|
-
return sheetName
|
|
31606
|
+
return getFullReference(sheetName, dataXC);
|
|
31420
31607
|
}
|
|
31421
31608
|
|
|
31422
31609
|
/**
|
|
@@ -34079,6 +34266,14 @@
|
|
|
34079
34266
|
// ---------------------------------------------------------------------------
|
|
34080
34267
|
// Command Handling
|
|
34081
34268
|
// ---------------------------------------------------------------------------
|
|
34269
|
+
allowDispatch(cmd) {
|
|
34270
|
+
switch (cmd.type) {
|
|
34271
|
+
case "SET_BORDER":
|
|
34272
|
+
return this.checkBordersUnchanged(cmd);
|
|
34273
|
+
default:
|
|
34274
|
+
return "Success" /* CommandResult.Success */;
|
|
34275
|
+
}
|
|
34276
|
+
}
|
|
34082
34277
|
handle(cmd) {
|
|
34083
34278
|
switch (cmd.type) {
|
|
34084
34279
|
case "ADD_MERGE":
|
|
@@ -34498,6 +34693,14 @@
|
|
|
34498
34693
|
this.setBorders(sheetId, [{ ...zone, left: right }], "right", bordersTopLeft.right);
|
|
34499
34694
|
}
|
|
34500
34695
|
}
|
|
34696
|
+
checkBordersUnchanged(cmd) {
|
|
34697
|
+
const currentBorder = this.getCellBorder(cmd);
|
|
34698
|
+
const areAllNewBordersUndefined = !cmd.border?.bottom && !cmd.border?.left && !cmd.border?.right && !cmd.border?.top;
|
|
34699
|
+
if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
|
|
34700
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
34701
|
+
}
|
|
34702
|
+
return "Success" /* CommandResult.Success */;
|
|
34703
|
+
}
|
|
34501
34704
|
// ---------------------------------------------------------------------------
|
|
34502
34705
|
// Import/Export
|
|
34503
34706
|
// ---------------------------------------------------------------------------
|
|
@@ -35324,7 +35527,6 @@
|
|
|
35324
35527
|
static getters = [
|
|
35325
35528
|
"zoneToXC",
|
|
35326
35529
|
"getCells",
|
|
35327
|
-
"getFormulaCellContent",
|
|
35328
35530
|
"getTranslatedCellFormula",
|
|
35329
35531
|
"getCellStyle",
|
|
35330
35532
|
"getCellById",
|
|
@@ -35353,8 +35555,9 @@
|
|
|
35353
35555
|
allowDispatch(cmd) {
|
|
35354
35556
|
switch (cmd.type) {
|
|
35355
35557
|
case "UPDATE_CELL":
|
|
35558
|
+
return this.checkCellOutOfSheet(cmd);
|
|
35356
35559
|
case "CLEAR_CELL":
|
|
35357
|
-
return this.
|
|
35560
|
+
return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
|
|
35358
35561
|
default:
|
|
35359
35562
|
return "Success" /* CommandResult.Success */;
|
|
35360
35563
|
}
|
|
@@ -35523,24 +35726,18 @@
|
|
|
35523
35726
|
*/
|
|
35524
35727
|
getCellById(cellId) {
|
|
35525
35728
|
// this must be as fast as possible
|
|
35526
|
-
|
|
35527
|
-
|
|
35528
|
-
|
|
35529
|
-
if (cell) {
|
|
35530
|
-
return cell;
|
|
35531
|
-
}
|
|
35532
|
-
}
|
|
35533
|
-
return undefined;
|
|
35729
|
+
const position = this.getters.getCellPosition(cellId);
|
|
35730
|
+
const sheet = this.cells[position.sheetId];
|
|
35731
|
+
return sheet[cellId];
|
|
35534
35732
|
}
|
|
35535
35733
|
/*
|
|
35536
35734
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
35537
35735
|
*/
|
|
35538
35736
|
getFormulaCellContent(sheetId, compiledFormula, dependencies) {
|
|
35539
|
-
const ranges = dependencies || compiledFormula.dependencies;
|
|
35540
35737
|
let rangeIndex = 0;
|
|
35541
35738
|
return concat(compiledFormula.tokens.map((token) => {
|
|
35542
35739
|
if (token.type === "REFERENCE") {
|
|
35543
|
-
const range =
|
|
35740
|
+
const range = dependencies[rangeIndex++];
|
|
35544
35741
|
return this.getters.getRangeString(range, sheetId);
|
|
35545
35742
|
}
|
|
35546
35743
|
return token.value;
|
|
@@ -35761,13 +35958,23 @@
|
|
|
35761
35958
|
},
|
|
35762
35959
|
};
|
|
35763
35960
|
}
|
|
35764
|
-
checkCellOutOfSheet(
|
|
35961
|
+
checkCellOutOfSheet(cmd) {
|
|
35962
|
+
const { sheetId, col, row } = cmd;
|
|
35765
35963
|
const sheet = this.getters.tryGetSheet(sheetId);
|
|
35766
35964
|
if (!sheet)
|
|
35767
35965
|
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
35768
35966
|
const sheetZone = this.getters.getSheetZone(sheetId);
|
|
35769
35967
|
return isInside(col, row, sheetZone) ? "Success" /* CommandResult.Success */ : "TargetOutOfSheet" /* CommandResult.TargetOutOfSheet */;
|
|
35770
35968
|
}
|
|
35969
|
+
checkUselessClearCell(cmd) {
|
|
35970
|
+
const cell = this.getters.getCell(cmd);
|
|
35971
|
+
if (!cell)
|
|
35972
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
35973
|
+
if (!cell.content && !cell.style && !cell.format) {
|
|
35974
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
35975
|
+
}
|
|
35976
|
+
return "Success" /* CommandResult.Success */;
|
|
35977
|
+
}
|
|
35771
35978
|
}
|
|
35772
35979
|
class FormulaCellWithDependencies {
|
|
35773
35980
|
id;
|
|
@@ -36457,6 +36664,9 @@
|
|
|
36457
36664
|
return this.rules[sheetId].find((rule) => rule.id === id);
|
|
36458
36665
|
}
|
|
36459
36666
|
getValidationRuleForCell({ sheetId, col, row }) {
|
|
36667
|
+
if (!this.rules[sheetId]) {
|
|
36668
|
+
return undefined;
|
|
36669
|
+
}
|
|
36460
36670
|
for (const rule of this.rules[sheetId]) {
|
|
36461
36671
|
for (const range of rule.ranges) {
|
|
36462
36672
|
if (isInside(col, row, range.zone)) {
|
|
@@ -37629,7 +37839,7 @@
|
|
|
37629
37839
|
const rangeString = this.getters.getRangeString(expandedRange, forSheetId);
|
|
37630
37840
|
if (this.isSingleCellOrMerge(rangeImpl.sheetId, rangeImpl.zone)) {
|
|
37631
37841
|
const { sheetName, xc } = splitReference(rangeString);
|
|
37632
|
-
return
|
|
37842
|
+
return getFullReference(sheetName, xc.split(":")[0]);
|
|
37633
37843
|
}
|
|
37634
37844
|
return rangeString;
|
|
37635
37845
|
}
|
|
@@ -39054,10 +39264,13 @@
|
|
|
39054
39264
|
// begin with the end.
|
|
39055
39265
|
rows.sort((a, b) => b - a);
|
|
39056
39266
|
for (let group of groupConsecutive(rows)) {
|
|
39267
|
+
// indexes are sorted in the descending order
|
|
39268
|
+
const from = group[group.length - 1];
|
|
39269
|
+
const to = group[0];
|
|
39057
39270
|
// Move the cells.
|
|
39058
|
-
this.moveCellOnRowsDeletion(sheet,
|
|
39059
|
-
// Effectively delete the
|
|
39060
|
-
|
|
39271
|
+
this.moveCellOnRowsDeletion(sheet, from, to);
|
|
39272
|
+
// Effectively delete the rows
|
|
39273
|
+
this.updateRowsStructureOnDeletion(sheet, from, to);
|
|
39061
39274
|
}
|
|
39062
39275
|
const count = rows.filter((row) => row < sheet.panes.ySplit).length;
|
|
39063
39276
|
if (count) {
|
|
@@ -39079,8 +39292,6 @@
|
|
|
39079
39292
|
this.addEmptyRows(sheet, quantity);
|
|
39080
39293
|
// Move the cells.
|
|
39081
39294
|
this.moveCellsOnAddition(sheet, index, quantity, "rows");
|
|
39082
|
-
// Recompute the left-right/top-bottom.
|
|
39083
|
-
this.updateRowsStructureOnAddition(sheet, row, quantity);
|
|
39084
39295
|
if (index < sheet.panes.ySplit) {
|
|
39085
39296
|
this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
|
|
39086
39297
|
}
|
|
@@ -39181,35 +39392,20 @@
|
|
|
39181
39392
|
}
|
|
39182
39393
|
}
|
|
39183
39394
|
}
|
|
39184
|
-
updateRowsStructureOnDeletion(
|
|
39395
|
+
updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
39185
39396
|
const rows = [];
|
|
39186
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
39397
|
+
const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
|
|
39187
39398
|
for (let i in sheet.rows) {
|
|
39188
|
-
|
|
39399
|
+
const row = Number(i);
|
|
39400
|
+
if (row >= deleteFromRow && row <= deleteToRow) {
|
|
39189
39401
|
continue;
|
|
39190
39402
|
}
|
|
39191
39403
|
rows.push({
|
|
39192
|
-
cells: cellsQueue.
|
|
39404
|
+
cells: cellsQueue.pop(),
|
|
39193
39405
|
});
|
|
39194
39406
|
}
|
|
39195
39407
|
this.history.update("sheets", sheet.id, "rows", rows);
|
|
39196
39408
|
}
|
|
39197
|
-
/**
|
|
39198
|
-
* Update the rows of the sheet after an addition:
|
|
39199
|
-
* - Rename the rows
|
|
39200
|
-
*
|
|
39201
|
-
* @param sheet Sheet on which the deletion occurs
|
|
39202
|
-
* @param addedRow Index of the added row
|
|
39203
|
-
* @param rowsToAdd Number of the rows to add
|
|
39204
|
-
*/
|
|
39205
|
-
updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
|
|
39206
|
-
const rows = [];
|
|
39207
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
39208
|
-
sheet.rows.forEach(() => rows.push({
|
|
39209
|
-
cells: cellsQueue.shift(),
|
|
39210
|
-
}));
|
|
39211
|
-
this.history.update("sheets", sheet.id, "rows", rows);
|
|
39212
|
-
}
|
|
39213
39409
|
/**
|
|
39214
39410
|
* Add empty rows at the end of the rows
|
|
39215
39411
|
*
|
|
@@ -39736,6 +39932,7 @@
|
|
|
39736
39932
|
getters;
|
|
39737
39933
|
computeCell;
|
|
39738
39934
|
evalContext;
|
|
39935
|
+
rangeCache = {};
|
|
39739
39936
|
constructor(context, getters, computeCell) {
|
|
39740
39937
|
this.getters = getters;
|
|
39741
39938
|
this.computeCell = computeCell;
|
|
@@ -39758,7 +39955,8 @@
|
|
|
39758
39955
|
refFn(range, isMeta, functionName, paramNumber) {
|
|
39759
39956
|
if (isMeta) {
|
|
39760
39957
|
// Use zoneToXc of zone instead of getRangeString to avoid sending unbounded ranges
|
|
39761
|
-
|
|
39958
|
+
const sheetName = this.getters.getSheetName(range.sheetId);
|
|
39959
|
+
return { value: getFullReference(sheetName, zoneToXc(range.zone)) };
|
|
39762
39960
|
}
|
|
39763
39961
|
if (!isZoneValid(range.zone)) {
|
|
39764
39962
|
throw new InvalidReferenceError();
|
|
@@ -39821,17 +40019,24 @@
|
|
|
39821
40019
|
if (!_zone) {
|
|
39822
40020
|
return [[]];
|
|
39823
40021
|
}
|
|
40022
|
+
const { top, left, bottom, right } = zone;
|
|
40023
|
+
const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
|
|
40024
|
+
if (cacheKey in this.rangeCache) {
|
|
40025
|
+
return this.rangeCache[cacheKey];
|
|
40026
|
+
}
|
|
39824
40027
|
const height = _zone.bottom - _zone.top + 1;
|
|
39825
40028
|
const width = _zone.right - _zone.left + 1;
|
|
39826
|
-
const matrix = Array
|
|
40029
|
+
const matrix = new Array(width);
|
|
39827
40030
|
// Performance issue: nested loop is faster than a map here
|
|
39828
40031
|
for (let col = _zone.left; col <= _zone.right; col++) {
|
|
40032
|
+
const colIndex = col - _zone.left;
|
|
40033
|
+
matrix[colIndex] = new Array(height);
|
|
39829
40034
|
for (let row = _zone.top; row <= _zone.bottom; row++) {
|
|
39830
|
-
const colIndex = col - _zone.left;
|
|
39831
40035
|
const rowIndex = row - _zone.top;
|
|
39832
40036
|
matrix[colIndex][rowIndex] = this.readCell({ sheetId, col, row });
|
|
39833
40037
|
}
|
|
39834
40038
|
}
|
|
40039
|
+
this.rangeCache[cacheKey] = matrix;
|
|
39835
40040
|
return matrix;
|
|
39836
40041
|
}
|
|
39837
40042
|
}
|
|
@@ -40037,6 +40242,7 @@
|
|
|
40037
40242
|
this.formulaDependencies().addDependencies(positionId, dependencies);
|
|
40038
40243
|
}
|
|
40039
40244
|
updateCompilationParameters() {
|
|
40245
|
+
// rebuild the compilation parameters (with a clean cache)
|
|
40040
40246
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
40041
40247
|
}
|
|
40042
40248
|
evaluateCells(positions) {
|
|
@@ -40080,6 +40286,16 @@
|
|
|
40080
40286
|
this.evaluatedCells = new Map();
|
|
40081
40287
|
this.evaluate(this.getAllCells());
|
|
40082
40288
|
}
|
|
40289
|
+
evaluateFormula(sheetId, formulaString) {
|
|
40290
|
+
const compiledFormula = compile(formulaString);
|
|
40291
|
+
const ranges = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
40292
|
+
this.updateCompilationParameters();
|
|
40293
|
+
const result = updateEvalContextAndExecute({ ...compiledFormula, dependencies: ranges }, this.compilationParams, sheetId);
|
|
40294
|
+
if (isMatrix(result)) {
|
|
40295
|
+
return matrixMap(result, (cell) => cell.value);
|
|
40296
|
+
}
|
|
40297
|
+
return result.value;
|
|
40298
|
+
}
|
|
40083
40299
|
getAllCells() {
|
|
40084
40300
|
const positionIds = new JetSet();
|
|
40085
40301
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
@@ -40106,6 +40322,7 @@
|
|
|
40106
40322
|
this.nextPositionsToUpdate = cells;
|
|
40107
40323
|
let currentIteration = 0;
|
|
40108
40324
|
while (this.nextPositionsToUpdate.size && currentIteration++ < MAX_ITERATION) {
|
|
40325
|
+
this.updateCompilationParameters();
|
|
40109
40326
|
const positionIds = Array.from(this.nextPositionsToUpdate);
|
|
40110
40327
|
this.nextPositionsToUpdate.clear();
|
|
40111
40328
|
for (let i = 0; i < positionIds.length; ++i) {
|
|
@@ -40129,7 +40346,8 @@
|
|
|
40129
40346
|
if (!this.blockedArrayFormulas.has(positionId)) {
|
|
40130
40347
|
this.invalidateSpreading(positionId);
|
|
40131
40348
|
}
|
|
40132
|
-
const
|
|
40349
|
+
const cellPosition = this.decodePosition(positionId);
|
|
40350
|
+
const cell = this.getters.getCell(cellPosition);
|
|
40133
40351
|
if (cell === undefined) {
|
|
40134
40352
|
return createEvaluatedCell("", { locale: this.getters.getLocale() });
|
|
40135
40353
|
}
|
|
@@ -40140,7 +40358,7 @@
|
|
|
40140
40358
|
}
|
|
40141
40359
|
this.cellsBeingComputed.add(cellId);
|
|
40142
40360
|
return cell.isFormula
|
|
40143
|
-
? this.computeFormulaCell(cell)
|
|
40361
|
+
? this.computeFormulaCell(cellPosition.sheetId, cell)
|
|
40144
40362
|
: evaluateLiteral(cell.content, { format: cell.format, locale: this.getters.getLocale() });
|
|
40145
40363
|
}
|
|
40146
40364
|
catch (e) {
|
|
@@ -40166,14 +40384,9 @@
|
|
|
40166
40384
|
e.message = e.message.replace("[[FUNCTION_NAME]]", __lastFnCalled);
|
|
40167
40385
|
return errorCell(e);
|
|
40168
40386
|
}
|
|
40169
|
-
computeFormulaCell(cellData) {
|
|
40387
|
+
computeFormulaCell(sheetId, cellData) {
|
|
40170
40388
|
const cellId = cellData.id;
|
|
40171
|
-
this.compilationParams
|
|
40172
|
-
// compute the value lazily for performance reasons
|
|
40173
|
-
const position = this.compilationParams[2].getters.getCellPosition(cellId);
|
|
40174
|
-
return toXC(position.col, position.row);
|
|
40175
|
-
};
|
|
40176
|
-
const formulaReturn = cellData.compiledFormula.execute(cellData.compiledFormula.dependencies, ...this.compilationParams);
|
|
40389
|
+
const formulaReturn = updateEvalContextAndExecute(cellData.compiledFormula, this.compilationParams, sheetId, cellId);
|
|
40177
40390
|
if (!isMatrix(formulaReturn)) {
|
|
40178
40391
|
return createEvaluatedCell(formulaReturn.value, {
|
|
40179
40392
|
format: cellData.format || formulaReturn.format,
|
|
@@ -40375,6 +40588,18 @@
|
|
|
40375
40588
|
return sheetId;
|
|
40376
40589
|
}
|
|
40377
40590
|
}
|
|
40591
|
+
function updateEvalContextAndExecute(compiledFormula, compilationParams, sheetId, cellId) {
|
|
40592
|
+
compilationParams[2].__originCellXC = lazy(() => {
|
|
40593
|
+
if (!cellId) {
|
|
40594
|
+
return undefined;
|
|
40595
|
+
}
|
|
40596
|
+
// compute the value lazily for performance reasons
|
|
40597
|
+
const position = compilationParams[2].getters.getCellPosition(cellId);
|
|
40598
|
+
return toXC(position.col, position.row);
|
|
40599
|
+
});
|
|
40600
|
+
compilationParams[2].__originSheetId = sheetId;
|
|
40601
|
+
return compiledFormula.execute(compiledFormula.dependencies, ...compilationParams);
|
|
40602
|
+
}
|
|
40378
40603
|
|
|
40379
40604
|
//#region
|
|
40380
40605
|
// ---------------------------------------------------------------------------
|
|
@@ -40469,7 +40694,6 @@
|
|
|
40469
40694
|
// of other cells depending on it, at the next iteration.
|
|
40470
40695
|
//#endregion
|
|
40471
40696
|
class EvaluationPlugin extends UIPlugin {
|
|
40472
|
-
config;
|
|
40473
40697
|
static getters = [
|
|
40474
40698
|
"evaluateFormula",
|
|
40475
40699
|
"getCorrespondingFormulaCell",
|
|
@@ -40480,15 +40704,13 @@
|
|
|
40480
40704
|
"getEvaluatedCells",
|
|
40481
40705
|
"getEvaluatedCellsInZone",
|
|
40482
40706
|
"getSpreadPositionsOf",
|
|
40707
|
+
"getArrayFormulaSpreadingOn",
|
|
40483
40708
|
];
|
|
40484
40709
|
shouldRebuildDependenciesGraph = true;
|
|
40485
40710
|
evaluator;
|
|
40486
|
-
compilationParams;
|
|
40487
40711
|
positionsToUpdate = [];
|
|
40488
40712
|
constructor(config) {
|
|
40489
40713
|
super(config);
|
|
40490
|
-
this.config = config;
|
|
40491
|
-
this.compilationParams = this.getCompilationParameters();
|
|
40492
40714
|
this.evaluator = new Evaluator(config.custom, this.getters);
|
|
40493
40715
|
}
|
|
40494
40716
|
// ---------------------------------------------------------------------------
|
|
@@ -40513,10 +40735,6 @@
|
|
|
40513
40735
|
case "EVALUATE_CELLS":
|
|
40514
40736
|
this.evaluator.evaluateAllCells();
|
|
40515
40737
|
break;
|
|
40516
|
-
case "UPDATE_LOCALE":
|
|
40517
|
-
this.compilationParams = this.getCompilationParameters();
|
|
40518
|
-
this.evaluator.updateCompilationParameters();
|
|
40519
|
-
break;
|
|
40520
40738
|
}
|
|
40521
40739
|
}
|
|
40522
40740
|
finalize() {
|
|
@@ -40534,16 +40752,7 @@
|
|
|
40534
40752
|
// Getters
|
|
40535
40753
|
// ---------------------------------------------------------------------------
|
|
40536
40754
|
evaluateFormula(sheetId, formulaString) {
|
|
40537
|
-
|
|
40538
|
-
const ranges = [];
|
|
40539
|
-
for (let xc of compiledFormula.dependencies) {
|
|
40540
|
-
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
40541
|
-
}
|
|
40542
|
-
const array = compiledFormula.execute(ranges, ...this.compilationParams);
|
|
40543
|
-
if (isMatrix(array)) {
|
|
40544
|
-
return array.map((col) => col.map((row) => row.value));
|
|
40545
|
-
}
|
|
40546
|
-
return array.value;
|
|
40755
|
+
return this.evaluator.evaluateFormula(sheetId, formulaString);
|
|
40547
40756
|
}
|
|
40548
40757
|
/**
|
|
40549
40758
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -40592,6 +40801,9 @@
|
|
|
40592
40801
|
getSpreadPositionsOf(position) {
|
|
40593
40802
|
return this.evaluator.getSpreadPositionsOf(position);
|
|
40594
40803
|
}
|
|
40804
|
+
getArrayFormulaSpreadingOn(position) {
|
|
40805
|
+
return this.evaluator.getArrayFormulaSpreadingOn(position);
|
|
40806
|
+
}
|
|
40595
40807
|
// ---------------------------------------------------------------------------
|
|
40596
40808
|
// Export
|
|
40597
40809
|
// ---------------------------------------------------------------------------
|
|
@@ -40635,7 +40847,7 @@
|
|
|
40635
40847
|
else if (cell && cell.content) {
|
|
40636
40848
|
return undefined;
|
|
40637
40849
|
}
|
|
40638
|
-
const spreadingFormulaPosition = this.
|
|
40850
|
+
const spreadingFormulaPosition = this.getArrayFormulaSpreadingOn(position);
|
|
40639
40851
|
if (spreadingFormulaPosition === undefined) {
|
|
40640
40852
|
return undefined;
|
|
40641
40853
|
}
|
|
@@ -40645,9 +40857,6 @@
|
|
|
40645
40857
|
}
|
|
40646
40858
|
return undefined;
|
|
40647
40859
|
}
|
|
40648
|
-
getCompilationParameters() {
|
|
40649
|
-
return buildCompilationParameters(this.config.custom, this.getters, (position) => this.evaluator.getEvaluatedCell(position));
|
|
40650
|
-
}
|
|
40651
40860
|
}
|
|
40652
40861
|
function isBadExpression(tokens) {
|
|
40653
40862
|
try {
|
|
@@ -43346,11 +43555,26 @@
|
|
|
43346
43555
|
let cellsInRow = [];
|
|
43347
43556
|
for (let col of columnsIndex) {
|
|
43348
43557
|
const position = { col, row, sheetId };
|
|
43558
|
+
const spreader = getters.getArrayFormulaSpreadingOn(position);
|
|
43559
|
+
let cell = getters.getCell(position);
|
|
43560
|
+
const evaluatedCell = getters.getEvaluatedCell(position);
|
|
43561
|
+
if (spreader) {
|
|
43562
|
+
const isSpreaderCopied = rowsIndex.includes(spreader.row) && columnsIndex.includes(spreader.col);
|
|
43563
|
+
const content = isSpreaderCopied
|
|
43564
|
+
? ""
|
|
43565
|
+
: formatValue(evaluatedCell.value, { locale: getters.getLocale() });
|
|
43566
|
+
cell = {
|
|
43567
|
+
id: cell?.id || "",
|
|
43568
|
+
style: cell?.style,
|
|
43569
|
+
format: evaluatedCell.format,
|
|
43570
|
+
content,
|
|
43571
|
+
isFormula: false,
|
|
43572
|
+
};
|
|
43573
|
+
}
|
|
43349
43574
|
cellsInRow.push({
|
|
43350
|
-
cell
|
|
43351
|
-
style: getters.getCellComputedStyle(position),
|
|
43352
|
-
evaluatedCell: getters.getEvaluatedCell(position),
|
|
43575
|
+
cell,
|
|
43353
43576
|
border: getters.getCellBorder(position) || undefined,
|
|
43577
|
+
evaluatedCell,
|
|
43354
43578
|
position,
|
|
43355
43579
|
});
|
|
43356
43580
|
}
|
|
@@ -43472,13 +43696,6 @@
|
|
|
43472
43696
|
});
|
|
43473
43697
|
}
|
|
43474
43698
|
this.pasteCopiedTables(target);
|
|
43475
|
-
this.cells.forEach((row) => {
|
|
43476
|
-
row.forEach((c) => {
|
|
43477
|
-
if (c.cell) {
|
|
43478
|
-
c.cell = undefined;
|
|
43479
|
-
}
|
|
43480
|
-
});
|
|
43481
|
-
});
|
|
43482
43699
|
}
|
|
43483
43700
|
/**
|
|
43484
43701
|
* The clipped zone is copied as many times as it fits in the target.
|
|
@@ -43552,7 +43769,7 @@
|
|
|
43552
43769
|
clearClippedZones() {
|
|
43553
43770
|
for (const row of this.cells) {
|
|
43554
43771
|
for (const cell of row) {
|
|
43555
|
-
if (cell
|
|
43772
|
+
if (cell?.cell) {
|
|
43556
43773
|
this.dispatch("CLEAR_CELL", cell.position);
|
|
43557
43774
|
}
|
|
43558
43775
|
}
|
|
@@ -43578,6 +43795,9 @@
|
|
|
43578
43795
|
const rowCells = this.cells[r];
|
|
43579
43796
|
for (let c = 0; c < width; c++) {
|
|
43580
43797
|
const origin = rowCells[c];
|
|
43798
|
+
if (!origin) {
|
|
43799
|
+
continue;
|
|
43800
|
+
}
|
|
43581
43801
|
const position = { col: col + c, row: row + r, sheetId: sheetId };
|
|
43582
43802
|
// TODO: refactor this part. the "Paste merge" action is also executed with
|
|
43583
43803
|
// MOVE_RANGES in pasteFromCut. Adding a condition on the operation type here
|
|
@@ -43601,53 +43821,42 @@
|
|
|
43601
43821
|
pasteCell(origin, target, operation, clipboardOption) {
|
|
43602
43822
|
const { sheetId, col, row } = target;
|
|
43603
43823
|
const targetCell = this.getters.getEvaluatedCell(target);
|
|
43604
|
-
if (clipboardOption?.pasteOption
|
|
43605
|
-
const
|
|
43606
|
-
const
|
|
43607
|
-
|
|
43608
|
-
|
|
43609
|
-
bottom: targetBorders?.bottom || originBorders?.bottom,
|
|
43610
|
-
left: targetBorders?.left || originBorders?.left,
|
|
43611
|
-
right: targetBorders?.right || originBorders?.right,
|
|
43612
|
-
};
|
|
43613
|
-
this.dispatch("SET_BORDER", { sheetId, col, row, border });
|
|
43824
|
+
if (clipboardOption?.pasteOption === "onlyValue") {
|
|
43825
|
+
const locale = this.getters.getLocale();
|
|
43826
|
+
const content = formatValue(origin.evaluatedCell.value, { locale });
|
|
43827
|
+
this.dispatch("UPDATE_CELL", { ...target, content });
|
|
43828
|
+
return;
|
|
43614
43829
|
}
|
|
43615
|
-
|
|
43616
|
-
|
|
43617
|
-
|
|
43618
|
-
|
|
43619
|
-
|
|
43620
|
-
|
|
43621
|
-
|
|
43622
|
-
|
|
43623
|
-
|
|
43624
|
-
|
|
43625
|
-
|
|
43626
|
-
|
|
43627
|
-
|
|
43628
|
-
|
|
43629
|
-
}
|
|
43630
|
-
|
|
43631
|
-
|
|
43632
|
-
|
|
43633
|
-
|
|
43830
|
+
const targetBorders = this.getters.getCellBorder(target);
|
|
43831
|
+
const originBorders = origin.border;
|
|
43832
|
+
const border = {
|
|
43833
|
+
top: targetBorders?.top || originBorders?.top,
|
|
43834
|
+
bottom: targetBorders?.bottom || originBorders?.bottom,
|
|
43835
|
+
left: targetBorders?.left || originBorders?.left,
|
|
43836
|
+
right: targetBorders?.right || originBorders?.right,
|
|
43837
|
+
};
|
|
43838
|
+
this.dispatch("SET_BORDER", { sheetId, col, row, border });
|
|
43839
|
+
if (clipboardOption?.pasteOption === "onlyFormat") {
|
|
43840
|
+
this.dispatch("UPDATE_CELL", {
|
|
43841
|
+
...target,
|
|
43842
|
+
style: origin.cell?.style ?? null,
|
|
43843
|
+
format: origin.cell?.format ?? origin.evaluatedCell.format ?? targetCell.format,
|
|
43844
|
+
});
|
|
43845
|
+
return;
|
|
43846
|
+
}
|
|
43847
|
+
const content = origin.cell && origin.cell.isFormula && operation === "COPY"
|
|
43848
|
+
? this.getters.getTranslatedCellFormula(sheetId, col - origin.position.col, row - origin.position.row, origin.cell.compiledFormula)
|
|
43849
|
+
: origin.cell?.content;
|
|
43850
|
+
if (content !== "" || origin.cell?.format || origin.cell?.style) {
|
|
43634
43851
|
this.dispatch("UPDATE_CELL", {
|
|
43635
43852
|
...target,
|
|
43636
43853
|
content,
|
|
43637
|
-
style: origin.cell
|
|
43638
|
-
format: origin.cell
|
|
43854
|
+
style: origin.cell?.style || null,
|
|
43855
|
+
format: origin.cell?.format,
|
|
43639
43856
|
});
|
|
43640
43857
|
}
|
|
43641
43858
|
else if (targetCell) {
|
|
43642
|
-
|
|
43643
|
-
this.dispatch("UPDATE_CELL", { ...target, content: "" });
|
|
43644
|
-
}
|
|
43645
|
-
else if (clipboardOption?.pasteOption === "onlyFormat") {
|
|
43646
|
-
this.dispatch("UPDATE_CELL", { ...target, style: null, format: "" });
|
|
43647
|
-
}
|
|
43648
|
-
else {
|
|
43649
|
-
this.dispatch("CLEAR_CELL", target);
|
|
43650
|
-
}
|
|
43859
|
+
this.dispatch("CLEAR_CELL", target);
|
|
43651
43860
|
}
|
|
43652
43861
|
}
|
|
43653
43862
|
/**
|
|
@@ -43709,22 +43918,28 @@
|
|
|
43709
43918
|
return (this.cells
|
|
43710
43919
|
.map((cells) => {
|
|
43711
43920
|
return cells
|
|
43712
|
-
.map((c) => this.getters.shouldShowFormulas() && c
|
|
43921
|
+
.map((c) => this.getters.shouldShowFormulas() && c?.cell?.isFormula
|
|
43713
43922
|
? c.cell?.content || ""
|
|
43714
|
-
: c
|
|
43923
|
+
: c?.evaluatedCell?.formattedValue || "")
|
|
43715
43924
|
.join("\t");
|
|
43716
43925
|
})
|
|
43717
43926
|
.join("\n") || "\t");
|
|
43718
43927
|
}
|
|
43719
43928
|
getHTMLContent() {
|
|
43720
43929
|
if (this.cells.length === 1 && this.cells[0].length === 1) {
|
|
43930
|
+
if (!this.cells[0][0]) {
|
|
43931
|
+
return "";
|
|
43932
|
+
}
|
|
43721
43933
|
return this.getters.getCellText(this.cells[0][0].position);
|
|
43722
43934
|
}
|
|
43723
43935
|
let htmlTable = '<table border="1" style="border-collapse:collapse">';
|
|
43724
43936
|
for (const row of this.cells) {
|
|
43725
43937
|
htmlTable += "<tr>";
|
|
43726
43938
|
for (const cell of row) {
|
|
43727
|
-
|
|
43939
|
+
if (!cell) {
|
|
43940
|
+
continue;
|
|
43941
|
+
}
|
|
43942
|
+
const cssStyle = cssPropertiesToCss(cellStyleToCss(this.getters.getCellComputedStyle(cell.position)));
|
|
43728
43943
|
const cellText = this.getters.getCellText(cell.position);
|
|
43729
43944
|
htmlTable += `<td style="${cssStyle}">` + xmlEscape(cellText) + "</td>";
|
|
43730
43945
|
}
|
|
@@ -44052,24 +44267,49 @@
|
|
|
44052
44267
|
*/
|
|
44053
44268
|
class FindAndReplacePlugin extends UIPlugin {
|
|
44054
44269
|
static layers = [3 /* LAYERS.Search */];
|
|
44055
|
-
static getters = [
|
|
44056
|
-
|
|
44270
|
+
static getters = [
|
|
44271
|
+
"getSearchMatches",
|
|
44272
|
+
"getCurrentSelectedMatchIndex",
|
|
44273
|
+
"getSearchOptions",
|
|
44274
|
+
"getAllSheetMatchesCount",
|
|
44275
|
+
"getActiveSheetMatchesCount",
|
|
44276
|
+
"getSpecificRangeMatchesCount",
|
|
44277
|
+
];
|
|
44278
|
+
allSheetsMatches = [];
|
|
44279
|
+
activeSheetMatches = [];
|
|
44280
|
+
specificRangeMatches = [];
|
|
44281
|
+
// fixme: why do we make selectedMatchIndex on top of a selected
|
|
44282
|
+
// property in the matches?
|
|
44057
44283
|
selectedMatchIndex = null;
|
|
44058
44284
|
currentSearchRegex = null;
|
|
44059
44285
|
searchOptions = {
|
|
44060
44286
|
matchCase: false,
|
|
44061
44287
|
exactMatch: false,
|
|
44062
44288
|
searchFormulas: false,
|
|
44289
|
+
searchScope: "allSheets",
|
|
44290
|
+
specificRange: undefined,
|
|
44063
44291
|
};
|
|
44064
44292
|
toSearch = "";
|
|
44065
44293
|
isSearchDirty = false;
|
|
44294
|
+
get searchMatches() {
|
|
44295
|
+
switch (this.searchOptions.searchScope) {
|
|
44296
|
+
case "allSheets":
|
|
44297
|
+
return this.allSheetsMatches;
|
|
44298
|
+
case "activeSheet":
|
|
44299
|
+
return this.activeSheetMatches;
|
|
44300
|
+
case "specificRange":
|
|
44301
|
+
return this.specificRangeMatches;
|
|
44302
|
+
}
|
|
44303
|
+
}
|
|
44066
44304
|
// ---------------------------------------------------------------------------
|
|
44067
44305
|
// Command Handling
|
|
44068
44306
|
// ---------------------------------------------------------------------------
|
|
44069
44307
|
handle(cmd) {
|
|
44070
44308
|
switch (cmd.type) {
|
|
44071
44309
|
case "UPDATE_SEARCH":
|
|
44072
|
-
|
|
44310
|
+
const rangeData = cmd.searchOptions.specificRange;
|
|
44311
|
+
const specificRange = rangeData && this.getters.getRangeFromRangeData(rangeData);
|
|
44312
|
+
this.updateSearch(cmd.toSearch, { ...cmd.searchOptions, specificRange });
|
|
44073
44313
|
break;
|
|
44074
44314
|
case "CLEAR_SEARCH":
|
|
44075
44315
|
this.clearSearch();
|
|
@@ -44099,7 +44339,9 @@
|
|
|
44099
44339
|
this.isSearchDirty = true;
|
|
44100
44340
|
break;
|
|
44101
44341
|
case "ACTIVATE_SHEET":
|
|
44102
|
-
this.
|
|
44342
|
+
if (this.searchOptions.searchScope === "activeSheet") {
|
|
44343
|
+
this.isSearchDirty = true;
|
|
44344
|
+
}
|
|
44103
44345
|
break;
|
|
44104
44346
|
}
|
|
44105
44347
|
}
|
|
@@ -44118,6 +44360,18 @@
|
|
|
44118
44360
|
getCurrentSelectedMatchIndex() {
|
|
44119
44361
|
return this.selectedMatchIndex;
|
|
44120
44362
|
}
|
|
44363
|
+
getSearchOptions() {
|
|
44364
|
+
return { ...this.searchOptions, specificRange: this.searchOptions.specificRange?.rangeData };
|
|
44365
|
+
}
|
|
44366
|
+
getAllSheetMatchesCount() {
|
|
44367
|
+
return this.allSheetsMatches.length;
|
|
44368
|
+
}
|
|
44369
|
+
getActiveSheetMatchesCount() {
|
|
44370
|
+
return this.activeSheetMatches.length;
|
|
44371
|
+
}
|
|
44372
|
+
getSpecificRangeMatchesCount() {
|
|
44373
|
+
return this.specificRangeMatches.length;
|
|
44374
|
+
}
|
|
44121
44375
|
// ---------------------------------------------------------------------------
|
|
44122
44376
|
// Search
|
|
44123
44377
|
// ---------------------------------------------------------------------------
|
|
@@ -44138,8 +44392,8 @@
|
|
|
44138
44392
|
* refresh the matches according to the current search options
|
|
44139
44393
|
*/
|
|
44140
44394
|
refreshSearch() {
|
|
44141
|
-
|
|
44142
|
-
this.
|
|
44395
|
+
this.selectedMatchIndex = null;
|
|
44396
|
+
this.findMatches();
|
|
44143
44397
|
this.selectNextCell(Direction.current);
|
|
44144
44398
|
}
|
|
44145
44399
|
/**
|
|
@@ -44154,45 +44408,65 @@
|
|
|
44154
44408
|
}
|
|
44155
44409
|
this.currentSearchRegex = RegExp(searchValue, flags);
|
|
44156
44410
|
}
|
|
44411
|
+
getSheetsInSearchOrder() {
|
|
44412
|
+
switch (this.searchOptions.searchScope) {
|
|
44413
|
+
case "allSheets":
|
|
44414
|
+
const sheetIds = this.getters.getSheetIds();
|
|
44415
|
+
const activeSheetIndex = sheetIds.findIndex((id) => id === this.getters.getActiveSheetId());
|
|
44416
|
+
return [
|
|
44417
|
+
sheetIds[activeSheetIndex],
|
|
44418
|
+
...sheetIds.slice(activeSheetIndex + 1),
|
|
44419
|
+
...sheetIds.slice(0, activeSheetIndex),
|
|
44420
|
+
];
|
|
44421
|
+
case "activeSheet":
|
|
44422
|
+
return [this.getters.getActiveSheetId()];
|
|
44423
|
+
case "specificRange":
|
|
44424
|
+
const specificRange = this.searchOptions.specificRange;
|
|
44425
|
+
if (!specificRange) {
|
|
44426
|
+
return [];
|
|
44427
|
+
}
|
|
44428
|
+
return specificRange ? [specificRange.sheetId] : [];
|
|
44429
|
+
}
|
|
44430
|
+
}
|
|
44157
44431
|
/**
|
|
44158
44432
|
* Find matches using the current regex
|
|
44159
44433
|
*/
|
|
44160
44434
|
findMatches() {
|
|
44161
|
-
const sheetId = this.getters.getActiveSheetId();
|
|
44162
|
-
const cells = this.getters.getCells(sheetId);
|
|
44163
44435
|
const matches = [];
|
|
44164
|
-
if (this.toSearch
|
|
44165
|
-
for (const
|
|
44166
|
-
|
|
44167
|
-
|
|
44436
|
+
if (this.toSearch) {
|
|
44437
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
44438
|
+
matches.push(...this.findMatchesInSheet(sheetId));
|
|
44439
|
+
}
|
|
44440
|
+
}
|
|
44441
|
+
// set results
|
|
44442
|
+
this.allSheetsMatches = matches;
|
|
44443
|
+
this.activeSheetMatches = matches.filter((match) => match.sheetId === this.getters.getActiveSheetId());
|
|
44444
|
+
if (this.searchOptions.specificRange) {
|
|
44445
|
+
const { sheetId, zone } = this.searchOptions.specificRange;
|
|
44446
|
+
this.specificRangeMatches = matches.filter((match) => match.sheetId === sheetId && isInside(match.col, match.row, zone));
|
|
44447
|
+
}
|
|
44448
|
+
else {
|
|
44449
|
+
this.specificRangeMatches = [];
|
|
44450
|
+
}
|
|
44451
|
+
}
|
|
44452
|
+
findMatchesInSheet(sheetId) {
|
|
44453
|
+
const matches = [];
|
|
44454
|
+
const { left, right, top, bottom } = this.getters.getSheetZone(sheetId);
|
|
44455
|
+
for (let row = top; row <= bottom; row++) {
|
|
44456
|
+
for (let col = left; col <= right; col++) {
|
|
44168
44457
|
const isColHidden = this.getters.isColHidden(sheetId, col);
|
|
44169
44458
|
const isRowHidden = this.getters.isRowHidden(sheetId, row);
|
|
44170
44459
|
if (isColHidden || isRowHidden) {
|
|
44171
44460
|
continue;
|
|
44172
44461
|
}
|
|
44173
|
-
|
|
44174
|
-
|
|
44462
|
+
const cellPosition = { sheetId, col, row };
|
|
44463
|
+
if (this.currentSearchRegex?.test(this.getSearchableString(cellPosition))) {
|
|
44464
|
+
const match = { sheetId, col, row };
|
|
44175
44465
|
matches.push(match);
|
|
44176
44466
|
}
|
|
44177
|
-
for (const spreadPosition of this.getters.getSpreadPositionsOf(cellPosition)) {
|
|
44178
|
-
if (this.currentSearchRegex.test(this.getSearchableString(spreadPosition))) {
|
|
44179
|
-
const match = {
|
|
44180
|
-
col: spreadPosition.col,
|
|
44181
|
-
row: spreadPosition.row,
|
|
44182
|
-
selected: false,
|
|
44183
|
-
};
|
|
44184
|
-
matches.push(match);
|
|
44185
|
-
}
|
|
44186
|
-
}
|
|
44187
44467
|
}
|
|
44188
44468
|
}
|
|
44189
|
-
return matches
|
|
44190
|
-
}
|
|
44191
|
-
sortByRowThenColumn(a, b) {
|
|
44192
|
-
if (a.row === b.row) {
|
|
44193
|
-
return a.col - b.col;
|
|
44194
|
-
}
|
|
44195
|
-
return a.row > b.row ? 1 : -1;
|
|
44469
|
+
return matches;
|
|
44196
44470
|
}
|
|
44197
44471
|
/**
|
|
44198
44472
|
* Changes the selected search cell. Given a direction it will
|
|
@@ -44210,30 +44484,47 @@
|
|
|
44210
44484
|
}
|
|
44211
44485
|
let nextIndex;
|
|
44212
44486
|
if (this.selectedMatchIndex === null) {
|
|
44213
|
-
|
|
44487
|
+
let nextMatchIndex = -1;
|
|
44488
|
+
// if search is not available in current sheet will select in next sheet
|
|
44489
|
+
for (const sheetId of this.getSheetsInSearchOrder()) {
|
|
44490
|
+
nextMatchIndex = matches.findIndex((match) => match.sheetId === sheetId);
|
|
44491
|
+
if (nextMatchIndex !== -1) {
|
|
44492
|
+
break;
|
|
44493
|
+
}
|
|
44494
|
+
}
|
|
44495
|
+
nextIndex = nextMatchIndex;
|
|
44214
44496
|
}
|
|
44215
44497
|
else {
|
|
44216
44498
|
nextIndex = this.selectedMatchIndex + indexChange;
|
|
44217
44499
|
}
|
|
44218
|
-
//
|
|
44219
|
-
nextIndex = (
|
|
44500
|
+
// loop index value inside the array (index -1 => last index)
|
|
44501
|
+
nextIndex = (nextIndex + matches.length) % matches.length;
|
|
44220
44502
|
this.selectedMatchIndex = nextIndex;
|
|
44503
|
+
const selectedMatch = matches[nextIndex];
|
|
44504
|
+
// Switch to the sheet where the match is located
|
|
44505
|
+
if (this.getters.getActiveSheetId() !== selectedMatch.sheetId) {
|
|
44506
|
+
this.dispatch("ACTIVATE_SHEET", {
|
|
44507
|
+
sheetIdFrom: this.getters.getActiveSheetId(),
|
|
44508
|
+
sheetIdTo: selectedMatch.sheetId,
|
|
44509
|
+
});
|
|
44510
|
+
}
|
|
44221
44511
|
// we want grid selection to capture the selection stream
|
|
44222
44512
|
this.selection.getBackToDefault();
|
|
44223
|
-
this.selection.selectCell(
|
|
44224
|
-
for (let index = 0; index < this.searchMatches.length; index++) {
|
|
44225
|
-
this.searchMatches[index].selected = index === this.selectedMatchIndex;
|
|
44226
|
-
}
|
|
44513
|
+
this.selection.selectCell(selectedMatch.col, selectedMatch.row);
|
|
44227
44514
|
}
|
|
44228
44515
|
clearSearch() {
|
|
44229
44516
|
this.toSearch = "";
|
|
44230
|
-
this.searchMatches = [];
|
|
44231
44517
|
this.selectedMatchIndex = null;
|
|
44232
44518
|
this.currentSearchRegex = null;
|
|
44519
|
+
this.allSheetsMatches = [];
|
|
44520
|
+
this.activeSheetMatches = [];
|
|
44521
|
+
this.specificRangeMatches = [];
|
|
44233
44522
|
this.searchOptions = {
|
|
44234
44523
|
matchCase: false,
|
|
44235
44524
|
exactMatch: false,
|
|
44236
44525
|
searchFormulas: false,
|
|
44526
|
+
searchScope: "allSheets",
|
|
44527
|
+
specificRange: undefined,
|
|
44237
44528
|
};
|
|
44238
44529
|
}
|
|
44239
44530
|
// ---------------------------------------------------------------------------
|
|
@@ -44243,9 +44534,7 @@
|
|
|
44243
44534
|
if (!this.currentSearchRegex) {
|
|
44244
44535
|
return;
|
|
44245
44536
|
}
|
|
44246
|
-
const
|
|
44247
|
-
const position = { sheetId, ...selectedMatch };
|
|
44248
|
-
const cell = this.getters.getCell(position);
|
|
44537
|
+
const cell = this.getters.getCell(selectedMatch);
|
|
44249
44538
|
if (!cell?.content) {
|
|
44250
44539
|
return;
|
|
44251
44540
|
}
|
|
@@ -44253,10 +44542,10 @@
|
|
|
44253
44542
|
return;
|
|
44254
44543
|
}
|
|
44255
44544
|
const replaceRegex = new RegExp(this.currentSearchRegex.source, this.currentSearchRegex.flags + "g");
|
|
44256
|
-
const toReplace = this.getSearchableString(
|
|
44545
|
+
const toReplace = this.getSearchableString(selectedMatch);
|
|
44257
44546
|
const content = toReplace.replace(replaceRegex, replaceWith);
|
|
44258
44547
|
const canonicalContent = canonicalizeNumberContent(content, this.getters.getLocale());
|
|
44259
|
-
this.dispatch("UPDATE_CELL", { ...
|
|
44548
|
+
this.dispatch("UPDATE_CELL", { ...selectedMatch, content: canonicalContent });
|
|
44260
44549
|
}
|
|
44261
44550
|
/**
|
|
44262
44551
|
* Replace the value of the currently selected match
|
|
@@ -44287,7 +44576,10 @@
|
|
|
44287
44576
|
drawGrid(renderingContext) {
|
|
44288
44577
|
const { ctx } = renderingContext;
|
|
44289
44578
|
const sheetId = this.getters.getActiveSheetId();
|
|
44290
|
-
for (const match of this.searchMatches) {
|
|
44579
|
+
for (const [index, match] of this.searchMatches.entries()) {
|
|
44580
|
+
if (match.sheetId !== sheetId) {
|
|
44581
|
+
continue; // Skip drawing matches from other sheets
|
|
44582
|
+
}
|
|
44291
44583
|
const merge = this.getters.getMerge({ sheetId, col: match.col, row: match.row });
|
|
44292
44584
|
const left = merge ? merge.left : match.col;
|
|
44293
44585
|
const right = merge ? merge.right : match.col;
|
|
@@ -44297,12 +44589,21 @@
|
|
|
44297
44589
|
if (width > 0 && height > 0) {
|
|
44298
44590
|
ctx.fillStyle = BACKGROUND_COLOR;
|
|
44299
44591
|
ctx.fillRect(x, y, width, height);
|
|
44300
|
-
if (
|
|
44592
|
+
if (index === this.selectedMatchIndex) {
|
|
44301
44593
|
ctx.strokeStyle = BORDER_COLOR;
|
|
44302
44594
|
ctx.strokeRect(x, y, width, height);
|
|
44303
44595
|
}
|
|
44304
44596
|
}
|
|
44305
44597
|
}
|
|
44598
|
+
if (this.searchOptions.searchScope === "specificRange") {
|
|
44599
|
+
const range = this.searchOptions.specificRange;
|
|
44600
|
+
if (!range || range.sheetId !== sheetId) {
|
|
44601
|
+
return;
|
|
44602
|
+
}
|
|
44603
|
+
const { x, y, width, height } = this.getters.getVisibleRect(range.zone);
|
|
44604
|
+
ctx.strokeStyle = BORDER_COLOR;
|
|
44605
|
+
ctx.strokeRect(x, y, width, height);
|
|
44606
|
+
}
|
|
44306
44607
|
}
|
|
44307
44608
|
}
|
|
44308
44609
|
|
|
@@ -46768,11 +47069,14 @@
|
|
|
46768
47069
|
}
|
|
46769
47070
|
const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
|
|
46770
47071
|
this.state.paste(cmd.target, { pasteOption, shouldPasteCF: true, selectTarget: true });
|
|
47072
|
+
if (this.state.operation === "CUT") {
|
|
47073
|
+
this.state = undefined;
|
|
47074
|
+
}
|
|
46771
47075
|
this.lastPasteState = this.state;
|
|
46772
47076
|
if (this.paintFormatStatus === "oneOff") {
|
|
46773
47077
|
this.paintFormatStatus = "inactive";
|
|
46774
|
-
this.status = "invisible";
|
|
46775
47078
|
}
|
|
47079
|
+
this.status = "invisible";
|
|
46776
47080
|
break;
|
|
46777
47081
|
case "COPY_PASTE_CELLS_ABOVE":
|
|
46778
47082
|
{
|
|
@@ -46999,92 +47303,6 @@
|
|
|
46999
47303
|
}
|
|
47000
47304
|
}
|
|
47001
47305
|
|
|
47002
|
-
/**
|
|
47003
|
-
* Change the reference types inside the given token, if the token represent a range or a cell
|
|
47004
|
-
*
|
|
47005
|
-
* Eg. :
|
|
47006
|
-
* A1 => $A$1 => A$1 => $A1 => A1
|
|
47007
|
-
* A1:$B$1 => $A$1:B$1 => A$1:$B1 => $A1:B1 => A1:$B$1
|
|
47008
|
-
*/
|
|
47009
|
-
function loopThroughReferenceType(token) {
|
|
47010
|
-
if (token.type !== "REFERENCE")
|
|
47011
|
-
return token;
|
|
47012
|
-
const { xc, sheetName } = splitReference(token.value);
|
|
47013
|
-
const [left, right] = xc.split(":");
|
|
47014
|
-
const sheetRef = sheetName ? `${getCanonicalSheetName(sheetName)}!` : "";
|
|
47015
|
-
const updatedLeft = getTokenNextReferenceType(left);
|
|
47016
|
-
const updatedRight = right ? `:${getTokenNextReferenceType(right)}` : "";
|
|
47017
|
-
return { ...token, value: sheetRef + updatedLeft + updatedRight };
|
|
47018
|
-
}
|
|
47019
|
-
/**
|
|
47020
|
-
* Get a new token with a changed type of reference from the given cell token symbol.
|
|
47021
|
-
* Undefined behavior if given a token other than a cell or if the Xc contains a sheet reference
|
|
47022
|
-
*
|
|
47023
|
-
* A1 => $A$1 => A$1 => $A1 => A1
|
|
47024
|
-
*/
|
|
47025
|
-
function getTokenNextReferenceType(xc) {
|
|
47026
|
-
switch (getReferenceType(xc)) {
|
|
47027
|
-
case "none":
|
|
47028
|
-
xc = setXcToReferenceType(xc, "colrow");
|
|
47029
|
-
break;
|
|
47030
|
-
case "colrow":
|
|
47031
|
-
xc = setXcToReferenceType(xc, "row");
|
|
47032
|
-
break;
|
|
47033
|
-
case "row":
|
|
47034
|
-
xc = setXcToReferenceType(xc, "col");
|
|
47035
|
-
break;
|
|
47036
|
-
case "col":
|
|
47037
|
-
xc = setXcToReferenceType(xc, "none");
|
|
47038
|
-
break;
|
|
47039
|
-
}
|
|
47040
|
-
return xc;
|
|
47041
|
-
}
|
|
47042
|
-
/**
|
|
47043
|
-
* Returns the given XC with the given reference type.
|
|
47044
|
-
*/
|
|
47045
|
-
function setXcToReferenceType(xc, referenceType) {
|
|
47046
|
-
xc = xc.replace(/\$/g, "");
|
|
47047
|
-
let indexOfNumber;
|
|
47048
|
-
switch (referenceType) {
|
|
47049
|
-
case "col":
|
|
47050
|
-
return "$" + xc;
|
|
47051
|
-
case "row":
|
|
47052
|
-
indexOfNumber = xc.search(/[0-9]/);
|
|
47053
|
-
return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
47054
|
-
case "colrow":
|
|
47055
|
-
indexOfNumber = xc.search(/[0-9]/);
|
|
47056
|
-
xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
47057
|
-
return "$" + xc;
|
|
47058
|
-
case "none":
|
|
47059
|
-
return xc;
|
|
47060
|
-
}
|
|
47061
|
-
}
|
|
47062
|
-
/**
|
|
47063
|
-
* Return the type of reference used in the given XC of a cell.
|
|
47064
|
-
* Undefined behavior if the XC have a sheet reference
|
|
47065
|
-
*/
|
|
47066
|
-
function getReferenceType(xcCell) {
|
|
47067
|
-
if (isColAndRowFixed(xcCell)) {
|
|
47068
|
-
return "colrow";
|
|
47069
|
-
}
|
|
47070
|
-
else if (isColFixed(xcCell)) {
|
|
47071
|
-
return "col";
|
|
47072
|
-
}
|
|
47073
|
-
else if (isRowFixed(xcCell)) {
|
|
47074
|
-
return "row";
|
|
47075
|
-
}
|
|
47076
|
-
return "none";
|
|
47077
|
-
}
|
|
47078
|
-
function isColFixed(xc) {
|
|
47079
|
-
return xc.startsWith("$");
|
|
47080
|
-
}
|
|
47081
|
-
function isRowFixed(xc) {
|
|
47082
|
-
return xc.includes("$", 1);
|
|
47083
|
-
}
|
|
47084
|
-
function isColAndRowFixed(xc) {
|
|
47085
|
-
return xc.startsWith("$") && xc.length > 1 && xc.slice(1).includes("$");
|
|
47086
|
-
}
|
|
47087
|
-
|
|
47088
47306
|
const CELL_DELETED_MESSAGE = _t("The cell you are trying to edit has been deleted.");
|
|
47089
47307
|
class EditionPlugin extends UIPlugin {
|
|
47090
47308
|
static getters = [
|
|
@@ -48002,32 +48220,32 @@
|
|
|
48002
48220
|
{
|
|
48003
48221
|
name: _t("Sum"),
|
|
48004
48222
|
types: [CellValueType.number],
|
|
48005
|
-
compute: (values, locale) =>
|
|
48223
|
+
compute: (values, locale) => sum([[values]], locale),
|
|
48006
48224
|
},
|
|
48007
48225
|
{
|
|
48008
48226
|
name: _t("Avg"),
|
|
48009
48227
|
types: [CellValueType.number],
|
|
48010
|
-
compute: (values, locale) =>
|
|
48228
|
+
compute: (values, locale) => average([[values]], locale),
|
|
48011
48229
|
},
|
|
48012
48230
|
{
|
|
48013
48231
|
name: _t("Min"),
|
|
48014
48232
|
types: [CellValueType.number],
|
|
48015
|
-
compute: (values, locale) =>
|
|
48233
|
+
compute: (values, locale) => min([[values]], locale),
|
|
48016
48234
|
},
|
|
48017
48235
|
{
|
|
48018
48236
|
name: _t("Max"),
|
|
48019
48237
|
types: [CellValueType.number],
|
|
48020
|
-
compute: (values, locale) =>
|
|
48238
|
+
compute: (values, locale) => max([[values]], locale),
|
|
48021
48239
|
},
|
|
48022
48240
|
{
|
|
48023
48241
|
name: _t("Count"),
|
|
48024
48242
|
types: [CellValueType.number, CellValueType.text, CellValueType.boolean, CellValueType.error],
|
|
48025
|
-
compute: (values
|
|
48243
|
+
compute: (values) => countAny([[values]]),
|
|
48026
48244
|
},
|
|
48027
48245
|
{
|
|
48028
48246
|
name: _t("Count Numbers"),
|
|
48029
48247
|
types: [CellValueType.number, CellValueType.text, CellValueType.boolean, CellValueType.error],
|
|
48030
|
-
compute: (values, locale) =>
|
|
48248
|
+
compute: (values, locale) => countNumbers([[values]], locale),
|
|
48031
48249
|
},
|
|
48032
48250
|
];
|
|
48033
48251
|
/**
|
|
@@ -51942,6 +52160,7 @@
|
|
|
51942
52160
|
};
|
|
51943
52161
|
sidePanel;
|
|
51944
52162
|
composer;
|
|
52163
|
+
spreadsheetRef = owl.useRef("spreadsheet");
|
|
51945
52164
|
_focusGrid;
|
|
51946
52165
|
keyDownMapping;
|
|
51947
52166
|
isViewportTooSmall = false;
|
|
@@ -51976,6 +52195,18 @@
|
|
|
51976
52195
|
clipboard: this.env.clipboard || instantiateClipboard(),
|
|
51977
52196
|
startCellEdition: (content) => this.onGridComposerCellFocused(content),
|
|
51978
52197
|
});
|
|
52198
|
+
owl.useEffect(() => {
|
|
52199
|
+
/**
|
|
52200
|
+
* Only refocus the grid if the active element is not a child of the spreadsheet
|
|
52201
|
+
* (i.e. activeElement is outside of the spreadsheetRef component)
|
|
52202
|
+
* and spreadsheet is a child of that element. Anything else means that the focus
|
|
52203
|
+
* is on an element that needs to keep it.
|
|
52204
|
+
*/
|
|
52205
|
+
if (!this.spreadsheetRef.el.contains(document.activeElement) &&
|
|
52206
|
+
document.activeElement?.contains(this.spreadsheetRef.el)) {
|
|
52207
|
+
this.focusGrid();
|
|
52208
|
+
}
|
|
52209
|
+
}, () => [this.env.model.getters.getActiveSheetId()]);
|
|
51979
52210
|
owl.useExternalListener(window, "resize", () => this.render(true));
|
|
51980
52211
|
owl.useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
|
|
51981
52212
|
this.bindModelEvents();
|
|
@@ -52057,7 +52288,7 @@
|
|
|
52057
52288
|
}
|
|
52058
52289
|
focusGrid() {
|
|
52059
52290
|
if (!this._focusGrid) {
|
|
52060
|
-
|
|
52291
|
+
return;
|
|
52061
52292
|
}
|
|
52062
52293
|
this._focusGrid();
|
|
52063
52294
|
}
|
|
@@ -55450,19 +55681,22 @@
|
|
|
55450
55681
|
* Check if the given command is allowed by all the plugins and the history.
|
|
55451
55682
|
*/
|
|
55452
55683
|
checkDispatchAllowed(command) {
|
|
55453
|
-
|
|
55454
|
-
|
|
55684
|
+
const results = isCoreCommand(command)
|
|
55685
|
+
? this.checkDispatchAllowedCoreCommand(command)
|
|
55686
|
+
: this.checkDispatchAllowedLocalCommand(command);
|
|
55687
|
+
if (results.some((r) => r !== "Success" /* CommandResult.Success */)) {
|
|
55688
|
+
return new DispatchResult(results.flat());
|
|
55455
55689
|
}
|
|
55456
|
-
return
|
|
55690
|
+
return DispatchResult.Success;
|
|
55457
55691
|
}
|
|
55458
55692
|
checkDispatchAllowedCoreCommand(command) {
|
|
55459
55693
|
const results = this.corePlugins.map((handler) => handler.allowDispatch(command));
|
|
55460
55694
|
results.push(this.range.allowDispatch(command));
|
|
55461
|
-
return
|
|
55695
|
+
return results;
|
|
55462
55696
|
}
|
|
55463
55697
|
checkDispatchAllowedLocalCommand(command) {
|
|
55464
55698
|
const results = this.uiHandlers.map((handler) => handler.allowDispatch(command));
|
|
55465
|
-
return
|
|
55699
|
+
return results;
|
|
55466
55700
|
}
|
|
55467
55701
|
finalize() {
|
|
55468
55702
|
this.status = 3 /* Status.Finalizing */;
|
|
@@ -55757,6 +55991,7 @@
|
|
|
55757
55991
|
FigureComponent,
|
|
55758
55992
|
Menu,
|
|
55759
55993
|
SelectionInput,
|
|
55994
|
+
ValidationMessages,
|
|
55760
55995
|
};
|
|
55761
55996
|
const hooks = {
|
|
55762
55997
|
useDragAndDropListItems,
|
|
@@ -55809,9 +56044,9 @@
|
|
|
55809
56044
|
exports.tokenize = tokenize;
|
|
55810
56045
|
|
|
55811
56046
|
|
|
55812
|
-
__info__.version = "17.1.0-alpha.
|
|
55813
|
-
__info__.date = "2023-11-
|
|
55814
|
-
__info__.hash = "
|
|
56047
|
+
__info__.version = "17.1.0-alpha.4";
|
|
56048
|
+
__info__.date = "2023-11-24T13:12:24.882Z";
|
|
56049
|
+
__info__.hash = "255821b";
|
|
55815
56050
|
|
|
55816
56051
|
|
|
55817
56052
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|