@odoo/o-spreadsheet 17.1.0-alpha.5 → 17.1.0-alpha.7
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 +1749 -772
- package/dist/o-spreadsheet.d.ts +860 -47
- package/dist/o-spreadsheet.esm.js +1749 -772
- package/dist/o-spreadsheet.iife.js +1749 -772
- package/dist/o-spreadsheet.iife.min.js +292 -286
- package/dist/o_spreadsheet.xml +339 -468
- package/package.json +8 -4
|
@@ -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
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.1.0-alpha.7
|
|
6
|
+
* @date 2024-01-12T13:45:00.505Z
|
|
7
|
+
* @hash cbce1ed
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -329,13 +329,6 @@
|
|
|
329
329
|
//------------------------------------------------------------------------------
|
|
330
330
|
// Miscellaneous
|
|
331
331
|
//------------------------------------------------------------------------------
|
|
332
|
-
/**
|
|
333
|
-
* Stringify an object, like JSON.stringify, except that the first level of keys
|
|
334
|
-
* is ordered.
|
|
335
|
-
*/
|
|
336
|
-
function stringify(obj) {
|
|
337
|
-
return JSON.stringify(obj, Object.keys(obj).sort());
|
|
338
|
-
}
|
|
339
332
|
/**
|
|
340
333
|
* Remove quotes from a quoted string
|
|
341
334
|
* ```js
|
|
@@ -558,7 +551,7 @@
|
|
|
558
551
|
*/
|
|
559
552
|
function getItemId(item, itemsDic) {
|
|
560
553
|
for (let [key, value] of Object.entries(itemsDic)) {
|
|
561
|
-
if (
|
|
554
|
+
if (deepEquals(value, item)) {
|
|
562
555
|
return parseInt(key, 10);
|
|
563
556
|
}
|
|
564
557
|
}
|
|
@@ -1208,16 +1201,84 @@
|
|
|
1208
1201
|
// -----------------------------------------------------------------------------
|
|
1209
1202
|
// Date Type
|
|
1210
1203
|
// -----------------------------------------------------------------------------
|
|
1204
|
+
/**
|
|
1205
|
+
* A DateTime object that can be used to manipulate spreadsheet dates.
|
|
1206
|
+
* Conceptually, a spreadsheet date is simply a number with a date format,
|
|
1207
|
+
* and it is timezone-agnostic.
|
|
1208
|
+
* This DateTime object consistently uses UTC time to represent a naive date and time.
|
|
1209
|
+
*/
|
|
1210
|
+
class DateTime {
|
|
1211
|
+
jsDate;
|
|
1212
|
+
constructor(year, month, day, hours = 0, minutes = 0, seconds = 0) {
|
|
1213
|
+
this.jsDate = new Date(Date.UTC(year, month, day, hours, minutes, seconds, 0));
|
|
1214
|
+
}
|
|
1215
|
+
static fromTimestamp(timestamp) {
|
|
1216
|
+
const date = new Date(timestamp);
|
|
1217
|
+
return new DateTime(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
|
|
1218
|
+
}
|
|
1219
|
+
static now() {
|
|
1220
|
+
const now = new Date();
|
|
1221
|
+
return new DateTime(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes(), now.getSeconds());
|
|
1222
|
+
}
|
|
1223
|
+
toString() {
|
|
1224
|
+
return this.jsDate.toString();
|
|
1225
|
+
}
|
|
1226
|
+
toLocaleDateString() {
|
|
1227
|
+
return this.jsDate.toLocaleDateString();
|
|
1228
|
+
}
|
|
1229
|
+
getTime() {
|
|
1230
|
+
return this.jsDate.getTime();
|
|
1231
|
+
}
|
|
1232
|
+
getFullYear() {
|
|
1233
|
+
return this.jsDate.getUTCFullYear();
|
|
1234
|
+
}
|
|
1235
|
+
getMonth() {
|
|
1236
|
+
return this.jsDate.getUTCMonth();
|
|
1237
|
+
}
|
|
1238
|
+
getDate() {
|
|
1239
|
+
return this.jsDate.getUTCDate();
|
|
1240
|
+
}
|
|
1241
|
+
getDay() {
|
|
1242
|
+
return this.jsDate.getUTCDay();
|
|
1243
|
+
}
|
|
1244
|
+
getHours() {
|
|
1245
|
+
return this.jsDate.getUTCHours();
|
|
1246
|
+
}
|
|
1247
|
+
getMinutes() {
|
|
1248
|
+
return this.jsDate.getUTCMinutes();
|
|
1249
|
+
}
|
|
1250
|
+
getSeconds() {
|
|
1251
|
+
return this.jsDate.getUTCSeconds();
|
|
1252
|
+
}
|
|
1253
|
+
setFullYear(year) {
|
|
1254
|
+
return this.jsDate.setUTCFullYear(year);
|
|
1255
|
+
}
|
|
1256
|
+
setMonth(month) {
|
|
1257
|
+
return this.jsDate.setUTCMonth(month);
|
|
1258
|
+
}
|
|
1259
|
+
setDate(date) {
|
|
1260
|
+
return this.jsDate.setUTCDate(date);
|
|
1261
|
+
}
|
|
1262
|
+
setHours(hours) {
|
|
1263
|
+
return this.jsDate.setUTCHours(hours);
|
|
1264
|
+
}
|
|
1265
|
+
setMinutes(minutes) {
|
|
1266
|
+
return this.jsDate.setUTCMinutes(minutes);
|
|
1267
|
+
}
|
|
1268
|
+
setSeconds(seconds) {
|
|
1269
|
+
return this.jsDate.setUTCSeconds(seconds);
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1211
1272
|
// -----------------------------------------------------------------------------
|
|
1212
1273
|
// Parsing
|
|
1213
1274
|
// -----------------------------------------------------------------------------
|
|
1214
|
-
const INITIAL_1900_DAY = new
|
|
1275
|
+
const INITIAL_1900_DAY = new DateTime(1899, 11, 30);
|
|
1215
1276
|
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
1216
1277
|
const CURRENT_MILLENIAL = 2000; // note: don't forget to update this in 2999
|
|
1217
|
-
const CURRENT_YEAR =
|
|
1218
|
-
const CURRENT_MONTH =
|
|
1219
|
-
const INITIAL_JS_DAY =
|
|
1220
|
-
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY - INITIAL_1900_DAY;
|
|
1278
|
+
const CURRENT_YEAR = DateTime.now().getFullYear();
|
|
1279
|
+
const CURRENT_MONTH = DateTime.now().getMonth();
|
|
1280
|
+
const INITIAL_JS_DAY = DateTime.fromTimestamp(0);
|
|
1281
|
+
const DATE_JS_1900_OFFSET = INITIAL_JS_DAY.getTime() - INITIAL_1900_DAY.getTime();
|
|
1221
1282
|
const mdyDateRegexp = /^\d{1,2}(\/|-|\s)\d{1,2}((\/|-|\s)\d{1,4})?$/;
|
|
1222
1283
|
const ymdDateRegexp = /^\d{3,4}(\/|-|\s)\d{1,2}(\/|-|\s)\d{1,2}$/;
|
|
1223
1284
|
const dateSeparatorsRegex = /\/|-|\s/;
|
|
@@ -1278,7 +1339,7 @@
|
|
|
1278
1339
|
return {
|
|
1279
1340
|
value: date.value + time.value,
|
|
1280
1341
|
format: date.format + " " + (time.format === "hhhh:mm:ss" ? "hh:mm:ss" : time.format),
|
|
1281
|
-
jsDate: new
|
|
1342
|
+
jsDate: new DateTime(date.jsDate.getFullYear() + time.jsDate.getFullYear() - 1899, date.jsDate.getMonth() + time.jsDate.getMonth() - 11, date.jsDate.getDate() + time.jsDate.getDate() - 30, date.jsDate.getHours() + time.jsDate.getHours(), date.jsDate.getMinutes() + time.jsDate.getMinutes(), date.jsDate.getSeconds() + time.jsDate.getSeconds()),
|
|
1282
1343
|
};
|
|
1283
1344
|
}
|
|
1284
1345
|
return date || time;
|
|
@@ -1354,12 +1415,12 @@
|
|
|
1354
1415
|
// month + 1: months are 0-indexed in JS
|
|
1355
1416
|
const leadingZero = (monthStr?.length === 2 && month + 1 < 10) || (dayStr?.length === 2 && day < 10);
|
|
1356
1417
|
const fullYear = yearStr?.length !== 2;
|
|
1357
|
-
const jsDate = new
|
|
1418
|
+
const jsDate = new DateTime(year, month, day);
|
|
1358
1419
|
if (jsDate.getMonth() !== month || jsDate.getDate() !== day) {
|
|
1359
1420
|
// invalid date
|
|
1360
1421
|
return null;
|
|
1361
1422
|
}
|
|
1362
|
-
const delta = jsDate - INITIAL_1900_DAY;
|
|
1423
|
+
const delta = jsDate.getTime() - INITIAL_1900_DAY.getTime();
|
|
1363
1424
|
const format = getFormatFromDateParts(parts, separator, leadingZero, fullYear);
|
|
1364
1425
|
return {
|
|
1365
1426
|
value: Math.round(delta / MS_PER_DAY),
|
|
@@ -1450,7 +1511,7 @@
|
|
|
1450
1511
|
if (hours >= 24) {
|
|
1451
1512
|
format = "hhhh:mm:ss";
|
|
1452
1513
|
}
|
|
1453
|
-
const jsDate = new
|
|
1514
|
+
const jsDate = new DateTime(1899, 11, 30, hours, minutes, seconds);
|
|
1454
1515
|
return {
|
|
1455
1516
|
value: hours / 24 + minutes / 1440 + seconds / 86400,
|
|
1456
1517
|
format: format,
|
|
@@ -1464,7 +1525,7 @@
|
|
|
1464
1525
|
// -----------------------------------------------------------------------------
|
|
1465
1526
|
function numberToJsDate(value) {
|
|
1466
1527
|
const truncValue = Math.trunc(value);
|
|
1467
|
-
let date =
|
|
1528
|
+
let date = DateTime.fromTimestamp(truncValue * MS_PER_DAY - DATE_JS_1900_OFFSET);
|
|
1468
1529
|
let time = value - truncValue;
|
|
1469
1530
|
time = time < 0 ? 1 + time : time;
|
|
1470
1531
|
const hours = Math.round(time * 24);
|
|
@@ -1484,7 +1545,7 @@
|
|
|
1484
1545
|
}
|
|
1485
1546
|
/** Return the number of days in the current month of the given date */
|
|
1486
1547
|
function getDaysInMonth(date) {
|
|
1487
|
-
return new
|
|
1548
|
+
return new DateTime(date.getFullYear(), date.getMonth() + 1, 0).getDate();
|
|
1488
1549
|
}
|
|
1489
1550
|
function isLastDayOfMonth(date) {
|
|
1490
1551
|
return getDaysInMonth(date) === date.getDate();
|
|
@@ -1502,7 +1563,7 @@
|
|
|
1502
1563
|
const yStart = date.getFullYear();
|
|
1503
1564
|
const mStart = date.getMonth();
|
|
1504
1565
|
const dStart = date.getDate();
|
|
1505
|
-
const jsDate = new
|
|
1566
|
+
const jsDate = new DateTime(yStart, mStart + months, 1);
|
|
1506
1567
|
if (keepEndOfMonth && dStart === getDaysInMonth(date)) {
|
|
1507
1568
|
jsDate.setDate(getDaysInMonth(jsDate));
|
|
1508
1569
|
}
|
|
@@ -2061,6 +2122,8 @@
|
|
|
2061
2122
|
CommandResult["NoChanges"] = "NoChanges";
|
|
2062
2123
|
})(exports.CommandResult || (exports.CommandResult = {}));
|
|
2063
2124
|
|
|
2125
|
+
const PLAIN_TEXT_FORMAT = "@"; // see OpenXML spec §18.8.31
|
|
2126
|
+
|
|
2064
2127
|
const DEFAULT_LOCALES = [
|
|
2065
2128
|
{
|
|
2066
2129
|
name: "English (US)",
|
|
@@ -2725,20 +2788,20 @@
|
|
|
2725
2788
|
}
|
|
2726
2789
|
|
|
2727
2790
|
function toCriterionDateNumber(dateValue) {
|
|
2728
|
-
const today =
|
|
2791
|
+
const today = DateTime.now();
|
|
2729
2792
|
switch (dateValue) {
|
|
2730
2793
|
case "today":
|
|
2731
2794
|
return jsDateToNumber(today);
|
|
2732
2795
|
case "yesterday":
|
|
2733
|
-
return jsDateToNumber(
|
|
2796
|
+
return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() - 1)));
|
|
2734
2797
|
case "tomorrow":
|
|
2735
|
-
return jsDateToNumber(
|
|
2798
|
+
return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() + 1)));
|
|
2736
2799
|
case "lastWeek":
|
|
2737
|
-
return jsDateToNumber(
|
|
2800
|
+
return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() - 7)));
|
|
2738
2801
|
case "lastMonth":
|
|
2739
|
-
return jsDateToNumber(
|
|
2802
|
+
return jsDateToNumber(DateTime.fromTimestamp(today.setMonth(today.getMonth() - 1)));
|
|
2740
2803
|
case "lastYear":
|
|
2741
|
-
return jsDateToNumber(
|
|
2804
|
+
return jsDateToNumber(DateTime.fromTimestamp(today.setFullYear(today.getFullYear() - 1)));
|
|
2742
2805
|
}
|
|
2743
2806
|
}
|
|
2744
2807
|
/** Get all the dates values of a criterion converted to numbers, converting date values such as "today" to actual dates */
|
|
@@ -2824,6 +2887,9 @@
|
|
|
2824
2887
|
* Formats a cell value with its format.
|
|
2825
2888
|
*/
|
|
2826
2889
|
function formatValue(value, { format, locale }) {
|
|
2890
|
+
if (format === PLAIN_TEXT_FORMAT) {
|
|
2891
|
+
return toString(value) || "";
|
|
2892
|
+
}
|
|
2827
2893
|
switch (typeof value) {
|
|
2828
2894
|
case "string":
|
|
2829
2895
|
return value;
|
|
@@ -3096,7 +3162,7 @@
|
|
|
3096
3162
|
.map((p) => {
|
|
3097
3163
|
switch (p) {
|
|
3098
3164
|
case "hhhh":
|
|
3099
|
-
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY) / (60 * 60 * 1000));
|
|
3165
|
+
const helapsedHours = Math.floor((jsDate.getTime() - INITIAL_1900_DAY.getTime()) / (60 * 60 * 1000));
|
|
3100
3166
|
return helapsedHours.toString();
|
|
3101
3167
|
case "hh":
|
|
3102
3168
|
return hours.toString().padStart(2, "0");
|
|
@@ -4664,6 +4730,9 @@
|
|
|
4664
4730
|
|
|
4665
4731
|
class ChartJsComponent extends owl.Component {
|
|
4666
4732
|
static template = "o-spreadsheet-ChartJsComponent";
|
|
4733
|
+
static props = {
|
|
4734
|
+
figure: Object,
|
|
4735
|
+
};
|
|
4667
4736
|
canvas = owl.useRef("graphContainer");
|
|
4668
4737
|
chart;
|
|
4669
4738
|
get background() {
|
|
@@ -4716,9 +4785,6 @@
|
|
|
4716
4785
|
this.chart.update("active");
|
|
4717
4786
|
}
|
|
4718
4787
|
}
|
|
4719
|
-
ChartJsComponent.props = {
|
|
4720
|
-
figure: Object,
|
|
4721
|
-
};
|
|
4722
4788
|
|
|
4723
4789
|
/**
|
|
4724
4790
|
* AbstractChart is the class from which every Chart should inherit.
|
|
@@ -5295,7 +5361,7 @@
|
|
|
5295
5361
|
};
|
|
5296
5362
|
baselineCell = getters.getEvaluatedCell(baselinePosition);
|
|
5297
5363
|
}
|
|
5298
|
-
const background = getters.
|
|
5364
|
+
const { background, fontColor } = getters.getStyleOfSingleCellChart(chart.background, chart.keyValue);
|
|
5299
5365
|
const locale = getters.getLocale();
|
|
5300
5366
|
return {
|
|
5301
5367
|
title: _t(chart.title),
|
|
@@ -5304,7 +5370,7 @@
|
|
|
5304
5370
|
baselineArrow: getBaselineArrowDirection(baselineCell, keyValueCell, chart.baselineMode),
|
|
5305
5371
|
baselineColor: getBaselineColor(baselineCell, chart.baselineMode, keyValueCell, chart.baselineColorUp, chart.baselineColorDown),
|
|
5306
5372
|
baselineDescr: chart.baselineDescr ? _t(chart.baselineDescr) : "",
|
|
5307
|
-
fontColor
|
|
5373
|
+
fontColor,
|
|
5308
5374
|
background,
|
|
5309
5375
|
baselineStyle: chart.baselineMode !== "percentage" && baseline
|
|
5310
5376
|
? getters.getCellStyle({
|
|
@@ -5569,6 +5635,9 @@
|
|
|
5569
5635
|
|
|
5570
5636
|
class ScorecardChart extends owl.Component {
|
|
5571
5637
|
static template = "o-spreadsheet-ScorecardChart";
|
|
5638
|
+
static props = {
|
|
5639
|
+
figure: Object,
|
|
5640
|
+
};
|
|
5572
5641
|
canvas = owl.useRef("chartContainer");
|
|
5573
5642
|
get runtime() {
|
|
5574
5643
|
return this.env.model.getters.getChartRuntime(this.props.figure.id);
|
|
@@ -5586,9 +5655,6 @@
|
|
|
5586
5655
|
drawScoreChart(config, canvas);
|
|
5587
5656
|
}
|
|
5588
5657
|
}
|
|
5589
|
-
ScorecardChart.props = {
|
|
5590
|
-
figure: Object,
|
|
5591
|
-
};
|
|
5592
5658
|
|
|
5593
5659
|
/**
|
|
5594
5660
|
* Registry
|
|
@@ -5730,6 +5796,9 @@
|
|
|
5730
5796
|
}
|
|
5731
5797
|
|
|
5732
5798
|
function evaluateLiteral(content, localeFormat) {
|
|
5799
|
+
if (localeFormat.format === PLAIN_TEXT_FORMAT) {
|
|
5800
|
+
return textCell(content || "", localeFormat);
|
|
5801
|
+
}
|
|
5733
5802
|
return createEvaluatedCell(parseLiteral(content || "", localeFormat.locale), localeFormat);
|
|
5734
5803
|
}
|
|
5735
5804
|
function parseLiteral(content, locale) {
|
|
@@ -5764,6 +5833,9 @@
|
|
|
5764
5833
|
}
|
|
5765
5834
|
function _createEvaluatedCell(value, localeFormat) {
|
|
5766
5835
|
try {
|
|
5836
|
+
if (localeFormat.format === PLAIN_TEXT_FORMAT) {
|
|
5837
|
+
return textCell(toString(value), localeFormat);
|
|
5838
|
+
}
|
|
5767
5839
|
for (const builder of builders) {
|
|
5768
5840
|
const evaluateCell = builder(value, localeFormat);
|
|
5769
5841
|
if (evaluateCell) {
|
|
@@ -6261,11 +6333,11 @@
|
|
|
6261
6333
|
class ErrorToolTip extends owl.Component {
|
|
6262
6334
|
static maxSize = { maxHeight: ERROR_TOOLTIP_MAX_HEIGHT };
|
|
6263
6335
|
static template = "o-spreadsheet-ErrorToolTip";
|
|
6336
|
+
static props = {
|
|
6337
|
+
errors: Array,
|
|
6338
|
+
onClosed: { type: Function, optional: true },
|
|
6339
|
+
};
|
|
6264
6340
|
}
|
|
6265
|
-
ErrorToolTip.props = {
|
|
6266
|
-
errors: Array,
|
|
6267
|
-
onClosed: { type: Function, optional: true },
|
|
6268
|
-
};
|
|
6269
6341
|
const ErrorToolTipPopoverBuilder = {
|
|
6270
6342
|
onHover: (position, getters) => {
|
|
6271
6343
|
const cell = getters.getEvaluatedCell(position);
|
|
@@ -6307,6 +6379,14 @@
|
|
|
6307
6379
|
`;
|
|
6308
6380
|
class FilterMenuValueItem extends owl.Component {
|
|
6309
6381
|
static template = "o-spreadsheet-FilterMenuValueItem";
|
|
6382
|
+
static props = {
|
|
6383
|
+
value: String,
|
|
6384
|
+
isChecked: Boolean,
|
|
6385
|
+
isSelected: Boolean,
|
|
6386
|
+
onMouseMove: Function,
|
|
6387
|
+
onClick: Function,
|
|
6388
|
+
scrolledTo: { type: String, optional: true },
|
|
6389
|
+
};
|
|
6310
6390
|
itemRef = owl.useRef("menuValueItem");
|
|
6311
6391
|
setup() {
|
|
6312
6392
|
owl.onWillPatch(() => {
|
|
@@ -6324,17 +6404,9 @@
|
|
|
6324
6404
|
});
|
|
6325
6405
|
}
|
|
6326
6406
|
}
|
|
6327
|
-
FilterMenuValueItem.props = {
|
|
6328
|
-
value: String,
|
|
6329
|
-
isChecked: Boolean,
|
|
6330
|
-
isSelected: Boolean,
|
|
6331
|
-
onMouseMove: Function,
|
|
6332
|
-
onClick: Function,
|
|
6333
|
-
scrolledTo: { type: String, optional: true },
|
|
6334
|
-
};
|
|
6335
6407
|
|
|
6336
6408
|
const FILTER_MENU_HEIGHT = 295;
|
|
6337
|
-
const CSS
|
|
6409
|
+
const CSS = css /* scss */ `
|
|
6338
6410
|
.o-filter-menu {
|
|
6339
6411
|
box-sizing: border-box;
|
|
6340
6412
|
padding: 8px 16px;
|
|
@@ -6430,9 +6502,12 @@
|
|
|
6430
6502
|
}
|
|
6431
6503
|
`;
|
|
6432
6504
|
class FilterMenu extends owl.Component {
|
|
6433
|
-
static size = { width: MENU_WIDTH, height: FILTER_MENU_HEIGHT };
|
|
6434
6505
|
static template = "o-spreadsheet-FilterMenu";
|
|
6435
|
-
static
|
|
6506
|
+
static props = {
|
|
6507
|
+
filterPosition: Object,
|
|
6508
|
+
onClosed: { type: Function, optional: true },
|
|
6509
|
+
};
|
|
6510
|
+
static style = CSS;
|
|
6436
6511
|
static components = { FilterMenuValueItem };
|
|
6437
6512
|
state = owl.useState({
|
|
6438
6513
|
values: [],
|
|
@@ -6584,10 +6659,6 @@
|
|
|
6584
6659
|
this.props.onClosed?.();
|
|
6585
6660
|
}
|
|
6586
6661
|
}
|
|
6587
|
-
FilterMenu.props = {
|
|
6588
|
-
filterPosition: Object,
|
|
6589
|
-
onClosed: { type: Function, optional: true },
|
|
6590
|
-
};
|
|
6591
6662
|
const FilterMenuPopoverBuilder = {
|
|
6592
6663
|
onOpen: (position, getters) => {
|
|
6593
6664
|
return {
|
|
@@ -6599,6 +6670,7 @@
|
|
|
6599
6670
|
},
|
|
6600
6671
|
};
|
|
6601
6672
|
|
|
6673
|
+
const macRegex = /Mac/i;
|
|
6602
6674
|
/**
|
|
6603
6675
|
* Return true if the event was triggered from
|
|
6604
6676
|
* a child element.
|
|
@@ -6650,7 +6722,7 @@
|
|
|
6650
6722
|
*/
|
|
6651
6723
|
function keyboardEventToShortcutString(ev, mode = "key") {
|
|
6652
6724
|
let keyDownString = "";
|
|
6653
|
-
if (ev
|
|
6725
|
+
if (isCtrlKey(ev) && ev.key !== "Ctrl")
|
|
6654
6726
|
keyDownString += "Ctrl+";
|
|
6655
6727
|
if (ev.metaKey)
|
|
6656
6728
|
keyDownString += "Ctrl+";
|
|
@@ -6663,7 +6735,15 @@
|
|
|
6663
6735
|
return keyDownString;
|
|
6664
6736
|
}
|
|
6665
6737
|
function isMacOS() {
|
|
6666
|
-
return navigator.userAgent
|
|
6738
|
+
return Boolean(macRegex.test(navigator.userAgent));
|
|
6739
|
+
}
|
|
6740
|
+
/**
|
|
6741
|
+
* @param {KeyboardEvent | MouseEvent} ev
|
|
6742
|
+
* @returns Returns true if the event was triggered with the "ctrl" modifier pressed.
|
|
6743
|
+
* On Mac, this is the "meta" or "command" key.
|
|
6744
|
+
*/
|
|
6745
|
+
function isCtrlKey(ev) {
|
|
6746
|
+
return isMacOS() ? ev.metaKey : ev.ctrlKey;
|
|
6667
6747
|
}
|
|
6668
6748
|
|
|
6669
6749
|
/**
|
|
@@ -6780,6 +6860,19 @@
|
|
|
6780
6860
|
`;
|
|
6781
6861
|
class Popover extends owl.Component {
|
|
6782
6862
|
static template = "o-spreadsheet-Popover";
|
|
6863
|
+
static props = {
|
|
6864
|
+
anchorRect: Object,
|
|
6865
|
+
containerRect: { type: Object, optional: true },
|
|
6866
|
+
positioning: { type: String, optional: true },
|
|
6867
|
+
maxWidth: { type: Number, optional: true },
|
|
6868
|
+
maxHeight: { type: Number, optional: true },
|
|
6869
|
+
verticalOffset: { type: Number, optional: true },
|
|
6870
|
+
onMouseWheel: { type: Function, optional: true },
|
|
6871
|
+
onPopoverHidden: { type: Function, optional: true },
|
|
6872
|
+
onPopoverMoved: { type: Function, optional: true },
|
|
6873
|
+
zIndex: { type: Number, optional: true },
|
|
6874
|
+
slots: Object,
|
|
6875
|
+
};
|
|
6783
6876
|
static defaultProps = {
|
|
6784
6877
|
positioning: "BottomLeft",
|
|
6785
6878
|
verticalOffset: 0,
|
|
@@ -6836,19 +6929,6 @@
|
|
|
6836
6929
|
});
|
|
6837
6930
|
}
|
|
6838
6931
|
}
|
|
6839
|
-
Popover.props = {
|
|
6840
|
-
anchorRect: Object,
|
|
6841
|
-
containerRect: { type: Object, optional: true },
|
|
6842
|
-
positioning: { type: String, optional: true },
|
|
6843
|
-
maxWidth: { type: Number, optional: true },
|
|
6844
|
-
maxHeight: { type: Number, optional: true },
|
|
6845
|
-
verticalOffset: { type: Number, optional: true },
|
|
6846
|
-
onMouseWheel: { type: Function, optional: true },
|
|
6847
|
-
onPopoverHidden: { type: Function, optional: true },
|
|
6848
|
-
onPopoverMoved: { type: Function, optional: true },
|
|
6849
|
-
zIndex: { type: Number, optional: true },
|
|
6850
|
-
slots: Object,
|
|
6851
|
-
};
|
|
6852
6932
|
class PopoverPositionContext {
|
|
6853
6933
|
anchorRect;
|
|
6854
6934
|
containerRect;
|
|
@@ -7030,6 +7110,15 @@
|
|
|
7030
7110
|
`;
|
|
7031
7111
|
class Menu extends owl.Component {
|
|
7032
7112
|
static template = "o-spreadsheet-Menu";
|
|
7113
|
+
static props = {
|
|
7114
|
+
position: Object,
|
|
7115
|
+
menuItems: Array,
|
|
7116
|
+
depth: { type: Number, optional: true },
|
|
7117
|
+
maxHeight: { type: Number, optional: true },
|
|
7118
|
+
onClose: Function,
|
|
7119
|
+
onMenuClicked: { type: Function, optional: true },
|
|
7120
|
+
menuId: { type: String, optional: true },
|
|
7121
|
+
};
|
|
7033
7122
|
static components = { Menu, Popover };
|
|
7034
7123
|
static defaultProps = {
|
|
7035
7124
|
depth: 1,
|
|
@@ -7186,15 +7275,6 @@
|
|
|
7186
7275
|
}
|
|
7187
7276
|
}
|
|
7188
7277
|
}
|
|
7189
|
-
Menu.props = {
|
|
7190
|
-
position: Object,
|
|
7191
|
-
menuItems: Array,
|
|
7192
|
-
depth: { type: Number, optional: true },
|
|
7193
|
-
maxHeight: { type: Number, optional: true },
|
|
7194
|
-
onClose: Function,
|
|
7195
|
-
onMenuClicked: { type: Function, optional: true },
|
|
7196
|
-
menuId: { type: String, optional: true },
|
|
7197
|
-
};
|
|
7198
7278
|
|
|
7199
7279
|
const LINK_TOOLTIP_HEIGHT = 32;
|
|
7200
7280
|
const LINK_TOOLTIP_WIDTH = 220;
|
|
@@ -7247,8 +7327,12 @@
|
|
|
7247
7327
|
}
|
|
7248
7328
|
`;
|
|
7249
7329
|
class LinkDisplay extends owl.Component {
|
|
7250
|
-
static components = { Menu };
|
|
7251
7330
|
static template = "o-spreadsheet-LinkDisplay";
|
|
7331
|
+
static props = {
|
|
7332
|
+
cellPosition: Object,
|
|
7333
|
+
onClosed: { type: Function, optional: true },
|
|
7334
|
+
};
|
|
7335
|
+
static components = { Menu };
|
|
7252
7336
|
get cell() {
|
|
7253
7337
|
const { col, row } = this.props.cellPosition;
|
|
7254
7338
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
@@ -7303,10 +7387,6 @@
|
|
|
7303
7387
|
};
|
|
7304
7388
|
},
|
|
7305
7389
|
};
|
|
7306
|
-
LinkDisplay.props = {
|
|
7307
|
-
cellPosition: Object,
|
|
7308
|
-
onClosed: { type: Function, optional: true },
|
|
7309
|
-
};
|
|
7310
7390
|
|
|
7311
7391
|
/**
|
|
7312
7392
|
* Tokenizer
|
|
@@ -7940,6 +8020,10 @@
|
|
|
7940
8020
|
`;
|
|
7941
8021
|
class LinkEditor extends owl.Component {
|
|
7942
8022
|
static template = "o-spreadsheet-LinkEditor";
|
|
8023
|
+
static props = {
|
|
8024
|
+
cellPosition: Object,
|
|
8025
|
+
onClosed: { type: Function, optional: true },
|
|
8026
|
+
};
|
|
7943
8027
|
static components = { Menu };
|
|
7944
8028
|
menuItems = linkMenuRegistry.getMenuItems();
|
|
7945
8029
|
link = owl.useState(this.defaultState);
|
|
@@ -8037,10 +8121,6 @@
|
|
|
8037
8121
|
};
|
|
8038
8122
|
},
|
|
8039
8123
|
};
|
|
8040
|
-
LinkEditor.props = {
|
|
8041
|
-
cellPosition: Object,
|
|
8042
|
-
onClosed: { type: Function, optional: true },
|
|
8043
|
-
};
|
|
8044
8124
|
|
|
8045
8125
|
const cellPopoverRegistry = new Registry();
|
|
8046
8126
|
cellPopoverRegistry
|
|
@@ -8323,6 +8403,7 @@
|
|
|
8323
8403
|
labels: labels.map(truncateLabel),
|
|
8324
8404
|
datasets: [],
|
|
8325
8405
|
},
|
|
8406
|
+
platform: undefined,
|
|
8326
8407
|
plugins: [],
|
|
8327
8408
|
};
|
|
8328
8409
|
}
|
|
@@ -8902,7 +8983,7 @@
|
|
|
8902
8983
|
});
|
|
8903
8984
|
return {
|
|
8904
8985
|
chartJsConfig: config,
|
|
8905
|
-
background: getters.
|
|
8986
|
+
background: getters.getStyleOfSingleCellChart(chart.background, dataRange).background,
|
|
8906
8987
|
};
|
|
8907
8988
|
}
|
|
8908
8989
|
|
|
@@ -8983,7 +9064,7 @@
|
|
|
8983
9064
|
else if (format.includes("h") || format.includes("H")) {
|
|
8984
9065
|
return "hour";
|
|
8985
9066
|
}
|
|
8986
|
-
else if (format.includes("
|
|
9067
|
+
else if (format.includes("d")) {
|
|
8987
9068
|
return "day";
|
|
8988
9069
|
}
|
|
8989
9070
|
else if (format.includes("M")) {
|
|
@@ -9495,6 +9576,27 @@
|
|
|
9495
9576
|
const percentage = (dataset[dataIndex] / total) * 100;
|
|
9496
9577
|
return percentage.toFixed(2);
|
|
9497
9578
|
}
|
|
9579
|
+
function filterNegativeValues(labels, datasets) {
|
|
9580
|
+
const dataPointsIndexes = labels.reduce((indexes, label, i) => {
|
|
9581
|
+
const shouldKeep = datasets.some((dataset) => {
|
|
9582
|
+
const dataPoint = dataset.data[i];
|
|
9583
|
+
return typeof dataPoint !== "number" || dataPoint >= 0;
|
|
9584
|
+
});
|
|
9585
|
+
if (shouldKeep) {
|
|
9586
|
+
indexes.push(i);
|
|
9587
|
+
}
|
|
9588
|
+
return indexes;
|
|
9589
|
+
}, []);
|
|
9590
|
+
const filteredLabels = dataPointsIndexes.map((i) => labels[i] || "");
|
|
9591
|
+
const filteredDatasets = datasets.map((dataset) => ({
|
|
9592
|
+
...dataset,
|
|
9593
|
+
data: dataPointsIndexes.map((i) => {
|
|
9594
|
+
const dataPoint = dataset.data[i];
|
|
9595
|
+
return typeof dataPoint !== "number" || dataPoint >= 0 ? dataPoint : 0;
|
|
9596
|
+
}),
|
|
9597
|
+
}));
|
|
9598
|
+
return { labels: filteredLabels, dataSetsValues: filteredDatasets };
|
|
9599
|
+
}
|
|
9498
9600
|
function createPieChartRuntime(chart, getters) {
|
|
9499
9601
|
const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
|
|
9500
9602
|
let labels = labelValues.formattedValues;
|
|
@@ -9508,6 +9610,7 @@
|
|
|
9508
9610
|
if (chart.aggregated) {
|
|
9509
9611
|
({ labels, dataSetsValues } = aggregateDataForLabels(labels, dataSetsValues));
|
|
9510
9612
|
}
|
|
9613
|
+
({ dataSetsValues, labels } = filterNegativeValues(labels, dataSetsValues));
|
|
9511
9614
|
const dataSetFormat = getChartDatasetFormat(getters, chart.dataSets);
|
|
9512
9615
|
const locale = getters.getLocale();
|
|
9513
9616
|
const config = getPieConfiguration(chart, labels, { format: dataSetFormat, locale });
|
|
@@ -9605,6 +9708,10 @@
|
|
|
9605
9708
|
`;
|
|
9606
9709
|
class ChartFigure extends owl.Component {
|
|
9607
9710
|
static template = "o-spreadsheet-ChartFigure";
|
|
9711
|
+
static props = {
|
|
9712
|
+
figure: Object,
|
|
9713
|
+
onFigureDeleted: Function,
|
|
9714
|
+
};
|
|
9608
9715
|
static components = {};
|
|
9609
9716
|
onDoubleClick() {
|
|
9610
9717
|
this.env.model.dispatch("SELECT_FIGURE", { id: this.props.figure.id });
|
|
@@ -9622,13 +9729,13 @@
|
|
|
9622
9729
|
return component;
|
|
9623
9730
|
}
|
|
9624
9731
|
}
|
|
9625
|
-
ChartFigure.props = {
|
|
9626
|
-
figure: Object,
|
|
9627
|
-
onFigureDeleted: Function,
|
|
9628
|
-
};
|
|
9629
9732
|
|
|
9630
9733
|
class ImageFigure extends owl.Component {
|
|
9631
9734
|
static template = "o-spreadsheet-ImageFigure";
|
|
9735
|
+
static props = {
|
|
9736
|
+
figure: Object,
|
|
9737
|
+
onFigureDeleted: Function,
|
|
9738
|
+
};
|
|
9632
9739
|
static components = {};
|
|
9633
9740
|
// ---------------------------------------------------------------------------
|
|
9634
9741
|
// Getters
|
|
@@ -9640,10 +9747,6 @@
|
|
|
9640
9747
|
return this.env.model.getters.getImagePath(this.figureId);
|
|
9641
9748
|
}
|
|
9642
9749
|
}
|
|
9643
|
-
ImageFigure.props = {
|
|
9644
|
-
figure: Object,
|
|
9645
|
-
onFigureDeleted: Function,
|
|
9646
|
-
};
|
|
9647
9750
|
|
|
9648
9751
|
function centerFigurePosition(getters, size) {
|
|
9649
9752
|
const { x: offsetCorrectionX, y: offsetCorrectionY } = getters.getMainViewportCoordinates();
|
|
@@ -10345,7 +10448,7 @@
|
|
|
10345
10448
|
// Simple actions
|
|
10346
10449
|
//------------------------------------------------------------------------------
|
|
10347
10450
|
const PASTE_ACTION = async (env) => paste$1(env);
|
|
10348
|
-
const
|
|
10451
|
+
const PASTE_AS_VALUE_ACTION = async (env) => paste$1(env, "asValue");
|
|
10349
10452
|
async function paste$1(env, pasteOption) {
|
|
10350
10453
|
const spreadsheetClipboard = env.model.getters.getClipboardTextContent();
|
|
10351
10454
|
const osClipboard = await env.clipboard.readText();
|
|
@@ -10358,7 +10461,7 @@
|
|
|
10358
10461
|
else {
|
|
10359
10462
|
interactivePaste(env, target, pasteOption);
|
|
10360
10463
|
}
|
|
10361
|
-
if (env.model.getters.isCutOperation() && pasteOption !== "
|
|
10464
|
+
if (env.model.getters.isCutOperation() && pasteOption !== "asValue") {
|
|
10362
10465
|
await env.clipboard.write({ [ClipboardMIMEType.PlainText]: "" });
|
|
10363
10466
|
}
|
|
10364
10467
|
break;
|
|
@@ -10773,9 +10876,9 @@
|
|
|
10773
10876
|
icon: "o-spreadsheet-Icon.PASTE",
|
|
10774
10877
|
};
|
|
10775
10878
|
const pasteSpecialValue = {
|
|
10776
|
-
name: _t("Paste value
|
|
10879
|
+
name: _t("Paste as value"),
|
|
10777
10880
|
description: "Ctrl+Shift+V",
|
|
10778
|
-
execute:
|
|
10881
|
+
execute: PASTE_AS_VALUE_ACTION,
|
|
10779
10882
|
};
|
|
10780
10883
|
const pasteSpecialFormat = {
|
|
10781
10884
|
name: _t("Paste format only"),
|
|
@@ -10931,6 +11034,9 @@
|
|
|
10931
11034
|
function makeArg(str, description) {
|
|
10932
11035
|
let parts = str.match(ARG_REGEXP);
|
|
10933
11036
|
let name = parts[1].trim();
|
|
11037
|
+
if (!name) {
|
|
11038
|
+
throw new Error(`Function argument definition is missing a name: '${str}'.`);
|
|
11039
|
+
}
|
|
10934
11040
|
let types = [];
|
|
10935
11041
|
let isOptional = false;
|
|
10936
11042
|
let isRepeating = false;
|
|
@@ -14653,7 +14759,7 @@
|
|
|
14653
14759
|
if (_year < 1900) {
|
|
14654
14760
|
_year += 1900;
|
|
14655
14761
|
}
|
|
14656
|
-
const jsDate = new
|
|
14762
|
+
const jsDate = new DateTime(_year, _month - 1, _day);
|
|
14657
14763
|
const result = jsDateToRoundNumber(jsDate);
|
|
14658
14764
|
assert(() => result >= 0, _t("The function [[FUNCTION_NAME]] result must be greater than or equal 01/01/1900."));
|
|
14659
14765
|
return result;
|
|
@@ -14696,7 +14802,7 @@
|
|
|
14696
14802
|
// See: https://support.microsoft.com/en-us/office/datedif-function-25dba1a4-2812-480b-84dd-8b32a451b35c
|
|
14697
14803
|
let days = jsEndDate.getDate() - jsStartDate.getDate();
|
|
14698
14804
|
if (days < 0) {
|
|
14699
|
-
const monthBeforeEndMonth = new
|
|
14805
|
+
const monthBeforeEndMonth = new DateTime(jsEndDate.getFullYear(), jsEndDate.getMonth() - 1, 1);
|
|
14700
14806
|
const daysInMonthBeforeEndMonth = getDaysInMonth(monthBeforeEndMonth);
|
|
14701
14807
|
days = daysInMonthBeforeEndMonth - Math.abs(days);
|
|
14702
14808
|
}
|
|
@@ -14705,7 +14811,7 @@
|
|
|
14705
14811
|
if (areTwoDatesWithinOneYear(_startDate, _endDate)) {
|
|
14706
14812
|
return getTimeDifferenceInWholeDays(jsStartDate, jsEndDate);
|
|
14707
14813
|
}
|
|
14708
|
-
const endDateWithinOneYear = new
|
|
14814
|
+
const endDateWithinOneYear = new DateTime(jsStartDate.getFullYear(), jsEndDate.getMonth(), jsEndDate.getDate());
|
|
14709
14815
|
let days = getTimeDifferenceInWholeDays(jsStartDate, endDateWithinOneYear);
|
|
14710
14816
|
if (days < 0) {
|
|
14711
14817
|
endDateWithinOneYear.setFullYear(jsStartDate.getFullYear() + 1);
|
|
@@ -14822,7 +14928,7 @@
|
|
|
14822
14928
|
const _months = Math.trunc(toNumber(months, this.locale));
|
|
14823
14929
|
const yStart = _startDate.getFullYear();
|
|
14824
14930
|
const mStart = _startDate.getMonth();
|
|
14825
|
-
const jsDate = new
|
|
14931
|
+
const jsDate = new DateTime(yStart, mStart + _months + 1, 0);
|
|
14826
14932
|
return jsDateToRoundNumber(jsDate);
|
|
14827
14933
|
},
|
|
14828
14934
|
isExported: true,
|
|
@@ -14859,17 +14965,17 @@
|
|
|
14859
14965
|
// The first week of the year is the week that contains the first
|
|
14860
14966
|
// Thursday of the year.
|
|
14861
14967
|
let firstThursday = 1;
|
|
14862
|
-
while (new
|
|
14968
|
+
while (new DateTime(y, 0, firstThursday).getDay() !== 4) {
|
|
14863
14969
|
firstThursday += 1;
|
|
14864
14970
|
}
|
|
14865
|
-
const firstDayOfFirstWeek = new
|
|
14971
|
+
const firstDayOfFirstWeek = new DateTime(y, 0, firstThursday - 3);
|
|
14866
14972
|
// The last week of the year is the week that contains the last Thursday of
|
|
14867
14973
|
// the year.
|
|
14868
14974
|
let lastThursday = 31;
|
|
14869
|
-
while (new
|
|
14975
|
+
while (new DateTime(y, 11, lastThursday).getDay() !== 4) {
|
|
14870
14976
|
lastThursday -= 1;
|
|
14871
14977
|
}
|
|
14872
|
-
const lastDayOfLastWeek = new
|
|
14978
|
+
const lastDayOfLastWeek = new DateTime(y, 11, lastThursday + 3);
|
|
14873
14979
|
// B - If our date > lastDayOfLastWeek then it's in the weeks of the year after
|
|
14874
14980
|
// If our date < firstDayOfFirstWeek then it's in the weeks of the year before
|
|
14875
14981
|
let offsetYear;
|
|
@@ -14895,17 +15001,17 @@
|
|
|
14895
15001
|
case 1:
|
|
14896
15002
|
// firstDay is the 1st day of the 1st week of the year after
|
|
14897
15003
|
// firstDay = lastDayOfLastWeek + 1 Day
|
|
14898
|
-
firstDay = new
|
|
15004
|
+
firstDay = new DateTime(y, 11, lastThursday + 3 + 1);
|
|
14899
15005
|
break;
|
|
14900
15006
|
case -1:
|
|
14901
15007
|
// firstDay is the 1st day of the 1st week of the previous year.
|
|
14902
15008
|
// The first week of the previous year is the week that contains the
|
|
14903
15009
|
// first Thursday of the previous year.
|
|
14904
15010
|
let firstThursdayPreviousYear = 1;
|
|
14905
|
-
while (new
|
|
15011
|
+
while (new DateTime(y - 1, 0, firstThursdayPreviousYear).getDay() !== 4) {
|
|
14906
15012
|
firstThursdayPreviousYear += 1;
|
|
14907
15013
|
}
|
|
14908
|
-
firstDay = new
|
|
15014
|
+
firstDay = new DateTime(y - 1, 0, firstThursdayPreviousYear - 3);
|
|
14909
15015
|
break;
|
|
14910
15016
|
}
|
|
14911
15017
|
const diff = (_date.getTime() - firstDay.getTime()) / MS_PER_DAY;
|
|
@@ -15040,8 +15146,8 @@
|
|
|
15040
15146
|
});
|
|
15041
15147
|
}
|
|
15042
15148
|
const invertDate = _startDate.getTime() > _endDate.getTime();
|
|
15043
|
-
const stopDate =
|
|
15044
|
-
let stepDate =
|
|
15149
|
+
const stopDate = DateTime.fromTimestamp((invertDate ? _startDate : _endDate).getTime());
|
|
15150
|
+
let stepDate = DateTime.fromTimestamp((invertDate ? _endDate : _startDate).getTime());
|
|
15045
15151
|
const timeStopDate = stopDate.getTime();
|
|
15046
15152
|
let timeStepDate = stepDate.getTime();
|
|
15047
15153
|
let netWorkingDay = 0;
|
|
@@ -15067,8 +15173,7 @@
|
|
|
15067
15173
|
return getDateTimeFormat(this.locale);
|
|
15068
15174
|
},
|
|
15069
15175
|
compute: function () {
|
|
15070
|
-
let today =
|
|
15071
|
-
today.setMilliseconds(0);
|
|
15176
|
+
let today = DateTime.now();
|
|
15072
15177
|
const delta = today.getTime() - INITIAL_1900_DAY.getTime();
|
|
15073
15178
|
const time = today.getHours() / 24 + today.getMinutes() / 1440 + today.getSeconds() / 86400;
|
|
15074
15179
|
return Math.floor(delta / MS_PER_DAY) + time;
|
|
@@ -15142,8 +15247,8 @@
|
|
|
15142
15247
|
return this.locale.dateFormat;
|
|
15143
15248
|
},
|
|
15144
15249
|
compute: function () {
|
|
15145
|
-
const today =
|
|
15146
|
-
const jsDate = new
|
|
15250
|
+
const today = DateTime.now();
|
|
15251
|
+
const jsDate = new DateTime(today.getFullYear(), today.getMonth(), today.getDate());
|
|
15147
15252
|
return jsDateToRoundNumber(jsDate);
|
|
15148
15253
|
},
|
|
15149
15254
|
isExported: true,
|
|
@@ -15198,10 +15303,10 @@
|
|
|
15198
15303
|
}
|
|
15199
15304
|
const y = _date.getFullYear();
|
|
15200
15305
|
let dayStart = 1;
|
|
15201
|
-
let startDayOfFirstWeek = new
|
|
15306
|
+
let startDayOfFirstWeek = new DateTime(y, 0, dayStart);
|
|
15202
15307
|
while (startDayOfFirstWeek.getDay() !== startDayOfWeek) {
|
|
15203
15308
|
dayStart += 1;
|
|
15204
|
-
startDayOfFirstWeek = new
|
|
15309
|
+
startDayOfFirstWeek = new DateTime(y, 0, dayStart);
|
|
15205
15310
|
}
|
|
15206
15311
|
const dif = (_date.getTime() - startDayOfFirstWeek.getTime()) / MS_PER_DAY;
|
|
15207
15312
|
if (dif < 0) {
|
|
@@ -15259,7 +15364,7 @@
|
|
|
15259
15364
|
timesHoliday.add(holiday.getTime());
|
|
15260
15365
|
});
|
|
15261
15366
|
}
|
|
15262
|
-
let stepDate =
|
|
15367
|
+
let stepDate = DateTime.fromTimestamp(_startDate.getTime());
|
|
15263
15368
|
let timeStepDate = stepDate.getTime();
|
|
15264
15369
|
const unitDay = Math.sign(_numDays);
|
|
15265
15370
|
let stepDay = Math.abs(_numDays);
|
|
@@ -15323,7 +15428,7 @@
|
|
|
15323
15428
|
const _startDate = toJsDate(date, this.locale);
|
|
15324
15429
|
const yStart = _startDate.getFullYear();
|
|
15325
15430
|
const mStart = _startDate.getMonth();
|
|
15326
|
-
const jsDate = new
|
|
15431
|
+
const jsDate = new DateTime(yStart, mStart, 1);
|
|
15327
15432
|
return jsDateToRoundNumber(jsDate);
|
|
15328
15433
|
},
|
|
15329
15434
|
};
|
|
@@ -15365,7 +15470,7 @@
|
|
|
15365
15470
|
compute: function (date) {
|
|
15366
15471
|
const quarter = QUARTER.compute.bind(this)(date);
|
|
15367
15472
|
const year = YEAR.compute.bind(this)(date);
|
|
15368
|
-
const jsDate = new
|
|
15473
|
+
const jsDate = new DateTime(year, (quarter - 1) * 3, 1);
|
|
15369
15474
|
return jsDateToRoundNumber(jsDate);
|
|
15370
15475
|
},
|
|
15371
15476
|
};
|
|
@@ -15382,7 +15487,7 @@
|
|
|
15382
15487
|
compute: function (date) {
|
|
15383
15488
|
const quarter = QUARTER.compute.bind(this)(date);
|
|
15384
15489
|
const year = YEAR.compute.bind(this)(date);
|
|
15385
|
-
const jsDate = new
|
|
15490
|
+
const jsDate = new DateTime(year, quarter * 3, 0);
|
|
15386
15491
|
return jsDateToRoundNumber(jsDate);
|
|
15387
15492
|
},
|
|
15388
15493
|
};
|
|
@@ -15398,7 +15503,7 @@
|
|
|
15398
15503
|
},
|
|
15399
15504
|
compute: function (date) {
|
|
15400
15505
|
const year = YEAR.compute.bind(this)(date);
|
|
15401
|
-
const jsDate = new
|
|
15506
|
+
const jsDate = new DateTime(year, 0, 1);
|
|
15402
15507
|
return jsDateToRoundNumber(jsDate);
|
|
15403
15508
|
},
|
|
15404
15509
|
};
|
|
@@ -15414,7 +15519,7 @@
|
|
|
15414
15519
|
},
|
|
15415
15520
|
compute: function (date) {
|
|
15416
15521
|
const year = YEAR.compute.bind(this)(date);
|
|
15417
|
-
const jsDate = new
|
|
15522
|
+
const jsDate = new DateTime(year + 1, 0, 0);
|
|
15418
15523
|
return jsDateToRoundNumber(jsDate);
|
|
15419
15524
|
},
|
|
15420
15525
|
};
|
|
@@ -15462,8 +15567,8 @@
|
|
|
15462
15567
|
const DELTA = {
|
|
15463
15568
|
description: _t("Compare two numeric values, returning 1 if they're equal."),
|
|
15464
15569
|
args: [
|
|
15465
|
-
arg(" (number)", _t("The first number to compare.")),
|
|
15466
|
-
arg(` (number, default=${DEFAULT_DELTA_ARG})`, _t("The second number to compare.")),
|
|
15570
|
+
arg("number1 (number)", _t("The first number to compare.")),
|
|
15571
|
+
arg(`number2 (number, default=${DEFAULT_DELTA_ARG})`, _t("The second number to compare.")),
|
|
15467
15572
|
],
|
|
15468
15573
|
returns: ["NUMBER"],
|
|
15469
15574
|
compute: function (number1, number2 = DEFAULT_DELTA_ARG) {
|
|
@@ -15890,7 +15995,7 @@
|
|
|
15890
15995
|
function assertSettlementLessThanOneYearBeforeMaturity(settlement, maturity, locale) {
|
|
15891
15996
|
const startDate = toJsDate(settlement, locale);
|
|
15892
15997
|
const endDate = toJsDate(maturity, locale);
|
|
15893
|
-
const startDatePlusOneYear =
|
|
15998
|
+
const startDatePlusOneYear = toJsDate(settlement, locale);
|
|
15894
15999
|
startDatePlusOneYear.setFullYear(startDate.getFullYear() + 1);
|
|
15895
16000
|
assert(() => endDate.getTime() <= startDatePlusOneYear.getTime(), _t("The settlement date (%s) must at most one year after the maturity date (%s).", settlement.toString(), maturity.toString()));
|
|
15896
16001
|
}
|
|
@@ -16025,7 +16130,7 @@
|
|
|
16025
16130
|
arg("salvage (number)", _t("The value of the asset at the end of depreciation.")),
|
|
16026
16131
|
arg("period (number)", _t("The single period within life for which to calculate depreciation.")),
|
|
16027
16132
|
arg("rate (number)", _t("The deprecation rate.")),
|
|
16028
|
-
arg(" (number, optional)", _t("An indicator of what day count method to use.")),
|
|
16133
|
+
arg("day_count_convention (number, optional)", _t("An indicator of what day count method to use.")),
|
|
16029
16134
|
],
|
|
16030
16135
|
returns: ["NUMBER"],
|
|
16031
16136
|
compute: function (cost, purchaseDate, firstPeriodEnd, salvage, period, rate, dayCountConvention = DEFAULT_DAY_COUNT_CONVENTION) {
|
|
@@ -19197,8 +19302,8 @@
|
|
|
19197
19302
|
description: _t("A segment of a string."),
|
|
19198
19303
|
args: [
|
|
19199
19304
|
arg("text (string)", _t("The string to extract a segment from.")),
|
|
19200
|
-
arg(" (number)", _t("The index from the left of string from which to begin extracting. The first character in string has the index 1.")),
|
|
19201
|
-
arg(" (number)", _t("The length of the segment to extract.")),
|
|
19305
|
+
arg("starting_at (number)", _t("The index from the left of string from which to begin extracting. The first character in string has the index 1.")),
|
|
19306
|
+
arg("extract_length (number)", _t("The length of the segment to extract.")),
|
|
19202
19307
|
],
|
|
19203
19308
|
returns: ["STRING"],
|
|
19204
19309
|
compute: function (text, starting_at, extract_length) {
|
|
@@ -20014,6 +20119,11 @@
|
|
|
20014
20119
|
execute: (env) => setFormatter(env, ""),
|
|
20015
20120
|
isActive: (env) => isAutomaticFormatSelected(env),
|
|
20016
20121
|
};
|
|
20122
|
+
const formatNumberPlainText = {
|
|
20123
|
+
name: _t("Plain text"),
|
|
20124
|
+
execute: (env) => setFormatter(env, PLAIN_TEXT_FORMAT),
|
|
20125
|
+
isActive: (env) => isFormatSelected(env, PLAIN_TEXT_FORMAT),
|
|
20126
|
+
};
|
|
20017
20127
|
const formatNumberNumber = createFormatActionSpec({
|
|
20018
20128
|
name: _t("Number"),
|
|
20019
20129
|
descriptionValue: 1000.12,
|
|
@@ -20373,6 +20483,7 @@
|
|
|
20373
20483
|
formatNumberFullWeekDayAndMonth: formatNumberFullWeekDayAndMonth,
|
|
20374
20484
|
formatNumberNumber: formatNumberNumber,
|
|
20375
20485
|
formatNumberPercent: formatNumberPercent,
|
|
20486
|
+
formatNumberPlainText: formatNumberPlainText,
|
|
20376
20487
|
formatNumberShortMonth: formatNumberShortMonth,
|
|
20377
20488
|
formatNumberShortWeekDay: formatNumberShortWeekDay,
|
|
20378
20489
|
formatNumberTime: formatNumberTime,
|
|
@@ -20803,6 +20914,10 @@
|
|
|
20803
20914
|
.add("format_number_automatic", {
|
|
20804
20915
|
...formatNumberAutomatic,
|
|
20805
20916
|
sequence: 10,
|
|
20917
|
+
})
|
|
20918
|
+
.add("format_number_plain_text", {
|
|
20919
|
+
...formatNumberPlainText,
|
|
20920
|
+
sequence: 15,
|
|
20806
20921
|
separator: true,
|
|
20807
20922
|
})
|
|
20808
20923
|
.add("format_number_number", {
|
|
@@ -21401,10 +21516,10 @@
|
|
|
21401
21516
|
function updateSelectionWithArrowKeys(ev, selection) {
|
|
21402
21517
|
const direction = arrowMap[ev.key];
|
|
21403
21518
|
if (ev.shiftKey) {
|
|
21404
|
-
selection.resizeAnchorZone(direction, ev
|
|
21519
|
+
selection.resizeAnchorZone(direction, isCtrlKey(ev) ? "end" : 1);
|
|
21405
21520
|
}
|
|
21406
21521
|
else {
|
|
21407
|
-
selection.moveAnchorCell(direction, ev
|
|
21522
|
+
selection.moveAnchorCell(direction, isCtrlKey(ev) ? "end" : 1);
|
|
21408
21523
|
}
|
|
21409
21524
|
}
|
|
21410
21525
|
|
|
@@ -21471,6 +21586,15 @@
|
|
|
21471
21586
|
*/
|
|
21472
21587
|
class SelectionInput extends owl.Component {
|
|
21473
21588
|
static template = "o-spreadsheet-SelectionInput";
|
|
21589
|
+
static props = {
|
|
21590
|
+
ranges: Function,
|
|
21591
|
+
hasSingleRange: { type: Boolean, optional: true },
|
|
21592
|
+
required: { type: Boolean, optional: true },
|
|
21593
|
+
isInvalid: { type: Boolean, optional: true },
|
|
21594
|
+
class: { type: String, optional: true },
|
|
21595
|
+
onSelectionChanged: { type: Function, optional: true },
|
|
21596
|
+
onSelectionConfirmed: { type: Function, optional: true },
|
|
21597
|
+
};
|
|
21474
21598
|
id = uuidGenerator$1.uuidv4();
|
|
21475
21599
|
previousRanges = this.props.ranges() || [];
|
|
21476
21600
|
originSheet = this.env.model.getters.getActiveSheetId();
|
|
@@ -21633,15 +21757,6 @@
|
|
|
21633
21757
|
this.env.model.dispatch("UNFOCUS_SELECTION_INPUT");
|
|
21634
21758
|
}
|
|
21635
21759
|
}
|
|
21636
|
-
SelectionInput.props = {
|
|
21637
|
-
ranges: Function,
|
|
21638
|
-
hasSingleRange: { type: Boolean, optional: true },
|
|
21639
|
-
required: { type: Boolean, optional: true },
|
|
21640
|
-
isInvalid: { type: Boolean, optional: true },
|
|
21641
|
-
class: { type: String, optional: true },
|
|
21642
|
-
onSelectionChanged: { type: Function, optional: true },
|
|
21643
|
-
onSelectionConfirmed: { type: Function, optional: true },
|
|
21644
|
-
};
|
|
21645
21760
|
|
|
21646
21761
|
css /* scss */ `
|
|
21647
21762
|
.o-validation-error,
|
|
@@ -21657,6 +21772,10 @@
|
|
|
21657
21772
|
`;
|
|
21658
21773
|
class ValidationMessages extends owl.Component {
|
|
21659
21774
|
static template = "o-spreadsheet-ValidationMessages";
|
|
21775
|
+
static props = {
|
|
21776
|
+
messages: Array,
|
|
21777
|
+
msgType: String,
|
|
21778
|
+
};
|
|
21660
21779
|
get divClasses() {
|
|
21661
21780
|
if (this.props.msgType === "warning") {
|
|
21662
21781
|
return "o-validation-warning text-warning";
|
|
@@ -21664,14 +21783,96 @@
|
|
|
21664
21783
|
return "o-validation-error text-danger";
|
|
21665
21784
|
}
|
|
21666
21785
|
}
|
|
21667
|
-
|
|
21668
|
-
|
|
21669
|
-
|
|
21670
|
-
|
|
21786
|
+
|
|
21787
|
+
css /* scss */ `
|
|
21788
|
+
.o-checkbox {
|
|
21789
|
+
display: flex;
|
|
21790
|
+
justify-items: center;
|
|
21791
|
+
input {
|
|
21792
|
+
margin-right: 5px;
|
|
21793
|
+
}
|
|
21794
|
+
}
|
|
21795
|
+
`;
|
|
21796
|
+
class Checkbox extends owl.Component {
|
|
21797
|
+
static template = "o-spreadsheet.Checkbox";
|
|
21798
|
+
static props = {
|
|
21799
|
+
label: { type: String, optional: true },
|
|
21800
|
+
value: { type: Boolean, optional: true },
|
|
21801
|
+
className: { type: String, optional: true },
|
|
21802
|
+
name: { type: String, optional: true },
|
|
21803
|
+
onChange: Function,
|
|
21804
|
+
};
|
|
21805
|
+
static defaultProps = { value: false };
|
|
21806
|
+
onChange(ev) {
|
|
21807
|
+
const value = ev.target.checked;
|
|
21808
|
+
this.props.onChange(value);
|
|
21809
|
+
}
|
|
21810
|
+
}
|
|
21811
|
+
|
|
21812
|
+
class Section extends owl.Component {
|
|
21813
|
+
static template = "o_spreadsheet.Section";
|
|
21814
|
+
static props = {
|
|
21815
|
+
class: { type: String, optional: true },
|
|
21816
|
+
slots: Object,
|
|
21817
|
+
};
|
|
21818
|
+
}
|
|
21819
|
+
|
|
21820
|
+
class ChartDataSeries extends owl.Component {
|
|
21821
|
+
static template = "o-spreadsheet.ChartDataSeries";
|
|
21822
|
+
static components = { SelectionInput, Section };
|
|
21823
|
+
static props = {
|
|
21824
|
+
ranges: Function,
|
|
21825
|
+
hasSingleRange: { type: Boolean, optional: true },
|
|
21826
|
+
onSelectionChanged: Function,
|
|
21827
|
+
onSelectionConfirmed: Function,
|
|
21828
|
+
};
|
|
21829
|
+
get title() {
|
|
21830
|
+
return this.props.hasSingleRange ? _t("Data range") : _t("Data series");
|
|
21831
|
+
}
|
|
21832
|
+
}
|
|
21833
|
+
|
|
21834
|
+
class ChartErrorSection extends owl.Component {
|
|
21835
|
+
static template = "o-spreadsheet.ChartErrorSection";
|
|
21836
|
+
static components = { Section, ValidationMessages };
|
|
21837
|
+
static props = { messages: { type: Array, element: String } };
|
|
21838
|
+
}
|
|
21839
|
+
|
|
21840
|
+
class ChartLabelRange extends owl.Component {
|
|
21841
|
+
static template = "o-spreadsheet.ChartLabelRange";
|
|
21842
|
+
static components = { SelectionInput, Checkbox, Section };
|
|
21843
|
+
static props = {
|
|
21844
|
+
title: { type: String, optional: true },
|
|
21845
|
+
range: Function,
|
|
21846
|
+
isInvalid: Boolean,
|
|
21847
|
+
required: { type: Boolean, optional: true },
|
|
21848
|
+
onSelectionChanged: Function,
|
|
21849
|
+
onSelectionConfirmed: Function,
|
|
21850
|
+
options: { type: Array, optional: true },
|
|
21851
|
+
};
|
|
21852
|
+
static defaultProps = {
|
|
21853
|
+
title: _t("Categories / Labels"),
|
|
21854
|
+
options: [],
|
|
21855
|
+
required: false,
|
|
21856
|
+
};
|
|
21857
|
+
}
|
|
21671
21858
|
|
|
21672
21859
|
class LineBarPieConfigPanel extends owl.Component {
|
|
21673
21860
|
static template = "o-spreadsheet-LineBarPieConfigPanel";
|
|
21674
|
-
static components = {
|
|
21861
|
+
static components = {
|
|
21862
|
+
SelectionInput,
|
|
21863
|
+
ValidationMessages,
|
|
21864
|
+
ChartDataSeries,
|
|
21865
|
+
ChartLabelRange,
|
|
21866
|
+
Section,
|
|
21867
|
+
Checkbox,
|
|
21868
|
+
ChartErrorSection,
|
|
21869
|
+
};
|
|
21870
|
+
static props = {
|
|
21871
|
+
figureId: String,
|
|
21872
|
+
definition: Object,
|
|
21873
|
+
updateChart: Function,
|
|
21874
|
+
canUpdateChart: Function,
|
|
21875
|
+
};
|
|
21675
21876
|
state = owl.useState({
|
|
21676
21877
|
datasetDispatchResult: undefined,
|
|
21677
21878
|
labelsDispatchResult: undefined,
|
|
@@ -21695,9 +21896,22 @@
|
|
|
21695
21896
|
get isLabelInvalid() {
|
|
21696
21897
|
return !!this.state.labelsDispatchResult?.isCancelledBecause("InvalidLabelRange" /* CommandResult.InvalidLabelRange */);
|
|
21697
21898
|
}
|
|
21698
|
-
|
|
21899
|
+
get dataSetsHaveTitleLabel() {
|
|
21900
|
+
return _t("Use row %s as headers", this.calculateHeaderPosition() || "");
|
|
21901
|
+
}
|
|
21902
|
+
getLabelRangeOptions() {
|
|
21903
|
+
return [
|
|
21904
|
+
{
|
|
21905
|
+
name: "aggregated",
|
|
21906
|
+
label: _t("Aggregate"),
|
|
21907
|
+
value: this.props.definition.aggregated,
|
|
21908
|
+
onChange: this.onUpdateAggregated.bind(this),
|
|
21909
|
+
},
|
|
21910
|
+
];
|
|
21911
|
+
}
|
|
21912
|
+
onUpdateDataSetsHaveTitle(dataSetsHaveTitle) {
|
|
21699
21913
|
this.props.updateChart(this.props.figureId, {
|
|
21700
|
-
dataSetsHaveTitle
|
|
21914
|
+
dataSetsHaveTitle,
|
|
21701
21915
|
});
|
|
21702
21916
|
}
|
|
21703
21917
|
/**
|
|
@@ -21737,9 +21951,9 @@
|
|
|
21737
21951
|
getLabelRange() {
|
|
21738
21952
|
return this.labelRange || "";
|
|
21739
21953
|
}
|
|
21740
|
-
onUpdateAggregated(
|
|
21954
|
+
onUpdateAggregated(aggregated) {
|
|
21741
21955
|
this.props.updateChart(this.props.figureId, {
|
|
21742
|
-
aggregated
|
|
21956
|
+
aggregated,
|
|
21743
21957
|
});
|
|
21744
21958
|
}
|
|
21745
21959
|
calculateHeaderPosition() {
|
|
@@ -21759,23 +21973,20 @@
|
|
|
21759
21973
|
return undefined;
|
|
21760
21974
|
}
|
|
21761
21975
|
}
|
|
21762
|
-
LineBarPieConfigPanel.props = {
|
|
21763
|
-
figureId: String,
|
|
21764
|
-
definition: Object,
|
|
21765
|
-
updateChart: Function,
|
|
21766
|
-
canUpdateChart: Function,
|
|
21767
|
-
};
|
|
21768
21976
|
|
|
21769
21977
|
class BarConfigPanel extends LineBarPieConfigPanel {
|
|
21770
21978
|
static template = "o-spreadsheet-BarConfigPanel";
|
|
21771
|
-
|
|
21979
|
+
get stackedLabel() {
|
|
21980
|
+
return _t("Stacked barchart");
|
|
21981
|
+
}
|
|
21982
|
+
onUpdateStacked(stacked) {
|
|
21772
21983
|
this.props.updateChart(this.props.figureId, {
|
|
21773
|
-
stacked
|
|
21984
|
+
stacked,
|
|
21774
21985
|
});
|
|
21775
21986
|
}
|
|
21776
|
-
onUpdateAggregated(
|
|
21987
|
+
onUpdateAggregated(aggregated) {
|
|
21777
21988
|
this.props.updateChart(this.props.figureId, {
|
|
21778
|
-
aggregated
|
|
21989
|
+
aggregated,
|
|
21779
21990
|
});
|
|
21780
21991
|
}
|
|
21781
21992
|
}
|
|
@@ -22103,6 +22314,12 @@
|
|
|
22103
22314
|
`;
|
|
22104
22315
|
class ColorPicker extends owl.Component {
|
|
22105
22316
|
static template = "o-spreadsheet-ColorPicker";
|
|
22317
|
+
static props = {
|
|
22318
|
+
onColorPicked: Function,
|
|
22319
|
+
currentColor: { type: String, optional: true },
|
|
22320
|
+
maxHeight: { type: Number, optional: true },
|
|
22321
|
+
anchorRect: Object,
|
|
22322
|
+
};
|
|
22106
22323
|
static defaultProps = { currentColor: "" };
|
|
22107
22324
|
static components = { Popover };
|
|
22108
22325
|
COLORS = COLOR_PICKER_DEFAULTS;
|
|
@@ -22238,12 +22455,6 @@
|
|
|
22238
22455
|
return isSameColor(color1, color2);
|
|
22239
22456
|
}
|
|
22240
22457
|
}
|
|
22241
|
-
ColorPicker.props = {
|
|
22242
|
-
onColorPicked: Function,
|
|
22243
|
-
currentColor: { type: String, optional: true },
|
|
22244
|
-
maxHeight: { type: Number, optional: true },
|
|
22245
|
-
anchorRect: Object,
|
|
22246
|
-
};
|
|
22247
22458
|
|
|
22248
22459
|
css /* scss */ `
|
|
22249
22460
|
.o-color-picker-widget {
|
|
@@ -22281,6 +22492,17 @@
|
|
|
22281
22492
|
`;
|
|
22282
22493
|
class ColorPickerWidget extends owl.Component {
|
|
22283
22494
|
static template = "o-spreadsheet-ColorPickerWidget";
|
|
22495
|
+
static props = {
|
|
22496
|
+
currentColor: { type: String, optional: true },
|
|
22497
|
+
toggleColorPicker: Function,
|
|
22498
|
+
showColorPicker: Boolean,
|
|
22499
|
+
onColorPicked: Function,
|
|
22500
|
+
icon: String,
|
|
22501
|
+
title: { type: String, optional: true },
|
|
22502
|
+
disabled: { type: Boolean, optional: true },
|
|
22503
|
+
dropdownMaxHeight: { type: Number, optional: true },
|
|
22504
|
+
class: { type: String, optional: true },
|
|
22505
|
+
};
|
|
22284
22506
|
static components = { ColorPicker };
|
|
22285
22507
|
colorPickerButtonRef = owl.useRef("colorPickerButton");
|
|
22286
22508
|
get iconStyle() {
|
|
@@ -22299,44 +22521,55 @@
|
|
|
22299
22521
|
};
|
|
22300
22522
|
}
|
|
22301
22523
|
}
|
|
22302
|
-
ColorPickerWidget.props = {
|
|
22303
|
-
currentColor: { type: String, optional: true },
|
|
22304
|
-
toggleColorPicker: Function,
|
|
22305
|
-
showColorPicker: Boolean,
|
|
22306
|
-
onColorPicked: Function,
|
|
22307
|
-
icon: String,
|
|
22308
|
-
title: { type: String, optional: true },
|
|
22309
|
-
disabled: { type: Boolean, optional: true },
|
|
22310
|
-
dropdownMaxHeight: { type: Number, optional: true },
|
|
22311
|
-
class: { type: String, optional: true },
|
|
22312
|
-
};
|
|
22313
22524
|
|
|
22314
|
-
class
|
|
22315
|
-
static template = "o-spreadsheet
|
|
22316
|
-
static components = { ColorPickerWidget };
|
|
22317
|
-
|
|
22318
|
-
|
|
22319
|
-
|
|
22320
|
-
}
|
|
22321
|
-
|
|
22322
|
-
this.state.fillColorTool = false;
|
|
22323
|
-
}
|
|
22525
|
+
class ChartColor extends owl.Component {
|
|
22526
|
+
static template = "o-spreadsheet.ChartColor";
|
|
22527
|
+
static components = { ColorPickerWidget, Section };
|
|
22528
|
+
static props = {
|
|
22529
|
+
currentColor: { type: String, optional: true },
|
|
22530
|
+
onColorPicked: Function,
|
|
22531
|
+
};
|
|
22532
|
+
state;
|
|
22324
22533
|
setup() {
|
|
22325
|
-
this.state
|
|
22326
|
-
owl.useExternalListener(window, "click", this.
|
|
22534
|
+
this.state = owl.useState({ pickerOpened: false });
|
|
22535
|
+
owl.useExternalListener(window, "click", this.closePicker);
|
|
22327
22536
|
}
|
|
22328
|
-
|
|
22329
|
-
this.state.
|
|
22537
|
+
closePicker() {
|
|
22538
|
+
this.state.pickerOpened = false;
|
|
22539
|
+
}
|
|
22540
|
+
togglePicker() {
|
|
22541
|
+
this.state.pickerOpened = !this.state.pickerOpened;
|
|
22542
|
+
}
|
|
22543
|
+
}
|
|
22544
|
+
|
|
22545
|
+
class ChartTitle extends owl.Component {
|
|
22546
|
+
static template = "o-spreadsheet.ChartTitle";
|
|
22547
|
+
static components = { ColorPickerWidget, Section };
|
|
22548
|
+
static props = { title: String, update: Function };
|
|
22549
|
+
updateTitle(ev) {
|
|
22550
|
+
this.props.update(ev.target.value);
|
|
22551
|
+
}
|
|
22552
|
+
}
|
|
22553
|
+
|
|
22554
|
+
class LineBarPieDesignPanel extends owl.Component {
|
|
22555
|
+
static template = "o-spreadsheet-LineBarPieDesignPanel";
|
|
22556
|
+
static components = { ChartColor, ColorPickerWidget, ChartTitle, Section };
|
|
22557
|
+
static props = {
|
|
22558
|
+
figureId: String,
|
|
22559
|
+
definition: Object,
|
|
22560
|
+
updateChart: Function,
|
|
22561
|
+
canUpdateChart: Function,
|
|
22562
|
+
};
|
|
22563
|
+
get title() {
|
|
22564
|
+
return _t(this.props.definition.title);
|
|
22330
22565
|
}
|
|
22331
22566
|
updateBackgroundColor(color) {
|
|
22332
22567
|
this.props.updateChart(this.props.figureId, {
|
|
22333
22568
|
background: color,
|
|
22334
22569
|
});
|
|
22335
22570
|
}
|
|
22336
|
-
updateTitle() {
|
|
22337
|
-
this.props.updateChart(this.props.figureId, {
|
|
22338
|
-
title: this.state.title,
|
|
22339
|
-
});
|
|
22571
|
+
updateTitle(title) {
|
|
22572
|
+
this.props.updateChart(this.props.figureId, { title });
|
|
22340
22573
|
}
|
|
22341
22574
|
updateSelect(attr, ev) {
|
|
22342
22575
|
this.props.updateChart(this.props.figureId, {
|
|
@@ -22344,12 +22577,6 @@
|
|
|
22344
22577
|
});
|
|
22345
22578
|
}
|
|
22346
22579
|
}
|
|
22347
|
-
LineBarPieDesignPanel.props = {
|
|
22348
|
-
figureId: String,
|
|
22349
|
-
definition: Object,
|
|
22350
|
-
updateChart: Function,
|
|
22351
|
-
canUpdateChart: Function,
|
|
22352
|
-
};
|
|
22353
22580
|
|
|
22354
22581
|
class BarChartDesignPanel extends LineBarPieDesignPanel {
|
|
22355
22582
|
static template = "o-spreadsheet-BarChartDesignPanel";
|
|
@@ -22357,7 +22584,13 @@
|
|
|
22357
22584
|
|
|
22358
22585
|
class GaugeChartConfigPanel extends owl.Component {
|
|
22359
22586
|
static template = "o-spreadsheet-GaugeChartConfigPanel";
|
|
22360
|
-
static components = { SelectionInput,
|
|
22587
|
+
static components = { SelectionInput, ChartErrorSection, ChartDataSeries };
|
|
22588
|
+
static props = {
|
|
22589
|
+
figureId: String,
|
|
22590
|
+
definition: Object,
|
|
22591
|
+
updateChart: Function,
|
|
22592
|
+
canUpdateChart: Function,
|
|
22593
|
+
};
|
|
22361
22594
|
state = owl.useState({
|
|
22362
22595
|
dataRangeDispatchResult: undefined,
|
|
22363
22596
|
});
|
|
@@ -22384,12 +22617,6 @@
|
|
|
22384
22617
|
return this.dataRange || "";
|
|
22385
22618
|
}
|
|
22386
22619
|
}
|
|
22387
|
-
GaugeChartConfigPanel.props = {
|
|
22388
|
-
figureId: String,
|
|
22389
|
-
definition: Object,
|
|
22390
|
-
updateChart: Function,
|
|
22391
|
-
canUpdateChart: Function,
|
|
22392
|
-
};
|
|
22393
22620
|
|
|
22394
22621
|
css /* scss */ `
|
|
22395
22622
|
.o-gauge-color-set {
|
|
@@ -22424,31 +22651,35 @@
|
|
|
22424
22651
|
`;
|
|
22425
22652
|
class GaugeChartDesignPanel extends owl.Component {
|
|
22426
22653
|
static template = "o-spreadsheet-GaugeChartDesignPanel";
|
|
22427
|
-
static components = { ColorPickerWidget,
|
|
22654
|
+
static components = { ColorPickerWidget, ChartErrorSection, ChartColor, ChartTitle, Section };
|
|
22655
|
+
static props = {
|
|
22656
|
+
figureId: String,
|
|
22657
|
+
definition: Object,
|
|
22658
|
+
updateChart: Function,
|
|
22659
|
+
canUpdateChart: Function,
|
|
22660
|
+
};
|
|
22428
22661
|
state = owl.useState({
|
|
22429
|
-
title: "",
|
|
22430
22662
|
openedMenu: undefined,
|
|
22431
22663
|
sectionRuleDispatchResult: undefined,
|
|
22432
22664
|
sectionRule: deepCopy(this.props.definition.sectionRule),
|
|
22433
22665
|
});
|
|
22434
22666
|
setup() {
|
|
22435
|
-
this.state.title = _t(this.props.definition.title);
|
|
22436
22667
|
owl.useExternalListener(window, "click", this.closeMenus);
|
|
22437
22668
|
}
|
|
22669
|
+
get title() {
|
|
22670
|
+
return _t(this.props.definition.title);
|
|
22671
|
+
}
|
|
22438
22672
|
get designErrorMessages() {
|
|
22439
22673
|
const cancelledReasons = [...(this.state.sectionRuleDispatchResult?.reasons || [])];
|
|
22440
22674
|
return cancelledReasons.map((error) => ChartTerms.Errors[error] || ChartTerms.Errors.Unexpected);
|
|
22441
22675
|
}
|
|
22442
22676
|
updateBackgroundColor(color) {
|
|
22443
|
-
this.state.openedMenu = undefined;
|
|
22444
22677
|
this.props.updateChart(this.props.figureId, {
|
|
22445
22678
|
background: color,
|
|
22446
22679
|
});
|
|
22447
22680
|
}
|
|
22448
|
-
updateTitle() {
|
|
22449
|
-
this.props.updateChart(this.props.figureId, {
|
|
22450
|
-
title: this.state.title,
|
|
22451
|
-
});
|
|
22681
|
+
updateTitle(title) {
|
|
22682
|
+
this.props.updateChart(this.props.figureId, { title });
|
|
22452
22683
|
}
|
|
22453
22684
|
isRangeMinInvalid() {
|
|
22454
22685
|
return !!(this.state.sectionRuleDispatchResult?.isCancelledBecause("EmptyGaugeRangeMin" /* CommandResult.EmptyGaugeRangeMin */) ||
|
|
@@ -22498,12 +22729,6 @@
|
|
|
22498
22729
|
this.state.openedMenu = undefined;
|
|
22499
22730
|
}
|
|
22500
22731
|
}
|
|
22501
|
-
GaugeChartDesignPanel.props = {
|
|
22502
|
-
figureId: String,
|
|
22503
|
-
definition: Object,
|
|
22504
|
-
updateChart: Function,
|
|
22505
|
-
canUpdateChart: Function,
|
|
22506
|
-
};
|
|
22507
22732
|
|
|
22508
22733
|
class LineConfigPanel extends LineBarPieConfigPanel {
|
|
22509
22734
|
static template = "o-spreadsheet-LineConfigPanel";
|
|
@@ -22514,24 +22739,42 @@
|
|
|
22514
22739
|
}
|
|
22515
22740
|
return false;
|
|
22516
22741
|
}
|
|
22517
|
-
|
|
22742
|
+
get stackedLabel() {
|
|
22743
|
+
return _t("Stacked linechart");
|
|
22744
|
+
}
|
|
22745
|
+
get cumulativeLabel() {
|
|
22746
|
+
return _t("Cumulative data");
|
|
22747
|
+
}
|
|
22748
|
+
getLabelRangeOptions() {
|
|
22749
|
+
const options = super.getLabelRangeOptions();
|
|
22750
|
+
if (this.canTreatLabelsAsText) {
|
|
22751
|
+
options.push({
|
|
22752
|
+
name: "labelsAsText",
|
|
22753
|
+
value: this.props.definition.labelsAsText,
|
|
22754
|
+
label: _t("Treat labels as text"),
|
|
22755
|
+
onChange: this.onUpdateLabelsAsText.bind(this),
|
|
22756
|
+
});
|
|
22757
|
+
}
|
|
22758
|
+
return options;
|
|
22759
|
+
}
|
|
22760
|
+
onUpdateLabelsAsText(labelsAsText) {
|
|
22518
22761
|
this.props.updateChart(this.props.figureId, {
|
|
22519
|
-
labelsAsText
|
|
22762
|
+
labelsAsText,
|
|
22520
22763
|
});
|
|
22521
22764
|
}
|
|
22522
|
-
onUpdateStacked(
|
|
22765
|
+
onUpdateStacked(stacked) {
|
|
22523
22766
|
this.props.updateChart(this.props.figureId, {
|
|
22524
|
-
stacked
|
|
22767
|
+
stacked,
|
|
22525
22768
|
});
|
|
22526
22769
|
}
|
|
22527
|
-
onUpdateAggregated(
|
|
22770
|
+
onUpdateAggregated(aggregated) {
|
|
22528
22771
|
this.props.updateChart(this.props.figureId, {
|
|
22529
|
-
aggregated
|
|
22772
|
+
aggregated,
|
|
22530
22773
|
});
|
|
22531
22774
|
}
|
|
22532
|
-
onUpdateCumulative(
|
|
22775
|
+
onUpdateCumulative(cumulative) {
|
|
22533
22776
|
this.props.updateChart(this.props.figureId, {
|
|
22534
|
-
cumulative
|
|
22777
|
+
cumulative,
|
|
22535
22778
|
});
|
|
22536
22779
|
}
|
|
22537
22780
|
}
|
|
@@ -22542,7 +22785,13 @@
|
|
|
22542
22785
|
|
|
22543
22786
|
class ScorecardChartConfigPanel extends owl.Component {
|
|
22544
22787
|
static template = "o-spreadsheet-ScorecardChartConfigPanel";
|
|
22545
|
-
static components = { SelectionInput, ValidationMessages };
|
|
22788
|
+
static components = { SelectionInput, ValidationMessages, ChartErrorSection, Section };
|
|
22789
|
+
static props = {
|
|
22790
|
+
figureId: String,
|
|
22791
|
+
definition: Object,
|
|
22792
|
+
updateChart: Function,
|
|
22793
|
+
canUpdateChart: Function,
|
|
22794
|
+
};
|
|
22546
22795
|
state = owl.useState({
|
|
22547
22796
|
keyValueDispatchResult: undefined,
|
|
22548
22797
|
baselineDispatchResult: undefined,
|
|
@@ -22594,28 +22843,27 @@
|
|
|
22594
22843
|
this.props.updateChart(this.props.figureId, { baselineMode: ev.target.value });
|
|
22595
22844
|
}
|
|
22596
22845
|
}
|
|
22597
|
-
ScorecardChartConfigPanel.props = {
|
|
22598
|
-
figureId: String,
|
|
22599
|
-
definition: Object,
|
|
22600
|
-
updateChart: Function,
|
|
22601
|
-
canUpdateChart: Function,
|
|
22602
|
-
};
|
|
22603
22846
|
|
|
22604
22847
|
class ScorecardChartDesignPanel extends owl.Component {
|
|
22605
22848
|
static template = "o-spreadsheet-ScorecardChartDesignPanel";
|
|
22606
|
-
static components = { ColorPickerWidget };
|
|
22849
|
+
static components = { ColorPickerWidget, ChartColor, ChartTitle, Section };
|
|
22850
|
+
static props = {
|
|
22851
|
+
figureId: String,
|
|
22852
|
+
definition: Object,
|
|
22853
|
+
updateChart: Function,
|
|
22854
|
+
canUpdateChart: Function,
|
|
22855
|
+
};
|
|
22607
22856
|
state = owl.useState({
|
|
22608
|
-
title: "",
|
|
22609
22857
|
openedColorPicker: undefined,
|
|
22610
22858
|
});
|
|
22611
22859
|
setup() {
|
|
22612
|
-
this.state.title = _t(this.props.definition.title);
|
|
22613
22860
|
owl.useExternalListener(window, "click", this.closeMenus);
|
|
22614
22861
|
}
|
|
22615
|
-
|
|
22616
|
-
this.props.
|
|
22617
|
-
|
|
22618
|
-
|
|
22862
|
+
get title() {
|
|
22863
|
+
return _t(this.props.definition.title);
|
|
22864
|
+
}
|
|
22865
|
+
updateTitle(title) {
|
|
22866
|
+
this.props.updateChart(this.props.figureId, { title });
|
|
22619
22867
|
}
|
|
22620
22868
|
translate(term) {
|
|
22621
22869
|
return _t(term);
|
|
@@ -22649,12 +22897,6 @@
|
|
|
22649
22897
|
this.state.openedColorPicker = undefined;
|
|
22650
22898
|
}
|
|
22651
22899
|
}
|
|
22652
|
-
ScorecardChartDesignPanel.props = {
|
|
22653
|
-
figureId: String,
|
|
22654
|
-
definition: Object,
|
|
22655
|
-
updateChart: Function,
|
|
22656
|
-
canUpdateChart: Function,
|
|
22657
|
-
};
|
|
22658
22900
|
|
|
22659
22901
|
const chartSidePanelComponentRegistry = new Registry();
|
|
22660
22902
|
chartSidePanelComponentRegistry
|
|
@@ -22705,6 +22947,8 @@
|
|
|
22705
22947
|
`;
|
|
22706
22948
|
class ChartPanel extends owl.Component {
|
|
22707
22949
|
static template = "o-spreadsheet-ChartPanel";
|
|
22950
|
+
static components = { Section };
|
|
22951
|
+
static props = { onCloseSidePanel: Function };
|
|
22708
22952
|
state;
|
|
22709
22953
|
get figureId() {
|
|
22710
22954
|
return this.state.figureId;
|
|
@@ -22791,9 +23035,6 @@
|
|
|
22791
23035
|
this.state.panel = panel;
|
|
22792
23036
|
}
|
|
22793
23037
|
}
|
|
22794
|
-
ChartPanel.props = {
|
|
22795
|
-
onCloseSidePanel: Function,
|
|
22796
|
-
};
|
|
22797
23038
|
|
|
22798
23039
|
css /* scss */ `
|
|
22799
23040
|
.o-spreadsheet {
|
|
@@ -22904,6 +23145,9 @@
|
|
|
22904
23145
|
`;
|
|
22905
23146
|
class IconPicker extends owl.Component {
|
|
22906
23147
|
static template = "o-spreadsheet-IconPicker";
|
|
23148
|
+
static props = {
|
|
23149
|
+
onIconPicked: Function,
|
|
23150
|
+
};
|
|
22907
23151
|
icons = ICONS;
|
|
22908
23152
|
iconSets = ICON_SETS;
|
|
22909
23153
|
onIconClick(icon) {
|
|
@@ -22912,9 +23156,6 @@
|
|
|
22912
23156
|
}
|
|
22913
23157
|
}
|
|
22914
23158
|
}
|
|
22915
|
-
IconPicker.props = {
|
|
22916
|
-
onIconPicked: Function,
|
|
22917
|
-
};
|
|
22918
23159
|
|
|
22919
23160
|
function useDragAndDropListItems() {
|
|
22920
23161
|
let dndHelper;
|
|
@@ -23269,6 +23510,11 @@
|
|
|
23269
23510
|
`;
|
|
23270
23511
|
class ConditionalFormatPreviewList extends owl.Component {
|
|
23271
23512
|
static template = "o-spreadsheet-ConditionalFormatPreviewList";
|
|
23513
|
+
static props = {
|
|
23514
|
+
conditionalFormats: Array,
|
|
23515
|
+
onPreviewClick: Function,
|
|
23516
|
+
onAddConditionalFormat: Function,
|
|
23517
|
+
};
|
|
23272
23518
|
icons = ICONS;
|
|
23273
23519
|
dragAndDrop = useDragAndDropListItems();
|
|
23274
23520
|
cfListRef = owl.useRef("cfList");
|
|
@@ -23349,11 +23595,6 @@
|
|
|
23349
23595
|
}
|
|
23350
23596
|
}
|
|
23351
23597
|
}
|
|
23352
|
-
ConditionalFormatPreviewList.props = {
|
|
23353
|
-
conditionalFormats: Array,
|
|
23354
|
-
onPreviewClick: Function,
|
|
23355
|
-
onAddConditionalFormat: Function,
|
|
23356
|
-
};
|
|
23357
23598
|
|
|
23358
23599
|
css /* scss */ `
|
|
23359
23600
|
label {
|
|
@@ -23526,11 +23767,16 @@
|
|
|
23526
23767
|
`;
|
|
23527
23768
|
class ConditionalFormattingEditor extends owl.Component {
|
|
23528
23769
|
static template = "o-spreadsheet-ConditionalFormattingEditor";
|
|
23770
|
+
static props = {
|
|
23771
|
+
editedCf: { type: Object, optional: true },
|
|
23772
|
+
onExitEdition: Function,
|
|
23773
|
+
};
|
|
23529
23774
|
static components = {
|
|
23530
23775
|
SelectionInput,
|
|
23531
23776
|
IconPicker,
|
|
23532
23777
|
ColorPickerWidget,
|
|
23533
23778
|
ConditionalFormatPreviewList,
|
|
23779
|
+
Section,
|
|
23534
23780
|
};
|
|
23535
23781
|
icons = ICONS;
|
|
23536
23782
|
cellIsOperators = CellIsOperators;
|
|
@@ -23790,13 +24036,13 @@
|
|
|
23790
24036
|
this.state.rules.iconSet.icons[target] = icon;
|
|
23791
24037
|
}
|
|
23792
24038
|
}
|
|
23793
|
-
ConditionalFormattingEditor.props = {
|
|
23794
|
-
editedCf: { type: Object, optional: true },
|
|
23795
|
-
onExitEdition: Function,
|
|
23796
|
-
};
|
|
23797
24039
|
|
|
23798
24040
|
class ConditionalFormattingPanel extends owl.Component {
|
|
23799
24041
|
static template = "o-spreadsheet-ConditionalFormattingPanel";
|
|
24042
|
+
static props = {
|
|
24043
|
+
selection: { type: Object, optional: true },
|
|
24044
|
+
onCloseSidePanel: Function,
|
|
24045
|
+
};
|
|
23800
24046
|
static components = {
|
|
23801
24047
|
ConditionalFormatPreviewList,
|
|
23802
24048
|
ConditionalFormattingEditor,
|
|
@@ -23855,10 +24101,6 @@
|
|
|
23855
24101
|
this.state.editedCf = cf;
|
|
23856
24102
|
}
|
|
23857
24103
|
}
|
|
23858
|
-
ConditionalFormattingPanel.props = {
|
|
23859
|
-
selection: { type: Object, optional: true },
|
|
23860
|
-
onCloseSidePanel: Function,
|
|
23861
|
-
};
|
|
23862
24104
|
|
|
23863
24105
|
css /* scss */ `
|
|
23864
24106
|
.o-custom-currency {
|
|
@@ -23869,6 +24111,8 @@
|
|
|
23869
24111
|
`;
|
|
23870
24112
|
class CustomCurrencyPanel extends owl.Component {
|
|
23871
24113
|
static template = "o-spreadsheet-CustomCurrencyPanel";
|
|
24114
|
+
static components = { Section };
|
|
24115
|
+
static props = { onCloseSidePanel: Function };
|
|
23872
24116
|
availableCurrencies;
|
|
23873
24117
|
state;
|
|
23874
24118
|
setup() {
|
|
@@ -23991,9 +24235,6 @@
|
|
|
23991
24235
|
return currency.name + (currency.code ? ` (${currency.code})` : "");
|
|
23992
24236
|
}
|
|
23993
24237
|
}
|
|
23994
|
-
CustomCurrencyPanel.props = {
|
|
23995
|
-
onCloseSidePanel: Function,
|
|
23996
|
-
};
|
|
23997
24238
|
|
|
23998
24239
|
css /* scss */ `
|
|
23999
24240
|
.o-find-and-replace {
|
|
@@ -24013,11 +24254,20 @@
|
|
|
24013
24254
|
padding: 4px 0 4px 4px;
|
|
24014
24255
|
}
|
|
24015
24256
|
}
|
|
24257
|
+
|
|
24258
|
+
.o-matches-count div {
|
|
24259
|
+
text-overflow: ellipsis;
|
|
24260
|
+
overflow: hidden;
|
|
24261
|
+
white-space: nowrap;
|
|
24262
|
+
}
|
|
24016
24263
|
}
|
|
24017
24264
|
`;
|
|
24018
24265
|
class FindAndReplacePanel extends owl.Component {
|
|
24019
24266
|
static template = "o-spreadsheet-FindAndReplacePanel";
|
|
24020
|
-
static components = { SelectionInput };
|
|
24267
|
+
static components = { SelectionInput, Section, Checkbox };
|
|
24268
|
+
static props = {
|
|
24269
|
+
onCloseSidePanel: Function,
|
|
24270
|
+
};
|
|
24021
24271
|
debounceTimeoutId;
|
|
24022
24272
|
initialShowFormulaState = false;
|
|
24023
24273
|
dataRange = "";
|
|
@@ -24092,19 +24342,16 @@
|
|
|
24092
24342
|
this.replace();
|
|
24093
24343
|
}
|
|
24094
24344
|
}
|
|
24095
|
-
searchFormulas(
|
|
24096
|
-
const showFormula = ev.target.checked;
|
|
24345
|
+
searchFormulas(showFormula) {
|
|
24097
24346
|
this.env.model.dispatch("SET_FORMULA_VISIBILITY", {
|
|
24098
24347
|
show: showFormula,
|
|
24099
24348
|
});
|
|
24100
24349
|
this.updateSearch({ searchFormulas: showFormula });
|
|
24101
24350
|
}
|
|
24102
|
-
searchExactMatch(
|
|
24103
|
-
const exactMatch = ev.target.checked;
|
|
24351
|
+
searchExactMatch(exactMatch) {
|
|
24104
24352
|
this.updateSearch({ exactMatch });
|
|
24105
24353
|
}
|
|
24106
|
-
searchMatchCase(
|
|
24107
|
-
const matchCase = ev.target.checked;
|
|
24354
|
+
searchMatchCase(matchCase) {
|
|
24108
24355
|
this.updateSearch({ matchCase });
|
|
24109
24356
|
}
|
|
24110
24357
|
changeSearchScope(ev) {
|
|
@@ -24157,9 +24404,6 @@
|
|
|
24157
24404
|
});
|
|
24158
24405
|
}
|
|
24159
24406
|
}
|
|
24160
|
-
FindAndReplacePanel.props = {
|
|
24161
|
-
onCloseSidePanel: Function,
|
|
24162
|
-
};
|
|
24163
24407
|
|
|
24164
24408
|
css /* scss */ `
|
|
24165
24409
|
.o-more-formats-panel {
|
|
@@ -24191,13 +24435,13 @@
|
|
|
24191
24435
|
]);
|
|
24192
24436
|
class MoreFormatsPanel extends owl.Component {
|
|
24193
24437
|
static template = "o-spreadsheet-MoreFormatsPanel";
|
|
24438
|
+
static props = {
|
|
24439
|
+
onCloseSidePanel: Function,
|
|
24440
|
+
};
|
|
24194
24441
|
get dateFormatsActions() {
|
|
24195
24442
|
return DATE_FORMAT_ACTIONS;
|
|
24196
24443
|
}
|
|
24197
24444
|
}
|
|
24198
|
-
MoreFormatsPanel.props = {
|
|
24199
|
-
onCloseSidePanel: Function,
|
|
24200
|
-
};
|
|
24201
24445
|
|
|
24202
24446
|
css /* scss */ `
|
|
24203
24447
|
.o-checkbox-selection {
|
|
@@ -24206,7 +24450,7 @@
|
|
|
24206
24450
|
`;
|
|
24207
24451
|
class RemoveDuplicatesPanel extends owl.Component {
|
|
24208
24452
|
static template = "o-spreadsheet-RemoveDuplicatesPanel";
|
|
24209
|
-
static components = { ValidationMessages };
|
|
24453
|
+
static components = { ValidationMessages, Section, Checkbox };
|
|
24210
24454
|
state = owl.useState({
|
|
24211
24455
|
hasHeader: false,
|
|
24212
24456
|
columns: {},
|
|
@@ -24295,6 +24539,8 @@
|
|
|
24295
24539
|
`;
|
|
24296
24540
|
class SettingsPanel extends owl.Component {
|
|
24297
24541
|
static template = "o-spreadsheet-SettingsPanel";
|
|
24542
|
+
static components = { Section };
|
|
24543
|
+
static props = { onCloseSidePanel: Function };
|
|
24298
24544
|
loadedLocales = [];
|
|
24299
24545
|
setup() {
|
|
24300
24546
|
owl.onWillStart(() => this.loadLocales());
|
|
@@ -24343,9 +24589,6 @@
|
|
|
24343
24589
|
return this.loadedLocales;
|
|
24344
24590
|
}
|
|
24345
24591
|
}
|
|
24346
|
-
SettingsPanel.props = {
|
|
24347
|
-
onCloseSidePanel: Function,
|
|
24348
|
-
};
|
|
24349
24592
|
|
|
24350
24593
|
const SplitToColumnsInteractiveContent = {
|
|
24351
24594
|
SplitIsDestructive: _t("This will overwrite data in the subsequent columns. Split anyway?"),
|
|
@@ -24441,7 +24684,7 @@
|
|
|
24441
24684
|
return false;
|
|
24442
24685
|
}
|
|
24443
24686
|
if (["lastWeek", "lastMonth", "lastYear"].includes(criterion.dateValue)) {
|
|
24444
|
-
const today = jsDateToRoundNumber(
|
|
24687
|
+
const today = jsDateToRoundNumber(DateTime.now());
|
|
24445
24688
|
return isDateBetween(dateValue, today, criterionValue);
|
|
24446
24689
|
}
|
|
24447
24690
|
return areDatesSameDay(dateValue, criterionValue);
|
|
@@ -24933,7 +25176,8 @@
|
|
|
24933
25176
|
];
|
|
24934
25177
|
class SplitIntoColumnsPanel extends owl.Component {
|
|
24935
25178
|
static template = "o-spreadsheet-SplitIntoColumnsPanel";
|
|
24936
|
-
static components = { ValidationMessages };
|
|
25179
|
+
static components = { ValidationMessages, Section, Checkbox };
|
|
25180
|
+
static props = { onCloseSidePanel: Function };
|
|
24937
25181
|
state = owl.useState({ separatorValue: "auto", addNewColumns: false, customSeparator: "" });
|
|
24938
25182
|
setup() {
|
|
24939
25183
|
owl.onWillUpdateProps(() => {
|
|
@@ -24955,10 +25199,8 @@
|
|
|
24955
25199
|
return;
|
|
24956
25200
|
this.state.customSeparator = ev.target.value;
|
|
24957
25201
|
}
|
|
24958
|
-
updateAddNewColumnsCheckbox(
|
|
24959
|
-
|
|
24960
|
-
return;
|
|
24961
|
-
this.state.addNewColumns = ev.target.checked;
|
|
25202
|
+
updateAddNewColumnsCheckbox(addNewColumns) {
|
|
25203
|
+
this.state.addNewColumns = addNewColumns;
|
|
24962
25204
|
}
|
|
24963
25205
|
confirm() {
|
|
24964
25206
|
const result = interactiveSplitToColumns(this.env, this.separatorValue, this.state.addNewColumns);
|
|
@@ -25012,13 +25254,15 @@
|
|
|
25012
25254
|
return !this.separatorValue || this.errorMessages.length > 0;
|
|
25013
25255
|
}
|
|
25014
25256
|
}
|
|
25015
|
-
SplitIntoColumnsPanel.props = {
|
|
25016
|
-
onCloseSidePanel: Function,
|
|
25017
|
-
};
|
|
25018
25257
|
|
|
25019
25258
|
/** This component looks like a select input, but on click it opens a Menu with the items given as props instead of a dropdown */
|
|
25020
25259
|
class SelectMenu extends owl.Component {
|
|
25021
25260
|
static template = "o-spreadsheet-SelectMenu";
|
|
25261
|
+
static props = {
|
|
25262
|
+
menuItems: Array,
|
|
25263
|
+
selectedValue: String,
|
|
25264
|
+
class: { type: String, optional: true },
|
|
25265
|
+
};
|
|
25022
25266
|
static components = { Menu };
|
|
25023
25267
|
selectRef = owl.useRef("select");
|
|
25024
25268
|
selectRect = useAbsoluteBoundingRect(this.selectRef);
|
|
@@ -25038,13 +25282,12 @@
|
|
|
25038
25282
|
};
|
|
25039
25283
|
}
|
|
25040
25284
|
}
|
|
25041
|
-
SelectMenu.props = {
|
|
25042
|
-
menuItems: Array,
|
|
25043
|
-
selectedValue: String,
|
|
25044
|
-
class: { type: String, optional: true },
|
|
25045
|
-
};
|
|
25046
25285
|
|
|
25047
25286
|
class DataValidationCriterionForm extends owl.Component {
|
|
25287
|
+
static props = {
|
|
25288
|
+
criterion: Object,
|
|
25289
|
+
onCriterionChanged: Function,
|
|
25290
|
+
};
|
|
25048
25291
|
setup() {
|
|
25049
25292
|
owl.onMounted(() => {
|
|
25050
25293
|
interactiveStopEdition(this.env);
|
|
@@ -25058,10 +25301,6 @@
|
|
|
25058
25301
|
this.props.onCriterionChanged(filteredCriterion);
|
|
25059
25302
|
}
|
|
25060
25303
|
}
|
|
25061
|
-
DataValidationCriterionForm.props = {
|
|
25062
|
-
criterion: Object,
|
|
25063
|
-
onCriterionChanged: Function,
|
|
25064
|
-
};
|
|
25065
25304
|
|
|
25066
25305
|
css /* scss */ `
|
|
25067
25306
|
.o-dv-input {
|
|
@@ -25076,6 +25315,15 @@
|
|
|
25076
25315
|
`;
|
|
25077
25316
|
class DataValidationInput extends owl.Component {
|
|
25078
25317
|
static template = "o-spreadsheet-DataValidationInput";
|
|
25318
|
+
static props = {
|
|
25319
|
+
value: { type: String, optional: true },
|
|
25320
|
+
criterionType: String,
|
|
25321
|
+
onValueChanged: Function,
|
|
25322
|
+
onKeyDown: { type: Function, optional: true },
|
|
25323
|
+
focused: { type: Boolean, optional: true },
|
|
25324
|
+
onBlur: { type: Function, optional: true },
|
|
25325
|
+
onFocus: { type: Function, optional: true },
|
|
25326
|
+
};
|
|
25079
25327
|
static defaultProps = {
|
|
25080
25328
|
value: "",
|
|
25081
25329
|
onKeyDown: () => { },
|
|
@@ -25114,15 +25362,6 @@
|
|
|
25114
25362
|
return this.env.model.getters.getDataValidationInvalidCriterionValueMessage(this.props.criterionType, canonicalizeContent(this.props.value, this.env.model.getters.getLocale()));
|
|
25115
25363
|
}
|
|
25116
25364
|
}
|
|
25117
|
-
DataValidationInput.props = {
|
|
25118
|
-
value: { type: String, optional: true },
|
|
25119
|
-
criterionType: String,
|
|
25120
|
-
onValueChanged: Function,
|
|
25121
|
-
onKeyDown: { type: Function, optional: true },
|
|
25122
|
-
focused: { type: Boolean, optional: true },
|
|
25123
|
-
onBlur: { type: Function, optional: true },
|
|
25124
|
-
onFocus: { type: Function, optional: true },
|
|
25125
|
-
};
|
|
25126
25365
|
|
|
25127
25366
|
const DATES_VALUES = {
|
|
25128
25367
|
today: _t("today"),
|
|
@@ -25458,7 +25697,11 @@
|
|
|
25458
25697
|
`;
|
|
25459
25698
|
class DataValidationEditor extends owl.Component {
|
|
25460
25699
|
static template = "o-spreadsheet-DataValidationEditor";
|
|
25461
|
-
static components = { SelectionInput, SelectMenu };
|
|
25700
|
+
static components = { SelectionInput, SelectMenu, Section };
|
|
25701
|
+
static props = {
|
|
25702
|
+
rule: { type: Object, optional: true },
|
|
25703
|
+
onExit: Function,
|
|
25704
|
+
};
|
|
25462
25705
|
state = owl.useState({ rule: this.defaultDataValidationRule });
|
|
25463
25706
|
setup() {
|
|
25464
25707
|
if (this.props.rule) {
|
|
@@ -25534,10 +25777,6 @@
|
|
|
25534
25777
|
return dataValidationPanelCriteriaRegistry.get(this.state.rule.criterion.type).component;
|
|
25535
25778
|
}
|
|
25536
25779
|
}
|
|
25537
|
-
DataValidationEditor.props = {
|
|
25538
|
-
rule: { type: Object, optional: true },
|
|
25539
|
-
onExit: Function,
|
|
25540
|
-
};
|
|
25541
25780
|
|
|
25542
25781
|
css /* scss */ `
|
|
25543
25782
|
.o-sidePanel {
|
|
@@ -25567,6 +25806,10 @@
|
|
|
25567
25806
|
`;
|
|
25568
25807
|
class DataValidationPreview extends owl.Component {
|
|
25569
25808
|
static template = "o-spreadsheet-DataValidationPreview";
|
|
25809
|
+
static props = {
|
|
25810
|
+
onClick: Function,
|
|
25811
|
+
rule: Object,
|
|
25812
|
+
};
|
|
25570
25813
|
deleteDataValidation() {
|
|
25571
25814
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
25572
25815
|
this.env.model.dispatch("REMOVE_DATA_VALIDATION_RULE", { sheetId, id: this.props.rule.id });
|
|
@@ -25583,13 +25826,12 @@
|
|
|
25583
25826
|
.getPreview(this.props.rule.criterion, this.env.model.getters);
|
|
25584
25827
|
}
|
|
25585
25828
|
}
|
|
25586
|
-
DataValidationPreview.props = {
|
|
25587
|
-
onClick: Function,
|
|
25588
|
-
rule: Object,
|
|
25589
|
-
};
|
|
25590
25829
|
|
|
25591
25830
|
class DataValidationPanel extends owl.Component {
|
|
25592
25831
|
static template = "o-spreadsheet-DataValidationPanel";
|
|
25832
|
+
static props = {
|
|
25833
|
+
onCloseSidePanel: Function,
|
|
25834
|
+
};
|
|
25593
25835
|
static components = { DataValidationPreview, DataValidationEditor };
|
|
25594
25836
|
state = owl.useState({ mode: "list", activeRule: undefined });
|
|
25595
25837
|
onPreviewClick(id) {
|
|
@@ -25619,9 +25861,6 @@
|
|
|
25619
25861
|
return this.env.model.getters.getDataValidationRules(sheetId);
|
|
25620
25862
|
}
|
|
25621
25863
|
}
|
|
25622
|
-
DataValidationPanel.props = {
|
|
25623
|
-
onCloseSidePanel: Function,
|
|
25624
|
-
};
|
|
25625
25864
|
|
|
25626
25865
|
const sidePanelRegistry = new Registry();
|
|
25627
25866
|
sidePanelRegistry.add("ConditionalFormatting", {
|
|
@@ -25753,6 +25992,13 @@
|
|
|
25753
25992
|
`;
|
|
25754
25993
|
class FigureComponent extends owl.Component {
|
|
25755
25994
|
static template = "o-spreadsheet-FigureComponent";
|
|
25995
|
+
static props = {
|
|
25996
|
+
figure: Object,
|
|
25997
|
+
style: { type: String, optional: true },
|
|
25998
|
+
onFigureDeleted: { type: Function, optional: true },
|
|
25999
|
+
onMouseDown: { type: Function, optional: true },
|
|
26000
|
+
onClickAnchor: { type: Function, optional: true },
|
|
26001
|
+
};
|
|
25756
26002
|
static components = { Menu };
|
|
25757
26003
|
static defaultProps = {
|
|
25758
26004
|
onFigureDeleted: () => { },
|
|
@@ -25895,13 +26141,6 @@
|
|
|
25895
26141
|
.menuBuilder(this.props.figure.id, this.props.onFigureDeleted, this.env);
|
|
25896
26142
|
}
|
|
25897
26143
|
}
|
|
25898
|
-
FigureComponent.props = {
|
|
25899
|
-
figure: Object,
|
|
25900
|
-
style: { type: String, optional: true },
|
|
25901
|
-
onFigureDeleted: { type: Function, optional: true },
|
|
25902
|
-
onMouseDown: { type: Function, optional: true },
|
|
25903
|
-
onClickAnchor: { type: Function, optional: true },
|
|
25904
|
-
};
|
|
25905
26144
|
|
|
25906
26145
|
const ToggleGroupInteractiveContent = {
|
|
25907
26146
|
CannotHideAllRows: _t("Cannot hide all the rows of a sheet."),
|
|
@@ -26039,6 +26278,10 @@
|
|
|
26039
26278
|
`;
|
|
26040
26279
|
class Autofill extends owl.Component {
|
|
26041
26280
|
static template = "o-spreadsheet-Autofill";
|
|
26281
|
+
static props = {
|
|
26282
|
+
position: Object,
|
|
26283
|
+
isVisible: Boolean,
|
|
26284
|
+
};
|
|
26042
26285
|
state = owl.useState({
|
|
26043
26286
|
position: { left: 0, top: 0 },
|
|
26044
26287
|
handler: false,
|
|
@@ -26107,18 +26350,14 @@
|
|
|
26107
26350
|
this.env.model.dispatch("AUTOFILL_AUTO");
|
|
26108
26351
|
}
|
|
26109
26352
|
}
|
|
26110
|
-
Autofill.props = {
|
|
26111
|
-
position: Object,
|
|
26112
|
-
isVisible: Boolean,
|
|
26113
|
-
};
|
|
26114
26353
|
class TooltipComponent extends owl.Component {
|
|
26354
|
+
static props = {
|
|
26355
|
+
content: String,
|
|
26356
|
+
};
|
|
26115
26357
|
static template = owl.xml /* xml */ `
|
|
26116
26358
|
<div t-esc="props.content"/>
|
|
26117
26359
|
`;
|
|
26118
26360
|
}
|
|
26119
|
-
TooltipComponent.props = {
|
|
26120
|
-
content: String,
|
|
26121
|
-
};
|
|
26122
26361
|
|
|
26123
26362
|
css /* scss */ `
|
|
26124
26363
|
.o-client-tag {
|
|
@@ -26132,6 +26371,13 @@
|
|
|
26132
26371
|
`;
|
|
26133
26372
|
class ClientTag extends owl.Component {
|
|
26134
26373
|
static template = "o-spreadsheet-ClientTag";
|
|
26374
|
+
static props = {
|
|
26375
|
+
active: Boolean,
|
|
26376
|
+
name: String,
|
|
26377
|
+
color: String,
|
|
26378
|
+
col: Number,
|
|
26379
|
+
row: Number,
|
|
26380
|
+
};
|
|
26135
26381
|
get tagStyle() {
|
|
26136
26382
|
const { col, row, color } = this.props;
|
|
26137
26383
|
const { height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
|
@@ -26149,13 +26395,6 @@
|
|
|
26149
26395
|
});
|
|
26150
26396
|
}
|
|
26151
26397
|
}
|
|
26152
|
-
ClientTag.props = {
|
|
26153
|
-
active: Boolean,
|
|
26154
|
-
name: String,
|
|
26155
|
-
color: String,
|
|
26156
|
-
col: Number,
|
|
26157
|
-
row: Number,
|
|
26158
|
-
};
|
|
26159
26398
|
|
|
26160
26399
|
function getHtmlContentFromPattern(pattern, value, highlightColor, className) {
|
|
26161
26400
|
const pendingHtmlContent = [];
|
|
@@ -26195,14 +26434,14 @@
|
|
|
26195
26434
|
`;
|
|
26196
26435
|
class TextValueProvider extends owl.Component {
|
|
26197
26436
|
static template = "o-spreadsheet-TextValueProvider";
|
|
26437
|
+
static props = {
|
|
26438
|
+
values: Array,
|
|
26439
|
+
selectedIndex: { type: Number, optional: true },
|
|
26440
|
+
getHtmlContent: Function,
|
|
26441
|
+
onValueSelected: Function,
|
|
26442
|
+
onValueHovered: Function,
|
|
26443
|
+
};
|
|
26198
26444
|
}
|
|
26199
|
-
TextValueProvider.props = {
|
|
26200
|
-
values: Array,
|
|
26201
|
-
selectedIndex: { type: Number, optional: true },
|
|
26202
|
-
getHtmlContent: Function,
|
|
26203
|
-
onValueSelected: Function,
|
|
26204
|
-
onValueHovered: Function,
|
|
26205
|
-
};
|
|
26206
26445
|
|
|
26207
26446
|
class ContentEditableHelper {
|
|
26208
26447
|
// todo make el private and expose dedicated methods
|
|
@@ -26564,6 +26803,11 @@
|
|
|
26564
26803
|
`;
|
|
26565
26804
|
class FunctionDescriptionProvider extends owl.Component {
|
|
26566
26805
|
static template = "o-spreadsheet-FunctionDescriptionProvider";
|
|
26806
|
+
static props = {
|
|
26807
|
+
functionName: String,
|
|
26808
|
+
functionDescription: Object,
|
|
26809
|
+
argToFocus: Number,
|
|
26810
|
+
};
|
|
26567
26811
|
assistantState = owl.useState({
|
|
26568
26812
|
allowCellSelectionBehind: false,
|
|
26569
26813
|
});
|
|
@@ -26588,11 +26832,6 @@
|
|
|
26588
26832
|
}, 2000);
|
|
26589
26833
|
}
|
|
26590
26834
|
}
|
|
26591
|
-
FunctionDescriptionProvider.props = {
|
|
26592
|
-
functionName: String,
|
|
26593
|
-
functionDescription: Object,
|
|
26594
|
-
argToFocus: Number,
|
|
26595
|
-
};
|
|
26596
26835
|
|
|
26597
26836
|
const functions$2 = functionRegistry.content;
|
|
26598
26837
|
const ASSISTANT_WIDTH = 300;
|
|
@@ -26658,6 +26897,16 @@
|
|
|
26658
26897
|
`;
|
|
26659
26898
|
class Composer extends owl.Component {
|
|
26660
26899
|
static template = "o-spreadsheet-Composer";
|
|
26900
|
+
static props = {
|
|
26901
|
+
focus: {
|
|
26902
|
+
validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value),
|
|
26903
|
+
},
|
|
26904
|
+
onComposerContentFocused: Function,
|
|
26905
|
+
inputStyle: { type: String, optional: true },
|
|
26906
|
+
rect: { type: Object, optional: true },
|
|
26907
|
+
delimitation: { type: Object, optional: true },
|
|
26908
|
+
onComposerUnmounted: { type: Function, optional: true },
|
|
26909
|
+
};
|
|
26661
26910
|
static components = { TextValueProvider, FunctionDescriptionProvider };
|
|
26662
26911
|
static defaultProps = {
|
|
26663
26912
|
inputStyle: "",
|
|
@@ -27214,14 +27463,6 @@
|
|
|
27214
27463
|
this.autoCompleteState.getHtmlContent = (value) => [{ value }];
|
|
27215
27464
|
}
|
|
27216
27465
|
}
|
|
27217
|
-
Composer.props = {
|
|
27218
|
-
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
27219
|
-
onComposerContentFocused: Function,
|
|
27220
|
-
inputStyle: { type: String, optional: true },
|
|
27221
|
-
rect: { type: Object, optional: true },
|
|
27222
|
-
delimitation: { type: Object, optional: true },
|
|
27223
|
-
onComposerUnmounted: { type: Function, optional: true },
|
|
27224
|
-
};
|
|
27225
27466
|
|
|
27226
27467
|
const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
|
|
27227
27468
|
const GRID_CELL_REFERENCE_TOP_OFFSET = 28;
|
|
@@ -27253,6 +27494,14 @@
|
|
|
27253
27494
|
*/
|
|
27254
27495
|
class GridComposer extends owl.Component {
|
|
27255
27496
|
static template = "o-spreadsheet-GridComposer";
|
|
27497
|
+
static props = {
|
|
27498
|
+
focus: {
|
|
27499
|
+
validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value),
|
|
27500
|
+
},
|
|
27501
|
+
onComposerUnmounted: Function,
|
|
27502
|
+
onComposerContentFocused: Function,
|
|
27503
|
+
gridDims: Object,
|
|
27504
|
+
};
|
|
27256
27505
|
static components = { Composer };
|
|
27257
27506
|
gridComposerRef;
|
|
27258
27507
|
zone;
|
|
@@ -27359,22 +27608,22 @@
|
|
|
27359
27608
|
});
|
|
27360
27609
|
}
|
|
27361
27610
|
}
|
|
27362
|
-
GridComposer.props = {
|
|
27363
|
-
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
27364
|
-
onComposerUnmounted: Function,
|
|
27365
|
-
onComposerContentFocused: Function,
|
|
27366
|
-
gridDims: Object,
|
|
27367
|
-
};
|
|
27368
27611
|
|
|
27369
|
-
|
|
27612
|
+
css /* scss */ `
|
|
27370
27613
|
.o-grid-cell-icon {
|
|
27371
27614
|
width: ${GRID_ICON_EDGE_LENGTH}px;
|
|
27372
27615
|
height: ${GRID_ICON_EDGE_LENGTH}px;
|
|
27373
27616
|
}
|
|
27374
27617
|
`;
|
|
27375
27618
|
class GridCellIcon extends owl.Component {
|
|
27376
|
-
static style = CSS$1;
|
|
27377
27619
|
static template = "o-spreadsheet-GridCellIcon";
|
|
27620
|
+
static props = {
|
|
27621
|
+
cellPosition: Object,
|
|
27622
|
+
horizontalAlign: { type: String, optional: true },
|
|
27623
|
+
verticalAlign: { type: String, optional: true },
|
|
27624
|
+
offset: { type: Object, optional: true },
|
|
27625
|
+
slots: Object,
|
|
27626
|
+
};
|
|
27378
27627
|
get iconStyle() {
|
|
27379
27628
|
const x = this.getIconHorizontalPosition();
|
|
27380
27629
|
const y = this.getIconVerticalPosition();
|
|
@@ -27423,15 +27672,8 @@
|
|
|
27423
27672
|
return !(rect.width === 0 || rect.height === 0);
|
|
27424
27673
|
}
|
|
27425
27674
|
}
|
|
27426
|
-
GridCellIcon.props = {
|
|
27427
|
-
cellPosition: Object,
|
|
27428
|
-
horizontalAlign: { type: String, optional: true },
|
|
27429
|
-
verticalAlign: { type: String, optional: true },
|
|
27430
|
-
offset: { type: Object, optional: true },
|
|
27431
|
-
slots: Object,
|
|
27432
|
-
};
|
|
27433
27675
|
|
|
27434
|
-
|
|
27676
|
+
css /* scss */ `
|
|
27435
27677
|
.o-filter-icon {
|
|
27436
27678
|
color: ${FILTERS_COLOR};
|
|
27437
27679
|
display: flex;
|
|
@@ -27446,8 +27688,10 @@
|
|
|
27446
27688
|
}
|
|
27447
27689
|
`;
|
|
27448
27690
|
class FilterIcon extends owl.Component {
|
|
27449
|
-
static style = CSS;
|
|
27450
27691
|
static template = "o-spreadsheet-FilterIcon";
|
|
27692
|
+
static props = {
|
|
27693
|
+
cellPosition: Object,
|
|
27694
|
+
};
|
|
27451
27695
|
onClick() {
|
|
27452
27696
|
const position = this.props.cellPosition;
|
|
27453
27697
|
const activePopoverType = this.env.model.getters.getPersistentPopoverTypeAtPosition(position);
|
|
@@ -27466,12 +27710,12 @@
|
|
|
27466
27710
|
return this.env.model.getters.isFilterActive(this.props.cellPosition);
|
|
27467
27711
|
}
|
|
27468
27712
|
}
|
|
27469
|
-
FilterIcon.props = {
|
|
27470
|
-
cellPosition: Object,
|
|
27471
|
-
};
|
|
27472
27713
|
|
|
27473
27714
|
class FilterIconsOverlay extends owl.Component {
|
|
27474
27715
|
static template = "o-spreadsheet-FilterIconsOverlay";
|
|
27716
|
+
static props = {
|
|
27717
|
+
gridPosition: { type: Object, optional: true },
|
|
27718
|
+
};
|
|
27475
27719
|
static components = {
|
|
27476
27720
|
GridCellIcon,
|
|
27477
27721
|
FilterIcon,
|
|
@@ -27485,9 +27729,6 @@
|
|
|
27485
27729
|
return headerPositions.map((position) => ({ sheetId, ...position }));
|
|
27486
27730
|
}
|
|
27487
27731
|
}
|
|
27488
|
-
FilterIconsOverlay.props = {
|
|
27489
|
-
gridPosition: { type: Object, optional: true },
|
|
27490
|
-
};
|
|
27491
27732
|
|
|
27492
27733
|
const CHECKBOX_WIDTH = 15;
|
|
27493
27734
|
const MARGIN = (GRID_ICON_EDGE_LENGTH - CHECKBOX_WIDTH) / 2;
|
|
@@ -27501,6 +27742,9 @@
|
|
|
27501
27742
|
`;
|
|
27502
27743
|
class DataValidationCheckbox extends owl.Component {
|
|
27503
27744
|
static template = "o-spreadsheet-DataValidationCheckbox";
|
|
27745
|
+
static props = {
|
|
27746
|
+
cellPosition: Object,
|
|
27747
|
+
};
|
|
27504
27748
|
onCheckboxChange(ev) {
|
|
27505
27749
|
const newValue = ev.target.checked;
|
|
27506
27750
|
const { sheetId, col, row } = this.props.cellPosition;
|
|
@@ -27515,9 +27759,6 @@
|
|
|
27515
27759
|
return !!cell?.isFormula;
|
|
27516
27760
|
}
|
|
27517
27761
|
}
|
|
27518
|
-
DataValidationCheckbox.props = {
|
|
27519
|
-
cellPosition: Object,
|
|
27520
|
-
};
|
|
27521
27762
|
|
|
27522
27763
|
const ICON_WIDTH = 13;
|
|
27523
27764
|
css /* scss */ `
|
|
@@ -27540,18 +27781,19 @@
|
|
|
27540
27781
|
`;
|
|
27541
27782
|
class DataValidationListIcon extends owl.Component {
|
|
27542
27783
|
static template = "o-spreadsheet-DataValidationListIcon";
|
|
27784
|
+
static props = {
|
|
27785
|
+
cellPosition: Object,
|
|
27786
|
+
};
|
|
27543
27787
|
onClick() {
|
|
27544
27788
|
const { col, row } = this.props.cellPosition;
|
|
27545
27789
|
this.env.model.selection.selectCell(col, row);
|
|
27546
27790
|
this.env.startCellEdition();
|
|
27547
27791
|
}
|
|
27548
27792
|
}
|
|
27549
|
-
DataValidationListIcon.props = {
|
|
27550
|
-
cellPosition: Object,
|
|
27551
|
-
};
|
|
27552
27793
|
|
|
27553
27794
|
class DataValidationOverlay extends owl.Component {
|
|
27554
27795
|
static template = "o-spreadsheet-DataValidationOverlay";
|
|
27796
|
+
static props = {};
|
|
27555
27797
|
static components = { GridCellIcon, DataValidationCheckbox, DataValidationListIcon };
|
|
27556
27798
|
get checkBoxCellPositions() {
|
|
27557
27799
|
return this.env.model.getters.getDataValidationCheckBoxCellPositions();
|
|
@@ -27562,7 +27804,6 @@
|
|
|
27562
27804
|
: this.env.model.getters.getDataValidationListCellsPositions();
|
|
27563
27805
|
}
|
|
27564
27806
|
}
|
|
27565
|
-
DataValidationOverlay.props = {};
|
|
27566
27807
|
|
|
27567
27808
|
/**
|
|
27568
27809
|
* Transform a figure with coordinates from the model, to coordinates as they are shown on the screen,
|
|
@@ -27898,6 +28139,9 @@
|
|
|
27898
28139
|
*/
|
|
27899
28140
|
class FiguresContainer extends owl.Component {
|
|
27900
28141
|
static template = "o-spreadsheet-FiguresContainer";
|
|
28142
|
+
static props = {
|
|
28143
|
+
onFigureDeleted: Function,
|
|
28144
|
+
};
|
|
27901
28145
|
static components = { FigureComponent };
|
|
27902
28146
|
dnd = owl.useState({
|
|
27903
28147
|
draggedFigure: undefined,
|
|
@@ -28147,9 +28391,6 @@
|
|
|
28147
28391
|
}
|
|
28148
28392
|
}
|
|
28149
28393
|
}
|
|
28150
|
-
FiguresContainer.props = {
|
|
28151
|
-
onFigureDeleted: Function,
|
|
28152
|
-
};
|
|
28153
28394
|
|
|
28154
28395
|
css /* scss */ `
|
|
28155
28396
|
.o-grid-add-rows {
|
|
@@ -28168,6 +28409,9 @@
|
|
|
28168
28409
|
`;
|
|
28169
28410
|
class GridAddRowsFooter extends owl.Component {
|
|
28170
28411
|
static template = "o-spreadsheet-GridAddRowsFooter";
|
|
28412
|
+
static props = {
|
|
28413
|
+
focusGrid: Function,
|
|
28414
|
+
};
|
|
28171
28415
|
static components = { ValidationMessages };
|
|
28172
28416
|
inputRef = owl.useRef("inputRef");
|
|
28173
28417
|
state = owl.useState({
|
|
@@ -28234,9 +28478,6 @@
|
|
|
28234
28478
|
this.props.focusGrid();
|
|
28235
28479
|
}
|
|
28236
28480
|
}
|
|
28237
|
-
GridAddRowsFooter.props = {
|
|
28238
|
-
focusGrid: Function,
|
|
28239
|
-
};
|
|
28240
28481
|
|
|
28241
28482
|
/**
|
|
28242
28483
|
* Manages an event listener on a ref. Useful for hooks that want to manage
|
|
@@ -28392,6 +28633,16 @@
|
|
|
28392
28633
|
}
|
|
28393
28634
|
class GridOverlay extends owl.Component {
|
|
28394
28635
|
static template = "o-spreadsheet-GridOverlay";
|
|
28636
|
+
static props = {
|
|
28637
|
+
onCellHovered: { type: Function, optional: true },
|
|
28638
|
+
onCellDoubleClicked: { type: Function, optional: true },
|
|
28639
|
+
onCellClicked: { type: Function, optional: true },
|
|
28640
|
+
onCellRightClicked: { type: Function, optional: true },
|
|
28641
|
+
onGridResized: { type: Function, optional: true },
|
|
28642
|
+
onFigureDeleted: { type: Function, optional: true },
|
|
28643
|
+
onGridMoved: Function,
|
|
28644
|
+
gridOverlayDimensions: String,
|
|
28645
|
+
};
|
|
28395
28646
|
static components = { FiguresContainer, DataValidationOverlay, GridAddRowsFooter };
|
|
28396
28647
|
static defaultProps = {
|
|
28397
28648
|
onCellHovered: () => { },
|
|
@@ -28443,7 +28694,10 @@
|
|
|
28443
28694
|
return;
|
|
28444
28695
|
}
|
|
28445
28696
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
28446
|
-
this.props.onCellClicked(col, row, {
|
|
28697
|
+
this.props.onCellClicked(col, row, {
|
|
28698
|
+
expandZone: ev.shiftKey,
|
|
28699
|
+
addZone: isCtrlKey(ev),
|
|
28700
|
+
});
|
|
28447
28701
|
}
|
|
28448
28702
|
onDoubleClick(ev) {
|
|
28449
28703
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
@@ -28462,19 +28716,15 @@
|
|
|
28462
28716
|
return [colIndex, rowIndex];
|
|
28463
28717
|
}
|
|
28464
28718
|
}
|
|
28465
|
-
GridOverlay.props = {
|
|
28466
|
-
onCellHovered: { type: Function, optional: true },
|
|
28467
|
-
onCellDoubleClicked: { type: Function, optional: true },
|
|
28468
|
-
onCellClicked: { type: Function, optional: true },
|
|
28469
|
-
onCellRightClicked: { type: Function, optional: true },
|
|
28470
|
-
onGridResized: { type: Function, optional: true },
|
|
28471
|
-
onFigureDeleted: { type: Function, optional: true },
|
|
28472
|
-
onGridMoved: Function,
|
|
28473
|
-
gridOverlayDimensions: String,
|
|
28474
|
-
};
|
|
28475
28719
|
|
|
28476
28720
|
class GridPopover extends owl.Component {
|
|
28477
28721
|
static template = "o-spreadsheet-GridPopover";
|
|
28722
|
+
static props = {
|
|
28723
|
+
hoveredCell: Object,
|
|
28724
|
+
onClosePopover: Function,
|
|
28725
|
+
onMouseWheel: Function,
|
|
28726
|
+
gridRect: Object,
|
|
28727
|
+
};
|
|
28478
28728
|
static components = { Popover };
|
|
28479
28729
|
zIndex = ComponentsImportance.GridPopover;
|
|
28480
28730
|
get cellPopover() {
|
|
@@ -28494,14 +28744,11 @@
|
|
|
28494
28744
|
};
|
|
28495
28745
|
}
|
|
28496
28746
|
}
|
|
28497
|
-
GridPopover.props = {
|
|
28498
|
-
hoveredCell: Object,
|
|
28499
|
-
onClosePopover: Function,
|
|
28500
|
-
onMouseWheel: Function,
|
|
28501
|
-
gridRect: Object,
|
|
28502
|
-
};
|
|
28503
28747
|
|
|
28504
28748
|
class AbstractResizer extends owl.Component {
|
|
28749
|
+
static props = {
|
|
28750
|
+
onOpenContextMenu: Function,
|
|
28751
|
+
};
|
|
28505
28752
|
PADDING = 0;
|
|
28506
28753
|
MAX_SIZE_MARGIN = 0;
|
|
28507
28754
|
MIN_ELEMENT_SIZE = 0;
|
|
@@ -28673,7 +28920,7 @@
|
|
|
28673
28920
|
this._increaseSelection(index);
|
|
28674
28921
|
}
|
|
28675
28922
|
else {
|
|
28676
|
-
this._selectElement(index, ev
|
|
28923
|
+
this._selectElement(index, isCtrlKey(ev));
|
|
28677
28924
|
}
|
|
28678
28925
|
this.lastSelectedElementIndex = index;
|
|
28679
28926
|
const mouseMoveSelect = (col, row) => {
|
|
@@ -28758,10 +29005,10 @@
|
|
|
28758
29005
|
}
|
|
28759
29006
|
}
|
|
28760
29007
|
`;
|
|
28761
|
-
AbstractResizer.props = {
|
|
28762
|
-
onOpenContextMenu: Function,
|
|
28763
|
-
};
|
|
28764
29008
|
class ColResizer extends AbstractResizer {
|
|
29009
|
+
static props = {
|
|
29010
|
+
onOpenContextMenu: Function,
|
|
29011
|
+
};
|
|
28765
29012
|
static template = "o-spreadsheet-ColResizer";
|
|
28766
29013
|
colResizerRef;
|
|
28767
29014
|
setup() {
|
|
@@ -28830,8 +29077,8 @@
|
|
|
28830
29077
|
this.env.raiseError(MergeErrorMessage);
|
|
28831
29078
|
}
|
|
28832
29079
|
}
|
|
28833
|
-
_selectElement(index,
|
|
28834
|
-
this.env.model.selection.selectColumn(index,
|
|
29080
|
+
_selectElement(index, addDistinctHeader) {
|
|
29081
|
+
this.env.model.selection.selectColumn(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
|
|
28835
29082
|
}
|
|
28836
29083
|
_increaseSelection(index) {
|
|
28837
29084
|
this.env.model.selection.selectColumn(index, "updateAnchor");
|
|
@@ -28923,10 +29170,10 @@
|
|
|
28923
29170
|
}
|
|
28924
29171
|
}
|
|
28925
29172
|
`;
|
|
28926
|
-
ColResizer.props = {
|
|
28927
|
-
onOpenContextMenu: Function,
|
|
28928
|
-
};
|
|
28929
29173
|
class RowResizer extends AbstractResizer {
|
|
29174
|
+
static props = {
|
|
29175
|
+
onOpenContextMenu: Function,
|
|
29176
|
+
};
|
|
28930
29177
|
static template = "o-spreadsheet-RowResizer";
|
|
28931
29178
|
setup() {
|
|
28932
29179
|
super.setup();
|
|
@@ -28995,8 +29242,8 @@
|
|
|
28995
29242
|
this.env.raiseError(MergeErrorMessage);
|
|
28996
29243
|
}
|
|
28997
29244
|
}
|
|
28998
|
-
_selectElement(index,
|
|
28999
|
-
this.env.model.selection.selectRow(index,
|
|
29245
|
+
_selectElement(index, addDistinctHeader) {
|
|
29246
|
+
this.env.model.selection.selectRow(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
|
|
29000
29247
|
}
|
|
29001
29248
|
_increaseSelection(index) {
|
|
29002
29249
|
this.env.model.selection.selectRow(index, "updateAnchor");
|
|
@@ -29047,19 +29294,16 @@
|
|
|
29047
29294
|
}
|
|
29048
29295
|
}
|
|
29049
29296
|
`;
|
|
29050
|
-
RowResizer.props = {
|
|
29051
|
-
onOpenContextMenu: Function,
|
|
29052
|
-
};
|
|
29053
29297
|
class HeadersOverlay extends owl.Component {
|
|
29298
|
+
static props = {
|
|
29299
|
+
onOpenContextMenu: Function,
|
|
29300
|
+
};
|
|
29054
29301
|
static template = "o-spreadsheet-HeadersOverlay";
|
|
29055
29302
|
static components = { ColResizer, RowResizer };
|
|
29056
29303
|
selectAll() {
|
|
29057
29304
|
this.env.model.selection.selectAll();
|
|
29058
29305
|
}
|
|
29059
29306
|
}
|
|
29060
|
-
HeadersOverlay.props = {
|
|
29061
|
-
onOpenContextMenu: Function,
|
|
29062
|
-
};
|
|
29063
29307
|
|
|
29064
29308
|
function useGridDrawing(refName, model, canvasSize) {
|
|
29065
29309
|
const canvasRef = owl.useRef(refName);
|
|
@@ -29117,6 +29361,12 @@
|
|
|
29117
29361
|
`;
|
|
29118
29362
|
class Border extends owl.Component {
|
|
29119
29363
|
static template = "o-spreadsheet-Border";
|
|
29364
|
+
static props = {
|
|
29365
|
+
zone: Object,
|
|
29366
|
+
orientation: String,
|
|
29367
|
+
isMoving: Boolean,
|
|
29368
|
+
onMoveHighlight: Function,
|
|
29369
|
+
};
|
|
29120
29370
|
get style() {
|
|
29121
29371
|
const isTop = ["n", "w", "e"].includes(this.props.orientation);
|
|
29122
29372
|
const isLeft = ["n", "w", "s"].includes(this.props.orientation);
|
|
@@ -29145,12 +29395,6 @@
|
|
|
29145
29395
|
this.props.onMoveHighlight(ev.clientX, ev.clientY);
|
|
29146
29396
|
}
|
|
29147
29397
|
}
|
|
29148
|
-
Border.props = {
|
|
29149
|
-
zone: Object,
|
|
29150
|
-
orientation: String,
|
|
29151
|
-
isMoving: Boolean,
|
|
29152
|
-
onMoveHighlight: Function,
|
|
29153
|
-
};
|
|
29154
29398
|
|
|
29155
29399
|
css /* scss */ `
|
|
29156
29400
|
.o-corner {
|
|
@@ -29177,6 +29421,13 @@
|
|
|
29177
29421
|
`;
|
|
29178
29422
|
class Corner extends owl.Component {
|
|
29179
29423
|
static template = "o-spreadsheet-Corner";
|
|
29424
|
+
static props = {
|
|
29425
|
+
zone: Object,
|
|
29426
|
+
color: String,
|
|
29427
|
+
orientation: String,
|
|
29428
|
+
isResizing: Boolean,
|
|
29429
|
+
onResizeHighlight: Function,
|
|
29430
|
+
};
|
|
29180
29431
|
isTop = this.props.orientation[0] === "n";
|
|
29181
29432
|
isLeft = this.props.orientation[1] === "w";
|
|
29182
29433
|
get style() {
|
|
@@ -29205,13 +29456,6 @@
|
|
|
29205
29456
|
this.props.onResizeHighlight(this.isLeft, this.isTop);
|
|
29206
29457
|
}
|
|
29207
29458
|
}
|
|
29208
|
-
Corner.props = {
|
|
29209
|
-
zone: Object,
|
|
29210
|
-
color: String,
|
|
29211
|
-
orientation: String,
|
|
29212
|
-
isResizing: Boolean,
|
|
29213
|
-
onResizeHighlight: Function,
|
|
29214
|
-
};
|
|
29215
29459
|
|
|
29216
29460
|
css /*SCSS*/ `
|
|
29217
29461
|
.o-highlight {
|
|
@@ -29220,6 +29464,10 @@
|
|
|
29220
29464
|
`;
|
|
29221
29465
|
class Highlight extends owl.Component {
|
|
29222
29466
|
static template = "o-spreadsheet-Highlight";
|
|
29467
|
+
static props = {
|
|
29468
|
+
zone: Object,
|
|
29469
|
+
color: String,
|
|
29470
|
+
};
|
|
29223
29471
|
static components = {
|
|
29224
29472
|
Corner,
|
|
29225
29473
|
Border,
|
|
@@ -29303,10 +29551,6 @@
|
|
|
29303
29551
|
dragAndDropBeyondTheViewport(this.env, mouseMove, mouseUp);
|
|
29304
29552
|
}
|
|
29305
29553
|
}
|
|
29306
|
-
Highlight.props = {
|
|
29307
|
-
zone: Object,
|
|
29308
|
-
color: String,
|
|
29309
|
-
};
|
|
29310
29554
|
|
|
29311
29555
|
let ScrollBar$1 = class ScrollBar {
|
|
29312
29556
|
direction;
|
|
@@ -29346,6 +29590,14 @@
|
|
|
29346
29590
|
}
|
|
29347
29591
|
`;
|
|
29348
29592
|
class ScrollBar extends owl.Component {
|
|
29593
|
+
static props = {
|
|
29594
|
+
width: { type: Number, optional: true },
|
|
29595
|
+
height: { type: Number, optional: true },
|
|
29596
|
+
direction: String,
|
|
29597
|
+
position: Object,
|
|
29598
|
+
offset: Number,
|
|
29599
|
+
onScroll: Function,
|
|
29600
|
+
};
|
|
29349
29601
|
static template = owl.xml /*xml*/ `
|
|
29350
29602
|
<div
|
|
29351
29603
|
t-attf-class="o-scrollbar {{props.direction}}"
|
|
@@ -29389,16 +29641,11 @@
|
|
|
29389
29641
|
}
|
|
29390
29642
|
}
|
|
29391
29643
|
}
|
|
29392
|
-
ScrollBar.props = {
|
|
29393
|
-
width: { type: Number, optional: true },
|
|
29394
|
-
height: { type: Number, optional: true },
|
|
29395
|
-
direction: String,
|
|
29396
|
-
position: Object,
|
|
29397
|
-
offset: Number,
|
|
29398
|
-
onScroll: Function,
|
|
29399
|
-
};
|
|
29400
29644
|
|
|
29401
29645
|
class HorizontalScrollBar extends owl.Component {
|
|
29646
|
+
static props = {
|
|
29647
|
+
leftOffset: { type: Number, optional: true },
|
|
29648
|
+
};
|
|
29402
29649
|
static components = { ScrollBar };
|
|
29403
29650
|
static template = owl.xml /*xml*/ `
|
|
29404
29651
|
<ScrollBar
|
|
@@ -29439,11 +29686,11 @@
|
|
|
29439
29686
|
});
|
|
29440
29687
|
}
|
|
29441
29688
|
}
|
|
29442
|
-
HorizontalScrollBar.props = {
|
|
29443
|
-
leftOffset: { type: Number, optional: true },
|
|
29444
|
-
};
|
|
29445
29689
|
|
|
29446
29690
|
class VerticalScrollBar extends owl.Component {
|
|
29691
|
+
static props = {
|
|
29692
|
+
topOffset: { type: Number, optional: true },
|
|
29693
|
+
};
|
|
29447
29694
|
static components = { ScrollBar };
|
|
29448
29695
|
static template = owl.xml /*xml*/ `
|
|
29449
29696
|
<ScrollBar
|
|
@@ -29484,9 +29731,6 @@
|
|
|
29484
29731
|
});
|
|
29485
29732
|
}
|
|
29486
29733
|
}
|
|
29487
|
-
VerticalScrollBar.props = {
|
|
29488
|
-
topOffset: { type: Number, optional: true },
|
|
29489
|
-
};
|
|
29490
29734
|
|
|
29491
29735
|
const registries$1 = {
|
|
29492
29736
|
ROW: rowMenuRegistry,
|
|
@@ -29500,6 +29744,13 @@
|
|
|
29500
29744
|
// -----------------------------------------------------------------------------
|
|
29501
29745
|
class Grid extends owl.Component {
|
|
29502
29746
|
static template = "o-spreadsheet-Grid";
|
|
29747
|
+
static props = {
|
|
29748
|
+
sidePanelIsOpen: Boolean,
|
|
29749
|
+
exposeFocus: Function,
|
|
29750
|
+
focusComposer: String,
|
|
29751
|
+
onComposerContentFocused: Function,
|
|
29752
|
+
onGridComposerCellFocused: Function,
|
|
29753
|
+
};
|
|
29503
29754
|
static components = {
|
|
29504
29755
|
GridComposer,
|
|
29505
29756
|
GridOverlay,
|
|
@@ -29689,7 +29940,7 @@
|
|
|
29689
29940
|
"Ctrl+Shift+E": () => this.setHorizontalAlign("center"),
|
|
29690
29941
|
"Ctrl+Shift+L": () => this.setHorizontalAlign("left"),
|
|
29691
29942
|
"Ctrl+Shift+R": () => this.setHorizontalAlign("right"),
|
|
29692
|
-
"Ctrl+Shift+V": () =>
|
|
29943
|
+
"Ctrl+Shift+V": () => PASTE_AS_VALUE_ACTION(this.env),
|
|
29693
29944
|
"Ctrl+Shift+<": () => this.clearFormatting(),
|
|
29694
29945
|
"Ctrl+<": () => this.clearFormatting(),
|
|
29695
29946
|
"Ctrl+Shift+ ": () => {
|
|
@@ -29797,17 +30048,17 @@
|
|
|
29797
30048
|
// ---------------------------------------------------------------------------
|
|
29798
30049
|
// Zone selection with mouse
|
|
29799
30050
|
// ---------------------------------------------------------------------------
|
|
29800
|
-
onCellClicked(col, row, {
|
|
30051
|
+
onCellClicked(col, row, { addZone, expandZone }) {
|
|
29801
30052
|
if (this.env.model.getters.hasOpenedPopover()) {
|
|
29802
30053
|
this.closeOpenedPopover();
|
|
29803
30054
|
}
|
|
29804
30055
|
if (this.env.model.getters.getEditionMode() === "editing") {
|
|
29805
30056
|
interactiveStopEdition(this.env);
|
|
29806
30057
|
}
|
|
29807
|
-
if (
|
|
30058
|
+
if (expandZone) {
|
|
29808
30059
|
this.env.model.selection.setAnchorCorner(col, row);
|
|
29809
30060
|
}
|
|
29810
|
-
else if (
|
|
30061
|
+
else if (addZone) {
|
|
29811
30062
|
this.env.model.selection.addCellToSelection(col, row);
|
|
29812
30063
|
}
|
|
29813
30064
|
else {
|
|
@@ -30104,13 +30355,6 @@
|
|
|
30104
30355
|
}
|
|
30105
30356
|
}
|
|
30106
30357
|
}
|
|
30107
|
-
Grid.props = {
|
|
30108
|
-
sidePanelIsOpen: Boolean,
|
|
30109
|
-
exposeFocus: Function,
|
|
30110
|
-
focusComposer: String,
|
|
30111
|
-
onComposerContentFocused: Function,
|
|
30112
|
-
onGridComposerCellFocused: Function,
|
|
30113
|
-
};
|
|
30114
30358
|
|
|
30115
30359
|
/**
|
|
30116
30360
|
* Represent a raw XML string
|
|
@@ -30610,7 +30854,7 @@
|
|
|
30610
30854
|
46: "hhhh:mm:ss",
|
|
30611
30855
|
47: "hhhh:mm:ss",
|
|
30612
30856
|
48: undefined,
|
|
30613
|
-
49:
|
|
30857
|
+
49: PLAIN_TEXT_FORMAT,
|
|
30614
30858
|
};
|
|
30615
30859
|
/**
|
|
30616
30860
|
* Mapping format index to format defined by default
|
|
@@ -31531,20 +31775,26 @@
|
|
|
31531
31775
|
.filter(isDefined$1);
|
|
31532
31776
|
}
|
|
31533
31777
|
function convertFigure(figure, id, sheetData) {
|
|
31534
|
-
|
|
31535
|
-
|
|
31536
|
-
|
|
31537
|
-
|
|
31538
|
-
|
|
31539
|
-
convertEMUToDotValue(figure.
|
|
31540
|
-
|
|
31541
|
-
|
|
31778
|
+
let x1, y1;
|
|
31779
|
+
let height, width;
|
|
31780
|
+
if (figure.anchors.length === 1) {
|
|
31781
|
+
// one cell anchor
|
|
31782
|
+
({ x: x1, y: y1 } = getPositionFromAnchor(figure.anchors[0], sheetData));
|
|
31783
|
+
width = convertEMUToDotValue(figure.figureSize.cx);
|
|
31784
|
+
height = convertEMUToDotValue(figure.figureSize.cy);
|
|
31785
|
+
}
|
|
31786
|
+
else {
|
|
31787
|
+
({ x: x1, y: y1 } = getPositionFromAnchor(figure.anchors[0], sheetData));
|
|
31788
|
+
const { x: x2, y: y2 } = getPositionFromAnchor(figure.anchors[1], sheetData);
|
|
31789
|
+
width = x2 - x1;
|
|
31790
|
+
height = y2 - y1;
|
|
31791
|
+
}
|
|
31542
31792
|
const figureData = { id, x: x1, y: y1 };
|
|
31543
31793
|
if (isChartData(figure.data)) {
|
|
31544
31794
|
return {
|
|
31545
31795
|
...figureData,
|
|
31546
|
-
width
|
|
31547
|
-
height
|
|
31796
|
+
width,
|
|
31797
|
+
height,
|
|
31548
31798
|
tag: "chart",
|
|
31549
31799
|
data: convertChartData(figure.data),
|
|
31550
31800
|
};
|
|
@@ -31610,6 +31860,12 @@
|
|
|
31610
31860
|
const dataXC = zoneToXc(zone);
|
|
31611
31861
|
return getFullReference(sheetName, dataXC);
|
|
31612
31862
|
}
|
|
31863
|
+
function getPositionFromAnchor(anchor, sheetData) {
|
|
31864
|
+
return {
|
|
31865
|
+
x: getColPosition(anchor.col, sheetData) + convertEMUToDotValue(anchor.colOffset),
|
|
31866
|
+
y: getRowPosition(anchor.row, sheetData) + convertEMUToDotValue(anchor.rowOffset),
|
|
31867
|
+
};
|
|
31868
|
+
}
|
|
31613
31869
|
|
|
31614
31870
|
/**
|
|
31615
31871
|
* Match external reference (ex. '[1]Sheet 3'!$B$4)
|
|
@@ -32733,27 +32989,50 @@
|
|
|
32733
32989
|
}
|
|
32734
32990
|
}
|
|
32735
32991
|
|
|
32992
|
+
const ONE_CELL_ANCHOR = "oneCellAnchor";
|
|
32993
|
+
const TWO_CELL_ANCHOR = "twoCellAnchor";
|
|
32736
32994
|
class XlsxFigureExtractor extends XlsxBaseExtractor {
|
|
32737
32995
|
extractFigures() {
|
|
32738
32996
|
return this.mapOnElements({ parent: this.rootFile.file.xml, query: "xdr:wsDr", children: true }, (figureElement) => {
|
|
32739
32997
|
const anchorType = removeTagEscapedNamespaces(figureElement.tagName);
|
|
32740
|
-
|
|
32741
|
-
throw new Error("Only twoCellAnchor are supported for xlsx drawings.");
|
|
32742
|
-
}
|
|
32998
|
+
const anchors = this.extractFigureAnchorsByType(figureElement, anchorType);
|
|
32743
32999
|
const chartElement = this.querySelector(figureElement, "c:chart");
|
|
32744
33000
|
const imageElement = this.querySelector(figureElement, "a:blip");
|
|
32745
33001
|
if (!chartElement && !imageElement) {
|
|
32746
33002
|
throw new Error("Only chart and image figures are currently supported.");
|
|
32747
33003
|
}
|
|
32748
33004
|
return {
|
|
32749
|
-
anchors
|
|
32750
|
-
this.extractFigureAnchor("xdr:from", figureElement),
|
|
32751
|
-
this.extractFigureAnchor("xdr:to", figureElement),
|
|
32752
|
-
],
|
|
33005
|
+
anchors,
|
|
32753
33006
|
data: chartElement ? this.extractChart(chartElement) : this.extractImage(figureElement),
|
|
33007
|
+
figureSize: anchorType === ONE_CELL_ANCHOR
|
|
33008
|
+
? this.extractFigureSizeFromSizeTag(figureElement, "xdr:ext")
|
|
33009
|
+
: undefined,
|
|
32754
33010
|
};
|
|
32755
33011
|
});
|
|
32756
33012
|
}
|
|
33013
|
+
extractFigureAnchorsByType(figureElement, anchorType) {
|
|
33014
|
+
switch (anchorType) {
|
|
33015
|
+
case ONE_CELL_ANCHOR:
|
|
33016
|
+
return [this.extractFigureAnchor("xdr:from", figureElement)];
|
|
33017
|
+
case TWO_CELL_ANCHOR:
|
|
33018
|
+
return [
|
|
33019
|
+
this.extractFigureAnchor("xdr:from", figureElement),
|
|
33020
|
+
this.extractFigureAnchor("xdr:to", figureElement),
|
|
33021
|
+
];
|
|
33022
|
+
default:
|
|
33023
|
+
throw new Error(`${anchorType} is not supported for xlsx drawings. `);
|
|
33024
|
+
}
|
|
33025
|
+
}
|
|
33026
|
+
extractFigureSizeFromSizeTag(figureElement, sizeTag) {
|
|
33027
|
+
const sizeElement = this.querySelector(figureElement, sizeTag);
|
|
33028
|
+
if (!sizeElement) {
|
|
33029
|
+
throw new Error(`Missing size element '${sizeTag}'`);
|
|
33030
|
+
}
|
|
33031
|
+
return {
|
|
33032
|
+
cx: this.extractAttr(sizeElement, "cx", { required: true }).asNum(),
|
|
33033
|
+
cy: this.extractAttr(sizeElement, "cy", { required: true }).asNum(),
|
|
33034
|
+
};
|
|
33035
|
+
}
|
|
32757
33036
|
extractFigureAnchor(anchorTag, figureElement) {
|
|
32758
33037
|
const anchor = this.querySelector(figureElement, anchorTag);
|
|
32759
33038
|
if (!anchor) {
|
|
@@ -32782,15 +33061,15 @@
|
|
|
32782
33061
|
if (!image) {
|
|
32783
33062
|
throw new Error("Unable to extract image");
|
|
32784
33063
|
}
|
|
32785
|
-
const shapePropertyElement = this.querySelector(figureElement, "a:xfrm");
|
|
32786
33064
|
const extension = image.fileName.split(".").at(-1);
|
|
33065
|
+
const anchorType = removeTagEscapedNamespaces(figureElement.tagName);
|
|
33066
|
+
const sizeElement = anchorType === TWO_CELL_ANCHOR ? this.querySelector(figureElement, "a:xfrm") : figureElement;
|
|
33067
|
+
const sizeTag = anchorType === TWO_CELL_ANCHOR ? "a:ext" : "xdr:ext";
|
|
33068
|
+
const size = this.extractFigureSizeFromSizeTag(sizeElement, sizeTag);
|
|
32787
33069
|
return {
|
|
32788
33070
|
imageSrc: image.imageSrc,
|
|
32789
33071
|
mimetype: extension ? IMAGE_EXTENSION_TO_MIMETYPE_MAPPING[extension] : undefined,
|
|
32790
|
-
size
|
|
32791
|
-
cx: this.extractChildAttr(shapePropertyElement, "a:ext", "cx", { required: true }).asNum(),
|
|
32792
|
-
cy: this.extractChildAttr(shapePropertyElement, "a:ext", "cy", { required: true }).asNum(),
|
|
32793
|
-
},
|
|
33072
|
+
size,
|
|
32794
33073
|
};
|
|
32795
33074
|
}
|
|
32796
33075
|
}
|
|
@@ -34743,7 +35022,7 @@
|
|
|
34743
35022
|
*/
|
|
34744
35023
|
function getBorderId(border) {
|
|
34745
35024
|
for (let [key, value] of Object.entries(borders)) {
|
|
34746
|
-
if (
|
|
35025
|
+
if (deepEquals(value, border)) {
|
|
34747
35026
|
return parseInt(key, 10);
|
|
34748
35027
|
}
|
|
34749
35028
|
}
|
|
@@ -35914,7 +36193,9 @@
|
|
|
35914
36193
|
}
|
|
35915
36194
|
createLiteralCell(id, content, format, style) {
|
|
35916
36195
|
const locale = this.getters.getLocale();
|
|
35917
|
-
|
|
36196
|
+
if (format !== PLAIN_TEXT_FORMAT) {
|
|
36197
|
+
content = toString(parseLiteral(content, locale));
|
|
36198
|
+
}
|
|
35918
36199
|
return {
|
|
35919
36200
|
id,
|
|
35920
36201
|
content,
|
|
@@ -40061,56 +40342,758 @@
|
|
|
40061
40342
|
}
|
|
40062
40343
|
}
|
|
40063
40344
|
|
|
40345
|
+
function quickselect(arr, k, left, right, compare) {
|
|
40346
|
+
quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare);
|
|
40347
|
+
}
|
|
40348
|
+
|
|
40349
|
+
function quickselectStep(arr, k, left, right, compare) {
|
|
40350
|
+
|
|
40351
|
+
while (right > left) {
|
|
40352
|
+
if (right - left > 600) {
|
|
40353
|
+
var n = right - left + 1;
|
|
40354
|
+
var m = k - left + 1;
|
|
40355
|
+
var z = Math.log(n);
|
|
40356
|
+
var s = 0.5 * Math.exp(2 * z / 3);
|
|
40357
|
+
var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
|
|
40358
|
+
var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
|
|
40359
|
+
var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
|
|
40360
|
+
quickselectStep(arr, k, newLeft, newRight, compare);
|
|
40361
|
+
}
|
|
40362
|
+
|
|
40363
|
+
var t = arr[k];
|
|
40364
|
+
var i = left;
|
|
40365
|
+
var j = right;
|
|
40366
|
+
|
|
40367
|
+
swap(arr, left, k);
|
|
40368
|
+
if (compare(arr[right], t) > 0) swap(arr, left, right);
|
|
40369
|
+
|
|
40370
|
+
while (i < j) {
|
|
40371
|
+
swap(arr, i, j);
|
|
40372
|
+
i++;
|
|
40373
|
+
j--;
|
|
40374
|
+
while (compare(arr[i], t) < 0) i++;
|
|
40375
|
+
while (compare(arr[j], t) > 0) j--;
|
|
40376
|
+
}
|
|
40377
|
+
|
|
40378
|
+
if (compare(arr[left], t) === 0) swap(arr, left, j);
|
|
40379
|
+
else {
|
|
40380
|
+
j++;
|
|
40381
|
+
swap(arr, j, right);
|
|
40382
|
+
}
|
|
40383
|
+
|
|
40384
|
+
if (j <= k) left = j + 1;
|
|
40385
|
+
if (k <= j) right = j - 1;
|
|
40386
|
+
}
|
|
40387
|
+
}
|
|
40388
|
+
|
|
40389
|
+
function swap(arr, i, j) {
|
|
40390
|
+
var tmp = arr[i];
|
|
40391
|
+
arr[i] = arr[j];
|
|
40392
|
+
arr[j] = tmp;
|
|
40393
|
+
}
|
|
40394
|
+
|
|
40395
|
+
function defaultCompare(a, b) {
|
|
40396
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
40397
|
+
}
|
|
40398
|
+
|
|
40399
|
+
class RBush {
|
|
40400
|
+
constructor(maxEntries = 9) {
|
|
40401
|
+
// max entries in a node is 9 by default; min node fill is 40% for best performance
|
|
40402
|
+
this._maxEntries = Math.max(4, maxEntries);
|
|
40403
|
+
this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
|
|
40404
|
+
this.clear();
|
|
40405
|
+
}
|
|
40406
|
+
|
|
40407
|
+
all() {
|
|
40408
|
+
return this._all(this.data, []);
|
|
40409
|
+
}
|
|
40410
|
+
|
|
40411
|
+
search(bbox) {
|
|
40412
|
+
let node = this.data;
|
|
40413
|
+
const result = [];
|
|
40414
|
+
|
|
40415
|
+
if (!intersects(bbox, node)) return result;
|
|
40416
|
+
|
|
40417
|
+
const toBBox = this.toBBox;
|
|
40418
|
+
const nodesToSearch = [];
|
|
40419
|
+
|
|
40420
|
+
while (node) {
|
|
40421
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
40422
|
+
const child = node.children[i];
|
|
40423
|
+
const childBBox = node.leaf ? toBBox(child) : child;
|
|
40424
|
+
|
|
40425
|
+
if (intersects(bbox, childBBox)) {
|
|
40426
|
+
if (node.leaf) result.push(child);
|
|
40427
|
+
else if (contains(bbox, childBBox)) this._all(child, result);
|
|
40428
|
+
else nodesToSearch.push(child);
|
|
40429
|
+
}
|
|
40430
|
+
}
|
|
40431
|
+
node = nodesToSearch.pop();
|
|
40432
|
+
}
|
|
40433
|
+
|
|
40434
|
+
return result;
|
|
40435
|
+
}
|
|
40436
|
+
|
|
40437
|
+
collides(bbox) {
|
|
40438
|
+
let node = this.data;
|
|
40439
|
+
|
|
40440
|
+
if (!intersects(bbox, node)) return false;
|
|
40441
|
+
|
|
40442
|
+
const nodesToSearch = [];
|
|
40443
|
+
while (node) {
|
|
40444
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
40445
|
+
const child = node.children[i];
|
|
40446
|
+
const childBBox = node.leaf ? this.toBBox(child) : child;
|
|
40447
|
+
|
|
40448
|
+
if (intersects(bbox, childBBox)) {
|
|
40449
|
+
if (node.leaf || contains(bbox, childBBox)) return true;
|
|
40450
|
+
nodesToSearch.push(child);
|
|
40451
|
+
}
|
|
40452
|
+
}
|
|
40453
|
+
node = nodesToSearch.pop();
|
|
40454
|
+
}
|
|
40455
|
+
|
|
40456
|
+
return false;
|
|
40457
|
+
}
|
|
40458
|
+
|
|
40459
|
+
load(data) {
|
|
40460
|
+
if (!(data && data.length)) return this;
|
|
40461
|
+
|
|
40462
|
+
if (data.length < this._minEntries) {
|
|
40463
|
+
for (let i = 0; i < data.length; i++) {
|
|
40464
|
+
this.insert(data[i]);
|
|
40465
|
+
}
|
|
40466
|
+
return this;
|
|
40467
|
+
}
|
|
40468
|
+
|
|
40469
|
+
// recursively build the tree with the given data from scratch using OMT algorithm
|
|
40470
|
+
let node = this._build(data.slice(), 0, data.length - 1, 0);
|
|
40471
|
+
|
|
40472
|
+
if (!this.data.children.length) {
|
|
40473
|
+
// save as is if tree is empty
|
|
40474
|
+
this.data = node;
|
|
40475
|
+
|
|
40476
|
+
} else if (this.data.height === node.height) {
|
|
40477
|
+
// split root if trees have the same height
|
|
40478
|
+
this._splitRoot(this.data, node);
|
|
40479
|
+
|
|
40480
|
+
} else {
|
|
40481
|
+
if (this.data.height < node.height) {
|
|
40482
|
+
// swap trees if inserted one is bigger
|
|
40483
|
+
const tmpNode = this.data;
|
|
40484
|
+
this.data = node;
|
|
40485
|
+
node = tmpNode;
|
|
40486
|
+
}
|
|
40487
|
+
|
|
40488
|
+
// insert the small tree into the large tree at appropriate level
|
|
40489
|
+
this._insert(node, this.data.height - node.height - 1, true);
|
|
40490
|
+
}
|
|
40491
|
+
|
|
40492
|
+
return this;
|
|
40493
|
+
}
|
|
40494
|
+
|
|
40495
|
+
insert(item) {
|
|
40496
|
+
if (item) this._insert(item, this.data.height - 1);
|
|
40497
|
+
return this;
|
|
40498
|
+
}
|
|
40499
|
+
|
|
40500
|
+
clear() {
|
|
40501
|
+
this.data = createNode([]);
|
|
40502
|
+
return this;
|
|
40503
|
+
}
|
|
40504
|
+
|
|
40505
|
+
remove(item, equalsFn) {
|
|
40506
|
+
if (!item) return this;
|
|
40507
|
+
|
|
40508
|
+
let node = this.data;
|
|
40509
|
+
const bbox = this.toBBox(item);
|
|
40510
|
+
const path = [];
|
|
40511
|
+
const indexes = [];
|
|
40512
|
+
let i, parent, goingUp;
|
|
40513
|
+
|
|
40514
|
+
// depth-first iterative tree traversal
|
|
40515
|
+
while (node || path.length) {
|
|
40516
|
+
|
|
40517
|
+
if (!node) { // go up
|
|
40518
|
+
node = path.pop();
|
|
40519
|
+
parent = path[path.length - 1];
|
|
40520
|
+
i = indexes.pop();
|
|
40521
|
+
goingUp = true;
|
|
40522
|
+
}
|
|
40523
|
+
|
|
40524
|
+
if (node.leaf) { // check current node
|
|
40525
|
+
const index = findItem(item, node.children, equalsFn);
|
|
40526
|
+
|
|
40527
|
+
if (index !== -1) {
|
|
40528
|
+
// item found, remove the item and condense tree upwards
|
|
40529
|
+
node.children.splice(index, 1);
|
|
40530
|
+
path.push(node);
|
|
40531
|
+
this._condense(path);
|
|
40532
|
+
return this;
|
|
40533
|
+
}
|
|
40534
|
+
}
|
|
40535
|
+
|
|
40536
|
+
if (!goingUp && !node.leaf && contains(node, bbox)) { // go down
|
|
40537
|
+
path.push(node);
|
|
40538
|
+
indexes.push(i);
|
|
40539
|
+
i = 0;
|
|
40540
|
+
parent = node;
|
|
40541
|
+
node = node.children[0];
|
|
40542
|
+
|
|
40543
|
+
} else if (parent) { // go right
|
|
40544
|
+
i++;
|
|
40545
|
+
node = parent.children[i];
|
|
40546
|
+
goingUp = false;
|
|
40547
|
+
|
|
40548
|
+
} else node = null; // nothing found
|
|
40549
|
+
}
|
|
40550
|
+
|
|
40551
|
+
return this;
|
|
40552
|
+
}
|
|
40553
|
+
|
|
40554
|
+
toBBox(item) { return item; }
|
|
40555
|
+
|
|
40556
|
+
compareMinX(a, b) { return a.minX - b.minX; }
|
|
40557
|
+
compareMinY(a, b) { return a.minY - b.minY; }
|
|
40558
|
+
|
|
40559
|
+
toJSON() { return this.data; }
|
|
40560
|
+
|
|
40561
|
+
fromJSON(data) {
|
|
40562
|
+
this.data = data;
|
|
40563
|
+
return this;
|
|
40564
|
+
}
|
|
40565
|
+
|
|
40566
|
+
_all(node, result) {
|
|
40567
|
+
const nodesToSearch = [];
|
|
40568
|
+
while (node) {
|
|
40569
|
+
if (node.leaf) result.push(...node.children);
|
|
40570
|
+
else nodesToSearch.push(...node.children);
|
|
40571
|
+
|
|
40572
|
+
node = nodesToSearch.pop();
|
|
40573
|
+
}
|
|
40574
|
+
return result;
|
|
40575
|
+
}
|
|
40576
|
+
|
|
40577
|
+
_build(items, left, right, height) {
|
|
40578
|
+
|
|
40579
|
+
const N = right - left + 1;
|
|
40580
|
+
let M = this._maxEntries;
|
|
40581
|
+
let node;
|
|
40582
|
+
|
|
40583
|
+
if (N <= M) {
|
|
40584
|
+
// reached leaf level; return leaf
|
|
40585
|
+
node = createNode(items.slice(left, right + 1));
|
|
40586
|
+
calcBBox(node, this.toBBox);
|
|
40587
|
+
return node;
|
|
40588
|
+
}
|
|
40589
|
+
|
|
40590
|
+
if (!height) {
|
|
40591
|
+
// target height of the bulk-loaded tree
|
|
40592
|
+
height = Math.ceil(Math.log(N) / Math.log(M));
|
|
40593
|
+
|
|
40594
|
+
// target number of root entries to maximize storage utilization
|
|
40595
|
+
M = Math.ceil(N / Math.pow(M, height - 1));
|
|
40596
|
+
}
|
|
40597
|
+
|
|
40598
|
+
node = createNode([]);
|
|
40599
|
+
node.leaf = false;
|
|
40600
|
+
node.height = height;
|
|
40601
|
+
|
|
40602
|
+
// split the items into M mostly square tiles
|
|
40603
|
+
|
|
40604
|
+
const N2 = Math.ceil(N / M);
|
|
40605
|
+
const N1 = N2 * Math.ceil(Math.sqrt(M));
|
|
40606
|
+
|
|
40607
|
+
multiSelect(items, left, right, N1, this.compareMinX);
|
|
40608
|
+
|
|
40609
|
+
for (let i = left; i <= right; i += N1) {
|
|
40610
|
+
|
|
40611
|
+
const right2 = Math.min(i + N1 - 1, right);
|
|
40612
|
+
|
|
40613
|
+
multiSelect(items, i, right2, N2, this.compareMinY);
|
|
40614
|
+
|
|
40615
|
+
for (let j = i; j <= right2; j += N2) {
|
|
40616
|
+
|
|
40617
|
+
const right3 = Math.min(j + N2 - 1, right2);
|
|
40618
|
+
|
|
40619
|
+
// pack each entry recursively
|
|
40620
|
+
node.children.push(this._build(items, j, right3, height - 1));
|
|
40621
|
+
}
|
|
40622
|
+
}
|
|
40623
|
+
|
|
40624
|
+
calcBBox(node, this.toBBox);
|
|
40625
|
+
|
|
40626
|
+
return node;
|
|
40627
|
+
}
|
|
40628
|
+
|
|
40629
|
+
_chooseSubtree(bbox, node, level, path) {
|
|
40630
|
+
while (true) {
|
|
40631
|
+
path.push(node);
|
|
40632
|
+
|
|
40633
|
+
if (node.leaf || path.length - 1 === level) break;
|
|
40634
|
+
|
|
40635
|
+
let minArea = Infinity;
|
|
40636
|
+
let minEnlargement = Infinity;
|
|
40637
|
+
let targetNode;
|
|
40638
|
+
|
|
40639
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
40640
|
+
const child = node.children[i];
|
|
40641
|
+
const area = bboxArea(child);
|
|
40642
|
+
const enlargement = enlargedArea(bbox, child) - area;
|
|
40643
|
+
|
|
40644
|
+
// choose entry with the least area enlargement
|
|
40645
|
+
if (enlargement < minEnlargement) {
|
|
40646
|
+
minEnlargement = enlargement;
|
|
40647
|
+
minArea = area < minArea ? area : minArea;
|
|
40648
|
+
targetNode = child;
|
|
40649
|
+
|
|
40650
|
+
} else if (enlargement === minEnlargement) {
|
|
40651
|
+
// otherwise choose one with the smallest area
|
|
40652
|
+
if (area < minArea) {
|
|
40653
|
+
minArea = area;
|
|
40654
|
+
targetNode = child;
|
|
40655
|
+
}
|
|
40656
|
+
}
|
|
40657
|
+
}
|
|
40658
|
+
|
|
40659
|
+
node = targetNode || node.children[0];
|
|
40660
|
+
}
|
|
40661
|
+
|
|
40662
|
+
return node;
|
|
40663
|
+
}
|
|
40664
|
+
|
|
40665
|
+
_insert(item, level, isNode) {
|
|
40666
|
+
const bbox = isNode ? item : this.toBBox(item);
|
|
40667
|
+
const insertPath = [];
|
|
40668
|
+
|
|
40669
|
+
// find the best node for accommodating the item, saving all nodes along the path too
|
|
40670
|
+
const node = this._chooseSubtree(bbox, this.data, level, insertPath);
|
|
40671
|
+
|
|
40672
|
+
// put the item into the node
|
|
40673
|
+
node.children.push(item);
|
|
40674
|
+
extend(node, bbox);
|
|
40675
|
+
|
|
40676
|
+
// split on node overflow; propagate upwards if necessary
|
|
40677
|
+
while (level >= 0) {
|
|
40678
|
+
if (insertPath[level].children.length > this._maxEntries) {
|
|
40679
|
+
this._split(insertPath, level);
|
|
40680
|
+
level--;
|
|
40681
|
+
} else break;
|
|
40682
|
+
}
|
|
40683
|
+
|
|
40684
|
+
// adjust bboxes along the insertion path
|
|
40685
|
+
this._adjustParentBBoxes(bbox, insertPath, level);
|
|
40686
|
+
}
|
|
40687
|
+
|
|
40688
|
+
// split overflowed node into two
|
|
40689
|
+
_split(insertPath, level) {
|
|
40690
|
+
const node = insertPath[level];
|
|
40691
|
+
const M = node.children.length;
|
|
40692
|
+
const m = this._minEntries;
|
|
40693
|
+
|
|
40694
|
+
this._chooseSplitAxis(node, m, M);
|
|
40695
|
+
|
|
40696
|
+
const splitIndex = this._chooseSplitIndex(node, m, M);
|
|
40697
|
+
|
|
40698
|
+
const newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
|
|
40699
|
+
newNode.height = node.height;
|
|
40700
|
+
newNode.leaf = node.leaf;
|
|
40701
|
+
|
|
40702
|
+
calcBBox(node, this.toBBox);
|
|
40703
|
+
calcBBox(newNode, this.toBBox);
|
|
40704
|
+
|
|
40705
|
+
if (level) insertPath[level - 1].children.push(newNode);
|
|
40706
|
+
else this._splitRoot(node, newNode);
|
|
40707
|
+
}
|
|
40708
|
+
|
|
40709
|
+
_splitRoot(node, newNode) {
|
|
40710
|
+
// split root node
|
|
40711
|
+
this.data = createNode([node, newNode]);
|
|
40712
|
+
this.data.height = node.height + 1;
|
|
40713
|
+
this.data.leaf = false;
|
|
40714
|
+
calcBBox(this.data, this.toBBox);
|
|
40715
|
+
}
|
|
40716
|
+
|
|
40717
|
+
_chooseSplitIndex(node, m, M) {
|
|
40718
|
+
let index;
|
|
40719
|
+
let minOverlap = Infinity;
|
|
40720
|
+
let minArea = Infinity;
|
|
40721
|
+
|
|
40722
|
+
for (let i = m; i <= M - m; i++) {
|
|
40723
|
+
const bbox1 = distBBox(node, 0, i, this.toBBox);
|
|
40724
|
+
const bbox2 = distBBox(node, i, M, this.toBBox);
|
|
40725
|
+
|
|
40726
|
+
const overlap = intersectionArea(bbox1, bbox2);
|
|
40727
|
+
const area = bboxArea(bbox1) + bboxArea(bbox2);
|
|
40728
|
+
|
|
40729
|
+
// choose distribution with minimum overlap
|
|
40730
|
+
if (overlap < minOverlap) {
|
|
40731
|
+
minOverlap = overlap;
|
|
40732
|
+
index = i;
|
|
40733
|
+
|
|
40734
|
+
minArea = area < minArea ? area : minArea;
|
|
40735
|
+
|
|
40736
|
+
} else if (overlap === minOverlap) {
|
|
40737
|
+
// otherwise choose distribution with minimum area
|
|
40738
|
+
if (area < minArea) {
|
|
40739
|
+
minArea = area;
|
|
40740
|
+
index = i;
|
|
40741
|
+
}
|
|
40742
|
+
}
|
|
40743
|
+
}
|
|
40744
|
+
|
|
40745
|
+
return index || M - m;
|
|
40746
|
+
}
|
|
40747
|
+
|
|
40748
|
+
// sorts node children by the best axis for split
|
|
40749
|
+
_chooseSplitAxis(node, m, M) {
|
|
40750
|
+
const compareMinX = node.leaf ? this.compareMinX : compareNodeMinX;
|
|
40751
|
+
const compareMinY = node.leaf ? this.compareMinY : compareNodeMinY;
|
|
40752
|
+
const xMargin = this._allDistMargin(node, m, M, compareMinX);
|
|
40753
|
+
const yMargin = this._allDistMargin(node, m, M, compareMinY);
|
|
40754
|
+
|
|
40755
|
+
// if total distributions margin value is minimal for x, sort by minX,
|
|
40756
|
+
// otherwise it's already sorted by minY
|
|
40757
|
+
if (xMargin < yMargin) node.children.sort(compareMinX);
|
|
40758
|
+
}
|
|
40759
|
+
|
|
40760
|
+
// total margin of all possible split distributions where each node is at least m full
|
|
40761
|
+
_allDistMargin(node, m, M, compare) {
|
|
40762
|
+
node.children.sort(compare);
|
|
40763
|
+
|
|
40764
|
+
const toBBox = this.toBBox;
|
|
40765
|
+
const leftBBox = distBBox(node, 0, m, toBBox);
|
|
40766
|
+
const rightBBox = distBBox(node, M - m, M, toBBox);
|
|
40767
|
+
let margin = bboxMargin(leftBBox) + bboxMargin(rightBBox);
|
|
40768
|
+
|
|
40769
|
+
for (let i = m; i < M - m; i++) {
|
|
40770
|
+
const child = node.children[i];
|
|
40771
|
+
extend(leftBBox, node.leaf ? toBBox(child) : child);
|
|
40772
|
+
margin += bboxMargin(leftBBox);
|
|
40773
|
+
}
|
|
40774
|
+
|
|
40775
|
+
for (let i = M - m - 1; i >= m; i--) {
|
|
40776
|
+
const child = node.children[i];
|
|
40777
|
+
extend(rightBBox, node.leaf ? toBBox(child) : child);
|
|
40778
|
+
margin += bboxMargin(rightBBox);
|
|
40779
|
+
}
|
|
40780
|
+
|
|
40781
|
+
return margin;
|
|
40782
|
+
}
|
|
40783
|
+
|
|
40784
|
+
_adjustParentBBoxes(bbox, path, level) {
|
|
40785
|
+
// adjust bboxes along the given tree path
|
|
40786
|
+
for (let i = level; i >= 0; i--) {
|
|
40787
|
+
extend(path[i], bbox);
|
|
40788
|
+
}
|
|
40789
|
+
}
|
|
40790
|
+
|
|
40791
|
+
_condense(path) {
|
|
40792
|
+
// go through the path, removing empty nodes and updating bboxes
|
|
40793
|
+
for (let i = path.length - 1, siblings; i >= 0; i--) {
|
|
40794
|
+
if (path[i].children.length === 0) {
|
|
40795
|
+
if (i > 0) {
|
|
40796
|
+
siblings = path[i - 1].children;
|
|
40797
|
+
siblings.splice(siblings.indexOf(path[i]), 1);
|
|
40798
|
+
|
|
40799
|
+
} else this.clear();
|
|
40800
|
+
|
|
40801
|
+
} else calcBBox(path[i], this.toBBox);
|
|
40802
|
+
}
|
|
40803
|
+
}
|
|
40804
|
+
}
|
|
40805
|
+
|
|
40806
|
+
function findItem(item, items, equalsFn) {
|
|
40807
|
+
if (!equalsFn) return items.indexOf(item);
|
|
40808
|
+
|
|
40809
|
+
for (let i = 0; i < items.length; i++) {
|
|
40810
|
+
if (equalsFn(item, items[i])) return i;
|
|
40811
|
+
}
|
|
40812
|
+
return -1;
|
|
40813
|
+
}
|
|
40814
|
+
|
|
40815
|
+
// calculate node's bbox from bboxes of its children
|
|
40816
|
+
function calcBBox(node, toBBox) {
|
|
40817
|
+
distBBox(node, 0, node.children.length, toBBox, node);
|
|
40818
|
+
}
|
|
40819
|
+
|
|
40820
|
+
// min bounding rectangle of node children from k to p-1
|
|
40821
|
+
function distBBox(node, k, p, toBBox, destNode) {
|
|
40822
|
+
if (!destNode) destNode = createNode(null);
|
|
40823
|
+
destNode.minX = Infinity;
|
|
40824
|
+
destNode.minY = Infinity;
|
|
40825
|
+
destNode.maxX = -Infinity;
|
|
40826
|
+
destNode.maxY = -Infinity;
|
|
40827
|
+
|
|
40828
|
+
for (let i = k; i < p; i++) {
|
|
40829
|
+
const child = node.children[i];
|
|
40830
|
+
extend(destNode, node.leaf ? toBBox(child) : child);
|
|
40831
|
+
}
|
|
40832
|
+
|
|
40833
|
+
return destNode;
|
|
40834
|
+
}
|
|
40835
|
+
|
|
40836
|
+
function extend(a, b) {
|
|
40837
|
+
a.minX = Math.min(a.minX, b.minX);
|
|
40838
|
+
a.minY = Math.min(a.minY, b.minY);
|
|
40839
|
+
a.maxX = Math.max(a.maxX, b.maxX);
|
|
40840
|
+
a.maxY = Math.max(a.maxY, b.maxY);
|
|
40841
|
+
return a;
|
|
40842
|
+
}
|
|
40843
|
+
|
|
40844
|
+
function compareNodeMinX(a, b) { return a.minX - b.minX; }
|
|
40845
|
+
function compareNodeMinY(a, b) { return a.minY - b.minY; }
|
|
40846
|
+
|
|
40847
|
+
function bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); }
|
|
40848
|
+
function bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }
|
|
40849
|
+
|
|
40850
|
+
function enlargedArea(a, b) {
|
|
40851
|
+
return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *
|
|
40852
|
+
(Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));
|
|
40853
|
+
}
|
|
40854
|
+
|
|
40855
|
+
function intersectionArea(a, b) {
|
|
40856
|
+
const minX = Math.max(a.minX, b.minX);
|
|
40857
|
+
const minY = Math.max(a.minY, b.minY);
|
|
40858
|
+
const maxX = Math.min(a.maxX, b.maxX);
|
|
40859
|
+
const maxY = Math.min(a.maxY, b.maxY);
|
|
40860
|
+
|
|
40861
|
+
return Math.max(0, maxX - minX) *
|
|
40862
|
+
Math.max(0, maxY - minY);
|
|
40863
|
+
}
|
|
40864
|
+
|
|
40865
|
+
function contains(a, b) {
|
|
40866
|
+
return a.minX <= b.minX &&
|
|
40867
|
+
a.minY <= b.minY &&
|
|
40868
|
+
b.maxX <= a.maxX &&
|
|
40869
|
+
b.maxY <= a.maxY;
|
|
40870
|
+
}
|
|
40871
|
+
|
|
40872
|
+
function intersects(a, b) {
|
|
40873
|
+
return b.minX <= a.maxX &&
|
|
40874
|
+
b.minY <= a.maxY &&
|
|
40875
|
+
b.maxX >= a.minX &&
|
|
40876
|
+
b.maxY >= a.minY;
|
|
40877
|
+
}
|
|
40878
|
+
|
|
40879
|
+
function createNode(children) {
|
|
40880
|
+
return {
|
|
40881
|
+
children,
|
|
40882
|
+
height: 1,
|
|
40883
|
+
leaf: true,
|
|
40884
|
+
minX: Infinity,
|
|
40885
|
+
minY: Infinity,
|
|
40886
|
+
maxX: -Infinity,
|
|
40887
|
+
maxY: -Infinity
|
|
40888
|
+
};
|
|
40889
|
+
}
|
|
40890
|
+
|
|
40891
|
+
// sort an array so that items come in groups of n unsorted items, with groups sorted between each other;
|
|
40892
|
+
// combines selection algorithm with binary divide & conquer approach
|
|
40893
|
+
|
|
40894
|
+
function multiSelect(arr, left, right, n, compare) {
|
|
40895
|
+
const stack = [left, right];
|
|
40896
|
+
|
|
40897
|
+
while (stack.length) {
|
|
40898
|
+
right = stack.pop();
|
|
40899
|
+
left = stack.pop();
|
|
40900
|
+
|
|
40901
|
+
if (right - left <= n) continue;
|
|
40902
|
+
|
|
40903
|
+
const mid = left + Math.ceil((right - left) / n / 2) * n;
|
|
40904
|
+
quickselect(arr, mid, left, right, compare);
|
|
40905
|
+
|
|
40906
|
+
stack.push(left, mid, mid, right);
|
|
40907
|
+
}
|
|
40908
|
+
}
|
|
40909
|
+
|
|
40064
40910
|
/**
|
|
40065
|
-
*
|
|
40911
|
+
* R-Tree Data Structure
|
|
40912
|
+
*
|
|
40913
|
+
* R-Tree is a spatial data structure used for efficient indexing and querying
|
|
40914
|
+
* of multi-dimensional objects, particularly in geometric and spatial applications.
|
|
40915
|
+
*
|
|
40916
|
+
* It organizes objects into a tree hierarchy, grouping nearby objects together
|
|
40917
|
+
* in bounding boxes. Each node in the tree represents a bounding box that
|
|
40918
|
+
* contains its child nodes or leaf objects. This hierarchical structure allows
|
|
40919
|
+
* for faster spatial queries.
|
|
40920
|
+
*
|
|
40921
|
+
* @see https://en.wikipedia.org/wiki/R-tree
|
|
40922
|
+
*
|
|
40923
|
+
* Consider a 2D Space with four zones: A, B, C, D
|
|
40924
|
+
* +--------------------------+
|
|
40925
|
+
* | |
|
|
40926
|
+
* | +---+ +-------+ |
|
|
40927
|
+
* | | A | | B | |
|
|
40928
|
+
* | +---+ +-------+ |
|
|
40929
|
+
* | |
|
|
40930
|
+
* | |
|
|
40931
|
+
* | +---+ |
|
|
40932
|
+
* | | C | |
|
|
40933
|
+
* | +---+ |
|
|
40934
|
+
* | +-----------+ |
|
|
40935
|
+
* | | D | |
|
|
40936
|
+
* | +-----------+ |
|
|
40937
|
+
* | |
|
|
40938
|
+
* +--------------------------+
|
|
40939
|
+
*
|
|
40940
|
+
* It groups together zones that are spatially close into a minimum bounding box.
|
|
40941
|
+
* For example, A and B are grouped together in rectangle R1, and C and D are grouped
|
|
40942
|
+
* in R2.
|
|
40943
|
+
*
|
|
40944
|
+
* R0
|
|
40945
|
+
* +--------------------------+
|
|
40946
|
+
* | R1 |
|
|
40947
|
+
* | +-----------------+ |
|
|
40948
|
+
* | | A | | B | |
|
|
40949
|
+
* | +-----------------+ |
|
|
40950
|
+
* | |
|
|
40951
|
+
* | R2 |
|
|
40952
|
+
* | +---+---+---+ |
|
|
40953
|
+
* | | | C | | |
|
|
40954
|
+
* | | +---+ | |
|
|
40955
|
+
* | +-----------+ |
|
|
40956
|
+
* | | D | |
|
|
40957
|
+
* | +-----------+ |
|
|
40958
|
+
* | |
|
|
40959
|
+
* +--------------------------+
|
|
40960
|
+
*
|
|
40961
|
+
* The tree would look like this:
|
|
40962
|
+
* R0
|
|
40963
|
+
* / \
|
|
40964
|
+
* / \
|
|
40965
|
+
* R1 R2
|
|
40966
|
+
* | |
|
|
40967
|
+
* A,B C,D
|
|
40968
|
+
|
|
40969
|
+
* Choosing how to group the zones is crucial for the performance of the tree.
|
|
40970
|
+
* Key considerations include avoiding excessive empty space coverage and minimizing overlap
|
|
40971
|
+
* to reduce the number of subtrees processed during searches.
|
|
40972
|
+
*
|
|
40973
|
+
* Various heuristics exist for determining the optimal grouping strategy, such as "least enlargement"
|
|
40974
|
+
* which prioritizes grouping nodes resulting in the smallest increase in bounding box size. In cases where
|
|
40975
|
+
* the choice cannot be made based on this criterion due to the same enlargement for different groupings,
|
|
40976
|
+
* we then evaluate "least area," aiming to minimize the overall area of bounding boxes.
|
|
40977
|
+
*
|
|
40978
|
+
* This implementation is tailored for spreadsheet use, indexing objects associated
|
|
40979
|
+
* with a zone and a sheet.
|
|
40980
|
+
*
|
|
40981
|
+
* It uses the RBush library under the hood. One 2D RBush R-tree per sheet.
|
|
40982
|
+
* @see https://github.com/mourner/rbush
|
|
40983
|
+
*/
|
|
40984
|
+
class SpreadsheetRTree {
|
|
40985
|
+
/**
|
|
40986
|
+
* One 2D R-tree per sheet
|
|
40987
|
+
*/
|
|
40988
|
+
rTrees = {};
|
|
40989
|
+
/**
|
|
40990
|
+
* Bulk-inserts the given items into the tree. Bulk insertion is usually ~2-3 times
|
|
40991
|
+
* faster than inserting items one by one. After bulk loading (bulk insertion into
|
|
40992
|
+
* an empty tree), subsequent query performance is also ~20-30% better.
|
|
40993
|
+
*/
|
|
40994
|
+
constructor(items = []) {
|
|
40995
|
+
const rangesPerSheet = {};
|
|
40996
|
+
for (const item of items) {
|
|
40997
|
+
const sheetId = item.boundingBox.sheetId;
|
|
40998
|
+
if (!rangesPerSheet[sheetId]) {
|
|
40999
|
+
rangesPerSheet[sheetId] = [];
|
|
41000
|
+
}
|
|
41001
|
+
rangesPerSheet[sheetId].push(item);
|
|
41002
|
+
}
|
|
41003
|
+
for (const sheetId in rangesPerSheet) {
|
|
41004
|
+
this.rTrees[sheetId] = new ZoneRBush();
|
|
41005
|
+
this.rTrees[sheetId].load(rangesPerSheet[sheetId]); // bulk-insert
|
|
41006
|
+
}
|
|
41007
|
+
}
|
|
41008
|
+
insert(item) {
|
|
41009
|
+
const sheetId = item.boundingBox.sheetId;
|
|
41010
|
+
if (!this.rTrees[sheetId]) {
|
|
41011
|
+
this.rTrees[sheetId] = new ZoneRBush();
|
|
41012
|
+
}
|
|
41013
|
+
this.rTrees[sheetId].insert(item);
|
|
41014
|
+
}
|
|
41015
|
+
search({ zone, sheetId }) {
|
|
41016
|
+
if (!this.rTrees[sheetId]) {
|
|
41017
|
+
return [];
|
|
41018
|
+
}
|
|
41019
|
+
return this.rTrees[sheetId].search({
|
|
41020
|
+
minX: zone.left,
|
|
41021
|
+
minY: zone.top,
|
|
41022
|
+
maxX: zone.right,
|
|
41023
|
+
maxY: zone.bottom,
|
|
41024
|
+
});
|
|
41025
|
+
}
|
|
41026
|
+
remove(item) {
|
|
41027
|
+
const sheetId = item.boundingBox.sheetId;
|
|
41028
|
+
if (!this.rTrees[sheetId]) {
|
|
41029
|
+
return;
|
|
41030
|
+
}
|
|
41031
|
+
this.rTrees[sheetId].remove(item, deepEquals);
|
|
41032
|
+
}
|
|
41033
|
+
}
|
|
41034
|
+
/**
|
|
41035
|
+
* RBush extension to use zones as bounding boxes
|
|
41036
|
+
*/
|
|
41037
|
+
class ZoneRBush extends RBush {
|
|
41038
|
+
toBBox({ boundingBox }) {
|
|
41039
|
+
const zone = boundingBox.zone;
|
|
41040
|
+
return {
|
|
41041
|
+
minX: zone.left,
|
|
41042
|
+
minY: zone.top,
|
|
41043
|
+
maxX: zone.right,
|
|
41044
|
+
maxY: zone.bottom,
|
|
41045
|
+
};
|
|
41046
|
+
}
|
|
41047
|
+
compareMinX(a, b) {
|
|
41048
|
+
return a.boundingBox.zone.left - b.boundingBox.zone.left;
|
|
41049
|
+
}
|
|
41050
|
+
compareMinY(a, b) {
|
|
41051
|
+
return a.boundingBox.zone.top - b.boundingBox.zone.top;
|
|
41052
|
+
}
|
|
41053
|
+
}
|
|
41054
|
+
|
|
41055
|
+
/**
|
|
41056
|
+
* Implementation of a dependency Graph.
|
|
40066
41057
|
* The graph is used to evaluate the cells in the correct
|
|
40067
41058
|
* order, and should be updated each time a cell's content is modified
|
|
40068
41059
|
*
|
|
41060
|
+
* It uses an R-Tree data structure to efficiently find dependent cells.
|
|
40069
41061
|
*/
|
|
40070
41062
|
class FormulaDependencyGraph {
|
|
40071
|
-
|
|
40072
|
-
* Internal structure:
|
|
40073
|
-
* - key: a cell position (encoded as an integer)
|
|
40074
|
-
* - value: a set of cell positions that depends on the key
|
|
40075
|
-
*
|
|
40076
|
-
* Given
|
|
40077
|
-
* - A1:"= B1 + SQRT(B2)"
|
|
40078
|
-
* - C1:"= B1";
|
|
40079
|
-
* - C2:"= C1"
|
|
40080
|
-
*
|
|
40081
|
-
* we will have something like:
|
|
40082
|
-
* - B1 ---> (A1, C1) meaning A1 and C1 depends on B1
|
|
40083
|
-
* - B2 ---> (A1) meaning A1 depends on B2
|
|
40084
|
-
* - C1 ---> (C2) meaning C2 depends on C1
|
|
40085
|
-
*/
|
|
40086
|
-
inverseDependencies = new Map();
|
|
41063
|
+
encoder;
|
|
40087
41064
|
dependencies = new Map();
|
|
41065
|
+
rTree;
|
|
41066
|
+
constructor(encoder, data = []) {
|
|
41067
|
+
this.encoder = encoder;
|
|
41068
|
+
this.rTree = new SpreadsheetRTree(data);
|
|
41069
|
+
}
|
|
40088
41070
|
removeAllDependencies(formulaPositionId) {
|
|
40089
|
-
const
|
|
40090
|
-
if (!
|
|
41071
|
+
const ranges = this.dependencies.get(formulaPositionId);
|
|
41072
|
+
if (!ranges) {
|
|
40091
41073
|
return;
|
|
40092
41074
|
}
|
|
40093
|
-
for (const
|
|
40094
|
-
this.
|
|
41075
|
+
for (const range of ranges) {
|
|
41076
|
+
this.rTree.remove(range);
|
|
40095
41077
|
}
|
|
40096
41078
|
this.dependencies.delete(formulaPositionId);
|
|
40097
41079
|
}
|
|
40098
41080
|
addDependencies(formulaPositionId, dependencies) {
|
|
40099
|
-
|
|
40100
|
-
|
|
40101
|
-
|
|
40102
|
-
|
|
40103
|
-
|
|
40104
|
-
|
|
40105
|
-
|
|
40106
|
-
|
|
41081
|
+
const rTreeItems = dependencies.map(({ sheetId, zone }) => ({
|
|
41082
|
+
data: formulaPositionId,
|
|
41083
|
+
boundingBox: {
|
|
41084
|
+
zone,
|
|
41085
|
+
sheetId,
|
|
41086
|
+
},
|
|
41087
|
+
}));
|
|
41088
|
+
for (const item of rTreeItems) {
|
|
41089
|
+
this.rTree.insert(item);
|
|
40107
41090
|
}
|
|
40108
41091
|
const existingDependencies = this.dependencies.get(formulaPositionId);
|
|
40109
41092
|
if (existingDependencies) {
|
|
40110
|
-
existingDependencies.push(...
|
|
41093
|
+
existingDependencies.push(...rTreeItems);
|
|
40111
41094
|
}
|
|
40112
41095
|
else {
|
|
40113
|
-
this.dependencies.set(formulaPositionId,
|
|
41096
|
+
this.dependencies.set(formulaPositionId, rTreeItems);
|
|
40114
41097
|
}
|
|
40115
41098
|
}
|
|
40116
41099
|
/**
|
|
@@ -40118,20 +41101,20 @@
|
|
|
40118
41101
|
* in the correct order they should be evaluated.
|
|
40119
41102
|
* This is called a topological ordering (excluding cycles)
|
|
40120
41103
|
*/
|
|
40121
|
-
getCellsDependingOn(
|
|
41104
|
+
getCellsDependingOn(ranges) {
|
|
40122
41105
|
const visited = new JetSet();
|
|
40123
|
-
const queue = Array.from(
|
|
41106
|
+
const queue = Array.from(ranges).reverse();
|
|
40124
41107
|
while (queue.length > 0) {
|
|
40125
|
-
const
|
|
40126
|
-
visited.add(
|
|
40127
|
-
const
|
|
40128
|
-
for (const
|
|
40129
|
-
if (!visited.has(
|
|
40130
|
-
queue.push(
|
|
41108
|
+
const range = queue.pop();
|
|
41109
|
+
visited.add(...this.encoder.encodeBoundingBox(range));
|
|
41110
|
+
const impactedPositionIds = this.rTree.search(range).map((dep) => dep.data);
|
|
41111
|
+
for (const positionId of impactedPositionIds) {
|
|
41112
|
+
if (!visited.has(positionId)) {
|
|
41113
|
+
queue.push(this.encoder.decodeToBoundingBox(positionId));
|
|
40131
41114
|
}
|
|
40132
41115
|
}
|
|
40133
41116
|
}
|
|
40134
|
-
visited.delete(...
|
|
41117
|
+
visited.delete(...ranges.flatMap((r) => this.encoder.encodeBoundingBox(r)));
|
|
40135
41118
|
return visited;
|
|
40136
41119
|
}
|
|
40137
41120
|
}
|
|
@@ -40219,9 +41202,9 @@
|
|
|
40219
41202
|
context;
|
|
40220
41203
|
getters;
|
|
40221
41204
|
compilationParams;
|
|
40222
|
-
|
|
41205
|
+
encoder = new PositionBitsEncoder();
|
|
40223
41206
|
evaluatedCells = new Map();
|
|
40224
|
-
formulaDependencies = lazy(new FormulaDependencyGraph());
|
|
41207
|
+
formulaDependencies = lazy(new FormulaDependencyGraph(this.encoder));
|
|
40225
41208
|
blockedArrayFormulas = new Set();
|
|
40226
41209
|
spreadingRelations = new SpreadingRelation();
|
|
40227
41210
|
constructor(context, getters) {
|
|
@@ -40230,23 +41213,23 @@
|
|
|
40230
41213
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
40231
41214
|
}
|
|
40232
41215
|
getEvaluatedCell(position) {
|
|
40233
|
-
return (this.evaluatedCells.get(this.
|
|
41216
|
+
return (this.evaluatedCells.get(this.encoder.encode(position)) ||
|
|
40234
41217
|
createEvaluatedCell("", { locale: this.getters.getLocale() }));
|
|
40235
41218
|
}
|
|
40236
41219
|
getSpreadPositionsOf(position) {
|
|
40237
|
-
const positionId = this.
|
|
41220
|
+
const positionId = this.encoder.encode(position);
|
|
40238
41221
|
if (!this.spreadingRelations.isArrayFormula(positionId)) {
|
|
40239
41222
|
return [];
|
|
40240
41223
|
}
|
|
40241
|
-
return Array.from(this.spreadingRelations.getArrayResultPositionIds(positionId)).map(this.
|
|
41224
|
+
return Array.from(this.spreadingRelations.getArrayResultPositionIds(positionId)).map((positionId) => this.encoder.decode(positionId));
|
|
40242
41225
|
}
|
|
40243
41226
|
getArrayFormulaSpreadingOn(position) {
|
|
40244
|
-
const positionId = this.
|
|
41227
|
+
const positionId = this.encoder.encode(position);
|
|
40245
41228
|
const formulaPosition = this.getArrayFormulaSpreadingOnId(positionId);
|
|
40246
|
-
return formulaPosition !== undefined ? this.
|
|
41229
|
+
return formulaPosition !== undefined ? this.encoder.decode(formulaPosition) : undefined;
|
|
40247
41230
|
}
|
|
40248
41231
|
getEvaluatedPositions() {
|
|
40249
|
-
return [...this.evaluatedCells.keys()].map(this.
|
|
41232
|
+
return [...this.evaluatedCells.keys()].map((p) => this.encoder.decode(p));
|
|
40250
41233
|
}
|
|
40251
41234
|
getArrayFormulaSpreadingOnId(positionId) {
|
|
40252
41235
|
if (!this.spreadingRelations.hasArrayFormulaResult(positionId)) {
|
|
@@ -40256,7 +41239,7 @@
|
|
|
40256
41239
|
return Array.from(arrayFormulas).find((positionId) => !this.blockedArrayFormulas.has(positionId));
|
|
40257
41240
|
}
|
|
40258
41241
|
updateDependencies(position) {
|
|
40259
|
-
const positionId = this.
|
|
41242
|
+
const positionId = this.encoder.encode(position);
|
|
40260
41243
|
this.formulaDependencies().removeAllDependencies(positionId);
|
|
40261
41244
|
const dependencies = this.getDirectDependencies(positionId);
|
|
40262
41245
|
this.formulaDependencies().addDependencies(positionId, dependencies);
|
|
@@ -40266,12 +41249,12 @@
|
|
|
40266
41249
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
40267
41250
|
}
|
|
40268
41251
|
evaluateCells(positions) {
|
|
40269
|
-
const cells = positions.map(this.
|
|
41252
|
+
const cells = positions.map((p) => this.encoder.encode(p));
|
|
40270
41253
|
const cellsToCompute = new JetSet(cells);
|
|
40271
|
-
const
|
|
41254
|
+
const arrayFormulasPositionIds = this.getArrayFormulasImpactedByChangesOf(cells);
|
|
40272
41255
|
cellsToCompute.add(...this.getCellsDependingOn(cells));
|
|
40273
|
-
cellsToCompute.add(...
|
|
40274
|
-
cellsToCompute.add(...this.getCellsDependingOn(
|
|
41256
|
+
cellsToCompute.add(...arrayFormulasPositionIds);
|
|
41257
|
+
cellsToCompute.add(...this.getCellsDependingOn(arrayFormulasPositionIds));
|
|
40275
41258
|
this.evaluate(cellsToCompute);
|
|
40276
41259
|
}
|
|
40277
41260
|
getArrayFormulasImpactedByChangesOf(positionIds) {
|
|
@@ -40294,12 +41277,14 @@
|
|
|
40294
41277
|
this.blockedArrayFormulas = new Set();
|
|
40295
41278
|
this.spreadingRelations = new SpreadingRelation();
|
|
40296
41279
|
this.formulaDependencies = lazy(() => {
|
|
40297
|
-
const
|
|
40298
|
-
|
|
40299
|
-
|
|
40300
|
-
|
|
40301
|
-
|
|
40302
|
-
|
|
41280
|
+
const dependencies = [...this.getAllCells()].flatMap((positionId) => this.getDirectDependencies(positionId).map((range) => ({
|
|
41281
|
+
data: positionId,
|
|
41282
|
+
boundingBox: {
|
|
41283
|
+
zone: range.zone,
|
|
41284
|
+
sheetId: range.sheetId,
|
|
41285
|
+
},
|
|
41286
|
+
})));
|
|
41287
|
+
return new FormulaDependencyGraph(this.encoder, dependencies);
|
|
40303
41288
|
});
|
|
40304
41289
|
}
|
|
40305
41290
|
evaluateAllCells() {
|
|
@@ -40321,7 +41306,7 @@
|
|
|
40321
41306
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
40322
41307
|
const cellIds = this.getters.getCells(sheetId);
|
|
40323
41308
|
for (const cellId in cellIds) {
|
|
40324
|
-
positionIds.add(this.
|
|
41309
|
+
positionIds.add(this.encoder.encode(this.getters.getCellPosition(cellId)));
|
|
40325
41310
|
}
|
|
40326
41311
|
}
|
|
40327
41312
|
return positionIds;
|
|
@@ -40366,7 +41351,7 @@
|
|
|
40366
41351
|
if (!this.blockedArrayFormulas.has(positionId)) {
|
|
40367
41352
|
this.invalidateSpreading(positionId);
|
|
40368
41353
|
}
|
|
40369
|
-
const cellPosition = this.
|
|
41354
|
+
const cellPosition = this.encoder.decode(positionId);
|
|
40370
41355
|
const cell = this.getters.getCell(cellPosition);
|
|
40371
41356
|
if (cell === undefined) {
|
|
40372
41357
|
return createEvaluatedCell("", { locale: this.getters.getLocale() });
|
|
@@ -40389,7 +41374,7 @@
|
|
|
40389
41374
|
}
|
|
40390
41375
|
}
|
|
40391
41376
|
computeAndSave(position) {
|
|
40392
|
-
const positionId = this.
|
|
41377
|
+
const positionId = this.encoder.encode(position);
|
|
40393
41378
|
const evaluatedCell = this.computeCell(positionId);
|
|
40394
41379
|
if (!this.evaluatedCells.has(positionId)) {
|
|
40395
41380
|
this.setEvaluatedCell(positionId, evaluatedCell);
|
|
@@ -40444,15 +41429,15 @@
|
|
|
40444
41429
|
throw new Error(_t("Result couldn't be automatically expanded. Please insert more columns and rows."));
|
|
40445
41430
|
}
|
|
40446
41431
|
updateSpreadRelation({ sheetId, col, row, }) {
|
|
40447
|
-
const arrayFormulaPositionId = this.
|
|
41432
|
+
const arrayFormulaPositionId = this.encoder.encode({ sheetId, col, row });
|
|
40448
41433
|
return (i, j) => {
|
|
40449
41434
|
const position = { sheetId, col: i + col, row: j + row };
|
|
40450
|
-
const resultPositionId = this.
|
|
41435
|
+
const resultPositionId = this.encoder.encode(position);
|
|
40451
41436
|
this.spreadingRelations.addRelation({ resultPositionId, arrayFormulaPositionId });
|
|
40452
41437
|
};
|
|
40453
41438
|
}
|
|
40454
41439
|
checkCollision({ sheetId, col, row }) {
|
|
40455
|
-
const formulaPositionId = this.
|
|
41440
|
+
const formulaPositionId = this.encoder.encode({ sheetId, col, row });
|
|
40456
41441
|
return (i, j) => {
|
|
40457
41442
|
const position = { sheetId: sheetId, col: i + col, row: j + row };
|
|
40458
41443
|
const rawCell = this.getters.getCell(position);
|
|
@@ -40473,7 +41458,7 @@
|
|
|
40473
41458
|
format: format || matrixResult[i][j]?.format,
|
|
40474
41459
|
locale: this.getters.getLocale(),
|
|
40475
41460
|
});
|
|
40476
|
-
const positionId = this.
|
|
41461
|
+
const positionId = this.encoder.encode(position);
|
|
40477
41462
|
this.setEvaluatedCell(positionId, evaluatedCell);
|
|
40478
41463
|
// check if formula dependencies present in the spread zone
|
|
40479
41464
|
// if so, they need to be recomputed
|
|
@@ -40505,29 +41490,17 @@
|
|
|
40505
41490
|
if (!cell?.isFormula) {
|
|
40506
41491
|
return [];
|
|
40507
41492
|
}
|
|
40508
|
-
|
|
40509
|
-
for (const range of cell.compiledFormula.dependencies) {
|
|
40510
|
-
if (range.invalidSheetName || range.invalidXc) {
|
|
40511
|
-
continue;
|
|
40512
|
-
}
|
|
40513
|
-
const sheetId = range.sheetId;
|
|
40514
|
-
forEachPositionsInZone(range.zone, (col, row) => {
|
|
40515
|
-
dependencies.push(this.encodePosition({ sheetId, col, row }));
|
|
40516
|
-
});
|
|
40517
|
-
}
|
|
40518
|
-
return dependencies;
|
|
41493
|
+
return cell.compiledFormula.dependencies;
|
|
40519
41494
|
}
|
|
40520
41495
|
getCellsDependingOn(positionIds) {
|
|
40521
|
-
|
|
41496
|
+
const ranges = [];
|
|
41497
|
+
for (const positionId of positionIds) {
|
|
41498
|
+
ranges.push(this.encoder.decodeToBoundingBox(positionId));
|
|
41499
|
+
}
|
|
41500
|
+
return this.formulaDependencies().getCellsDependingOn(ranges);
|
|
40522
41501
|
}
|
|
40523
41502
|
getCell(positionId) {
|
|
40524
|
-
return this.getters.getCell(this.
|
|
40525
|
-
}
|
|
40526
|
-
encodePosition(position) {
|
|
40527
|
-
return this.positionEncoder.encode(position);
|
|
40528
|
-
}
|
|
40529
|
-
decodePosition(positionId) {
|
|
40530
|
-
return this.positionEncoder.decode(positionId);
|
|
41503
|
+
return this.getters.getCell(this.encoder.decode(positionId));
|
|
40531
41504
|
}
|
|
40532
41505
|
}
|
|
40533
41506
|
function forEachSpreadPositionInMatrix(nbColumns, nbRows, callback) {
|
|
@@ -40583,6 +41556,13 @@
|
|
|
40583
41556
|
encode({ sheetId, col, row }) {
|
|
40584
41557
|
return (this.encodeSheet(sheetId) << 42n) | (BigInt(col) << 21n) | BigInt(row);
|
|
40585
41558
|
}
|
|
41559
|
+
encodeBoundingBox({ sheetId, zone }) {
|
|
41560
|
+
const positions = [];
|
|
41561
|
+
forEachPositionsInZone(zone, (col, row) => {
|
|
41562
|
+
positions.push(this.encode({ sheetId, col, row }));
|
|
41563
|
+
});
|
|
41564
|
+
return positions;
|
|
41565
|
+
}
|
|
40586
41566
|
decode(id) {
|
|
40587
41567
|
// keep only the last 21 bits by AND-ing the bit sequence with 21 ones
|
|
40588
41568
|
const row = Number(id & 2097151n);
|
|
@@ -40590,6 +41570,10 @@
|
|
|
40590
41570
|
const sheetId = this.decodeSheet(id >> 42n);
|
|
40591
41571
|
return { sheetId, col, row };
|
|
40592
41572
|
}
|
|
41573
|
+
decodeToBoundingBox(id) {
|
|
41574
|
+
const { sheetId, col, row } = this.decode(id);
|
|
41575
|
+
return { sheetId, zone: { left: col, top: row, right: col, bottom: row } };
|
|
41576
|
+
}
|
|
40593
41577
|
encodeSheet(sheetId) {
|
|
40594
41578
|
const sheetKey = this.sheetMapping[sheetId];
|
|
40595
41579
|
if (sheetKey === undefined) {
|
|
@@ -40772,7 +41756,12 @@
|
|
|
40772
41756
|
// Getters
|
|
40773
41757
|
// ---------------------------------------------------------------------------
|
|
40774
41758
|
evaluateFormula(sheetId, formulaString) {
|
|
40775
|
-
|
|
41759
|
+
try {
|
|
41760
|
+
return this.evaluator.evaluateFormula(sheetId, formulaString);
|
|
41761
|
+
}
|
|
41762
|
+
catch (error) {
|
|
41763
|
+
return error instanceof EvaluationError ? error.errorType : CellErrorType.GenericError;
|
|
41764
|
+
}
|
|
40776
41765
|
}
|
|
40777
41766
|
/**
|
|
40778
41767
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -41041,7 +42030,7 @@
|
|
|
41041
42030
|
}
|
|
41042
42031
|
|
|
41043
42032
|
class EvaluationChartPlugin extends UIPlugin {
|
|
41044
|
-
static getters = ["getChartRuntime", "
|
|
42033
|
+
static getters = ["getChartRuntime", "getStyleOfSingleCellChart"];
|
|
41045
42034
|
charts = {};
|
|
41046
42035
|
createRuntimeChart = chartRuntimeFactory(this.getters);
|
|
41047
42036
|
handle(cmd) {
|
|
@@ -41079,25 +42068,26 @@
|
|
|
41079
42068
|
return this.charts[figureId];
|
|
41080
42069
|
}
|
|
41081
42070
|
/**
|
|
41082
|
-
* Get the background
|
|
41083
|
-
* of the chart. In order of priority, it will return :
|
|
41084
|
-
*
|
|
41085
|
-
* - the chart background color if one is defined
|
|
41086
|
-
* - the fill color of the cell if one is defined
|
|
41087
|
-
* - the fill color of the cell from conditional formats if one is defined
|
|
41088
|
-
* - the default chart color if no other color is defined
|
|
42071
|
+
* Get the background and textColor of a chart based on the color of the first cell of the main range of the chart.
|
|
41089
42072
|
*/
|
|
41090
|
-
|
|
42073
|
+
getStyleOfSingleCellChart(chartBackground, mainRange) {
|
|
41091
42074
|
if (chartBackground)
|
|
41092
|
-
return chartBackground;
|
|
42075
|
+
return { background: chartBackground, fontColor: chartFontColor(chartBackground) };
|
|
41093
42076
|
if (!mainRange) {
|
|
41094
|
-
return
|
|
42077
|
+
return {
|
|
42078
|
+
background: BACKGROUND_CHART_COLOR,
|
|
42079
|
+
fontColor: chartFontColor(BACKGROUND_CHART_COLOR),
|
|
42080
|
+
};
|
|
41095
42081
|
}
|
|
41096
42082
|
const col = mainRange.zone.left;
|
|
41097
42083
|
const row = mainRange.zone.top;
|
|
41098
42084
|
const sheetId = mainRange.sheetId;
|
|
41099
42085
|
const style = this.getters.getCellComputedStyle({ sheetId, col, row });
|
|
41100
|
-
|
|
42086
|
+
const background = style.fillColor || BACKGROUND_CHART_COLOR;
|
|
42087
|
+
return {
|
|
42088
|
+
background,
|
|
42089
|
+
fontColor: style.textColor || chartFontColor(background),
|
|
42090
|
+
};
|
|
41101
42091
|
}
|
|
41102
42092
|
exportForExcel(data) {
|
|
41103
42093
|
for (const sheet of data.sheets) {
|
|
@@ -41208,45 +42198,40 @@
|
|
|
41208
42198
|
getComputedStyles(sheetId) {
|
|
41209
42199
|
const computedStyle = {};
|
|
41210
42200
|
for (let cf of this.getters.getConditionalFormats(sheetId).reverse()) {
|
|
41211
|
-
|
|
41212
|
-
|
|
41213
|
-
|
|
41214
|
-
|
|
41215
|
-
|
|
41216
|
-
|
|
41217
|
-
|
|
41218
|
-
|
|
41219
|
-
|
|
41220
|
-
|
|
41221
|
-
|
|
41222
|
-
for (let
|
|
41223
|
-
|
|
41224
|
-
|
|
41225
|
-
|
|
41226
|
-
const
|
|
41227
|
-
|
|
41228
|
-
|
|
41229
|
-
|
|
41230
|
-
|
|
41231
|
-
|
|
41232
|
-
});
|
|
41233
|
-
}
|
|
41234
|
-
return value;
|
|
41235
|
-
});
|
|
41236
|
-
if (predicate && predicate(target, { ...cf.rule, values })) {
|
|
41237
|
-
if (!computedStyle[col])
|
|
41238
|
-
computedStyle[col] = [];
|
|
41239
|
-
// we must combine all the properties of all the CF rules applied to the given cell
|
|
41240
|
-
computedStyle[col][row] = Object.assign(computedStyle[col]?.[row] || {}, cf.rule.style);
|
|
42201
|
+
switch (cf.rule.type) {
|
|
42202
|
+
case "ColorScaleRule":
|
|
42203
|
+
for (let range of cf.ranges) {
|
|
42204
|
+
this.applyColorScale(sheetId, range, cf.rule, computedStyle);
|
|
42205
|
+
}
|
|
42206
|
+
break;
|
|
42207
|
+
case "CellIsRule":
|
|
42208
|
+
const formulas = cf.rule.values.map((value) => value.startsWith("=") ? compile(value) : undefined);
|
|
42209
|
+
for (let ref of cf.ranges) {
|
|
42210
|
+
const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
|
|
42211
|
+
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
42212
|
+
for (let col = zone.left; col <= zone.right; col++) {
|
|
42213
|
+
const predicate = this.rulePredicate[cf.rule.type];
|
|
42214
|
+
const target = { sheetId, col, row };
|
|
42215
|
+
const values = cf.rule.values.map((value, i) => {
|
|
42216
|
+
const compiledFormula = formulas[i];
|
|
42217
|
+
if (compiledFormula) {
|
|
42218
|
+
return this.getters.getTranslatedCellFormula(sheetId, col - zone.left, row - zone.top, {
|
|
42219
|
+
...compiledFormula,
|
|
42220
|
+
dependencies: compiledFormula.dependencies.map((d) => this.getters.getRangeFromSheetXC(sheetId, d)),
|
|
42221
|
+
});
|
|
41241
42222
|
}
|
|
42223
|
+
return value;
|
|
42224
|
+
});
|
|
42225
|
+
if (predicate && predicate(target, { ...cf.rule, values })) {
|
|
42226
|
+
if (!computedStyle[col])
|
|
42227
|
+
computedStyle[col] = [];
|
|
42228
|
+
// we must combine all the properties of all the CF rules applied to the given cell
|
|
42229
|
+
computedStyle[col][row] = Object.assign(computedStyle[col]?.[row] || {}, cf.rule.style);
|
|
41242
42230
|
}
|
|
41243
42231
|
}
|
|
41244
42232
|
}
|
|
41245
|
-
|
|
41246
|
-
|
|
41247
|
-
}
|
|
41248
|
-
catch (_) {
|
|
41249
|
-
// we don't care about the errors within the evaluation of a rule
|
|
42233
|
+
}
|
|
42234
|
+
break;
|
|
41250
42235
|
}
|
|
41251
42236
|
}
|
|
41252
42237
|
return computedStyle;
|
|
@@ -41857,11 +42842,6 @@
|
|
|
41857
42842
|
return "Success" /* CommandResult.Success */;
|
|
41858
42843
|
}
|
|
41859
42844
|
return "InvalidAutofillSelection" /* CommandResult.InvalidAutofillSelection */;
|
|
41860
|
-
case "AUTOFILL_AUTO":
|
|
41861
|
-
const zone = this.getters.getSelectedZone();
|
|
41862
|
-
return zone.top === zone.bottom
|
|
41863
|
-
? "Success" /* CommandResult.Success */
|
|
41864
|
-
: "CancelledForUnknownReason" /* CommandResult.CancelledForUnknownReason */;
|
|
41865
42845
|
}
|
|
41866
42846
|
return "Success" /* CommandResult.Success */;
|
|
41867
42847
|
}
|
|
@@ -42018,7 +42998,7 @@
|
|
|
42018
42998
|
let row = zone.bottom;
|
|
42019
42999
|
if (col > 0) {
|
|
42020
43000
|
let leftPosition = { sheetId, col: col - 1, row };
|
|
42021
|
-
while (this.getters.
|
|
43001
|
+
while (this.getters.getCorrespondingFormulaCell(leftPosition) ||
|
|
42022
43002
|
this.getters.getCell(leftPosition)?.content) {
|
|
42023
43003
|
row += 1;
|
|
42024
43004
|
leftPosition = { sheetId, col: col - 1, row };
|
|
@@ -42028,7 +43008,7 @@
|
|
|
42028
43008
|
col = zone.right;
|
|
42029
43009
|
if (col <= this.getters.getNumberCols(sheetId)) {
|
|
42030
43010
|
let rightPosition = { sheetId, col: col + 1, row };
|
|
42031
|
-
while (this.getters.
|
|
43011
|
+
while (this.getters.getCorrespondingFormulaCell(rightPosition) ||
|
|
42032
43012
|
this.getters.getCell(rightPosition)?.content) {
|
|
42033
43013
|
row += 1;
|
|
42034
43014
|
rightPosition = { sheetId, col: col + 1, row };
|
|
@@ -43623,7 +44603,7 @@
|
|
|
43623
44603
|
isPasteAllowed(target, clipboardOption) {
|
|
43624
44604
|
const sheetId = this.getters.getActiveSheetId();
|
|
43625
44605
|
if (this.operation === "CUT" && clipboardOption?.pasteOption !== undefined) {
|
|
43626
|
-
// cannot paste only format or
|
|
44606
|
+
// cannot paste only format or as value if the previous operation is a CUT
|
|
43627
44607
|
return "WrongPasteOption" /* CommandResult.WrongPasteOption */;
|
|
43628
44608
|
}
|
|
43629
44609
|
if (target.length > 1) {
|
|
@@ -43805,7 +44785,7 @@
|
|
|
43805
44785
|
// This condition is used to determine if we have to paste the CF or not.
|
|
43806
44786
|
// We have to do it when the command handled is "PASTE", not "INSERT_CELL"
|
|
43807
44787
|
// or "DELETE_CELL". So, the state should be the local state
|
|
43808
|
-
const shouldPasteCF = clipboardOptions?.pasteOption !== "
|
|
44788
|
+
const shouldPasteCF = clipboardOptions?.pasteOption !== "asValue" && clipboardOptions?.shouldPasteCF;
|
|
43809
44789
|
const shouldPasteDV = !clipboardOptions?.pasteOption;
|
|
43810
44790
|
const sheetId = this.getters.getActiveSheetId();
|
|
43811
44791
|
// first, add missing cols/rows if needed
|
|
@@ -43841,10 +44821,11 @@
|
|
|
43841
44821
|
pasteCell(origin, target, operation, clipboardOption) {
|
|
43842
44822
|
const { sheetId, col, row } = target;
|
|
43843
44823
|
const targetCell = this.getters.getEvaluatedCell(target);
|
|
43844
|
-
|
|
44824
|
+
const originFormat = origin.cell?.format ?? origin.evaluatedCell.format;
|
|
44825
|
+
if (clipboardOption?.pasteOption === "asValue") {
|
|
43845
44826
|
const locale = this.getters.getLocale();
|
|
43846
44827
|
const content = formatValue(origin.evaluatedCell.value, { locale });
|
|
43847
|
-
this.dispatch("UPDATE_CELL", { ...target, content });
|
|
44828
|
+
this.dispatch("UPDATE_CELL", { ...target, content, format: originFormat });
|
|
43848
44829
|
return;
|
|
43849
44830
|
}
|
|
43850
44831
|
const targetBorders = this.getters.getCellBorder(target);
|
|
@@ -43860,7 +44841,7 @@
|
|
|
43860
44841
|
this.dispatch("UPDATE_CELL", {
|
|
43861
44842
|
...target,
|
|
43862
44843
|
style: origin.cell?.style ?? null,
|
|
43863
|
-
format:
|
|
44844
|
+
format: originFormat ?? targetCell.format,
|
|
43864
44845
|
});
|
|
43865
44846
|
return;
|
|
43866
44847
|
}
|
|
@@ -50063,6 +51044,20 @@
|
|
|
50063
51044
|
`;
|
|
50064
51045
|
class RippleEffect extends owl.Component {
|
|
50065
51046
|
static template = "o-spreadsheet-RippleEffect";
|
|
51047
|
+
static props = {
|
|
51048
|
+
x: String,
|
|
51049
|
+
y: String,
|
|
51050
|
+
color: String,
|
|
51051
|
+
opacity: Number,
|
|
51052
|
+
duration: Number,
|
|
51053
|
+
width: Number,
|
|
51054
|
+
height: Number,
|
|
51055
|
+
offsetY: Number,
|
|
51056
|
+
offsetX: Number,
|
|
51057
|
+
allowOverflow: Boolean,
|
|
51058
|
+
onAnimationEnd: Function,
|
|
51059
|
+
style: String,
|
|
51060
|
+
};
|
|
50066
51061
|
rippleRef = owl.useRef("ripple");
|
|
50067
51062
|
setup() {
|
|
50068
51063
|
let animation = undefined;
|
|
@@ -50098,22 +51093,23 @@
|
|
|
50098
51093
|
});
|
|
50099
51094
|
}
|
|
50100
51095
|
}
|
|
50101
|
-
RippleEffect.props = {
|
|
50102
|
-
x: String,
|
|
50103
|
-
y: String,
|
|
50104
|
-
color: String,
|
|
50105
|
-
opacity: Number,
|
|
50106
|
-
duration: Number,
|
|
50107
|
-
width: Number,
|
|
50108
|
-
height: Number,
|
|
50109
|
-
offsetY: Number,
|
|
50110
|
-
offsetX: Number,
|
|
50111
|
-
allowOverflow: Boolean,
|
|
50112
|
-
onAnimationEnd: Function,
|
|
50113
|
-
style: String,
|
|
50114
|
-
};
|
|
50115
51096
|
class Ripple extends owl.Component {
|
|
50116
51097
|
static template = "o-spreadsheet-Ripple";
|
|
51098
|
+
static props = {
|
|
51099
|
+
color: { type: String, optional: true },
|
|
51100
|
+
opacity: { type: Number, optional: true },
|
|
51101
|
+
duration: { type: Number, optional: true },
|
|
51102
|
+
ignoreClickPosition: { type: Boolean, optional: true },
|
|
51103
|
+
width: { type: Number, optional: true },
|
|
51104
|
+
height: { type: Number, optional: true },
|
|
51105
|
+
offsetY: { type: Number, optional: true },
|
|
51106
|
+
offsetX: { type: Number, optional: true },
|
|
51107
|
+
allowOverflow: { type: Boolean, optional: true },
|
|
51108
|
+
enabled: { type: Boolean, optional: true },
|
|
51109
|
+
onAnimationEnd: { type: Function, optional: true },
|
|
51110
|
+
slots: Object,
|
|
51111
|
+
class: { type: String, optional: true },
|
|
51112
|
+
};
|
|
50117
51113
|
static components = { RippleEffect };
|
|
50118
51114
|
static defaultProps = {
|
|
50119
51115
|
color: "#aaaaaa",
|
|
@@ -50199,21 +51195,6 @@
|
|
|
50199
51195
|
};
|
|
50200
51196
|
}
|
|
50201
51197
|
}
|
|
50202
|
-
Ripple.props = {
|
|
50203
|
-
color: { type: String, optional: true },
|
|
50204
|
-
opacity: { type: Number, optional: true },
|
|
50205
|
-
duration: { type: Number, optional: true },
|
|
50206
|
-
ignoreClickPosition: { type: Boolean, optional: true },
|
|
50207
|
-
width: { type: Number, optional: true },
|
|
50208
|
-
height: { type: Number, optional: true },
|
|
50209
|
-
offsetY: { type: Number, optional: true },
|
|
50210
|
-
offsetX: { type: Number, optional: true },
|
|
50211
|
-
allowOverflow: { type: Boolean, optional: true },
|
|
50212
|
-
enabled: { type: Boolean, optional: true },
|
|
50213
|
-
onAnimationEnd: { type: Function, optional: true },
|
|
50214
|
-
slots: Object,
|
|
50215
|
-
class: { type: String, optional: true },
|
|
50216
|
-
};
|
|
50217
51198
|
|
|
50218
51199
|
function interactiveRenameSheet(env, sheetId, name, errorCallback) {
|
|
50219
51200
|
const result = env.model.dispatch("RENAME_SHEET", { sheetId, name });
|
|
@@ -50271,6 +51252,12 @@
|
|
|
50271
51252
|
`;
|
|
50272
51253
|
class BottomBarSheet extends owl.Component {
|
|
50273
51254
|
static template = "o-spreadsheet-BottomBarSheet";
|
|
51255
|
+
static props = {
|
|
51256
|
+
sheetId: String,
|
|
51257
|
+
openContextMenu: Function,
|
|
51258
|
+
style: { type: String, optional: true },
|
|
51259
|
+
onMouseDown: { type: Function, optional: true },
|
|
51260
|
+
};
|
|
50274
51261
|
static components = { Ripple };
|
|
50275
51262
|
static defaultProps = {
|
|
50276
51263
|
onMouseDown: () => { },
|
|
@@ -50392,12 +51379,6 @@
|
|
|
50392
51379
|
return this.env.model.getters.getSheetName(this.props.sheetId);
|
|
50393
51380
|
}
|
|
50394
51381
|
}
|
|
50395
|
-
BottomBarSheet.props = {
|
|
50396
|
-
sheetId: String,
|
|
50397
|
-
openContextMenu: Function,
|
|
50398
|
-
style: { type: String, optional: true },
|
|
50399
|
-
onMouseDown: { type: Function, optional: true },
|
|
50400
|
-
};
|
|
50401
51382
|
|
|
50402
51383
|
// -----------------------------------------------------------------------------
|
|
50403
51384
|
// SpreadSheet
|
|
@@ -50415,6 +51396,10 @@
|
|
|
50415
51396
|
`;
|
|
50416
51397
|
class BottomBarStatistic extends owl.Component {
|
|
50417
51398
|
static template = "o-spreadsheet-BottomBarStatisic";
|
|
51399
|
+
static props = {
|
|
51400
|
+
openContextMenu: Function,
|
|
51401
|
+
closeContextMenu: Function,
|
|
51402
|
+
};
|
|
50418
51403
|
static components = { Ripple };
|
|
50419
51404
|
selectedStatisticFn = "";
|
|
50420
51405
|
statisticFnResults = {};
|
|
@@ -50461,10 +51446,6 @@
|
|
|
50461
51446
|
return fnName + ": " + (fnValue !== undefined ? formatValue(fnValue, { locale }) : "__");
|
|
50462
51447
|
}
|
|
50463
51448
|
}
|
|
50464
|
-
BottomBarStatistic.props = {
|
|
50465
|
-
openContextMenu: Function,
|
|
50466
|
-
closeContextMenu: Function,
|
|
50467
|
-
};
|
|
50468
51449
|
|
|
50469
51450
|
// -----------------------------------------------------------------------------
|
|
50470
51451
|
// SpreadSheet
|
|
@@ -50515,6 +51496,9 @@
|
|
|
50515
51496
|
`;
|
|
50516
51497
|
class BottomBar extends owl.Component {
|
|
50517
51498
|
static template = "o-spreadsheet-BottomBar";
|
|
51499
|
+
static props = {
|
|
51500
|
+
onClick: Function,
|
|
51501
|
+
};
|
|
50518
51502
|
static components = { Menu, Ripple, BottomBarSheet, BottomBarStatistic };
|
|
50519
51503
|
bottomBarRef = owl.useRef("bottomBar");
|
|
50520
51504
|
sheetListRef = owl.useRef("sheetList");
|
|
@@ -50700,9 +51684,6 @@
|
|
|
50700
51684
|
return this.sheetListRef.el.scrollWidth - this.sheetListRef.el.clientWidth;
|
|
50701
51685
|
}
|
|
50702
51686
|
}
|
|
50703
|
-
BottomBar.props = {
|
|
50704
|
-
onClick: Function,
|
|
50705
|
-
};
|
|
50706
51687
|
|
|
50707
51688
|
css /* scss */ `
|
|
50708
51689
|
.o-dashboard-clickable-cell {
|
|
@@ -50713,6 +51694,7 @@
|
|
|
50713
51694
|
let tKey = 1;
|
|
50714
51695
|
class SpreadsheetDashboard extends owl.Component {
|
|
50715
51696
|
static template = "o-spreadsheet-SpreadsheetDashboard";
|
|
51697
|
+
static props = {};
|
|
50716
51698
|
static components = {
|
|
50717
51699
|
GridOverlay,
|
|
50718
51700
|
GridPopover,
|
|
@@ -50831,7 +51813,6 @@
|
|
|
50831
51813
|
return { ...this.canvasPosition, ...this.env.model.getters.getSheetViewDimensionWithHeaders() };
|
|
50832
51814
|
}
|
|
50833
51815
|
}
|
|
50834
|
-
SpreadsheetDashboard.props = {};
|
|
50835
51816
|
|
|
50836
51817
|
css /* scss */ `
|
|
50837
51818
|
.o-header-group {
|
|
@@ -50859,6 +51840,11 @@
|
|
|
50859
51840
|
`;
|
|
50860
51841
|
class AbstractHeaderGroup extends owl.Component {
|
|
50861
51842
|
static template = "o-spreadsheet-HeaderGroup";
|
|
51843
|
+
static props = {
|
|
51844
|
+
group: Object,
|
|
51845
|
+
layerOffset: Number,
|
|
51846
|
+
openContextMenu: Function,
|
|
51847
|
+
};
|
|
50862
51848
|
toggleGroup() {
|
|
50863
51849
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
50864
51850
|
const { start, end } = this.props.group;
|
|
@@ -50895,11 +51881,6 @@
|
|
|
50895
51881
|
this.props.openContextMenu(position, menuItems);
|
|
50896
51882
|
}
|
|
50897
51883
|
}
|
|
50898
|
-
AbstractHeaderGroup.props = {
|
|
50899
|
-
group: Object,
|
|
50900
|
-
layerOffset: Number,
|
|
50901
|
-
openContextMenu: Function,
|
|
50902
|
-
};
|
|
50903
51884
|
class RowGroup extends AbstractHeaderGroup {
|
|
50904
51885
|
dimension = "ROW";
|
|
50905
51886
|
get groupBorderStyle() {
|
|
@@ -51030,6 +52011,10 @@
|
|
|
51030
52011
|
`;
|
|
51031
52012
|
class HeaderGroupContainer extends owl.Component {
|
|
51032
52013
|
static template = "o-spreadsheet-HeaderGroupContainer";
|
|
52014
|
+
static props = {
|
|
52015
|
+
dimension: String,
|
|
52016
|
+
layers: Array,
|
|
52017
|
+
};
|
|
51033
52018
|
static components = { RowGroup, ColGroup, Menu };
|
|
51034
52019
|
menu = owl.useState({ isOpen: false, position: null, menuItems: [] });
|
|
51035
52020
|
getLayerOffset(layerIndex) {
|
|
@@ -51092,10 +52077,6 @@
|
|
|
51092
52077
|
}
|
|
51093
52078
|
}
|
|
51094
52079
|
}
|
|
51095
|
-
HeaderGroupContainer.props = {
|
|
51096
|
-
dimension: String,
|
|
51097
|
-
layers: Array,
|
|
51098
|
-
};
|
|
51099
52080
|
|
|
51100
52081
|
css /* scss */ `
|
|
51101
52082
|
.o-sidePanel {
|
|
@@ -51206,14 +52187,6 @@
|
|
|
51206
52187
|
text-align: left;
|
|
51207
52188
|
}
|
|
51208
52189
|
|
|
51209
|
-
.o-checkbox {
|
|
51210
|
-
display: flex;
|
|
51211
|
-
justify-items: center;
|
|
51212
|
-
input {
|
|
51213
|
-
margin-right: 5px;
|
|
51214
|
-
}
|
|
51215
|
-
}
|
|
51216
|
-
|
|
51217
52190
|
.o-inflection {
|
|
51218
52191
|
table {
|
|
51219
52192
|
table-layout: fixed;
|
|
@@ -51254,6 +52227,11 @@
|
|
|
51254
52227
|
`;
|
|
51255
52228
|
class SidePanel extends owl.Component {
|
|
51256
52229
|
static template = "o-spreadsheet-SidePanel";
|
|
52230
|
+
static props = {
|
|
52231
|
+
component: String,
|
|
52232
|
+
panelProps: { type: Object, optional: true },
|
|
52233
|
+
onCloseSidePanel: Function,
|
|
52234
|
+
};
|
|
51257
52235
|
state;
|
|
51258
52236
|
setup() {
|
|
51259
52237
|
this.state = owl.useState({
|
|
@@ -51267,11 +52245,6 @@
|
|
|
51267
52245
|
: this.state.panel.title;
|
|
51268
52246
|
}
|
|
51269
52247
|
}
|
|
51270
|
-
SidePanel.props = {
|
|
51271
|
-
component: String,
|
|
51272
|
-
panelProps: { type: Object, optional: true },
|
|
51273
|
-
onCloseSidePanel: Function,
|
|
51274
|
-
};
|
|
51275
52248
|
|
|
51276
52249
|
css /* scss */ `
|
|
51277
52250
|
.o-menu-item-button {
|
|
@@ -51289,6 +52262,13 @@
|
|
|
51289
52262
|
`;
|
|
51290
52263
|
class ActionButton extends owl.Component {
|
|
51291
52264
|
static template = "o-spreadsheet-ActionButton";
|
|
52265
|
+
static props = {
|
|
52266
|
+
action: Object,
|
|
52267
|
+
hasTriangleDownIcon: { type: Boolean, optional: true },
|
|
52268
|
+
selectedColor: { type: String, optional: true },
|
|
52269
|
+
class: { type: String, optional: true },
|
|
52270
|
+
onClick: { type: Function, optional: true },
|
|
52271
|
+
};
|
|
51292
52272
|
actionButton = createAction(this.props.action);
|
|
51293
52273
|
setup() {
|
|
51294
52274
|
owl.onWillUpdateProps((nextProps) => {
|
|
@@ -51331,13 +52311,6 @@
|
|
|
51331
52311
|
return "";
|
|
51332
52312
|
}
|
|
51333
52313
|
}
|
|
51334
|
-
ActionButton.props = {
|
|
51335
|
-
action: Object,
|
|
51336
|
-
hasTriangleDownIcon: { type: Boolean, optional: true },
|
|
51337
|
-
selectedColor: { type: String, optional: true },
|
|
51338
|
-
class: { type: String, optional: true },
|
|
51339
|
-
onClick: { type: Function, optional: true },
|
|
51340
|
-
};
|
|
51341
52314
|
|
|
51342
52315
|
/**
|
|
51343
52316
|
* List the available borders positions and the corresponding icons.
|
|
@@ -51434,6 +52407,17 @@
|
|
|
51434
52407
|
`;
|
|
51435
52408
|
class BorderEditor extends owl.Component {
|
|
51436
52409
|
static template = "o-spreadsheet-BorderEditor";
|
|
52410
|
+
static props = {
|
|
52411
|
+
class: { type: String, optional: true },
|
|
52412
|
+
currentBorderColor: { type: String, optional: false },
|
|
52413
|
+
currentBorderStyle: { type: String, optional: false },
|
|
52414
|
+
currentBorderPosition: { type: String, optional: true },
|
|
52415
|
+
onBorderColorPicked: Function,
|
|
52416
|
+
onBorderStylePicked: Function,
|
|
52417
|
+
onBorderPositionPicked: Function,
|
|
52418
|
+
maxHeight: { type: Number, optional: true },
|
|
52419
|
+
anchorRect: Object,
|
|
52420
|
+
};
|
|
51437
52421
|
static components = { ColorPickerWidget, Popover };
|
|
51438
52422
|
BORDER_POSITIONS = BORDER_POSITIONS;
|
|
51439
52423
|
lineStyleButtonRef = owl.useRef("lineStyleButton");
|
|
@@ -51489,20 +52473,16 @@
|
|
|
51489
52473
|
};
|
|
51490
52474
|
}
|
|
51491
52475
|
}
|
|
51492
|
-
BorderEditor.props = {
|
|
51493
|
-
class: { type: String, optional: true },
|
|
51494
|
-
currentBorderColor: { type: String, optional: false },
|
|
51495
|
-
currentBorderStyle: { type: String, optional: false },
|
|
51496
|
-
currentBorderPosition: { type: String, optional: true },
|
|
51497
|
-
onBorderColorPicked: Function,
|
|
51498
|
-
onBorderStylePicked: Function,
|
|
51499
|
-
onBorderPositionPicked: Function,
|
|
51500
|
-
maxHeight: { type: Number, optional: true },
|
|
51501
|
-
anchorRect: Object,
|
|
51502
|
-
};
|
|
51503
52476
|
|
|
51504
52477
|
class BorderEditorWidget extends owl.Component {
|
|
51505
52478
|
static template = "o-spreadsheet-BorderEditorWidget";
|
|
52479
|
+
static props = {
|
|
52480
|
+
toggleBorderEditor: Function,
|
|
52481
|
+
showBorderEditor: Boolean,
|
|
52482
|
+
disabled: { type: Boolean, optional: true },
|
|
52483
|
+
dropdownMaxHeight: { type: Number, optional: true },
|
|
52484
|
+
class: { type: String, optional: true },
|
|
52485
|
+
};
|
|
51506
52486
|
static components = { BorderEditor };
|
|
51507
52487
|
borderEditorButtonRef = owl.useRef("borderEditorButton");
|
|
51508
52488
|
state = owl.useState({
|
|
@@ -51547,13 +52527,6 @@
|
|
|
51547
52527
|
});
|
|
51548
52528
|
}
|
|
51549
52529
|
}
|
|
51550
|
-
BorderEditorWidget.props = {
|
|
51551
|
-
toggleBorderEditor: Function,
|
|
51552
|
-
showBorderEditor: Boolean,
|
|
51553
|
-
disabled: { type: Boolean, optional: true },
|
|
51554
|
-
dropdownMaxHeight: { type: Number, optional: true },
|
|
51555
|
-
class: { type: String, optional: true },
|
|
51556
|
-
};
|
|
51557
52530
|
|
|
51558
52531
|
const COMPOSER_MAX_HEIGHT = 100;
|
|
51559
52532
|
/* svg free of use from https://uxwing.com/formula-fx-icon/ */
|
|
@@ -51582,6 +52555,12 @@
|
|
|
51582
52555
|
`;
|
|
51583
52556
|
class TopBarComposer extends owl.Component {
|
|
51584
52557
|
static template = "o-spreadsheet-TopBarComposer";
|
|
52558
|
+
static props = {
|
|
52559
|
+
focus: {
|
|
52560
|
+
validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value),
|
|
52561
|
+
},
|
|
52562
|
+
onComposerContentFocused: Function,
|
|
52563
|
+
};
|
|
51585
52564
|
static components = { Composer };
|
|
51586
52565
|
get composerStyle() {
|
|
51587
52566
|
const style = {
|
|
@@ -51604,10 +52583,6 @@
|
|
|
51604
52583
|
});
|
|
51605
52584
|
}
|
|
51606
52585
|
}
|
|
51607
|
-
TopBarComposer.props = {
|
|
51608
|
-
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
51609
|
-
onComposerContentFocused: Function,
|
|
51610
|
-
};
|
|
51611
52586
|
|
|
51612
52587
|
css /* scss */ `
|
|
51613
52588
|
.o-font-size-editor {
|
|
@@ -51636,6 +52611,11 @@
|
|
|
51636
52611
|
`;
|
|
51637
52612
|
class FontSizeEditor extends owl.Component {
|
|
51638
52613
|
static template = "o-spreadsheet-FontSizeEditor";
|
|
52614
|
+
static props = {
|
|
52615
|
+
onToggle: Function,
|
|
52616
|
+
dropdownStyle: String,
|
|
52617
|
+
class: String,
|
|
52618
|
+
};
|
|
51639
52619
|
static components = {};
|
|
51640
52620
|
fontSizes = FONT_SIZES;
|
|
51641
52621
|
dropdown = owl.useState({ isOpen: false });
|
|
@@ -51692,14 +52672,12 @@
|
|
|
51692
52672
|
}
|
|
51693
52673
|
}
|
|
51694
52674
|
}
|
|
51695
|
-
FontSizeEditor.props = {
|
|
51696
|
-
onToggle: Function,
|
|
51697
|
-
dropdownStyle: String,
|
|
51698
|
-
class: String,
|
|
51699
|
-
};
|
|
51700
52675
|
|
|
51701
52676
|
class PaintFormatButton extends owl.Component {
|
|
51702
52677
|
static template = "o-spreadsheet-PaintFormatButton";
|
|
52678
|
+
static props = {
|
|
52679
|
+
class: { type: String, optional: true },
|
|
52680
|
+
};
|
|
51703
52681
|
get isActive() {
|
|
51704
52682
|
return this.env.model.getters.isPaintingFormat();
|
|
51705
52683
|
}
|
|
@@ -51715,9 +52693,6 @@
|
|
|
51715
52693
|
}
|
|
51716
52694
|
}
|
|
51717
52695
|
}
|
|
51718
|
-
PaintFormatButton.props = {
|
|
51719
|
-
class: { type: String, optional: true },
|
|
51720
|
-
};
|
|
51721
52696
|
|
|
51722
52697
|
// -----------------------------------------------------------------------------
|
|
51723
52698
|
// TopBar
|
|
@@ -51810,6 +52785,12 @@
|
|
|
51810
52785
|
`;
|
|
51811
52786
|
class TopBar extends owl.Component {
|
|
51812
52787
|
static template = "o-spreadsheet-TopBar";
|
|
52788
|
+
static props = {
|
|
52789
|
+
onClick: Function,
|
|
52790
|
+
focusComposer: String,
|
|
52791
|
+
onComposerContentFocused: Function,
|
|
52792
|
+
dropdownMaxHeight: Number,
|
|
52793
|
+
};
|
|
51813
52794
|
get dropdownStyle() {
|
|
51814
52795
|
return `max-height:${this.props.dropdownMaxHeight}px`;
|
|
51815
52796
|
}
|
|
@@ -51926,12 +52907,6 @@
|
|
|
51926
52907
|
this.onClick();
|
|
51927
52908
|
}
|
|
51928
52909
|
}
|
|
51929
|
-
TopBar.props = {
|
|
51930
|
-
onClick: Function,
|
|
51931
|
-
focusComposer: String,
|
|
51932
|
-
onComposerContentFocused: Function,
|
|
51933
|
-
dropdownMaxHeight: Number,
|
|
51934
|
-
};
|
|
51935
52910
|
|
|
51936
52911
|
function instantiateClipboard() {
|
|
51937
52912
|
return new WebClipboardWrapper(navigator.clipboard);
|
|
@@ -52164,6 +53139,9 @@
|
|
|
52164
53139
|
`;
|
|
52165
53140
|
class Spreadsheet extends owl.Component {
|
|
52166
53141
|
static template = "o-spreadsheet-Spreadsheet";
|
|
53142
|
+
static props = {
|
|
53143
|
+
model: Object,
|
|
53144
|
+
};
|
|
52167
53145
|
static components = {
|
|
52168
53146
|
TopBar,
|
|
52169
53147
|
Grid,
|
|
@@ -52308,7 +53286,7 @@
|
|
|
52308
53286
|
}
|
|
52309
53287
|
onKeydown(ev) {
|
|
52310
53288
|
let keyDownString = "";
|
|
52311
|
-
if (ev
|
|
53289
|
+
if (isCtrlKey(ev)) {
|
|
52312
53290
|
keyDownString += "CTRL+";
|
|
52313
53291
|
}
|
|
52314
53292
|
keyDownString += ev.key.toUpperCase();
|
|
@@ -52376,9 +53354,6 @@
|
|
|
52376
53354
|
return this.env.model.getters.getVisibleGroupLayers(sheetId, "COL");
|
|
52377
53355
|
}
|
|
52378
53356
|
}
|
|
52379
|
-
Spreadsheet.props = {
|
|
52380
|
-
model: Object,
|
|
52381
|
-
};
|
|
52382
53357
|
|
|
52383
53358
|
class LocalTransportService {
|
|
52384
53359
|
listeners = [];
|
|
@@ -55045,7 +56020,8 @@
|
|
|
55045
56020
|
}
|
|
55046
56021
|
else if (cell.content && cell.content !== "") {
|
|
55047
56022
|
const isTableHeader = isCellTableHeader(c, r, sheet);
|
|
55048
|
-
|
|
56023
|
+
const isPlainText = !!(cell.format && data.formats[cell.format] === PLAIN_TEXT_FORMAT);
|
|
56024
|
+
({ attrs: additionalAttrs, node: cellNode } = addContent(cell.content, construct.sharedStrings, isTableHeader || isPlainText));
|
|
55049
56025
|
}
|
|
55050
56026
|
attributes.push(...additionalAttrs);
|
|
55051
56027
|
cellNodes.push(escapeXml /*xml*/ `
|
|
@@ -55974,6 +56950,7 @@
|
|
|
55974
56950
|
colorToRGBA,
|
|
55975
56951
|
positionToZone,
|
|
55976
56952
|
isDefined: isDefined$1,
|
|
56953
|
+
isMatrix,
|
|
55977
56954
|
lazy,
|
|
55978
56955
|
genericRepeat,
|
|
55979
56956
|
createAction,
|
|
@@ -56058,9 +57035,9 @@
|
|
|
56058
57035
|
exports.tokenize = tokenize;
|
|
56059
57036
|
|
|
56060
57037
|
|
|
56061
|
-
__info__.version = "17.1.0-alpha.
|
|
56062
|
-
__info__.date = "
|
|
56063
|
-
__info__.hash = "
|
|
57038
|
+
__info__.version = "17.1.0-alpha.7";
|
|
57039
|
+
__info__.date = "2024-01-12T13:45:00.505Z";
|
|
57040
|
+
__info__.hash = "cbce1ed";
|
|
56064
57041
|
|
|
56065
57042
|
|
|
56066
57043
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|