@odoo/o-spreadsheet 17.5.0-alpha.6 → 17.5.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 +298 -216
- package/dist/o-spreadsheet.d.ts +21 -42
- package/dist/o-spreadsheet.esm.js +298 -216
- package/dist/o-spreadsheet.iife.js +298 -216
- package/dist/o-spreadsheet.iife.min.js +340 -340
- package/dist/o_spreadsheet.xml +39 -5
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 17.5.0-alpha.
|
|
6
|
-
* @date 2024-08-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.5.0-alpha.7
|
|
6
|
+
* @date 2024-08-26T13:49:04.156Z
|
|
7
|
+
* @hash f8d3f23
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -267,6 +267,7 @@ const PIVOT_TABLE_CONFIG = {
|
|
|
267
267
|
bandedRows: true,
|
|
268
268
|
bandedColumns: false,
|
|
269
269
|
styleId: "TableStyleMedium5",
|
|
270
|
+
automaticAutofill: true,
|
|
270
271
|
};
|
|
271
272
|
|
|
272
273
|
//------------------------------------------------------------------------------
|
|
@@ -2323,7 +2324,6 @@ exports.CommandResult = void 0;
|
|
|
2323
2324
|
CommandResult["NoSplitSeparatorInSelection"] = "NoSplitSeparatorInSelection";
|
|
2324
2325
|
CommandResult["NoActiveSheet"] = "NoActiveSheet";
|
|
2325
2326
|
CommandResult["InvalidLocale"] = "InvalidLocale";
|
|
2326
|
-
CommandResult["AlreadyInPaintingFormatMode"] = "AlreadyInPaintingFormatMode";
|
|
2327
2327
|
CommandResult["MoreThanOneRangeSelected"] = "MoreThanOneRangeSelected";
|
|
2328
2328
|
CommandResult["NoColumnsProvided"] = "NoColumnsProvided";
|
|
2329
2329
|
CommandResult["ColumnsNotIncludedInZone"] = "ColumnsNotIncludedInZone";
|
|
@@ -4640,6 +4640,42 @@ function isOneDimensional(zone) {
|
|
|
4640
4640
|
const { numberOfCols, numberOfRows } = zoneToDimension(zone);
|
|
4641
4641
|
return numberOfCols === 1 || numberOfRows === 1;
|
|
4642
4642
|
}
|
|
4643
|
+
function excludeTopLeft(zone) {
|
|
4644
|
+
const { top, left, bottom, right } = zone;
|
|
4645
|
+
if (getZoneArea(zone) === 1) {
|
|
4646
|
+
return [];
|
|
4647
|
+
}
|
|
4648
|
+
const leftColumnZone = {
|
|
4649
|
+
top: top + 1,
|
|
4650
|
+
bottom,
|
|
4651
|
+
left,
|
|
4652
|
+
right: left,
|
|
4653
|
+
};
|
|
4654
|
+
if (right === left) {
|
|
4655
|
+
return [leftColumnZone];
|
|
4656
|
+
}
|
|
4657
|
+
const rightPartZone = {
|
|
4658
|
+
top,
|
|
4659
|
+
bottom,
|
|
4660
|
+
left: left + 1,
|
|
4661
|
+
right,
|
|
4662
|
+
};
|
|
4663
|
+
if (top === bottom) {
|
|
4664
|
+
return [rightPartZone];
|
|
4665
|
+
}
|
|
4666
|
+
return [leftColumnZone, rightPartZone];
|
|
4667
|
+
}
|
|
4668
|
+
function aggregatePositionsToZones(positions) {
|
|
4669
|
+
const result = {};
|
|
4670
|
+
for (const position of positions) {
|
|
4671
|
+
result[position.sheetId] ??= [];
|
|
4672
|
+
result[position.sheetId].push(positionToZone(position));
|
|
4673
|
+
}
|
|
4674
|
+
for (const sheetId in result) {
|
|
4675
|
+
result[sheetId] = recomputeZones(result[sheetId]);
|
|
4676
|
+
}
|
|
4677
|
+
return result;
|
|
4678
|
+
}
|
|
4643
4679
|
/**
|
|
4644
4680
|
* Array of all positions in the zone.
|
|
4645
4681
|
*/
|
|
@@ -4814,16 +4850,6 @@ function getZonesRows(zones) {
|
|
|
4814
4850
|
}
|
|
4815
4851
|
return set;
|
|
4816
4852
|
}
|
|
4817
|
-
function unionPositionsToZone(positions) {
|
|
4818
|
-
const zone = { top: Infinity, left: Infinity, bottom: -Infinity, right: -Infinity };
|
|
4819
|
-
for (const { col, row } of positions) {
|
|
4820
|
-
zone.top = Math.min(zone.top, row);
|
|
4821
|
-
zone.left = Math.min(zone.left, col);
|
|
4822
|
-
zone.bottom = Math.max(zone.bottom, row);
|
|
4823
|
-
zone.right = Math.max(zone.right, col);
|
|
4824
|
-
}
|
|
4825
|
-
return zone;
|
|
4826
|
-
}
|
|
4827
4853
|
/**
|
|
4828
4854
|
* Check if two zones are contiguous, ie. that they share a border
|
|
4829
4855
|
*/
|
|
@@ -10979,8 +11005,8 @@ const RANDARRAY = {
|
|
|
10979
11005
|
const _min = toNumber(min, this.locale);
|
|
10980
11006
|
const _max = toNumber(max, this.locale);
|
|
10981
11007
|
const _whole_number = toBoolean(wholeNumber);
|
|
10982
|
-
assertPositive(_t("The number columns (%s) must be positive.", _cols.toString()), _cols);
|
|
10983
|
-
assertPositive(_t("The number rows (%s) must be positive.", _rows.toString()), _rows);
|
|
11008
|
+
assertPositive(_t("The number of columns (%s) must be positive.", _cols.toString()), _cols);
|
|
11009
|
+
assertPositive(_t("The number of rows (%s) must be positive.", _rows.toString()), _rows);
|
|
10984
11010
|
assert(() => _min <= _max, _t("The maximum (%s) must be greater than or equal to the minimum (%s).", _max.toString(), _min.toString()));
|
|
10985
11011
|
if (_whole_number) {
|
|
10986
11012
|
assert(() => Number.isInteger(_min) && Number.isInteger(_max), _t("The maximum (%s) and minimum (%s) must be integers when whole_number is TRUE.", _max.toString(), _min.toString()));
|
|
@@ -11140,6 +11166,32 @@ const SECH = {
|
|
|
11140
11166
|
isExported: true,
|
|
11141
11167
|
};
|
|
11142
11168
|
// -----------------------------------------------------------------------------
|
|
11169
|
+
// SEQUENCE
|
|
11170
|
+
// -----------------------------------------------------------------------------
|
|
11171
|
+
const SEQUENCE = {
|
|
11172
|
+
description: _t("Returns a sequence of numbers."),
|
|
11173
|
+
args: [
|
|
11174
|
+
arg("rows (number)", _t("The number of rows to return")),
|
|
11175
|
+
arg("columns (number, optional, default=1)", _t("The number of columns to return")),
|
|
11176
|
+
arg("start (number, optional, default=1)", _t("The first number in the sequence")),
|
|
11177
|
+
arg("step (number, optional, default=1)", _t("The amount to increment each value in the sequence")),
|
|
11178
|
+
],
|
|
11179
|
+
compute: function (rows, columns = { value: 1 }, start = { value: 1 }, step = { value: 1 }) {
|
|
11180
|
+
const _start = toNumber(start, this.locale);
|
|
11181
|
+
const _step = toNumber(step, this.locale);
|
|
11182
|
+
const _rows = toInteger(rows, this.locale);
|
|
11183
|
+
const _columns = toInteger(columns, this.locale);
|
|
11184
|
+
assertPositive(_t("The number of columns (%s) must be positive.", _columns), _columns);
|
|
11185
|
+
assertPositive(_t("The number of rows (%s) must be positive.", _rows), _rows);
|
|
11186
|
+
return generateMatrix(_columns, _rows, (col, row) => {
|
|
11187
|
+
return {
|
|
11188
|
+
value: _start + row * _columns * _step + col * _step,
|
|
11189
|
+
};
|
|
11190
|
+
});
|
|
11191
|
+
},
|
|
11192
|
+
isExported: true,
|
|
11193
|
+
};
|
|
11194
|
+
// -----------------------------------------------------------------------------
|
|
11143
11195
|
// SIN
|
|
11144
11196
|
// -----------------------------------------------------------------------------
|
|
11145
11197
|
const SIN = {
|
|
@@ -11351,6 +11403,7 @@ var math = /*#__PURE__*/Object.freeze({
|
|
|
11351
11403
|
ROUNDUP: ROUNDUP,
|
|
11352
11404
|
SEC: SEC,
|
|
11353
11405
|
SECH: SECH,
|
|
11406
|
+
SEQUENCE: SEQUENCE,
|
|
11354
11407
|
SIN: SIN,
|
|
11355
11408
|
SINH: SINH,
|
|
11356
11409
|
SQRT: SQRT,
|
|
@@ -30636,6 +30689,7 @@ const deleteSheet = {
|
|
|
30636
30689
|
execute: (env) => env.askConfirmation(_t("Are you sure you want to delete this sheet?"), () => {
|
|
30637
30690
|
env.model.dispatch("DELETE_SHEET", { sheetId: env.model.getters.getActiveSheetId() });
|
|
30638
30691
|
}),
|
|
30692
|
+
icon: "o-spreadsheet-Icon.TRASH",
|
|
30639
30693
|
};
|
|
30640
30694
|
const duplicateSheet = {
|
|
30641
30695
|
name: _t("Duplicate"),
|
|
@@ -30648,11 +30702,13 @@ const duplicateSheet = {
|
|
|
30648
30702
|
});
|
|
30649
30703
|
env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom, sheetIdTo });
|
|
30650
30704
|
},
|
|
30705
|
+
icon: "o-spreadsheet-Icon.COPY",
|
|
30651
30706
|
};
|
|
30652
30707
|
const renameSheet = (args) => {
|
|
30653
30708
|
return {
|
|
30654
30709
|
name: _t("Rename"),
|
|
30655
30710
|
execute: args.renameSheetCallback,
|
|
30711
|
+
icon: "o-spreadsheet-Icon.RENAME_SHEET",
|
|
30656
30712
|
};
|
|
30657
30713
|
};
|
|
30658
30714
|
const sheetMoveRight = {
|
|
@@ -30666,6 +30722,7 @@ const sheetMoveRight = {
|
|
|
30666
30722
|
sheetId: env.model.getters.getActiveSheetId(),
|
|
30667
30723
|
delta: 1,
|
|
30668
30724
|
}),
|
|
30725
|
+
icon: "o-spreadsheet-Icon.MOVE_SHEET_RIGHT",
|
|
30669
30726
|
};
|
|
30670
30727
|
const sheetMoveLeft = {
|
|
30671
30728
|
name: _t("Move left"),
|
|
@@ -30677,11 +30734,13 @@ const sheetMoveLeft = {
|
|
|
30677
30734
|
sheetId: env.model.getters.getActiveSheetId(),
|
|
30678
30735
|
delta: -1,
|
|
30679
30736
|
}),
|
|
30737
|
+
icon: "o-spreadsheet-Icon.MOVE_SHEET_LEFT",
|
|
30680
30738
|
};
|
|
30681
30739
|
const hideSheet = {
|
|
30682
30740
|
name: _t("Hide sheet"),
|
|
30683
30741
|
isVisible: (env) => env.model.getters.getVisibleSheetIds().length !== 1,
|
|
30684
30742
|
execute: (env) => env.model.dispatch("HIDE_SHEET", { sheetId: env.model.getters.getActiveSheetId() }),
|
|
30743
|
+
icon: "o-spreadsheet-Icon.HIDE_SHEET",
|
|
30685
30744
|
};
|
|
30686
30745
|
|
|
30687
30746
|
//------------------------------------------------------------------------------
|
|
@@ -39806,7 +39865,6 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
39806
39865
|
searchScope: "activeSheet",
|
|
39807
39866
|
specificRange: undefined,
|
|
39808
39867
|
};
|
|
39809
|
-
updateSearchContent = debounce(this._updateSearchContent.bind(this), 200);
|
|
39810
39868
|
constructor(get) {
|
|
39811
39869
|
super(get);
|
|
39812
39870
|
this.initialShowFormulaState = this.model.getters.shouldShowFormulas();
|
|
@@ -39815,7 +39873,6 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
39815
39873
|
highlightStore.register(this);
|
|
39816
39874
|
this.onDispose(() => {
|
|
39817
39875
|
this.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.initialShowFormulaState });
|
|
39818
|
-
this.updateSearchContent.stopDebounce();
|
|
39819
39876
|
highlightStore.unRegister(this);
|
|
39820
39877
|
});
|
|
39821
39878
|
}
|
|
@@ -39829,7 +39886,7 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
39829
39886
|
return this.specificRangeMatches;
|
|
39830
39887
|
}
|
|
39831
39888
|
}
|
|
39832
|
-
|
|
39889
|
+
updateSearchContent(toSearch) {
|
|
39833
39890
|
this._updateSearch(toSearch, this.searchOptions);
|
|
39834
39891
|
}
|
|
39835
39892
|
updateSearchOptions(searchOptions) {
|
|
@@ -39845,9 +39902,6 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
39845
39902
|
selectNextMatch() {
|
|
39846
39903
|
this.selectNextCell(Direction.next);
|
|
39847
39904
|
}
|
|
39848
|
-
get pendingSearch() {
|
|
39849
|
-
return this.updateSearchContent.isDebouncePending();
|
|
39850
|
-
}
|
|
39851
39905
|
handle(cmd) {
|
|
39852
39906
|
switch (cmd.type) {
|
|
39853
39907
|
case "SET_FORMULA_VISIBILITY":
|
|
@@ -40179,6 +40233,7 @@ class FindAndReplacePanel extends owl.Component {
|
|
|
40179
40233
|
searchInput = owl.useRef("searchInput");
|
|
40180
40234
|
store;
|
|
40181
40235
|
state;
|
|
40236
|
+
updateSearchContent;
|
|
40182
40237
|
get hasSearchResult() {
|
|
40183
40238
|
return this.store.selectedMatchIndex !== null;
|
|
40184
40239
|
}
|
|
@@ -40220,12 +40275,14 @@ class FindAndReplacePanel extends owl.Component {
|
|
|
40220
40275
|
this.store = useLocalStore(FindAndReplaceStore);
|
|
40221
40276
|
this.state = owl.useState({ dataRange: "" });
|
|
40222
40277
|
owl.onMounted(() => this.searchInput.el?.focus());
|
|
40278
|
+
owl.onWillUnmount(() => this.updateSearchContent.stopDebounce());
|
|
40279
|
+
this.updateSearchContent = debounce(this.store.updateSearchContent, 200);
|
|
40223
40280
|
}
|
|
40224
40281
|
onFocusSearch() {
|
|
40225
40282
|
this.updateDataRange();
|
|
40226
40283
|
}
|
|
40227
40284
|
onSearchInput(ev) {
|
|
40228
|
-
this.
|
|
40285
|
+
this.updateSearchContent(ev.target.value);
|
|
40229
40286
|
}
|
|
40230
40287
|
onKeydownSearch(ev) {
|
|
40231
40288
|
if (ev.key === "Enter") {
|
|
@@ -40264,6 +40321,9 @@ class FindAndReplacePanel extends owl.Component {
|
|
|
40264
40321
|
const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.dataRange);
|
|
40265
40322
|
this.store.updateSearchOptions({ specificRange });
|
|
40266
40323
|
}
|
|
40324
|
+
get pendingSearch() {
|
|
40325
|
+
return this.updateSearchContent.isDebouncePending();
|
|
40326
|
+
}
|
|
40267
40327
|
}
|
|
40268
40328
|
|
|
40269
40329
|
css /* scss */ `
|
|
@@ -40816,34 +40876,9 @@ class CogWheelMenu extends owl.Component {
|
|
|
40816
40876
|
}
|
|
40817
40877
|
}
|
|
40818
40878
|
|
|
40819
|
-
/** @odoo-module */
|
|
40820
|
-
class EditableName extends owl.Component {
|
|
40821
|
-
static template = "o-spreadsheet-EditableName";
|
|
40822
|
-
static props = {
|
|
40823
|
-
name: String,
|
|
40824
|
-
displayName: String,
|
|
40825
|
-
onChanged: Function,
|
|
40826
|
-
};
|
|
40827
|
-
state;
|
|
40828
|
-
setup() {
|
|
40829
|
-
this.state = owl.useState({
|
|
40830
|
-
isEditing: false,
|
|
40831
|
-
name: "",
|
|
40832
|
-
});
|
|
40833
|
-
}
|
|
40834
|
-
rename() {
|
|
40835
|
-
this.state.isEditing = true;
|
|
40836
|
-
this.state.name = this.props.name;
|
|
40837
|
-
}
|
|
40838
|
-
save() {
|
|
40839
|
-
this.props.onChanged(this.state.name.trim());
|
|
40840
|
-
this.state.isEditing = false;
|
|
40841
|
-
}
|
|
40842
|
-
}
|
|
40843
|
-
|
|
40844
40879
|
class PivotTitleSection extends owl.Component {
|
|
40845
40880
|
static template = "o-spreadsheet-PivotTitleSection";
|
|
40846
|
-
static components = { CogWheelMenu, Section,
|
|
40881
|
+
static components = { CogWheelMenu, Section, TextInput };
|
|
40847
40882
|
static props = {
|
|
40848
40883
|
pivotId: String,
|
|
40849
40884
|
flipAxis: Function,
|
|
@@ -41410,6 +41445,12 @@ function orderDataEntriesKeys(groups, dimension) {
|
|
|
41410
41445
|
* Used to order two values
|
|
41411
41446
|
*/
|
|
41412
41447
|
function compareDimensionValues(dimension, a, b) {
|
|
41448
|
+
if (a === "null") {
|
|
41449
|
+
return dimension.order === "asc" ? 1 : -1;
|
|
41450
|
+
}
|
|
41451
|
+
if (b === "null") {
|
|
41452
|
+
return dimension.order === "asc" ? -1 : 1;
|
|
41453
|
+
}
|
|
41413
41454
|
if (dimension.type === "integer" || dimension.type === "date") {
|
|
41414
41455
|
return dimension.order === "asc" ? Number(a) - Number(b) : Number(b) - Number(a);
|
|
41415
41456
|
}
|
|
@@ -41773,7 +41814,7 @@ class SpreadsheetPivot {
|
|
|
41773
41814
|
if (cell.type === CellValueType.error) {
|
|
41774
41815
|
throw new EvaluationError(_t("The pivot cannot be created because cell %s contains an error", toXC(col, row)));
|
|
41775
41816
|
}
|
|
41776
|
-
if (cell.type === CellValueType.empty) {
|
|
41817
|
+
if (cell.type === CellValueType.empty || cell.value === "") {
|
|
41777
41818
|
throw new EvaluationError(_t("The pivot cannot be created because cell %s is empty", toXC(col, row)));
|
|
41778
41819
|
}
|
|
41779
41820
|
if (cell.value === "__count") {
|
|
@@ -42118,15 +42159,11 @@ class PivotSpreadsheetSidePanel extends owl.Component {
|
|
|
42118
42159
|
}
|
|
42119
42160
|
onSelectionConfirmed() {
|
|
42120
42161
|
if (this.state.range) {
|
|
42121
|
-
const
|
|
42122
|
-
|
|
42123
|
-
? this.env.model.getters.getSheetIdByName(sheetName)
|
|
42124
|
-
: this.env.model.getters.getActiveSheetId();
|
|
42125
|
-
if (!sheetId) {
|
|
42162
|
+
const range = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.state.range);
|
|
42163
|
+
if (range.invalidSheetName || range.invalidXc) {
|
|
42126
42164
|
return;
|
|
42127
42165
|
}
|
|
42128
|
-
const
|
|
42129
|
-
const dataSet = { sheetId, zone };
|
|
42166
|
+
const dataSet = { sheetId: range.sheetId, zone: range.zone };
|
|
42130
42167
|
this.store.update({ dataSet });
|
|
42131
42168
|
// Immediately apply the update to recompute the pivot fields
|
|
42132
42169
|
this.store.applyUpdate();
|
|
@@ -43064,10 +43101,6 @@ class TablePanel extends owl.Component {
|
|
|
43064
43101
|
});
|
|
43065
43102
|
}
|
|
43066
43103
|
onRangeChanged(ranges) {
|
|
43067
|
-
if (!ranges[0] || !ranges[0].match(rangeReference)) {
|
|
43068
|
-
this.state.tableZoneErrors = ["InvalidRange" /* CommandResult.InvalidRange */];
|
|
43069
|
-
return;
|
|
43070
|
-
}
|
|
43071
43104
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
43072
43105
|
this.state.tableXc = ranges[0];
|
|
43073
43106
|
const newTableRange = this.env.model.getters.getRangeFromSheetXC(sheetId, this.state.tableXc);
|
|
@@ -43107,11 +43140,6 @@ class TablePanel extends owl.Component {
|
|
|
43107
43140
|
const newTableRange = updatedTable.range;
|
|
43108
43141
|
this.state.tableXc = this.env.model.getters.getRangeString(newTableRange, sheetId);
|
|
43109
43142
|
}
|
|
43110
|
-
else {
|
|
43111
|
-
const oldTableRange = this.props.table.range;
|
|
43112
|
-
this.state.tableXc = this.env.model.getters.getRangeString(oldTableRange, sheetId);
|
|
43113
|
-
}
|
|
43114
|
-
this.state.tableZoneErrors = [];
|
|
43115
43143
|
}
|
|
43116
43144
|
deleteTable() {
|
|
43117
43145
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
@@ -45200,6 +45228,64 @@ class GridAddRowsFooter extends owl.Component {
|
|
|
45200
45228
|
}
|
|
45201
45229
|
}
|
|
45202
45230
|
|
|
45231
|
+
class PaintFormatStore extends SpreadsheetStore {
|
|
45232
|
+
mutators = ["activate", "cancel", "pasteFormat"];
|
|
45233
|
+
highlightStore = this.get(HighlightStore);
|
|
45234
|
+
cellClipboardHandler = new CellClipboardHandler(this.getters, this.model.dispatch);
|
|
45235
|
+
status = "inactive";
|
|
45236
|
+
copiedData;
|
|
45237
|
+
constructor(get) {
|
|
45238
|
+
super(get);
|
|
45239
|
+
this.highlightStore.register(this);
|
|
45240
|
+
this.onDispose(() => {
|
|
45241
|
+
this.highlightStore.unRegister(this);
|
|
45242
|
+
});
|
|
45243
|
+
}
|
|
45244
|
+
activate(args) {
|
|
45245
|
+
this.copiedData = this.copyFormats();
|
|
45246
|
+
this.status = args.persistent ? "persistent" : "oneOff";
|
|
45247
|
+
}
|
|
45248
|
+
cancel() {
|
|
45249
|
+
this.status = "inactive";
|
|
45250
|
+
this.copiedData = undefined;
|
|
45251
|
+
}
|
|
45252
|
+
pasteFormat(target) {
|
|
45253
|
+
if (this.copiedData) {
|
|
45254
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
45255
|
+
this.cellClipboardHandler.paste({ zones: target, sheetId }, this.copiedData, {
|
|
45256
|
+
isCutOperation: false,
|
|
45257
|
+
pasteOption: "onlyFormat",
|
|
45258
|
+
});
|
|
45259
|
+
}
|
|
45260
|
+
if (this.status === "oneOff") {
|
|
45261
|
+
this.cancel();
|
|
45262
|
+
}
|
|
45263
|
+
}
|
|
45264
|
+
get isActive() {
|
|
45265
|
+
return this.status !== "inactive";
|
|
45266
|
+
}
|
|
45267
|
+
copyFormats() {
|
|
45268
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
45269
|
+
const zones = this.getters.getSelectedZones();
|
|
45270
|
+
return this.cellClipboardHandler.copy(getClipboardDataPositions(sheetId, zones));
|
|
45271
|
+
}
|
|
45272
|
+
get highlights() {
|
|
45273
|
+
const data = this.copiedData;
|
|
45274
|
+
if (!data) {
|
|
45275
|
+
return [];
|
|
45276
|
+
}
|
|
45277
|
+
return data.zones.map((zone) => ({
|
|
45278
|
+
zone,
|
|
45279
|
+
color: SELECTION_BORDER_COLOR,
|
|
45280
|
+
dashed: true,
|
|
45281
|
+
sheetId: data.sheetId,
|
|
45282
|
+
noFill: true,
|
|
45283
|
+
thinLine: true,
|
|
45284
|
+
interactive: false,
|
|
45285
|
+
}));
|
|
45286
|
+
}
|
|
45287
|
+
}
|
|
45288
|
+
|
|
45203
45289
|
const CURSOR_SVG = /*xml*/ `
|
|
45204
45290
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14" height="16"><path d="M6.5.4c1.3-.8 2.9-.1 3.8 1.4l2.9 5.1c.2.4.9 1.6-.4 2.3l-1.6.9 1.8 3.1c.2.4.1 1-.2 1.2l-1.6 1c-.3.1-.9 0-1.1-.4l-1.8-3.1-1.6 1c-.6.4-1.7 0-2.2-.8L0 4.3"/><path fill="#fff" d="M9.1 2a1.4 1.1 60 0 0-1.7-.6L5.5 2.5l.9 1.6-1 .6-.9-1.6-.6.4 1.8 3.1-1.3.7-1.8-3.1-1 .6 3.8 6.6 6.8-3.98M3.9 8.8 10.82 5l.795 1.4-6.81 3.96"/></svg>
|
|
45205
45291
|
`;
|
|
@@ -45346,6 +45432,7 @@ class GridOverlay extends owl.Component {
|
|
|
45346
45432
|
gridOverlay = owl.useRef("gridOverlay");
|
|
45347
45433
|
gridOverlayRect = useAbsoluteBoundingRect(this.gridOverlay);
|
|
45348
45434
|
cellPopovers;
|
|
45435
|
+
paintFormatStore;
|
|
45349
45436
|
setup() {
|
|
45350
45437
|
useCellHovered(this.env, this.gridOverlay, this.props.onCellHovered);
|
|
45351
45438
|
const resizeObserver = new ResizeObserver(() => {
|
|
@@ -45368,6 +45455,7 @@ class GridOverlay extends owl.Component {
|
|
|
45368
45455
|
return scrollY > 0;
|
|
45369
45456
|
});
|
|
45370
45457
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
45458
|
+
this.paintFormatStore = useStore(PaintFormatStore);
|
|
45371
45459
|
}
|
|
45372
45460
|
get gridOverlayEl() {
|
|
45373
45461
|
if (!this.gridOverlay.el) {
|
|
@@ -45379,7 +45467,7 @@ class GridOverlay extends owl.Component {
|
|
|
45379
45467
|
return this.props.gridOverlayDimensions;
|
|
45380
45468
|
}
|
|
45381
45469
|
get isPaintingFormat() {
|
|
45382
|
-
return this.
|
|
45470
|
+
return this.paintFormatStore.isActive;
|
|
45383
45471
|
}
|
|
45384
45472
|
onMouseDown(ev) {
|
|
45385
45473
|
if (ev.button > 0) {
|
|
@@ -47266,6 +47354,7 @@ class Grid extends owl.Component {
|
|
|
47266
47354
|
cellPopovers;
|
|
47267
47355
|
composerFocusStore;
|
|
47268
47356
|
DOMFocusableElementStore;
|
|
47357
|
+
paintFormatStore;
|
|
47269
47358
|
onMouseWheel;
|
|
47270
47359
|
canvasPosition;
|
|
47271
47360
|
hoveredCell;
|
|
@@ -47283,6 +47372,7 @@ class Grid extends owl.Component {
|
|
|
47283
47372
|
this.composerFocusStore = useStore(ComposerFocusStore);
|
|
47284
47373
|
this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
|
|
47285
47374
|
this.sidePanel = useStore(SidePanelStore);
|
|
47375
|
+
this.paintFormatStore = useStore(PaintFormatStore);
|
|
47286
47376
|
useStore(ArrayFormulaHighlight);
|
|
47287
47377
|
owl.useChildSubEnv({ getPopoverContainerRect: () => this.getGridRect() });
|
|
47288
47378
|
owl.useExternalListener(document.body, "cut", this.copy.bind(this, true));
|
|
@@ -47359,8 +47449,8 @@ class Grid extends owl.Component {
|
|
|
47359
47449
|
else if (this.menuState.isOpen) {
|
|
47360
47450
|
this.closeMenu();
|
|
47361
47451
|
}
|
|
47362
|
-
else if (this.
|
|
47363
|
-
this.
|
|
47452
|
+
else if (this.paintFormatStore.isActive) {
|
|
47453
|
+
this.paintFormatStore.cancel();
|
|
47364
47454
|
}
|
|
47365
47455
|
else {
|
|
47366
47456
|
this.env.model.dispatch("CLEAN_CLIPBOARD_HIGHLIGHT");
|
|
@@ -47583,10 +47673,8 @@ class Grid extends owl.Component {
|
|
|
47583
47673
|
}
|
|
47584
47674
|
};
|
|
47585
47675
|
const onMouseUp = () => {
|
|
47586
|
-
if (this.
|
|
47587
|
-
this.env.model.
|
|
47588
|
-
target: this.env.model.getters.getSelectedZones(),
|
|
47589
|
-
});
|
|
47676
|
+
if (this.paintFormatStore.isActive) {
|
|
47677
|
+
this.paintFormatStore.pasteFormat(this.env.model.getters.getSelectedZones());
|
|
47590
47678
|
}
|
|
47591
47679
|
};
|
|
47592
47680
|
dragAndDropBeyondTheViewport(this.env, onMouseMove, onMouseUp);
|
|
@@ -47612,10 +47700,8 @@ class Grid extends owl.Component {
|
|
|
47612
47700
|
this.cellPopovers.close();
|
|
47613
47701
|
}
|
|
47614
47702
|
updateSelectionWithArrowKeys(ev, this.env.model.selection);
|
|
47615
|
-
if (this.
|
|
47616
|
-
this.env.model.
|
|
47617
|
-
target: this.env.model.getters.getSelectedZones(),
|
|
47618
|
-
});
|
|
47703
|
+
if (this.paintFormatStore.isActive) {
|
|
47704
|
+
this.paintFormatStore.pasteFormat(this.env.model.getters.getSelectedZones());
|
|
47619
47705
|
}
|
|
47620
47706
|
}
|
|
47621
47707
|
onKeydown(ev) {
|
|
@@ -47844,6 +47930,31 @@ class Grid extends owl.Component {
|
|
|
47844
47930
|
}
|
|
47845
47931
|
}
|
|
47846
47932
|
|
|
47933
|
+
/** @odoo-module */
|
|
47934
|
+
class EditableName extends owl.Component {
|
|
47935
|
+
static template = "o-spreadsheet-EditableName";
|
|
47936
|
+
static props = {
|
|
47937
|
+
name: String,
|
|
47938
|
+
displayName: String,
|
|
47939
|
+
onChanged: Function,
|
|
47940
|
+
};
|
|
47941
|
+
state;
|
|
47942
|
+
setup() {
|
|
47943
|
+
this.state = owl.useState({
|
|
47944
|
+
isEditing: false,
|
|
47945
|
+
name: "",
|
|
47946
|
+
});
|
|
47947
|
+
}
|
|
47948
|
+
rename() {
|
|
47949
|
+
this.state.isEditing = true;
|
|
47950
|
+
this.state.name = this.props.name;
|
|
47951
|
+
}
|
|
47952
|
+
save() {
|
|
47953
|
+
this.props.onChanged(this.state.name.trim());
|
|
47954
|
+
this.state.isEditing = false;
|
|
47955
|
+
}
|
|
47956
|
+
}
|
|
47957
|
+
|
|
47847
47958
|
/**
|
|
47848
47959
|
* BasePlugin
|
|
47849
47960
|
*
|
|
@@ -49503,6 +49614,8 @@ class ConditionalFormatPlugin extends CorePlugin {
|
|
|
49503
49614
|
"LessThan",
|
|
49504
49615
|
"LessThanOrEqual",
|
|
49505
49616
|
"NotContains",
|
|
49617
|
+
"Equal",
|
|
49618
|
+
"NotEqual",
|
|
49506
49619
|
]), this.checkOperatorArgsNumber(0, ["IsEmpty", "IsNotEmpty"]), this.checkCFValues);
|
|
49507
49620
|
case "ColorScaleRule": {
|
|
49508
49621
|
return this.checkValidations(rule, this.chainValidations(this.checkThresholds(this.checkFormulaCompilation)), this.chainValidations(this.checkThresholds(this.checkNaN), this.batchValidations(this.checkMinBiggerThanMax, this.checkMinBiggerThanMid, this.checkMidBiggerThanMax
|
|
@@ -49694,7 +49807,7 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
49694
49807
|
allowDispatch(cmd) {
|
|
49695
49808
|
switch (cmd.type) {
|
|
49696
49809
|
case "ADD_DATA_VALIDATION_RULE":
|
|
49697
|
-
return this.checkValidations(cmd, this.chainValidations(this.checkCriterionTypeIsValid, this.checkCriterionHasValidNumberOfValues, this.checkCriterionValuesAreValid));
|
|
49810
|
+
return this.checkValidations(cmd, this.chainValidations(this.checkEmptyRange, this.checkCriterionTypeIsValid, this.checkCriterionHasValidNumberOfValues, this.checkCriterionValuesAreValid));
|
|
49698
49811
|
case "REMOVE_DATA_VALIDATION_RULE":
|
|
49699
49812
|
if (!this.rules[cmd.sheetId].find((rule) => rule.id === cmd.id)) {
|
|
49700
49813
|
return "UnknownDataValidationRule" /* CommandResult.UnknownDataValidationRule */;
|
|
@@ -49822,6 +49935,9 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
49822
49935
|
this.dispatch("UPDATE_CELL", { ...position, style });
|
|
49823
49936
|
}
|
|
49824
49937
|
}
|
|
49938
|
+
checkEmptyRange(cmd) {
|
|
49939
|
+
return cmd.ranges.length ? "Success" /* CommandResult.Success */ : "EmptyRange" /* CommandResult.EmptyRange */;
|
|
49940
|
+
}
|
|
49825
49941
|
import(data) {
|
|
49826
49942
|
for (const sheet of data.sheets) {
|
|
49827
49943
|
this.rules[sheet.id] = [];
|
|
@@ -50052,7 +50168,10 @@ class HeaderSizePlugin extends CorePlugin {
|
|
|
50052
50168
|
handle(cmd) {
|
|
50053
50169
|
switch (cmd.type) {
|
|
50054
50170
|
case "CREATE_SHEET": {
|
|
50055
|
-
this.history.update("sizes", cmd.sheetId, {
|
|
50171
|
+
this.history.update("sizes", cmd.sheetId, {
|
|
50172
|
+
COL: Array(this.getters.getNumberCols(cmd.sheetId)).fill(undefined),
|
|
50173
|
+
ROW: Array(this.getters.getNumberRows(cmd.sheetId)).fill(undefined),
|
|
50174
|
+
});
|
|
50056
50175
|
break;
|
|
50057
50176
|
}
|
|
50058
50177
|
case "DUPLICATE_SHEET":
|
|
@@ -53123,6 +53242,9 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
53123
53242
|
if (deepEquals(cmd.pivot, this.pivots[cmd.pivotId]?.definition)) {
|
|
53124
53243
|
return "NoChanges" /* CommandResult.NoChanges */;
|
|
53125
53244
|
}
|
|
53245
|
+
if (cmd.pivot.name === "") {
|
|
53246
|
+
return "EmptyName" /* CommandResult.EmptyName */;
|
|
53247
|
+
}
|
|
53126
53248
|
break;
|
|
53127
53249
|
}
|
|
53128
53250
|
case "RENAME_PIVOT":
|
|
@@ -54701,47 +54823,47 @@ class SpreadingRelation {
|
|
|
54701
54823
|
* | 4 | | E | |
|
|
54702
54824
|
* -----------------
|
|
54703
54825
|
* ```
|
|
54704
|
-
* We
|
|
54705
|
-
* - (
|
|
54706
|
-
* - (
|
|
54707
|
-
*
|
|
54708
|
-
*
|
|
54826
|
+
* We have `resultsToArrayFormulas` is an R-tree looking like:
|
|
54827
|
+
* - (A2:C2) --> A2 meaning values in A2:C2 are the result of A2
|
|
54828
|
+
* - (B1:B4) --> B1 meaning values in B1:B4 are the result of B1
|
|
54829
|
+
*
|
|
54830
|
+
* Note that B2 is part of both zones because it can be the result of
|
|
54831
|
+
* A2 or B1.
|
|
54832
|
+
* Using an R-tree allows for fast insertions while still having
|
|
54833
|
+
* a relatively fast lookup.
|
|
54709
54834
|
*
|
|
54710
|
-
* We
|
|
54711
|
-
* - (A2) -->
|
|
54712
|
-
* - (B1) -->
|
|
54835
|
+
* We have `arrayFormulasToResults` looking like:
|
|
54836
|
+
* - (A2) --> A2:C2 meaning A2 spreads on the zone A2:C2
|
|
54837
|
+
* - (B1) --> B1:B4 meaning B1 spreads on the zone B1:B4
|
|
54713
54838
|
*
|
|
54714
54839
|
*/
|
|
54715
|
-
resultsToArrayFormulas = new
|
|
54840
|
+
resultsToArrayFormulas = new SpreadsheetRTree();
|
|
54716
54841
|
arrayFormulasToResults = new PositionMap();
|
|
54717
|
-
|
|
54718
|
-
return this.resultsToArrayFormulas.
|
|
54842
|
+
searchFormulaPositionsSpreadingOn(sheetId, zone) {
|
|
54843
|
+
return (this.resultsToArrayFormulas.search({ sheetId, zone }).map((node) => node.data) || EMPTY_ARRAY);
|
|
54719
54844
|
}
|
|
54720
|
-
|
|
54721
|
-
return this.arrayFormulasToResults.get(formulasPosition)
|
|
54845
|
+
getArrayResultZone(formulasPosition) {
|
|
54846
|
+
return this.arrayFormulasToResults.get(formulasPosition);
|
|
54722
54847
|
}
|
|
54723
54848
|
/**
|
|
54724
54849
|
* Remove a node, also remove it from other nodes adjacency list
|
|
54725
54850
|
*/
|
|
54726
54851
|
removeNode(position) {
|
|
54727
|
-
this.resultsToArrayFormulas.
|
|
54852
|
+
this.resultsToArrayFormulas.remove({
|
|
54853
|
+
boundingBox: { sheetId: position.sheetId, zone: positionToZone(position) },
|
|
54854
|
+
data: position,
|
|
54855
|
+
});
|
|
54728
54856
|
this.arrayFormulasToResults.delete(position);
|
|
54729
54857
|
}
|
|
54730
54858
|
/**
|
|
54731
54859
|
* Create a spreading relation between two cells
|
|
54732
54860
|
*/
|
|
54733
|
-
addRelation({ arrayFormulaPosition, resultPosition, }) {
|
|
54734
|
-
|
|
54735
|
-
|
|
54736
|
-
|
|
54737
|
-
|
|
54738
|
-
|
|
54739
|
-
this.arrayFormulasToResults.set(arrayFormulaPosition, []);
|
|
54740
|
-
}
|
|
54741
|
-
this.arrayFormulasToResults.get(arrayFormulaPosition)?.push(resultPosition);
|
|
54742
|
-
}
|
|
54743
|
-
hasArrayFormulaResult(position) {
|
|
54744
|
-
return this.resultsToArrayFormulas.has(position);
|
|
54861
|
+
addRelation({ arrayFormulaPosition, resultZone: resultPosition, }) {
|
|
54862
|
+
this.resultsToArrayFormulas.insert({
|
|
54863
|
+
boundingBox: { sheetId: arrayFormulaPosition.sheetId, zone: resultPosition },
|
|
54864
|
+
data: arrayFormulaPosition,
|
|
54865
|
+
});
|
|
54866
|
+
this.arrayFormulasToResults.set(arrayFormulaPosition, resultPosition);
|
|
54745
54867
|
}
|
|
54746
54868
|
isArrayFormula(position) {
|
|
54747
54869
|
return this.arrayFormulasToResults.has(position);
|
|
@@ -54769,7 +54891,8 @@ class Evaluator {
|
|
|
54769
54891
|
return this.evaluatedCells.get(position) || EMPTY_CELL;
|
|
54770
54892
|
}
|
|
54771
54893
|
getSpreadZone(position, options = { ignoreSpillError: false }) {
|
|
54772
|
-
|
|
54894
|
+
const spreadZone = this.spreadingRelations.getArrayResultZone(position);
|
|
54895
|
+
if (!spreadZone) {
|
|
54773
54896
|
return undefined;
|
|
54774
54897
|
}
|
|
54775
54898
|
const evaluatedCell = this.evaluatedCells.get(position);
|
|
@@ -54777,8 +54900,7 @@ class Evaluator {
|
|
|
54777
54900
|
!(options.ignoreSpillError && evaluatedCell?.value === CellErrorType.SpilledBlocked)) {
|
|
54778
54901
|
return positionToZone(position);
|
|
54779
54902
|
}
|
|
54780
|
-
|
|
54781
|
-
return union(positionToZone(position), unionPositionsToZone(spreadPositions));
|
|
54903
|
+
return union(positionToZone(position), spreadZone);
|
|
54782
54904
|
}
|
|
54783
54905
|
getEvaluatedPositions() {
|
|
54784
54906
|
return this.evaluatedCells.keys();
|
|
@@ -54787,10 +54909,12 @@ class Evaluator {
|
|
|
54787
54909
|
return this.evaluatedCells.keysForSheet(sheetId);
|
|
54788
54910
|
}
|
|
54789
54911
|
getArrayFormulaSpreadingOn(position) {
|
|
54790
|
-
|
|
54912
|
+
const hasArrayFormulaResult = this.getEvaluatedCell(position).type !== CellValueType.empty &&
|
|
54913
|
+
!this.getters.getCell(position)?.isFormula;
|
|
54914
|
+
if (!hasArrayFormulaResult) {
|
|
54791
54915
|
return this.spreadingRelations.isArrayFormula(position) ? position : undefined;
|
|
54792
54916
|
}
|
|
54793
|
-
const arrayFormulas = this.spreadingRelations.
|
|
54917
|
+
const arrayFormulas = this.spreadingRelations.searchFormulaPositionsSpreadingOn(position.sheetId, positionToZone(position));
|
|
54794
54918
|
return Array.from(arrayFormulas).find((position) => !this.blockedArrayFormulas.has(position));
|
|
54795
54919
|
}
|
|
54796
54920
|
updateDependencies(position) {
|
|
@@ -54854,7 +54978,12 @@ class Evaluator {
|
|
|
54854
54978
|
impactedPositions.add(position);
|
|
54855
54979
|
}
|
|
54856
54980
|
}
|
|
54857
|
-
|
|
54981
|
+
const zonesBySheetIds = aggregatePositionsToZones(impactedPositions);
|
|
54982
|
+
for (const sheetId in zonesBySheetIds) {
|
|
54983
|
+
for (const zone of zonesBySheetIds[sheetId]) {
|
|
54984
|
+
impactedPositions.addMany(this.getArrayFormulasBlockedBy(sheetId, zone));
|
|
54985
|
+
}
|
|
54986
|
+
}
|
|
54858
54987
|
return impactedPositions;
|
|
54859
54988
|
}
|
|
54860
54989
|
buildDependencyGraph() {
|
|
@@ -54906,19 +55035,14 @@ class Evaluator {
|
|
|
54906
55035
|
* Return the position of formulas blocked by the given positions
|
|
54907
55036
|
* as well as all their dependencies.
|
|
54908
55037
|
*/
|
|
54909
|
-
getArrayFormulasBlockedBy(
|
|
55038
|
+
getArrayFormulasBlockedBy(sheetId, zone) {
|
|
54910
55039
|
const arrayFormulaPositions = this.createEmptyPositionSet();
|
|
54911
|
-
|
|
54912
|
-
|
|
54913
|
-
|
|
54914
|
-
|
|
54915
|
-
|
|
54916
|
-
arrayFormulaPositions.
|
|
54917
|
-
const arrayFormulaPosition = this.getArrayFormulaSpreadingOn(position);
|
|
54918
|
-
if (arrayFormulaPosition) {
|
|
54919
|
-
// ignore the formula spreading on the position. Keep only the blocked ones
|
|
54920
|
-
arrayFormulaPositions.delete(arrayFormulaPosition);
|
|
54921
|
-
}
|
|
55040
|
+
const arrayFormulas = this.spreadingRelations.searchFormulaPositionsSpreadingOn(sheetId, zone);
|
|
55041
|
+
arrayFormulaPositions.addMany(arrayFormulas);
|
|
55042
|
+
const spilledPositions = [...arrayFormulas].filter((position) => !this.blockedArrayFormulas.has(position));
|
|
55043
|
+
if (spilledPositions.length) {
|
|
55044
|
+
// ignore the formula spreading on the position. Keep only the blocked ones
|
|
55045
|
+
arrayFormulaPositions.deleteMany(spilledPositions);
|
|
54922
55046
|
}
|
|
54923
55047
|
arrayFormulaPositions.addMany(this.getCellsDependingOn(arrayFormulaPositions));
|
|
54924
55048
|
return arrayFormulaPositions;
|
|
@@ -54996,37 +55120,24 @@ class Evaluator {
|
|
|
54996
55120
|
this.assertSheetHasEnoughSpaceToSpreadFormulaResult(formulaPosition, formulaReturn);
|
|
54997
55121
|
const nbColumns = formulaReturn.length;
|
|
54998
55122
|
const nbRows = formulaReturn[0].length;
|
|
54999
|
-
|
|
55123
|
+
const resultZone = {
|
|
55124
|
+
top: formulaPosition.row,
|
|
55125
|
+
bottom: formulaPosition.row + nbRows - 1,
|
|
55126
|
+
left: formulaPosition.col,
|
|
55127
|
+
right: formulaPosition.col + nbColumns - 1,
|
|
55128
|
+
};
|
|
55129
|
+
this.spreadingRelations.addRelation({ resultZone, arrayFormulaPosition: formulaPosition });
|
|
55000
55130
|
this.assertNoMergedCellsInSpreadZone(formulaPosition, formulaReturn);
|
|
55001
55131
|
forEachSpreadPositionInMatrix(nbColumns, nbRows, this.checkCollision(formulaPosition));
|
|
55002
55132
|
forEachSpreadPositionInMatrix(nbColumns, nbRows,
|
|
55003
55133
|
// thanks to the isMatrix check above, we know that formulaReturn is MatrixFunctionReturn
|
|
55004
55134
|
this.spreadValues(formulaPosition, formulaReturn));
|
|
55005
|
-
this.invalidatePositionsDependingOnSpread(formulaPosition,
|
|
55135
|
+
this.invalidatePositionsDependingOnSpread(formulaPosition.sheetId, resultZone);
|
|
55006
55136
|
return createEvaluatedCell(nullValueToZeroValue(formulaReturn[0][0]), this.getters.getLocale(), cellData);
|
|
55007
55137
|
}
|
|
55008
|
-
invalidatePositionsDependingOnSpread(
|
|
55138
|
+
invalidatePositionsDependingOnSpread(sheetId, resultZone) {
|
|
55009
55139
|
// the result matrix is split in 2 zones to exclude the array formula position
|
|
55010
|
-
const
|
|
55011
|
-
const left = arrayFormulaPosition.col;
|
|
55012
|
-
const bottom = top + nbRows - 1;
|
|
55013
|
-
const leftColumnZone = {
|
|
55014
|
-
top: top + 1,
|
|
55015
|
-
bottom,
|
|
55016
|
-
left,
|
|
55017
|
-
right: left,
|
|
55018
|
-
};
|
|
55019
|
-
const rightPartZone = {
|
|
55020
|
-
top,
|
|
55021
|
-
bottom,
|
|
55022
|
-
left: left + 1,
|
|
55023
|
-
right: left + nbColumns - 1,
|
|
55024
|
-
};
|
|
55025
|
-
const sheetId = arrayFormulaPosition.sheetId;
|
|
55026
|
-
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn([
|
|
55027
|
-
{ sheetId, zone: rightPartZone },
|
|
55028
|
-
{ sheetId, zone: leftColumnZone },
|
|
55029
|
-
]);
|
|
55140
|
+
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })));
|
|
55030
55141
|
this.nextPositionsToUpdate.addMany(invalidatedPositions);
|
|
55031
55142
|
}
|
|
55032
55143
|
assertSheetHasEnoughSpaceToSpreadFormulaResult({ sheetId, col, row }, matrixResult) {
|
|
@@ -55057,14 +55168,6 @@ class Evaluator {
|
|
|
55057
55168
|
}
|
|
55058
55169
|
throw new SplillBlockedError(_t("Merged cells found in the spill zone. Please unmerge cells before using array formulas."));
|
|
55059
55170
|
}
|
|
55060
|
-
updateSpreadRelation({ sheetId, col, row, }) {
|
|
55061
|
-
const arrayFormulaPosition = { sheetId, col, row };
|
|
55062
|
-
const updateSpreadRelation = (i, j) => {
|
|
55063
|
-
const position = { sheetId, col: i + col, row: j + row };
|
|
55064
|
-
this.spreadingRelations.addRelation({ resultPosition: position, arrayFormulaPosition });
|
|
55065
|
-
};
|
|
55066
|
-
return updateSpreadRelation;
|
|
55067
|
-
}
|
|
55068
55171
|
checkCollision(formulaPosition) {
|
|
55069
55172
|
const { sheetId, col, row } = formulaPosition;
|
|
55070
55173
|
const checkCollision = (i, j) => {
|
|
@@ -55089,22 +55192,25 @@ class Evaluator {
|
|
|
55089
55192
|
return spreadValues;
|
|
55090
55193
|
}
|
|
55091
55194
|
invalidateSpreading(position) {
|
|
55092
|
-
|
|
55195
|
+
const zone = this.spreadingRelations.getArrayResultZone(position);
|
|
55196
|
+
if (!zone) {
|
|
55093
55197
|
return;
|
|
55094
55198
|
}
|
|
55095
|
-
|
|
55096
|
-
|
|
55097
|
-
|
|
55098
|
-
|
|
55099
|
-
|
|
55100
|
-
|
|
55101
|
-
|
|
55199
|
+
for (let col = zone.left; col <= zone.right; col++) {
|
|
55200
|
+
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
55201
|
+
const resultPosition = { sheetId: position.sheetId, col, row };
|
|
55202
|
+
const content = this.getters.getCell(resultPosition)?.content;
|
|
55203
|
+
if (content) {
|
|
55204
|
+
// there's no point at re-evaluating overlapping array formulas,
|
|
55205
|
+
// there's still a collision
|
|
55206
|
+
continue;
|
|
55207
|
+
}
|
|
55208
|
+
this.evaluatedCells.delete(resultPosition);
|
|
55102
55209
|
}
|
|
55103
|
-
invalidated.add(child);
|
|
55104
|
-
this.evaluatedCells.delete(child);
|
|
55105
55210
|
}
|
|
55106
|
-
|
|
55107
|
-
this.
|
|
55211
|
+
const sheetId = position.sheetId;
|
|
55212
|
+
this.invalidatePositionsDependingOnSpread(sheetId, zone);
|
|
55213
|
+
this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedBy(sheetId, zone));
|
|
55108
55214
|
}
|
|
55109
55215
|
// ----------------------------------------------------------
|
|
55110
55216
|
// COMMON FUNCTIONALITY
|
|
@@ -55284,9 +55390,10 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
55284
55390
|
if (!("content" in cmd || "format" in cmd) || this.shouldRebuildDependenciesGraph) {
|
|
55285
55391
|
return;
|
|
55286
55392
|
}
|
|
55287
|
-
|
|
55393
|
+
const position = { sheetId: cmd.sheetId, row: cmd.row, col: cmd.col };
|
|
55394
|
+
this.positionsToUpdate.push(position);
|
|
55288
55395
|
if ("content" in cmd) {
|
|
55289
|
-
this.evaluator.updateDependencies(
|
|
55396
|
+
this.evaluator.updateDependencies(position);
|
|
55290
55397
|
}
|
|
55291
55398
|
break;
|
|
55292
55399
|
case "EVALUATE_CELLS":
|
|
@@ -56572,10 +56679,6 @@ class PivotUIPlugin extends UIPlugin {
|
|
|
56572
56679
|
this.setupPivot(cmd.pivotId, { recreate: true });
|
|
56573
56680
|
break;
|
|
56574
56681
|
}
|
|
56575
|
-
case "REMOVE_PIVOT": {
|
|
56576
|
-
delete this.pivots[cmd.pivotId];
|
|
56577
|
-
break;
|
|
56578
|
-
}
|
|
56579
56682
|
case "DELETE_SHEET":
|
|
56580
56683
|
case "UPDATE_CELL": {
|
|
56581
56684
|
this.unusedPivots = undefined;
|
|
@@ -56717,6 +56820,9 @@ class PivotUIPlugin extends UIPlugin {
|
|
|
56717
56820
|
}
|
|
56718
56821
|
}
|
|
56719
56822
|
getPivot(pivotId) {
|
|
56823
|
+
if (!this.getters.isExistingPivot(pivotId)) {
|
|
56824
|
+
throw new Error(`pivot ${pivotId} not found`);
|
|
56825
|
+
}
|
|
56720
56826
|
return this.pivots[pivotId];
|
|
56721
56827
|
}
|
|
56722
56828
|
isPivotUnused(pivotId) {
|
|
@@ -58799,7 +58905,7 @@ class InsertPivotPlugin extends UIPlugin {
|
|
|
58799
58905
|
sheetId,
|
|
58800
58906
|
col,
|
|
58801
58907
|
row,
|
|
58802
|
-
content: `=PIVOT(
|
|
58908
|
+
content: `=PIVOT(${pivotFormulaId})`,
|
|
58803
58909
|
});
|
|
58804
58910
|
const zone = {
|
|
58805
58911
|
left: col,
|
|
@@ -60123,10 +60229,8 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
60123
60229
|
"getClipboardId",
|
|
60124
60230
|
"getClipboardTextContent",
|
|
60125
60231
|
"isCutOperation",
|
|
60126
|
-
"isPaintingFormat",
|
|
60127
60232
|
];
|
|
60128
60233
|
status = "invisible";
|
|
60129
|
-
paintFormatStatus = "inactive";
|
|
60130
60234
|
originSheetId;
|
|
60131
60235
|
copiedData;
|
|
60132
60236
|
_isCutOperation = false;
|
|
@@ -60141,14 +60245,14 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
60141
60245
|
return this.isCutAllowedOn(zones);
|
|
60142
60246
|
case "PASTE_FROM_OS_CLIPBOARD": {
|
|
60143
60247
|
const copiedData = this.convertOSClipboardData(cmd.clipboardContent[ClipboardMIMEType.PlainText] ?? "");
|
|
60144
|
-
const pasteOption = cmd.pasteOption
|
|
60248
|
+
const pasteOption = cmd.pasteOption;
|
|
60145
60249
|
return this.isPasteAllowed(cmd.target, copiedData, { pasteOption, isCutOperation: false });
|
|
60146
60250
|
}
|
|
60147
60251
|
case "PASTE": {
|
|
60148
60252
|
if (!this.copiedData) {
|
|
60149
60253
|
return "EmptyClipboard" /* CommandResult.EmptyClipboard */;
|
|
60150
60254
|
}
|
|
60151
|
-
const pasteOption = cmd.pasteOption
|
|
60255
|
+
const pasteOption = cmd.pasteOption;
|
|
60152
60256
|
return this.isPasteAllowed(cmd.target, this.copiedData, {
|
|
60153
60257
|
pasteOption: pasteOption,
|
|
60154
60258
|
isCutOperation: this._isCutOperation,
|
|
@@ -60178,12 +60282,6 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
60178
60282
|
const copiedData = this.copy(cut);
|
|
60179
60283
|
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
60180
60284
|
}
|
|
60181
|
-
case "ACTIVATE_PAINT_FORMAT": {
|
|
60182
|
-
if (this.paintFormatStatus !== "inactive") {
|
|
60183
|
-
return "AlreadyInPaintingFormatMode" /* CommandResult.AlreadyInPaintingFormatMode */;
|
|
60184
|
-
}
|
|
60185
|
-
return "Success" /* CommandResult.Success */;
|
|
60186
|
-
}
|
|
60187
60285
|
}
|
|
60188
60286
|
return "Success" /* CommandResult.Success */;
|
|
60189
60287
|
}
|
|
@@ -60205,7 +60303,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
60205
60303
|
else {
|
|
60206
60304
|
this.copiedData = this.convertOSClipboardData(cmd.clipboardContent[ClipboardMIMEType.PlainText] ?? "");
|
|
60207
60305
|
}
|
|
60208
|
-
const pasteOption = cmd.pasteOption
|
|
60306
|
+
const pasteOption = cmd.pasteOption;
|
|
60209
60307
|
this.paste(cmd.target, this.copiedData, {
|
|
60210
60308
|
pasteOption,
|
|
60211
60309
|
selectTarget: true,
|
|
@@ -60215,18 +60313,16 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
60215
60313
|
break;
|
|
60216
60314
|
}
|
|
60217
60315
|
case "PASTE": {
|
|
60218
|
-
const pasteOption = cmd.pasteOption
|
|
60316
|
+
const pasteOption = cmd.pasteOption;
|
|
60219
60317
|
this.paste(cmd.target, this.copiedData, {
|
|
60220
60318
|
pasteOption,
|
|
60221
60319
|
selectTarget: true,
|
|
60222
60320
|
isCutOperation: this._isCutOperation,
|
|
60223
60321
|
});
|
|
60224
|
-
if (this.paintFormatStatus === "oneOff") {
|
|
60225
|
-
this.paintFormatStatus = "inactive";
|
|
60226
|
-
}
|
|
60227
60322
|
this.status = "invisible";
|
|
60228
60323
|
if (this._isCutOperation) {
|
|
60229
60324
|
this.copiedData = undefined;
|
|
60325
|
+
this._isCutOperation = false;
|
|
60230
60326
|
}
|
|
60231
60327
|
break;
|
|
60232
60328
|
}
|
|
@@ -60322,18 +60418,6 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
60322
60418
|
});
|
|
60323
60419
|
break;
|
|
60324
60420
|
}
|
|
60325
|
-
case "ACTIVATE_PAINT_FORMAT": {
|
|
60326
|
-
const zones = this.getters.getSelectedZones();
|
|
60327
|
-
this.copiedData = this.copy(zones);
|
|
60328
|
-
this.status = "visible";
|
|
60329
|
-
if (cmd.persistent) {
|
|
60330
|
-
this.paintFormatStatus = "persistent";
|
|
60331
|
-
}
|
|
60332
|
-
else {
|
|
60333
|
-
this.paintFormatStatus = "oneOff";
|
|
60334
|
-
}
|
|
60335
|
-
break;
|
|
60336
|
-
}
|
|
60337
60421
|
case "DELETE_SHEET":
|
|
60338
60422
|
if (this._isCutOperation !== true) {
|
|
60339
60423
|
return;
|
|
@@ -60343,11 +60427,6 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
60343
60427
|
this.status = "invisible";
|
|
60344
60428
|
}
|
|
60345
60429
|
break;
|
|
60346
|
-
case "CANCEL_PAINT_FORMAT": {
|
|
60347
|
-
this.paintFormatStatus = "inactive";
|
|
60348
|
-
this.status = "invisible";
|
|
60349
|
-
break;
|
|
60350
|
-
}
|
|
60351
60430
|
default:
|
|
60352
60431
|
if (isCoreCommand(cmd)) {
|
|
60353
60432
|
this.status = "invisible";
|
|
@@ -60563,7 +60642,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
60563
60642
|
}
|
|
60564
60643
|
const cells = this.copiedData.cells;
|
|
60565
60644
|
if (cells.length === 1 && cells[0].length === 1) {
|
|
60566
|
-
return this.getters.getCellText(cells[0][0].position)
|
|
60645
|
+
return `<div data-clipboard-id="${this.clipboardId}">${this.getters.getCellText(cells[0][0].position)}</div>`;
|
|
60567
60646
|
}
|
|
60568
60647
|
if (!cells[0][0]) {
|
|
60569
60648
|
return "";
|
|
@@ -60587,9 +60666,6 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
60587
60666
|
isCutOperation() {
|
|
60588
60667
|
return this._isCutOperation ?? false;
|
|
60589
60668
|
}
|
|
60590
|
-
isPaintingFormat() {
|
|
60591
|
-
return this.paintFormatStatus !== "inactive";
|
|
60592
|
-
}
|
|
60593
60669
|
// ---------------------------------------------------------------------------
|
|
60594
60670
|
// Private methods
|
|
60595
60671
|
// ---------------------------------------------------------------------------
|
|
@@ -64494,18 +64570,22 @@ class PaintFormatButton extends owl.Component {
|
|
|
64494
64570
|
static props = {
|
|
64495
64571
|
class: { type: String, optional: true },
|
|
64496
64572
|
};
|
|
64573
|
+
paintFormatStore;
|
|
64574
|
+
setup() {
|
|
64575
|
+
this.paintFormatStore = useStore(PaintFormatStore);
|
|
64576
|
+
}
|
|
64497
64577
|
get isActive() {
|
|
64498
|
-
return this.
|
|
64578
|
+
return this.paintFormatStore.isActive;
|
|
64499
64579
|
}
|
|
64500
64580
|
onDblClick() {
|
|
64501
|
-
this.
|
|
64581
|
+
this.paintFormatStore.activate({ persistent: true });
|
|
64502
64582
|
}
|
|
64503
64583
|
togglePaintFormat() {
|
|
64504
64584
|
if (this.isActive) {
|
|
64505
|
-
this.
|
|
64585
|
+
this.paintFormatStore.cancel();
|
|
64506
64586
|
}
|
|
64507
64587
|
else {
|
|
64508
|
-
this.
|
|
64588
|
+
this.paintFormatStore.activate({ persistent: false });
|
|
64509
64589
|
}
|
|
64510
64590
|
}
|
|
64511
64591
|
}
|
|
@@ -68956,6 +69036,7 @@ class Model extends EventBus {
|
|
|
68956
69036
|
case 0 /* Status.Ready */:
|
|
68957
69037
|
const result = this.checkDispatchAllowed(command);
|
|
68958
69038
|
if (!result.isSuccessful) {
|
|
69039
|
+
this.trigger("update");
|
|
68959
69040
|
return result;
|
|
68960
69041
|
}
|
|
68961
69042
|
this.status = 1 /* Status.Running */;
|
|
@@ -69275,6 +69356,7 @@ const components = {
|
|
|
69275
69356
|
PivotTitleSection,
|
|
69276
69357
|
CogWheelMenu,
|
|
69277
69358
|
TextInput,
|
|
69359
|
+
SidePanelCollapsible,
|
|
69278
69360
|
};
|
|
69279
69361
|
const hooks = {
|
|
69280
69362
|
useDragAndDropListItems,
|
|
@@ -69361,6 +69443,6 @@ exports.tokenColors = tokenColors;
|
|
|
69361
69443
|
exports.tokenize = tokenize;
|
|
69362
69444
|
|
|
69363
69445
|
|
|
69364
|
-
__info__.version = "17.5.0-alpha.
|
|
69365
|
-
__info__.date = "2024-08-
|
|
69366
|
-
__info__.hash = "
|
|
69446
|
+
__info__.version = "17.5.0-alpha.7";
|
|
69447
|
+
__info__.date = "2024-08-26T13:49:04.156Z";
|
|
69448
|
+
__info__.hash = "f8d3f23";
|