@odoo/o-spreadsheet 18.2.0-alpha.5 → 18.2.0-alpha.6
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 +299 -249
- package/dist/o-spreadsheet.d.ts +27 -41
- package/dist/o-spreadsheet.esm.js +299 -249
- package/dist/o-spreadsheet.iife.js +299 -249
- package/dist/o-spreadsheet.iife.min.js +14 -14
- package/dist/o_spreadsheet.xml +3 -3
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.2.0-alpha.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.2.0-alpha.6
|
|
6
|
+
* @date 2025-02-05T06:50:47.008Z
|
|
7
|
+
* @hash dae9ab2
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -18634,19 +18634,20 @@ const HLOOKUP = {
|
|
|
18634
18634
|
description: _t("Horizontal lookup"),
|
|
18635
18635
|
args: [
|
|
18636
18636
|
arg("search_key (string, number, boolean)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18637
|
-
arg("range (range)", _t("The range to consider for the search. The first row in the range is searched for the key specified in search_key.")),
|
|
18637
|
+
arg("range (any, range)", _t("The range to consider for the search. The first row in the range is searched for the key specified in search_key.")),
|
|
18638
18638
|
arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
|
|
18639
18639
|
arg(`is_sorted (boolean, default=${DEFAULT_IS_SORTED})`, _t("Indicates whether the row to be searched (the first row of the specified range) is sorted, in which case the closest match for search_key will be returned.")),
|
|
18640
18640
|
],
|
|
18641
18641
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18642
18642
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18643
|
-
|
|
18643
|
+
const _range = toMatrix(range);
|
|
18644
|
+
assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18644
18645
|
const getValueFromRange = (range, index) => range[index][0].value;
|
|
18645
18646
|
const _isSorted = toBoolean(isSorted.value);
|
|
18646
18647
|
const colIndex = _isSorted
|
|
18647
|
-
? dichotomicSearch(
|
|
18648
|
-
: linearSearch(
|
|
18649
|
-
const col =
|
|
18648
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
18649
|
+
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
|
|
18650
|
+
const col = _range[colIndex];
|
|
18650
18651
|
if (col === undefined) {
|
|
18651
18652
|
return valueNotAvailable(searchKey);
|
|
18652
18653
|
}
|
|
@@ -18738,35 +18739,37 @@ const LOOKUP = {
|
|
|
18738
18739
|
description: _t("Look up a value."),
|
|
18739
18740
|
args: [
|
|
18740
18741
|
arg("search_key (string, number, boolean)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18741
|
-
arg("search_array (range)", _t("One method of using this function is to provide a single sorted row or column search_array to look through for the search_key with a second argument result_range. The other way is to combine these two arguments into one search_array where the first row or column is searched and a value is returned from the last row or column in the array. If search_key is not found, a non-exact match may be returned.")),
|
|
18742
|
-
arg("result_range (range, optional)", _t("The range from which to return a result. The value returned corresponds to the location where search_key is found in search_range. This range must be only a single row or column and should not be used if using the search_result_array method.")),
|
|
18742
|
+
arg("search_array (any, range)", _t("One method of using this function is to provide a single sorted row or column search_array to look through for the search_key with a second argument result_range. The other way is to combine these two arguments into one search_array where the first row or column is searched and a value is returned from the last row or column in the array. If search_key is not found, a non-exact match may be returned.")),
|
|
18743
|
+
arg("result_range (any, range, optional)", _t("The range from which to return a result. The value returned corresponds to the location where search_key is found in search_range. This range must be only a single row or column and should not be used if using the search_result_array method.")),
|
|
18743
18744
|
],
|
|
18744
18745
|
compute: function (searchKey, searchArray, resultRange) {
|
|
18745
|
-
|
|
18746
|
-
|
|
18746
|
+
const _searchArray = toMatrix(searchArray);
|
|
18747
|
+
const _resultRange = toMatrix(resultRange);
|
|
18748
|
+
let nbCol = _searchArray.length;
|
|
18749
|
+
let nbRow = _searchArray[0].length;
|
|
18747
18750
|
const verticalSearch = nbRow >= nbCol;
|
|
18748
18751
|
const getElement = verticalSearch
|
|
18749
18752
|
? (range, index) => range[0][index].value
|
|
18750
18753
|
: (range, index) => range[index][0].value;
|
|
18751
18754
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
18752
|
-
const index = dichotomicSearch(
|
|
18755
|
+
const index = dichotomicSearch(_searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
|
|
18753
18756
|
if (index === -1 ||
|
|
18754
|
-
(verticalSearch &&
|
|
18755
|
-
(!verticalSearch &&
|
|
18757
|
+
(verticalSearch && _searchArray[0][index] === undefined) ||
|
|
18758
|
+
(!verticalSearch && _searchArray[index][nbRow - 1] === undefined)) {
|
|
18756
18759
|
return valueNotAvailable(searchKey);
|
|
18757
18760
|
}
|
|
18758
|
-
if (
|
|
18759
|
-
return verticalSearch ?
|
|
18761
|
+
if (_resultRange[0].length === 0) {
|
|
18762
|
+
return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
|
|
18760
18763
|
}
|
|
18761
|
-
nbCol =
|
|
18762
|
-
nbRow =
|
|
18764
|
+
nbCol = _resultRange.length;
|
|
18765
|
+
nbRow = _resultRange[0].length;
|
|
18763
18766
|
assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
|
|
18764
18767
|
if (nbCol > 1) {
|
|
18765
18768
|
assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
|
|
18766
|
-
return
|
|
18769
|
+
return _resultRange[index][0];
|
|
18767
18770
|
}
|
|
18768
18771
|
assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
|
|
18769
|
-
return
|
|
18772
|
+
return _resultRange[0][index];
|
|
18770
18773
|
},
|
|
18771
18774
|
isExported: true,
|
|
18772
18775
|
};
|
|
@@ -18783,28 +18786,29 @@ const MATCH = {
|
|
|
18783
18786
|
],
|
|
18784
18787
|
compute: function (searchKey, range, searchType = { value: DEFAULT_SEARCH_TYPE }) {
|
|
18785
18788
|
let _searchType = toNumber(searchType, this.locale);
|
|
18786
|
-
const
|
|
18787
|
-
const
|
|
18789
|
+
const _range = toMatrix(range);
|
|
18790
|
+
const nbCol = _range.length;
|
|
18791
|
+
const nbRow = _range[0].length;
|
|
18788
18792
|
assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
|
|
18789
18793
|
let index = -1;
|
|
18790
18794
|
const getElement = nbCol === 1
|
|
18791
|
-
? (
|
|
18792
|
-
: (
|
|
18793
|
-
const rangeLen = nbCol === 1 ?
|
|
18795
|
+
? (_range, index) => _range[0][index].value
|
|
18796
|
+
: (_range, index) => _range[index][0].value;
|
|
18797
|
+
const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
|
|
18794
18798
|
_searchType = Math.sign(_searchType);
|
|
18795
18799
|
switch (_searchType) {
|
|
18796
18800
|
case 1:
|
|
18797
|
-
index = dichotomicSearch(
|
|
18801
|
+
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
18798
18802
|
break;
|
|
18799
18803
|
case 0:
|
|
18800
|
-
index = linearSearch(
|
|
18804
|
+
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
|
|
18801
18805
|
break;
|
|
18802
18806
|
case -1:
|
|
18803
|
-
index = dichotomicSearch(
|
|
18807
|
+
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
18804
18808
|
break;
|
|
18805
18809
|
}
|
|
18806
|
-
if ((nbCol === 1 &&
|
|
18807
|
-
(nbCol !== 1 &&
|
|
18810
|
+
if ((nbCol === 1 && _range[0][index] === undefined) ||
|
|
18811
|
+
(nbCol !== 1 && _range[index] === undefined)) {
|
|
18808
18812
|
return valueNotAvailable(searchKey);
|
|
18809
18813
|
}
|
|
18810
18814
|
return index + 1;
|
|
@@ -18859,13 +18863,14 @@ const VLOOKUP = {
|
|
|
18859
18863
|
],
|
|
18860
18864
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18861
18865
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18862
|
-
|
|
18866
|
+
const _range = toMatrix(range);
|
|
18867
|
+
assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18863
18868
|
const getValueFromRange = (range, index) => range[0][index].value;
|
|
18864
18869
|
const _isSorted = toBoolean(isSorted.value);
|
|
18865
18870
|
const rowIndex = _isSorted
|
|
18866
|
-
? dichotomicSearch(
|
|
18867
|
-
: linearSearch(
|
|
18868
|
-
const value =
|
|
18871
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
18872
|
+
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
|
|
18873
|
+
const value = _range[_index - 1][rowIndex];
|
|
18869
18874
|
if (value === undefined) {
|
|
18870
18875
|
return valueNotAvailable(searchKey);
|
|
18871
18876
|
}
|
|
@@ -18902,27 +18907,29 @@ const XLOOKUP = {
|
|
|
18902
18907
|
compute: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
|
|
18903
18908
|
const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
|
|
18904
18909
|
const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
|
|
18905
|
-
|
|
18910
|
+
const _lookupRange = toMatrix(lookupRange);
|
|
18911
|
+
const _returnRange = toMatrix(returnRange);
|
|
18912
|
+
assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
|
|
18906
18913
|
assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("search_mode should be a value in [-1, 1, -2, 2]."));
|
|
18907
18914
|
assert(() => [-1, 0, 1, 2].includes(_matchMode), _t("match_mode should be a value in [-1, 0, 1, 2]."));
|
|
18908
|
-
const lookupDirection =
|
|
18915
|
+
const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
|
|
18909
18916
|
assert(() => !(_matchMode === 2 && [-2, 2].includes(_searchMode)), _t("the search and match mode combination is not supported for XLOOKUP evaluation."));
|
|
18910
18917
|
assert(() => lookupDirection === "col"
|
|
18911
|
-
?
|
|
18912
|
-
:
|
|
18918
|
+
? _returnRange[0].length === _lookupRange[0].length
|
|
18919
|
+
: _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
|
|
18913
18920
|
const getElement = lookupDirection === "col"
|
|
18914
18921
|
? (range, index) => range[0][index].value
|
|
18915
18922
|
: (range, index) => range[index][0].value;
|
|
18916
|
-
const rangeLen = lookupDirection === "col" ?
|
|
18923
|
+
const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
|
|
18917
18924
|
const mode = MATCH_MODE[_matchMode];
|
|
18918
18925
|
const reverseSearch = _searchMode === -1;
|
|
18919
18926
|
const index = _searchMode === 2 || _searchMode === -2
|
|
18920
|
-
? dichotomicSearch(
|
|
18921
|
-
: linearSearch(
|
|
18927
|
+
? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
18928
|
+
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
|
|
18922
18929
|
if (index !== -1) {
|
|
18923
18930
|
return lookupDirection === "col"
|
|
18924
|
-
?
|
|
18925
|
-
: [
|
|
18931
|
+
? _returnRange.map((col) => [col[index]])
|
|
18932
|
+
: [_returnRange[index]];
|
|
18926
18933
|
}
|
|
18927
18934
|
if (defaultValue === undefined) {
|
|
18928
18935
|
return valueNotAvailable(searchKey);
|
|
@@ -28458,11 +28465,7 @@ function interpolateData(config, values, labels, newLabels) {
|
|
|
28458
28465
|
if (values.length < 2 || labels.length < 2 || newLabels.length === 0) {
|
|
28459
28466
|
return [];
|
|
28460
28467
|
}
|
|
28461
|
-
const
|
|
28462
|
-
const labelMax = Math.max(...labels);
|
|
28463
|
-
const labelRange = labelMax - labelMin;
|
|
28464
|
-
const normalizedLabels = labels.map((v) => (v - labelMin) / labelRange);
|
|
28465
|
-
const normalizedNewLabels = newLabels.map((v) => (v - labelMin) / labelRange);
|
|
28468
|
+
const { normalizedLabels, normalizedNewLabels } = normalizeLabels(labels, newLabels, config);
|
|
28466
28469
|
try {
|
|
28467
28470
|
switch (config.type) {
|
|
28468
28471
|
case "polynomial": {
|
|
@@ -28507,6 +28510,30 @@ function interpolateData(config, values, labels, newLabels) {
|
|
|
28507
28510
|
return newLabels.map((x) => ({ x, y: NaN }));
|
|
28508
28511
|
}
|
|
28509
28512
|
}
|
|
28513
|
+
function normalizeLabels(labels, newLabels, config) {
|
|
28514
|
+
let normalizedLabels = [];
|
|
28515
|
+
let normalizedNewLabels = [];
|
|
28516
|
+
if (config.type === "logarithmic") {
|
|
28517
|
+
// Logarithmic trends in charts are used to visualize proportional growth or
|
|
28518
|
+
// relative changes. Therefore, we change the normalization technique for
|
|
28519
|
+
// logarithmic trend lines for a better fit. The method used here is Max Absolute
|
|
28520
|
+
// Scaling. This Technique is ideal for data spanning several orders of magnitude,
|
|
28521
|
+
// as it balances differences between small and large values by compressing larger
|
|
28522
|
+
// values while preserving proportionality and ensuring all values are scaled relative
|
|
28523
|
+
// to the largest magnitude.
|
|
28524
|
+
const labelMax = Math.max(...labels.map(Math.abs));
|
|
28525
|
+
normalizedLabels = labels.map((l) => l / labelMax);
|
|
28526
|
+
normalizedNewLabels = newLabels.map((l) => l / labelMax);
|
|
28527
|
+
}
|
|
28528
|
+
else {
|
|
28529
|
+
const labelMax = Math.max(...labels);
|
|
28530
|
+
const labelMin = Math.min(...labels);
|
|
28531
|
+
const labelRange = labelMax - labelMin;
|
|
28532
|
+
normalizedLabels = labels.map((l) => (l - labelMax) / labelRange);
|
|
28533
|
+
normalizedNewLabels = newLabels.map((l) => (l - labelMax) / labelRange);
|
|
28534
|
+
}
|
|
28535
|
+
return { normalizedLabels, normalizedNewLabels };
|
|
28536
|
+
}
|
|
28510
28537
|
function getChartAxisType(chart, labelRange, getters) {
|
|
28511
28538
|
if (isDateChart(chart, labelRange, getters) && isLuxonTimeAdapterInstalled()) {
|
|
28512
28539
|
return "time";
|
|
@@ -37174,7 +37201,7 @@ function dragAndDropBeyondTheViewport(env, cbMouseMove, cbMouseUp, only = false)
|
|
|
37174
37201
|
}
|
|
37175
37202
|
const { x: offsetCorrectionX, y: offsetCorrectionY } = getters.getMainViewportCoordinates();
|
|
37176
37203
|
let { top, left, bottom, right } = getters.getActiveMainViewport();
|
|
37177
|
-
let { scrollX, scrollY } = getters.
|
|
37204
|
+
let { scrollX, scrollY } = getters.getActiveSheetScrollInfo();
|
|
37178
37205
|
const { xSplit, ySplit } = getters.getPaneDivisions(sheetId);
|
|
37179
37206
|
let canEdgeScroll = false;
|
|
37180
37207
|
let timeoutDelay = MAX_DELAY;
|
|
@@ -41347,6 +41374,16 @@ class StandaloneComposerStore extends AbstractComposerStore {
|
|
|
41347
41374
|
}
|
|
41348
41375
|
return providersDefinitions;
|
|
41349
41376
|
}
|
|
41377
|
+
/**
|
|
41378
|
+
* Replace the current reference selected by the new one.
|
|
41379
|
+
* */
|
|
41380
|
+
getZoneReference(zone) {
|
|
41381
|
+
const res = super.getZoneReference(zone);
|
|
41382
|
+
if (this.args().defaultStatic) {
|
|
41383
|
+
return setXcToFixedReferenceType(res, "colrow");
|
|
41384
|
+
}
|
|
41385
|
+
return res;
|
|
41386
|
+
}
|
|
41350
41387
|
getComposerContent() {
|
|
41351
41388
|
if (this.editionMode === "inactive") {
|
|
41352
41389
|
// References in the content might not be linked to the current active sheet
|
|
@@ -41412,6 +41449,7 @@ class StandaloneComposer extends owl.Component {
|
|
|
41412
41449
|
static props = {
|
|
41413
41450
|
composerContent: { type: String, optional: true },
|
|
41414
41451
|
defaultRangeSheetId: { type: String, optional: true },
|
|
41452
|
+
defaultStatic: { type: Boolean, optional: true },
|
|
41415
41453
|
onConfirm: Function,
|
|
41416
41454
|
contextualAutocomplete: { type: Object, optional: true },
|
|
41417
41455
|
placeholder: { type: String, optional: true },
|
|
@@ -41422,6 +41460,7 @@ class StandaloneComposer extends owl.Component {
|
|
|
41422
41460
|
static components = { Composer };
|
|
41423
41461
|
static defaultProps = {
|
|
41424
41462
|
composerContent: "",
|
|
41463
|
+
defaultStatic: false,
|
|
41425
41464
|
};
|
|
41426
41465
|
composerFocusStore;
|
|
41427
41466
|
standaloneComposerStore;
|
|
@@ -41432,6 +41471,7 @@ class StandaloneComposer extends owl.Component {
|
|
|
41432
41471
|
const standaloneComposerStore = useLocalStore(StandaloneComposerStore, () => ({
|
|
41433
41472
|
onConfirm: this.props.onConfirm,
|
|
41434
41473
|
content: this.props.composerContent,
|
|
41474
|
+
defaultStatic: this.props.defaultStatic ?? false,
|
|
41435
41475
|
contextualAutocomplete: this.props.contextualAutocomplete,
|
|
41436
41476
|
defaultRangeSheetId: this.props.defaultRangeSheetId,
|
|
41437
41477
|
getContextualColoredSymbolToken: this.props.getContextualColoredSymbolToken,
|
|
@@ -42167,6 +42207,7 @@ class ConditionalFormattingEditor extends owl.Component {
|
|
|
42167
42207
|
},
|
|
42168
42208
|
composerContent: this.state.rules.cellIs.values[valueIndex],
|
|
42169
42209
|
placeholder: _t("Value or formula"),
|
|
42210
|
+
defaultStatic: true,
|
|
42170
42211
|
invalid: isInvalid,
|
|
42171
42212
|
class: "o-sidePanel-composer",
|
|
42172
42213
|
defaultRangeSheetId: this.env.model.getters.getActiveSheetId(),
|
|
@@ -42185,6 +42226,7 @@ class ConditionalFormattingEditor extends owl.Component {
|
|
|
42185
42226
|
},
|
|
42186
42227
|
composerContent: threshold.value || "",
|
|
42187
42228
|
placeholder: _t("Formula"),
|
|
42229
|
+
defaultStatic: true,
|
|
42188
42230
|
invalid: isInvalid,
|
|
42189
42231
|
class: "o-sidePanel-composer",
|
|
42190
42232
|
defaultRangeSheetId: this.env.model.getters.getActiveSheetId(),
|
|
@@ -42200,6 +42242,7 @@ class ConditionalFormattingEditor extends owl.Component {
|
|
|
42200
42242
|
},
|
|
42201
42243
|
composerContent: inflection.value || "",
|
|
42202
42244
|
placeholder: _t("Formula"),
|
|
42245
|
+
defaultStatic: true,
|
|
42203
42246
|
invalid: isInvalid,
|
|
42204
42247
|
class: "o-sidePanel-composer",
|
|
42205
42248
|
defaultRangeSheetId: this.env.model.getters.getActiveSheetId(),
|
|
@@ -49808,7 +49851,7 @@ class GridAddRowsFooter extends owl.Component {
|
|
|
49808
49851
|
});
|
|
49809
49852
|
this.props.focusGrid();
|
|
49810
49853
|
// After adding new rows, scroll down to the new last row
|
|
49811
|
-
const { scrollX } = this.env.model.getters.
|
|
49854
|
+
const { scrollX } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
49812
49855
|
const { end } = this.env.model.getters.getRowDimensions(activeSheetId, rowNumber + quantity - 1);
|
|
49813
49856
|
this.env.model.dispatch("SET_VIEWPORT_OFFSET", {
|
|
49814
49857
|
offsetX: scrollX,
|
|
@@ -50066,7 +50109,7 @@ class GridOverlay extends owl.Component {
|
|
|
50066
50109
|
resizeObserver.disconnect();
|
|
50067
50110
|
});
|
|
50068
50111
|
useTouchMove(this.gridOverlay, this.props.onGridMoved, () => {
|
|
50069
|
-
const { scrollY } = this.env.model.getters.
|
|
50112
|
+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
50070
50113
|
return scrollY > 0;
|
|
50071
50114
|
});
|
|
50072
50115
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
@@ -50720,17 +50763,6 @@ class GridRenderer {
|
|
|
50720
50763
|
get renderingLayers() {
|
|
50721
50764
|
return ["Background", "Headers"];
|
|
50722
50765
|
}
|
|
50723
|
-
/**
|
|
50724
|
-
* Get the offset of a header (see getColRowOffsetInViewport), adjusted with the header
|
|
50725
|
-
* size (HEADER_HEIGHT and HEADER_WIDTH)
|
|
50726
|
-
*/
|
|
50727
|
-
getHeaderOffset(dimension, start, index) {
|
|
50728
|
-
let size = this.getters.getColRowOffsetInViewport(dimension, start, index);
|
|
50729
|
-
if (!this.getters.isDashboard()) {
|
|
50730
|
-
size += dimension === "ROW" ? HEADER_HEIGHT : HEADER_WIDTH;
|
|
50731
|
-
}
|
|
50732
|
-
return size;
|
|
50733
|
-
}
|
|
50734
50766
|
// ---------------------------------------------------------------------------
|
|
50735
50767
|
// Grid rendering
|
|
50736
50768
|
// ---------------------------------------------------------------------------
|
|
@@ -50738,11 +50770,10 @@ class GridRenderer {
|
|
|
50738
50770
|
switch (layer) {
|
|
50739
50771
|
case "Background":
|
|
50740
50772
|
this.drawGlobalBackground(renderingContext);
|
|
50741
|
-
for (const zone of this.getters.
|
|
50773
|
+
for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
|
|
50742
50774
|
const { ctx } = renderingContext;
|
|
50743
50775
|
ctx.save();
|
|
50744
50776
|
ctx.beginPath();
|
|
50745
|
-
const rect = this.getters.getVisibleRect(zone);
|
|
50746
50777
|
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
50747
50778
|
ctx.clip();
|
|
50748
50779
|
const boxes = this.getGridBoxes(zone);
|
|
@@ -51018,10 +51049,8 @@ class GridRenderer {
|
|
|
51018
51049
|
const { ctx, thinLineWidth } = renderingContext;
|
|
51019
51050
|
const visibleCols = this.getters.getSheetViewVisibleCols();
|
|
51020
51051
|
const left = visibleCols[0];
|
|
51021
|
-
const right = visibleCols[visibleCols.length - 1];
|
|
51022
51052
|
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
51023
51053
|
const top = visibleRows[0];
|
|
51024
|
-
const bottom = visibleRows[visibleRows.length - 1];
|
|
51025
51054
|
const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
|
|
51026
51055
|
const selection = this.getters.getSelectedZones();
|
|
51027
51056
|
const selectedCols = getZonesCols(selection);
|
|
@@ -51037,7 +51066,7 @@ class GridRenderer {
|
|
|
51037
51066
|
ctx.lineWidth = thinLineWidth;
|
|
51038
51067
|
ctx.strokeStyle = "#333";
|
|
51039
51068
|
// Columns headers background
|
|
51040
|
-
for (
|
|
51069
|
+
for (const col of visibleCols) {
|
|
51041
51070
|
const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
|
|
51042
51071
|
const { x, width } = this.getters.getVisibleRect(colZone);
|
|
51043
51072
|
const isColActive = activeCols.has(col);
|
|
@@ -51054,7 +51083,7 @@ class GridRenderer {
|
|
|
51054
51083
|
ctx.fillRect(x, 0, width, HEADER_HEIGHT);
|
|
51055
51084
|
}
|
|
51056
51085
|
// Rows headers background
|
|
51057
|
-
for (
|
|
51086
|
+
for (const row of visibleRows) {
|
|
51058
51087
|
const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
|
|
51059
51088
|
const { y, height } = this.getters.getVisibleRect(rowZone);
|
|
51060
51089
|
const isRowActive = activeRows.has(row);
|
|
@@ -51078,27 +51107,41 @@ class GridRenderer {
|
|
|
51078
51107
|
ctx.lineTo(width, HEADER_HEIGHT);
|
|
51079
51108
|
ctx.strokeStyle = HEADER_BORDER_COLOR;
|
|
51080
51109
|
ctx.stroke();
|
|
51081
|
-
ctx.beginPath();
|
|
51082
51110
|
// column text + separator
|
|
51083
|
-
for (const
|
|
51084
|
-
const
|
|
51085
|
-
|
|
51086
|
-
|
|
51087
|
-
|
|
51111
|
+
for (const col of visibleCols) {
|
|
51112
|
+
const colName = numberToLetters(col);
|
|
51113
|
+
ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
|
|
51114
|
+
const zone = { left: col, right: col, top: top, bottom: top };
|
|
51115
|
+
const { x: colStart, width: colSize } = this.getters.getRect(zone);
|
|
51116
|
+
const { x, width } = this.getters.getVisibleRect(zone);
|
|
51117
|
+
ctx.save();
|
|
51118
|
+
ctx.beginPath();
|
|
51119
|
+
ctx.rect(x, 0, width, HEADER_HEIGHT);
|
|
51120
|
+
ctx.clip();
|
|
51088
51121
|
ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
|
|
51122
|
+
ctx.restore();
|
|
51123
|
+
ctx.beginPath();
|
|
51089
51124
|
ctx.moveTo(colStart + colSize, 0);
|
|
51090
51125
|
ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
|
|
51126
|
+
ctx.stroke();
|
|
51091
51127
|
}
|
|
51092
51128
|
// row text + separator
|
|
51093
|
-
for (const
|
|
51094
|
-
|
|
51095
|
-
|
|
51096
|
-
|
|
51097
|
-
|
|
51129
|
+
for (const row of visibleRows) {
|
|
51130
|
+
ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
|
|
51131
|
+
const zone = { top: row, bottom: row, left: left, right: left };
|
|
51132
|
+
const { y: rowStart, height: rowSize } = this.getters.getRect(zone);
|
|
51133
|
+
const { y, height } = this.getters.getVisibleRect(zone);
|
|
51134
|
+
ctx.save();
|
|
51135
|
+
ctx.beginPath();
|
|
51136
|
+
ctx.rect(0, y, HEADER_WIDTH, height);
|
|
51137
|
+
ctx.clip();
|
|
51138
|
+
ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
|
|
51139
|
+
ctx.restore();
|
|
51140
|
+
ctx.beginPath();
|
|
51098
51141
|
ctx.moveTo(0, rowStart + rowSize);
|
|
51099
51142
|
ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
|
|
51143
|
+
ctx.stroke();
|
|
51100
51144
|
}
|
|
51101
|
-
ctx.stroke();
|
|
51102
51145
|
}
|
|
51103
51146
|
drawFrozenPanesHeaders(renderingContext) {
|
|
51104
51147
|
const { ctx, thinLineWidth } = renderingContext;
|
|
@@ -51401,6 +51444,9 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
51401
51444
|
canvas.width = width * dpr;
|
|
51402
51445
|
canvas.height = height * dpr;
|
|
51403
51446
|
canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
|
|
51447
|
+
if (width === 0 || height === 0) {
|
|
51448
|
+
return;
|
|
51449
|
+
}
|
|
51404
51450
|
// Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
|
|
51405
51451
|
// are the edges of the squares. If you draw a one-unit-wide line between whole-number
|
|
51406
51452
|
// coordinates, it will overlap opposite sides of the pixel square, and the resulting
|
|
@@ -51744,7 +51790,7 @@ class HorizontalScrollBar extends owl.Component {
|
|
|
51744
51790
|
leftOffset: 0,
|
|
51745
51791
|
};
|
|
51746
51792
|
get offset() {
|
|
51747
|
-
return this.env.model.getters.
|
|
51793
|
+
return this.env.model.getters.getActiveSheetScrollInfo().scrollX;
|
|
51748
51794
|
}
|
|
51749
51795
|
get width() {
|
|
51750
51796
|
return this.env.model.getters.getMainViewportRect().width;
|
|
@@ -51763,7 +51809,7 @@ class HorizontalScrollBar extends owl.Component {
|
|
|
51763
51809
|
};
|
|
51764
51810
|
}
|
|
51765
51811
|
onScroll(offset) {
|
|
51766
|
-
const { scrollY } = this.env.model.getters.
|
|
51812
|
+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
51767
51813
|
this.env.model.dispatch("SET_VIEWPORT_OFFSET", {
|
|
51768
51814
|
offsetX: offset,
|
|
51769
51815
|
offsetY: scrollY, // offsetY is the same
|
|
@@ -51789,7 +51835,7 @@ class VerticalScrollBar extends owl.Component {
|
|
|
51789
51835
|
topOffset: 0,
|
|
51790
51836
|
};
|
|
51791
51837
|
get offset() {
|
|
51792
|
-
return this.env.model.getters.
|
|
51838
|
+
return this.env.model.getters.getActiveSheetScrollInfo().scrollY;
|
|
51793
51839
|
}
|
|
51794
51840
|
get height() {
|
|
51795
51841
|
return this.env.model.getters.getMainViewportRect().height;
|
|
@@ -51808,7 +51854,7 @@ class VerticalScrollBar extends owl.Component {
|
|
|
51808
51854
|
};
|
|
51809
51855
|
}
|
|
51810
51856
|
onScroll(offset) {
|
|
51811
|
-
const { scrollX } = this.env.model.getters.
|
|
51857
|
+
const { scrollX } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
51812
51858
|
this.env.model.dispatch("SET_VIEWPORT_OFFSET", {
|
|
51813
51859
|
offsetX: scrollX, // offsetX is the same
|
|
51814
51860
|
offsetY: offset,
|
|
@@ -52279,7 +52325,7 @@ class Grid extends owl.Component {
|
|
|
52279
52325
|
});
|
|
52280
52326
|
}
|
|
52281
52327
|
moveCanvas(deltaX, deltaY) {
|
|
52282
|
-
const { scrollX, scrollY } = this.env.model.getters.
|
|
52328
|
+
const { scrollX, scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
52283
52329
|
this.env.model.dispatch("SET_VIEWPORT_OFFSET", {
|
|
52284
52330
|
offsetX: scrollX + deltaX,
|
|
52285
52331
|
offsetY: scrollY + deltaY,
|
|
@@ -67160,8 +67206,6 @@ class InternalViewport {
|
|
|
67160
67206
|
right;
|
|
67161
67207
|
offsetX;
|
|
67162
67208
|
offsetY;
|
|
67163
|
-
offsetScrollbarX;
|
|
67164
|
-
offsetScrollbarY;
|
|
67165
67209
|
canScrollVertically;
|
|
67166
67210
|
canScrollHorizontally;
|
|
67167
67211
|
viewportWidth;
|
|
@@ -67172,10 +67216,17 @@ class InternalViewport {
|
|
|
67172
67216
|
this.getters = getters;
|
|
67173
67217
|
this.sheetId = sheetId;
|
|
67174
67218
|
this.boundaries = boundaries;
|
|
67175
|
-
|
|
67176
|
-
|
|
67177
|
-
|
|
67178
|
-
this.
|
|
67219
|
+
if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
|
|
67220
|
+
throw new Error("Viewport size cannot be negative");
|
|
67221
|
+
}
|
|
67222
|
+
this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
|
|
67223
|
+
this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
|
|
67224
|
+
this.top = boundaries.top;
|
|
67225
|
+
this.bottom = boundaries.bottom;
|
|
67226
|
+
this.left = boundaries.left;
|
|
67227
|
+
this.right = boundaries.right;
|
|
67228
|
+
this.offsetX = offsets.x;
|
|
67229
|
+
this.offsetY = offsets.y;
|
|
67179
67230
|
this.canScrollVertically = options.canScrollVertically;
|
|
67180
67231
|
this.canScrollHorizontally = options.canScrollHorizontally;
|
|
67181
67232
|
this.offsetCorrectionX = this.getters.getColDimensions(this.sheetId, this.boundaries.left).start;
|
|
@@ -67216,9 +67267,9 @@ class InternalViewport {
|
|
|
67216
67267
|
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
67217
67268
|
);
|
|
67218
67269
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
67219
|
-
|
|
67220
|
-
|
|
67221
|
-
|
|
67270
|
+
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
67271
|
+
height += FOOTER_HEIGHT;
|
|
67272
|
+
}
|
|
67222
67273
|
}
|
|
67223
67274
|
return { width, height };
|
|
67224
67275
|
}
|
|
@@ -67231,7 +67282,7 @@ class InternalViewport {
|
|
|
67231
67282
|
if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.viewportWidth) {
|
|
67232
67283
|
return -1;
|
|
67233
67284
|
}
|
|
67234
|
-
return this.searchHeaderIndex("COL", x - this.offsetCorrectionX, this.left);
|
|
67285
|
+
return this.searchHeaderIndex("COL", x - this.offsetCorrectionX + this.snapCorrection.x, this.left);
|
|
67235
67286
|
}
|
|
67236
67287
|
/**
|
|
67237
67288
|
* Return the index of a row given an offset y, based on the pane top
|
|
@@ -67242,7 +67293,7 @@ class InternalViewport {
|
|
|
67242
67293
|
if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.viewportHeight) {
|
|
67243
67294
|
return -1;
|
|
67244
67295
|
}
|
|
67245
|
-
return this.searchHeaderIndex("ROW", y - this.offsetCorrectionY, this.top);
|
|
67296
|
+
return this.searchHeaderIndex("ROW", y - this.offsetCorrectionY + this.snapCorrection.y, this.top);
|
|
67246
67297
|
}
|
|
67247
67298
|
/**
|
|
67248
67299
|
* This function will make sure that the provided cell position (or current selected position) is part of
|
|
@@ -67262,55 +67313,29 @@ class InternalViewport {
|
|
|
67262
67313
|
}
|
|
67263
67314
|
adjustPositionX(targetCol) {
|
|
67264
67315
|
const sheetId = this.sheetId;
|
|
67265
|
-
const { end } = this.getters.getColDimensions(sheetId, targetCol);
|
|
67266
|
-
if (this.offsetX + this.
|
|
67267
|
-
|
|
67268
|
-
|
|
67269
|
-
|
|
67270
|
-
|
|
67271
|
-
}
|
|
67272
|
-
const finalTargetEnd = this.getters.getColDimensions(sheetId, finalTarget).end;
|
|
67273
|
-
const startIndex = this.searchHeaderIndex("COL", finalTargetEnd - this.viewportWidth - this.offsetCorrectionX, this.boundaries.left);
|
|
67274
|
-
this.offsetScrollbarX =
|
|
67275
|
-
this.getters.getColDimensions(sheetId, startIndex).end - this.offsetCorrectionX;
|
|
67276
|
-
}
|
|
67277
|
-
else if (this.left > targetCol) {
|
|
67278
|
-
let finalTarget = targetCol;
|
|
67279
|
-
while (this.getters.isColHidden(sheetId, finalTarget) && finalTarget > 0) {
|
|
67280
|
-
finalTarget--;
|
|
67281
|
-
}
|
|
67282
|
-
this.offsetScrollbarX =
|
|
67283
|
-
this.getters.getColDimensions(sheetId, finalTarget).start - this.offsetCorrectionX;
|
|
67316
|
+
const { start, end } = this.getters.getColDimensions(sheetId, targetCol);
|
|
67317
|
+
if (this.offsetX + this.viewportWidth + this.offsetCorrectionX < end) {
|
|
67318
|
+
this.offsetX = end - this.viewportWidth;
|
|
67319
|
+
}
|
|
67320
|
+
else if (this.offsetX + this.offsetCorrectionX > start) {
|
|
67321
|
+
this.offsetX = start - this.offsetCorrectionX;
|
|
67284
67322
|
}
|
|
67285
67323
|
this.adjustViewportZoneX();
|
|
67286
67324
|
}
|
|
67287
67325
|
adjustPositionY(targetRow) {
|
|
67288
67326
|
const sheetId = this.sheetId;
|
|
67289
|
-
const { end } = this.getters.getRowDimensions(sheetId, targetRow);
|
|
67327
|
+
const { start, end } = this.getters.getRowDimensions(sheetId, targetRow);
|
|
67290
67328
|
if (this.offsetY + this.viewportHeight + this.offsetCorrectionY < end) {
|
|
67291
|
-
|
|
67292
|
-
let finalTarget = targetRow;
|
|
67293
|
-
while (this.getters.isRowHidden(sheetId, finalTarget) && finalTarget < maxRow) {
|
|
67294
|
-
finalTarget++;
|
|
67295
|
-
}
|
|
67296
|
-
const finalTargetEnd = this.getters.getRowDimensions(sheetId, finalTarget).end;
|
|
67297
|
-
const startIndex = this.searchHeaderIndex("ROW", finalTargetEnd - this.viewportHeight - this.offsetCorrectionY, this.boundaries.top);
|
|
67298
|
-
this.offsetScrollbarY =
|
|
67299
|
-
this.getters.getRowDimensions(sheetId, startIndex).end - this.offsetCorrectionY;
|
|
67329
|
+
this.offsetY = end - this.viewportHeight;
|
|
67300
67330
|
}
|
|
67301
|
-
else if (this.
|
|
67302
|
-
|
|
67303
|
-
while (this.getters.isRowHidden(sheetId, finalTarget) && finalTarget > 0) {
|
|
67304
|
-
finalTarget--;
|
|
67305
|
-
}
|
|
67306
|
-
this.offsetScrollbarY =
|
|
67307
|
-
this.getters.getRowDimensions(sheetId, finalTarget).start - this.offsetCorrectionY;
|
|
67331
|
+
else if (this.offsetY + this.offsetCorrectionY > start) {
|
|
67332
|
+
this.offsetY = start - this.offsetCorrectionY;
|
|
67308
67333
|
}
|
|
67309
67334
|
this.adjustViewportZoneY();
|
|
67310
67335
|
}
|
|
67311
67336
|
willNewOffsetScrollViewport(offsetX, offsetY) {
|
|
67312
|
-
return ((this.canScrollHorizontally && this.
|
|
67313
|
-
(this.canScrollVertically && this.
|
|
67337
|
+
return ((this.canScrollHorizontally && this.offsetX !== offsetX) ||
|
|
67338
|
+
(this.canScrollVertically && this.offsetY !== offsetY));
|
|
67314
67339
|
}
|
|
67315
67340
|
setViewportOffset(offsetX, offsetY) {
|
|
67316
67341
|
this.setViewportOffsetX(offsetX);
|
|
@@ -67327,11 +67352,19 @@ class InternalViewport {
|
|
|
67327
67352
|
*/
|
|
67328
67353
|
getVisibleRect(zone) {
|
|
67329
67354
|
const targetZone = intersection(zone, this);
|
|
67355
|
+
const scrollDeltaX = this.snapCorrection.x;
|
|
67356
|
+
const scrollDeltaY = this.snapCorrection.y;
|
|
67330
67357
|
if (targetZone) {
|
|
67331
|
-
const x = this.getters.getColRowOffset("COL", this.left, targetZone.left) +
|
|
67332
|
-
|
|
67333
|
-
|
|
67334
|
-
const
|
|
67358
|
+
const x = this.getters.getColRowOffset("COL", this.left, targetZone.left) +
|
|
67359
|
+
this.offsetCorrectionX -
|
|
67360
|
+
(this.left !== targetZone.left ? scrollDeltaX : 0);
|
|
67361
|
+
const y = this.getters.getColRowOffset("ROW", this.top, targetZone.top) +
|
|
67362
|
+
this.offsetCorrectionY -
|
|
67363
|
+
(this.top !== targetZone.top ? scrollDeltaY : 0);
|
|
67364
|
+
const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1) -
|
|
67365
|
+
(this.left === targetZone.left ? scrollDeltaX : 0), this.viewportWidth);
|
|
67366
|
+
const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1) -
|
|
67367
|
+
(this.top === targetZone.top ? scrollDeltaY : 0), this.viewportHeight);
|
|
67335
67368
|
return { x, y, width, height };
|
|
67336
67369
|
}
|
|
67337
67370
|
return undefined;
|
|
@@ -67343,12 +67376,14 @@ class InternalViewport {
|
|
|
67343
67376
|
*/
|
|
67344
67377
|
getFullRect(zone) {
|
|
67345
67378
|
const targetZone = intersection(zone, this);
|
|
67379
|
+
const scrollDeltaX = this.snapCorrection.x;
|
|
67380
|
+
const scrollDeltaY = this.snapCorrection.y;
|
|
67346
67381
|
if (targetZone) {
|
|
67347
67382
|
const x = this.getters.getColRowOffset("COL", this.left, zone.left) + this.offsetCorrectionX;
|
|
67348
67383
|
const y = this.getters.getColRowOffset("ROW", this.top, zone.top) + this.offsetCorrectionY;
|
|
67349
67384
|
const width = this.getters.getColRowOffset("COL", zone.left, zone.right + 1);
|
|
67350
67385
|
const height = this.getters.getColRowOffset("ROW", zone.top, zone.bottom + 1);
|
|
67351
|
-
return { x, y, width, height };
|
|
67386
|
+
return { x: x - scrollDeltaX, y: y - scrollDeltaY, width, height };
|
|
67352
67387
|
}
|
|
67353
67388
|
return undefined;
|
|
67354
67389
|
}
|
|
@@ -67359,6 +67394,9 @@ class InternalViewport {
|
|
|
67359
67394
|
!this.getters.isRowHidden(this.sheetId, row));
|
|
67360
67395
|
}
|
|
67361
67396
|
searchHeaderIndex(dimension, position, startIndex = 0) {
|
|
67397
|
+
if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
|
|
67398
|
+
return -1;
|
|
67399
|
+
}
|
|
67362
67400
|
const sheetId = this.sheetId;
|
|
67363
67401
|
const headers = this.getters.getNumberHeaders(sheetId, dimension);
|
|
67364
67402
|
// using a binary search:
|
|
@@ -67384,36 +67422,36 @@ class InternalViewport {
|
|
|
67384
67422
|
if (!this.canScrollHorizontally) {
|
|
67385
67423
|
return;
|
|
67386
67424
|
}
|
|
67387
|
-
this.
|
|
67425
|
+
this.offsetX = offsetX;
|
|
67388
67426
|
this.adjustViewportZoneX();
|
|
67389
67427
|
}
|
|
67390
67428
|
setViewportOffsetY(offsetY) {
|
|
67391
67429
|
if (!this.canScrollVertically) {
|
|
67392
67430
|
return;
|
|
67393
67431
|
}
|
|
67394
|
-
this.
|
|
67432
|
+
this.offsetY = offsetY;
|
|
67395
67433
|
this.adjustViewportZoneY();
|
|
67396
67434
|
}
|
|
67397
67435
|
/** Corrects the viewport's horizontal offset based on the current structure
|
|
67398
|
-
* To make sure that at least
|
|
67436
|
+
* To make sure that at least one column is visible inside the viewport.
|
|
67399
67437
|
*/
|
|
67400
67438
|
adjustViewportOffsetX() {
|
|
67401
67439
|
if (this.canScrollHorizontally) {
|
|
67402
67440
|
const { width: viewportWidth } = this.getMaxSize();
|
|
67403
|
-
if (this.viewportWidth + this.
|
|
67404
|
-
this.
|
|
67441
|
+
if (this.viewportWidth + this.offsetX > viewportWidth) {
|
|
67442
|
+
this.offsetX = Math.max(0, viewportWidth - this.viewportWidth);
|
|
67405
67443
|
}
|
|
67406
67444
|
}
|
|
67407
67445
|
this.adjustViewportZoneX();
|
|
67408
67446
|
}
|
|
67409
67447
|
/** Corrects the viewport's vertical offset based on the current structure
|
|
67410
|
-
* To make sure that at least
|
|
67448
|
+
* To make sure that at least one row is visible inside the viewport.
|
|
67411
67449
|
*/
|
|
67412
67450
|
adjustViewportOffsetY() {
|
|
67413
67451
|
if (this.canScrollVertically) {
|
|
67414
67452
|
const { height: paneHeight } = this.getMaxSize();
|
|
67415
|
-
if (this.viewportHeight + this.
|
|
67416
|
-
this.
|
|
67453
|
+
if (this.viewportHeight + this.offsetY > paneHeight) {
|
|
67454
|
+
this.offsetY = Math.max(0, paneHeight - this.viewportHeight);
|
|
67417
67455
|
}
|
|
67418
67456
|
}
|
|
67419
67457
|
this.adjustViewportZoneY();
|
|
@@ -67421,34 +67459,47 @@ class InternalViewport {
|
|
|
67421
67459
|
/** Updates the pane zone and snapped offset based on its horizontal
|
|
67422
67460
|
* offset (will find Left) and its width (will find Right) */
|
|
67423
67461
|
adjustViewportZoneX() {
|
|
67424
|
-
|
|
67425
|
-
this.
|
|
67426
|
-
|
|
67462
|
+
this.left = this.searchHeaderIndex("COL", this.offsetX, this.boundaries.left);
|
|
67463
|
+
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL",
|
|
67464
|
+
// if we hit the border of two cells, we want to match the previous
|
|
67465
|
+
Math.max(this.viewportWidth + this.snapCorrection.x - 0.1), this.left));
|
|
67466
|
+
if (!this.viewportWidth) {
|
|
67467
|
+
return;
|
|
67468
|
+
}
|
|
67427
67469
|
if (this.left === -1) {
|
|
67428
67470
|
this.left = this.boundaries.left;
|
|
67429
67471
|
}
|
|
67430
67472
|
if (this.right === -1) {
|
|
67431
|
-
this.right = this.
|
|
67473
|
+
this.right = this.boundaries.right;
|
|
67432
67474
|
}
|
|
67433
|
-
this.offsetX =
|
|
67434
|
-
this.getters.getColDimensions(sheetId, this.left).start -
|
|
67435
|
-
this.getters.getColDimensions(sheetId, this.boundaries.left).start;
|
|
67436
67475
|
}
|
|
67437
67476
|
/** Updates the pane zone and snapped offset based on its vertical
|
|
67438
67477
|
* offset (will find Top) and its width (will find Bottom) */
|
|
67439
67478
|
adjustViewportZoneY() {
|
|
67440
|
-
|
|
67441
|
-
this.
|
|
67442
|
-
|
|
67479
|
+
this.top = this.searchHeaderIndex("ROW", this.offsetY, this.boundaries.top);
|
|
67480
|
+
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW",
|
|
67481
|
+
// if we hit the border of two cells, we want to match the previous
|
|
67482
|
+
Math.max(this.viewportHeight + this.snapCorrection.y - 0.1, 0), this.top));
|
|
67483
|
+
if (!this.viewportHeight) {
|
|
67484
|
+
return;
|
|
67485
|
+
}
|
|
67443
67486
|
if (this.top === -1) {
|
|
67444
67487
|
this.top = this.boundaries.top;
|
|
67445
67488
|
}
|
|
67446
67489
|
if (this.bottom === -1) {
|
|
67447
|
-
this.bottom = this.
|
|
67490
|
+
this.bottom = this.boundaries.bottom;
|
|
67448
67491
|
}
|
|
67449
|
-
|
|
67450
|
-
|
|
67451
|
-
|
|
67492
|
+
}
|
|
67493
|
+
/** represents the part of the header on the topLeft that could be partially
|
|
67494
|
+
* hidden due to the scroll
|
|
67495
|
+
* */
|
|
67496
|
+
get snapCorrection() {
|
|
67497
|
+
return {
|
|
67498
|
+
x: Math.abs(this.offsetX -
|
|
67499
|
+
this.getters.getColRowOffset("COL", this.boundaries.left, Math.max(0, this.left))),
|
|
67500
|
+
y: Math.abs(this.offsetY -
|
|
67501
|
+
this.getters.getColRowOffset("ROW", this.boundaries.top, Math.max(0, this.top))),
|
|
67502
|
+
};
|
|
67452
67503
|
}
|
|
67453
67504
|
}
|
|
67454
67505
|
|
|
@@ -67511,14 +67562,13 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67511
67562
|
"getColRowOffsetInViewport",
|
|
67512
67563
|
"getMainViewportCoordinates",
|
|
67513
67564
|
"getActiveSheetScrollInfo",
|
|
67514
|
-
"getActiveSheetDOMScrollInfo",
|
|
67515
67565
|
"getSheetViewVisibleCols",
|
|
67516
67566
|
"getSheetViewVisibleRows",
|
|
67517
67567
|
"getFrozenSheetViewRatio",
|
|
67518
67568
|
"isPixelPositionVisible",
|
|
67519
67569
|
"getColDimensionsInViewport",
|
|
67520
67570
|
"getRowDimensionsInViewport",
|
|
67521
|
-
"
|
|
67571
|
+
"getAllActiveViewportsZonesAndRect",
|
|
67522
67572
|
"getRect",
|
|
67523
67573
|
];
|
|
67524
67574
|
viewports = {};
|
|
@@ -67721,8 +67771,8 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67721
67771
|
return this.getMainViewport(sheetId);
|
|
67722
67772
|
}
|
|
67723
67773
|
/**
|
|
67724
|
-
* Return the scroll info of the active sheet, ie. the offset between the viewport left/top side and
|
|
67725
|
-
* the grid left/top side, snapped to the
|
|
67774
|
+
* Return the DOM scroll info of the active sheet, ie. the offset between the viewport left/top side and
|
|
67775
|
+
* the grid left/top side, corresponding to the scroll of the scrollbars and not snapped to the grid.
|
|
67726
67776
|
*/
|
|
67727
67777
|
getActiveSheetScrollInfo() {
|
|
67728
67778
|
const sheetId = this.getters.getActiveSheetId();
|
|
@@ -67732,28 +67782,16 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67732
67782
|
scrollY: viewport.offsetY,
|
|
67733
67783
|
};
|
|
67734
67784
|
}
|
|
67735
|
-
/**
|
|
67736
|
-
* Return the DOM scroll info of the active sheet, ie. the offset between the viewport left/top side and
|
|
67737
|
-
* the grid left/top side, corresponding to the scroll of the scrollbars and not snapped to the grid.
|
|
67738
|
-
*/
|
|
67739
|
-
getActiveSheetDOMScrollInfo() {
|
|
67740
|
-
const sheetId = this.getters.getActiveSheetId();
|
|
67741
|
-
const viewport = this.getMainInternalViewport(sheetId);
|
|
67742
|
-
return {
|
|
67743
|
-
scrollX: viewport.offsetScrollbarX,
|
|
67744
|
-
scrollY: viewport.offsetScrollbarY,
|
|
67745
|
-
};
|
|
67746
|
-
}
|
|
67747
67785
|
getSheetViewVisibleCols() {
|
|
67748
67786
|
const sheetId = this.getters.getActiveSheetId();
|
|
67749
67787
|
const viewports = this.getSubViewports(sheetId);
|
|
67750
67788
|
//TODO ake another commit to eimprove this
|
|
67751
|
-
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
67789
|
+
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
67752
67790
|
}
|
|
67753
67791
|
getSheetViewVisibleRows() {
|
|
67754
67792
|
const sheetId = this.getters.getActiveSheetId();
|
|
67755
67793
|
const viewports = this.getSubViewports(sheetId);
|
|
67756
|
-
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
67794
|
+
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
67757
67795
|
}
|
|
67758
67796
|
/**
|
|
67759
67797
|
* Get the positions of all the cells that are visible in the viewport, taking merges into account.
|
|
@@ -67796,19 +67834,19 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67796
67834
|
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
67797
67835
|
};
|
|
67798
67836
|
}
|
|
67799
|
-
getColRowOffsetInViewport(dimension,
|
|
67800
|
-
|
|
67801
|
-
|
|
67802
|
-
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
67803
|
-
if (index < referenceIndex) {
|
|
67804
|
-
return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
|
|
67837
|
+
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
67838
|
+
if (targetHeaderIndex < referenceHeaderIndex) {
|
|
67839
|
+
return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
|
|
67805
67840
|
}
|
|
67841
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
67842
|
+
const visibleHeaders = dimension === "COL"
|
|
67843
|
+
? this.getters.getSheetViewVisibleCols()
|
|
67844
|
+
: this.getters.getSheetViewVisibleRows();
|
|
67845
|
+
const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
|
|
67846
|
+
const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
|
|
67847
|
+
const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
|
|
67806
67848
|
let offset = 0;
|
|
67807
|
-
const
|
|
67808
|
-
for (let i = referenceIndex; i < index; i++) {
|
|
67809
|
-
if (!visibleIndexes.includes(i)) {
|
|
67810
|
-
continue;
|
|
67811
|
-
}
|
|
67849
|
+
for (const i of relevantIndexes) {
|
|
67812
67850
|
offset += this.getters.getHeaderSize(sheetId, dimension, i);
|
|
67813
67851
|
}
|
|
67814
67852
|
return offset;
|
|
@@ -67855,7 +67893,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67855
67893
|
}
|
|
67856
67894
|
return { canEdgeScroll, direction, delay };
|
|
67857
67895
|
}
|
|
67858
|
-
getEdgeScrollRow(y, previousY,
|
|
67896
|
+
getEdgeScrollRow(y, previousY, startingY) {
|
|
67859
67897
|
let canEdgeScroll = false;
|
|
67860
67898
|
let direction = 0;
|
|
67861
67899
|
let delay = 0;
|
|
@@ -67876,7 +67914,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67876
67914
|
delay = scrollDelay(y - height);
|
|
67877
67915
|
direction = 1;
|
|
67878
67916
|
}
|
|
67879
|
-
else if (y < offsetCorrectionY &&
|
|
67917
|
+
else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
|
|
67880
67918
|
// 2
|
|
67881
67919
|
canEdgeScroll = true;
|
|
67882
67920
|
delay = scrollDelay(offsetCorrectionY - y);
|
|
@@ -67902,13 +67940,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67902
67940
|
*/
|
|
67903
67941
|
getVisibleRectWithoutHeaders(zone) {
|
|
67904
67942
|
const sheetId = this.getters.getActiveSheetId();
|
|
67905
|
-
|
|
67906
|
-
.map((viewport) => viewport.getVisibleRect(zone))
|
|
67907
|
-
.filter(isDefined);
|
|
67908
|
-
if (viewportRects.length === 0) {
|
|
67909
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
67910
|
-
}
|
|
67911
|
-
return this.recomposeRect(viewportRects);
|
|
67943
|
+
return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
|
|
67912
67944
|
}
|
|
67913
67945
|
/**
|
|
67914
67946
|
* Computes the actual size and position (:Rect) of the zone on the canvas
|
|
@@ -67916,13 +67948,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67916
67948
|
*/
|
|
67917
67949
|
getRect(zone) {
|
|
67918
67950
|
const sheetId = this.getters.getActiveSheetId();
|
|
67919
|
-
const
|
|
67920
|
-
.map((viewport) => viewport.getFullRect(zone))
|
|
67921
|
-
.filter(isDefined);
|
|
67922
|
-
if (viewportRects.length === 0) {
|
|
67923
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
67924
|
-
}
|
|
67925
|
-
const rect = this.recomposeRect(viewportRects);
|
|
67951
|
+
const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
|
|
67926
67952
|
return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
|
|
67927
67953
|
}
|
|
67928
67954
|
/**
|
|
@@ -67942,34 +67968,43 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
67942
67968
|
* column of the current viewport
|
|
67943
67969
|
*/
|
|
67944
67970
|
getColDimensionsInViewport(sheetId, col) {
|
|
67945
|
-
const
|
|
67946
|
-
|
|
67947
|
-
|
|
67948
|
-
|
|
67949
|
-
|
|
67950
|
-
start,
|
|
67951
|
-
size: size,
|
|
67952
|
-
end: start + (isColHidden ? 0 : size),
|
|
67971
|
+
const zone = {
|
|
67972
|
+
left: col,
|
|
67973
|
+
right: col,
|
|
67974
|
+
top: 0,
|
|
67975
|
+
bottom: this.getters.getNumberRows(sheetId) - 1,
|
|
67953
67976
|
};
|
|
67977
|
+
const { x, width } = this.getVisibleRect(zone);
|
|
67978
|
+
const start = x - this.gridOffsetX;
|
|
67979
|
+
return { start, size: width, end: start + width };
|
|
67954
67980
|
}
|
|
67955
67981
|
/**
|
|
67956
67982
|
* Returns the size, start and end coordinates of a row relative to the top row
|
|
67957
67983
|
* of the current viewport
|
|
67958
67984
|
*/
|
|
67959
67985
|
getRowDimensionsInViewport(sheetId, row) {
|
|
67960
|
-
const
|
|
67961
|
-
|
|
67962
|
-
|
|
67963
|
-
|
|
67964
|
-
|
|
67965
|
-
start,
|
|
67966
|
-
size: size,
|
|
67967
|
-
end: start + (isRowHidden ? 0 : size),
|
|
67986
|
+
const zone = {
|
|
67987
|
+
left: 0,
|
|
67988
|
+
right: this.getters.getNumberCols(sheetId) - 1,
|
|
67989
|
+
top: row,
|
|
67990
|
+
bottom: row,
|
|
67968
67991
|
};
|
|
67992
|
+
const { y, height } = this.getVisibleRect(zone);
|
|
67993
|
+
const start = y - this.gridOffsetY;
|
|
67994
|
+
return { start, size: height, end: start + height };
|
|
67969
67995
|
}
|
|
67970
|
-
|
|
67996
|
+
getAllActiveViewportsZonesAndRect() {
|
|
67971
67997
|
const sheetId = this.getters.getActiveSheetId();
|
|
67972
|
-
return this.getSubViewports(sheetId)
|
|
67998
|
+
return this.getSubViewports(sheetId).map((viewport) => {
|
|
67999
|
+
return {
|
|
68000
|
+
zone: viewport,
|
|
68001
|
+
rect: {
|
|
68002
|
+
x: viewport.offsetCorrectionX + this.gridOffsetX,
|
|
68003
|
+
y: viewport.offsetCorrectionY + this.gridOffsetY,
|
|
68004
|
+
...viewport.getMaxSize(),
|
|
68005
|
+
},
|
|
68006
|
+
};
|
|
68007
|
+
});
|
|
67973
68008
|
}
|
|
67974
68009
|
// ---------------------------------------------------------------------------
|
|
67975
68010
|
// Private
|
|
@@ -68028,12 +68063,11 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
68028
68063
|
}
|
|
68029
68064
|
/** gets rid of deprecated sheetIds */
|
|
68030
68065
|
cleanViewports() {
|
|
68031
|
-
const
|
|
68032
|
-
for (
|
|
68033
|
-
|
|
68034
|
-
delete this.viewports[sheetId];
|
|
68035
|
-
}
|
|
68066
|
+
const newViewport = {};
|
|
68067
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
68068
|
+
newViewport[sheetId] = this.viewports[sheetId];
|
|
68036
68069
|
}
|
|
68070
|
+
this.viewports = newViewport;
|
|
68037
68071
|
}
|
|
68038
68072
|
resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
|
|
68039
68073
|
this.sheetViewHeight = height;
|
|
@@ -68043,7 +68077,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
68043
68077
|
this.recomputeViewports();
|
|
68044
68078
|
}
|
|
68045
68079
|
recomputeViewports() {
|
|
68046
|
-
for (
|
|
68080
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
68047
68081
|
this.resetViewports(sheetId);
|
|
68048
68082
|
}
|
|
68049
68083
|
}
|
|
@@ -68054,8 +68088,8 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
68054
68088
|
}
|
|
68055
68089
|
getViewportOffset(sheetId) {
|
|
68056
68090
|
return {
|
|
68057
|
-
x: this.viewports[sheetId]?.bottomRight.
|
|
68058
|
-
y: this.viewports[sheetId]?.bottomRight.
|
|
68091
|
+
x: this.viewports[sheetId]?.bottomRight.offsetX || 0,
|
|
68092
|
+
y: this.viewports[sheetId]?.bottomRight.offsetY || 0,
|
|
68059
68093
|
};
|
|
68060
68094
|
}
|
|
68061
68095
|
resetViewports(sheetId) {
|
|
@@ -68065,8 +68099,10 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
68065
68099
|
const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
|
|
68066
68100
|
const nCols = this.getters.getNumberCols(sheetId);
|
|
68067
68101
|
const nRows = this.getters.getNumberRows(sheetId);
|
|
68068
|
-
const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
|
|
68069
|
-
const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
|
|
68102
|
+
const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
|
|
68103
|
+
const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
|
|
68104
|
+
const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
|
|
68105
|
+
const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
|
|
68070
68106
|
const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
|
|
68071
68107
|
const canScrollHorizontally = xRatio < 1.0;
|
|
68072
68108
|
const canScrollVertically = yRatio < 1.0;
|
|
@@ -68077,14 +68113,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
68077
68113
|
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: 0, bottom: ySplit - 1 }, { width: colOffset, height: rowOffset }, { canScrollHorizontally: false, canScrollVertically: false }, { x: 0, y: 0 })) ||
|
|
68078
68114
|
undefined,
|
|
68079
68115
|
topRight: (ySplit &&
|
|
68080
|
-
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width:
|
|
68116
|
+
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width: unfrozenWidth, height: rowOffset }, { canScrollHorizontally, canScrollVertically: false }, { x: canScrollHorizontally ? previousOffset.x : 0, y: 0 })) ||
|
|
68081
68117
|
undefined,
|
|
68082
68118
|
bottomLeft: (xSplit &&
|
|
68083
|
-
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height:
|
|
68119
|
+
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height: unfrozenHeight }, { canScrollHorizontally: false, canScrollVertically }, { x: 0, y: canScrollVertically ? previousOffset.y : 0 })) ||
|
|
68084
68120
|
undefined,
|
|
68085
68121
|
bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
|
|
68086
|
-
width:
|
|
68087
|
-
height:
|
|
68122
|
+
width: unfrozenWidth,
|
|
68123
|
+
height: unfrozenHeight,
|
|
68088
68124
|
}, { canScrollHorizontally, canScrollVertically }, {
|
|
68089
68125
|
x: canScrollHorizontally ? previousOffset.x : 0,
|
|
68090
68126
|
y: canScrollVertically ? previousOffset.y : 0,
|
|
@@ -68161,12 +68197,26 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
68161
68197
|
const height = this.sheetViewHeight + this.gridOffsetY;
|
|
68162
68198
|
return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
|
|
68163
68199
|
}
|
|
68164
|
-
|
|
68165
|
-
|
|
68166
|
-
|
|
68167
|
-
|
|
68168
|
-
|
|
68169
|
-
|
|
68200
|
+
mapViewportsToRect(sheetId, rectCallBack) {
|
|
68201
|
+
let x = Infinity;
|
|
68202
|
+
let y = Infinity;
|
|
68203
|
+
let width = 0;
|
|
68204
|
+
let height = 0;
|
|
68205
|
+
let hasViewports = false;
|
|
68206
|
+
for (const viewport of this.getSubViewports(sheetId)) {
|
|
68207
|
+
const rect = rectCallBack(viewport);
|
|
68208
|
+
if (rect) {
|
|
68209
|
+
hasViewports = true;
|
|
68210
|
+
x = Math.min(x, rect.x);
|
|
68211
|
+
y = Math.min(y, rect.y);
|
|
68212
|
+
width = Math.max(width, rect.x + rect.width);
|
|
68213
|
+
height = Math.max(height, rect.y + rect.height);
|
|
68214
|
+
}
|
|
68215
|
+
}
|
|
68216
|
+
if (!hasViewports) {
|
|
68217
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
68218
|
+
}
|
|
68219
|
+
return { x, y, width: width - x, height: height - y };
|
|
68170
68220
|
}
|
|
68171
68221
|
}
|
|
68172
68222
|
|
|
@@ -69341,7 +69391,7 @@ class SpreadsheetDashboard extends owl.Component {
|
|
|
69341
69391
|
});
|
|
69342
69392
|
}
|
|
69343
69393
|
moveCanvas(deltaX, deltaY) {
|
|
69344
|
-
const { scrollX, scrollY } = this.env.model.getters.
|
|
69394
|
+
const { scrollX, scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
69345
69395
|
this.env.model.dispatch("SET_VIEWPORT_OFFSET", {
|
|
69346
69396
|
offsetX: scrollX + deltaX,
|
|
69347
69397
|
offsetY: scrollY + deltaY,
|
|
@@ -75329,6 +75379,6 @@ exports.tokenColors = tokenColors;
|
|
|
75329
75379
|
exports.tokenize = tokenize;
|
|
75330
75380
|
|
|
75331
75381
|
|
|
75332
|
-
__info__.version = "18.2.0-alpha.
|
|
75333
|
-
__info__.date = "2025-
|
|
75334
|
-
__info__.hash = "
|
|
75382
|
+
__info__.version = "18.2.0-alpha.6";
|
|
75383
|
+
__info__.date = "2025-02-05T06:50:47.008Z";
|
|
75384
|
+
__info__.hash = "dae9ab2";
|