@odoo/o-spreadsheet 16.4.21 → 16.4.24
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 +257 -154
- package/dist/o-spreadsheet.d.ts +28 -14
- package/dist/o-spreadsheet.esm.js +257 -154
- package/dist/o-spreadsheet.iife.js +257 -154
- package/dist/o-spreadsheet.iife.min.js +103 -103
- package/dist/o_spreadsheet.xml +15 -33
- package/package.json +1 -1
|
@@ -702,18 +702,18 @@
|
|
|
702
702
|
return true;
|
|
703
703
|
}
|
|
704
704
|
class JetSet extends Set {
|
|
705
|
-
|
|
705
|
+
addMany(iterable) {
|
|
706
706
|
for (const element of iterable) {
|
|
707
707
|
super.add(element);
|
|
708
708
|
}
|
|
709
709
|
return this;
|
|
710
710
|
}
|
|
711
|
-
|
|
712
|
-
let
|
|
711
|
+
deleteMany(iterable) {
|
|
712
|
+
let wasDeleted = false;
|
|
713
713
|
for (const element of iterable) {
|
|
714
|
-
|
|
714
|
+
wasDeleted ||= super.delete(element);
|
|
715
715
|
}
|
|
716
|
-
return
|
|
716
|
+
return wasDeleted;
|
|
717
717
|
}
|
|
718
718
|
}
|
|
719
719
|
/**
|
|
@@ -1839,6 +1839,9 @@
|
|
|
1839
1839
|
function formatValue(value, { format, locale }) {
|
|
1840
1840
|
switch (typeof value) {
|
|
1841
1841
|
case "string":
|
|
1842
|
+
if (value.includes('\\"')) {
|
|
1843
|
+
return value.replace(/\\"/g, '"');
|
|
1844
|
+
}
|
|
1842
1845
|
return value;
|
|
1843
1846
|
case "boolean":
|
|
1844
1847
|
return value ? "TRUE" : "FALSE";
|
|
@@ -15236,6 +15239,9 @@
|
|
|
15236
15239
|
if (locale.formulaArgSeparator === locale.decimalSeparator) {
|
|
15237
15240
|
return false;
|
|
15238
15241
|
}
|
|
15242
|
+
if (locale.thousandsSeparator === locale.decimalSeparator) {
|
|
15243
|
+
return false;
|
|
15244
|
+
}
|
|
15239
15245
|
try {
|
|
15240
15246
|
formatValue(1, { locale, format: "#,##0.00" });
|
|
15241
15247
|
formatValue(1, { locale, format: locale.dateFormat });
|
|
@@ -15326,7 +15332,7 @@
|
|
|
15326
15332
|
if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
|
|
15327
15333
|
return content;
|
|
15328
15334
|
}
|
|
15329
|
-
return content.replace(locale.decimalSeparator, ".");
|
|
15335
|
+
return content.replace(locale.thousandsSeparator, "").replace(locale.decimalSeparator, ".");
|
|
15330
15336
|
}
|
|
15331
15337
|
/**
|
|
15332
15338
|
* Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
|
|
@@ -18628,6 +18634,12 @@
|
|
|
18628
18634
|
let { col, row } = env.model.getters.getActivePosition();
|
|
18629
18635
|
env.model.dispatch("OPEN_CELL_POPOVER", { col, row, popoverType: "LinkEditor" });
|
|
18630
18636
|
};
|
|
18637
|
+
const INSERT_LINK_NAME = (env) => {
|
|
18638
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
18639
|
+
const { col, row } = env.model.getters.getActivePosition();
|
|
18640
|
+
const cell = env.model.getters.getEvaluatedCell({ sheetId, col, row });
|
|
18641
|
+
return cell && cell.link ? _lt("Edit link") : _lt("Insert link");
|
|
18642
|
+
};
|
|
18631
18643
|
//------------------------------------------------------------------------------
|
|
18632
18644
|
// Filters action
|
|
18633
18645
|
//------------------------------------------------------------------------------
|
|
@@ -19168,7 +19180,7 @@
|
|
|
19168
19180
|
})
|
|
19169
19181
|
.add("insert_link", {
|
|
19170
19182
|
...insertLink,
|
|
19171
|
-
name:
|
|
19183
|
+
name: INSERT_LINK_NAME,
|
|
19172
19184
|
sequence: 150,
|
|
19173
19185
|
separator: true,
|
|
19174
19186
|
});
|
|
@@ -20656,7 +20668,7 @@
|
|
|
20656
20668
|
: this.props.ranges()
|
|
20657
20669
|
? this.props.ranges().map((xc, id) => ({
|
|
20658
20670
|
xc,
|
|
20659
|
-
id,
|
|
20671
|
+
id: id + 1,
|
|
20660
20672
|
isFocused: false,
|
|
20661
20673
|
}))
|
|
20662
20674
|
: [];
|
|
@@ -24079,6 +24091,7 @@
|
|
|
24079
24091
|
static components = { TextValueProvider, FunctionDescriptionProvider };
|
|
24080
24092
|
static defaultProps = {
|
|
24081
24093
|
inputStyle: "",
|
|
24094
|
+
isDefaultFocus: false,
|
|
24082
24095
|
};
|
|
24083
24096
|
composerRef = owl.useRef("o_composer");
|
|
24084
24097
|
contentHelper = new ContentEditableHelper(this.composerRef.el);
|
|
@@ -24131,7 +24144,6 @@
|
|
|
24131
24144
|
F2: () => console.warn("Not implemented"),
|
|
24132
24145
|
F4: this.processF4Key,
|
|
24133
24146
|
Tab: (ev) => this.processTabKey(ev),
|
|
24134
|
-
" ": (ev) => this.processSpaceKey(ev),
|
|
24135
24147
|
};
|
|
24136
24148
|
keyCodeMapping = {
|
|
24137
24149
|
NumpadDecimal: this.processNumpadDecimal,
|
|
@@ -24139,11 +24151,11 @@
|
|
|
24139
24151
|
setup() {
|
|
24140
24152
|
owl.onMounted(() => {
|
|
24141
24153
|
const el = this.composerRef.el;
|
|
24154
|
+
if (this.props.isDefaultFocus) {
|
|
24155
|
+
this.env.focusableElement.setFocusableElement(el);
|
|
24156
|
+
}
|
|
24142
24157
|
this.contentHelper.updateEl(el);
|
|
24143
24158
|
});
|
|
24144
|
-
owl.onWillUnmount(() => {
|
|
24145
|
-
this.props.onComposerUnmounted?.();
|
|
24146
|
-
});
|
|
24147
24159
|
owl.useEffect(() => {
|
|
24148
24160
|
this.processContent();
|
|
24149
24161
|
});
|
|
@@ -24152,7 +24164,8 @@
|
|
|
24152
24164
|
// Handlers
|
|
24153
24165
|
// ---------------------------------------------------------------------------
|
|
24154
24166
|
processArrowKeys(ev) {
|
|
24155
|
-
if (this.env.model.getters.isSelectingForComposer()
|
|
24167
|
+
if (this.env.model.getters.isSelectingForComposer() ||
|
|
24168
|
+
this.env.model.getters.getEditionMode() === "inactive") {
|
|
24156
24169
|
this.functionDescriptionState.showDescription = false;
|
|
24157
24170
|
// Prevent the default content editable behavior which moves the cursor
|
|
24158
24171
|
ev.preventDefault();
|
|
@@ -24191,25 +24204,19 @@
|
|
|
24191
24204
|
processTabKey(ev) {
|
|
24192
24205
|
ev.preventDefault();
|
|
24193
24206
|
ev.stopPropagation();
|
|
24194
|
-
if (this.
|
|
24195
|
-
|
|
24196
|
-
|
|
24197
|
-
|
|
24198
|
-
|
|
24207
|
+
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
24208
|
+
if (this.autoCompleteState.showProvider) {
|
|
24209
|
+
const autoCompleteValue = this.autoCompleteState.values[this.autoCompleteState.selectedIndex]?.text;
|
|
24210
|
+
if (autoCompleteValue) {
|
|
24211
|
+
this.autoComplete(autoCompleteValue);
|
|
24212
|
+
return;
|
|
24213
|
+
}
|
|
24199
24214
|
}
|
|
24215
|
+
this.env.model.dispatch("STOP_EDITION");
|
|
24200
24216
|
}
|
|
24201
24217
|
const direction = ev.shiftKey ? "left" : "right";
|
|
24202
|
-
this.env.model.dispatch("STOP_EDITION");
|
|
24203
24218
|
this.env.model.selection.moveAnchorCell(direction, 1);
|
|
24204
24219
|
}
|
|
24205
|
-
processSpaceKey(ev) {
|
|
24206
|
-
if (ev.ctrlKey) {
|
|
24207
|
-
ev.preventDefault();
|
|
24208
|
-
ev.stopPropagation();
|
|
24209
|
-
this.showAutocomplete("");
|
|
24210
|
-
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
|
24211
|
-
}
|
|
24212
|
-
}
|
|
24213
24220
|
processEnterKey(ev) {
|
|
24214
24221
|
ev.preventDefault();
|
|
24215
24222
|
ev.stopPropagation();
|
|
@@ -24261,6 +24268,9 @@
|
|
|
24261
24268
|
this.compositionActive = false;
|
|
24262
24269
|
}
|
|
24263
24270
|
onKeydown(ev) {
|
|
24271
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
24272
|
+
return;
|
|
24273
|
+
}
|
|
24264
24274
|
let handler = this.keyMapping[ev.key] || this.keyCodeMapping[ev.code];
|
|
24265
24275
|
if (handler) {
|
|
24266
24276
|
handler.call(this, ev);
|
|
@@ -24269,14 +24279,33 @@
|
|
|
24269
24279
|
ev.stopPropagation();
|
|
24270
24280
|
}
|
|
24271
24281
|
}
|
|
24282
|
+
onPaste(ev) {
|
|
24283
|
+
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
24284
|
+
ev.stopPropagation();
|
|
24285
|
+
}
|
|
24286
|
+
}
|
|
24272
24287
|
/*
|
|
24273
24288
|
* Triggered automatically by the content-editable between the keydown and key up
|
|
24274
24289
|
* */
|
|
24275
24290
|
onInput(ev) {
|
|
24276
|
-
if (
|
|
24291
|
+
if (!this.shouldProcessInputEvents) {
|
|
24277
24292
|
return;
|
|
24278
24293
|
}
|
|
24279
|
-
|
|
24294
|
+
if (ev.inputType === "insertFromPaste" &&
|
|
24295
|
+
this.env.model.getters.getEditionMode() === "inactive") {
|
|
24296
|
+
return;
|
|
24297
|
+
}
|
|
24298
|
+
ev.stopPropagation();
|
|
24299
|
+
let content;
|
|
24300
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
24301
|
+
content = ev.data || "";
|
|
24302
|
+
}
|
|
24303
|
+
else {
|
|
24304
|
+
content = this.contentHelper.getText();
|
|
24305
|
+
}
|
|
24306
|
+
if (this.props.focus === "inactive") {
|
|
24307
|
+
return this.props.onComposerCellFocused?.(content);
|
|
24308
|
+
}
|
|
24280
24309
|
let selection = this.contentHelper.getCurrentSelection();
|
|
24281
24310
|
if (ev.inputType === "insertParagraph") {
|
|
24282
24311
|
const start = Math.min(selection.start, selection.end);
|
|
@@ -24354,9 +24383,8 @@
|
|
|
24354
24383
|
}
|
|
24355
24384
|
const newSelection = this.contentHelper.getCurrentSelection();
|
|
24356
24385
|
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
|
24357
|
-
|
|
24358
|
-
|
|
24359
|
-
}
|
|
24386
|
+
this.props.onComposerContentFocused();
|
|
24387
|
+
if (this.props.focus === "inactive") ;
|
|
24360
24388
|
this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", newSelection);
|
|
24361
24389
|
this.processTokenAtCursor();
|
|
24362
24390
|
}
|
|
@@ -24523,7 +24551,7 @@
|
|
|
24523
24551
|
const highlights = this.env.model.getters.getHighlights();
|
|
24524
24552
|
const refSheet = sheetName
|
|
24525
24553
|
? this.env.model.getters.getSheetIdByName(sheetName)
|
|
24526
|
-
: this.env.model.getters.getCurrentEditedCell()
|
|
24554
|
+
: this.env.model.getters.getCurrentEditedCell()?.sheetId;
|
|
24527
24555
|
const highlight = highlights.find((highlight) => {
|
|
24528
24556
|
if (highlight.sheetId !== refSheet)
|
|
24529
24557
|
return false;
|
|
@@ -24603,12 +24631,13 @@
|
|
|
24603
24631
|
}
|
|
24604
24632
|
}
|
|
24605
24633
|
Composer.props = {
|
|
24606
|
-
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
24607
|
-
onComposerContentFocused: Function,
|
|
24608
24634
|
inputStyle: { type: String, optional: true },
|
|
24609
24635
|
rect: { type: Object, optional: true },
|
|
24610
24636
|
delimitation: { type: Object, optional: true },
|
|
24611
|
-
|
|
24637
|
+
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
24638
|
+
onComposerCellFocused: { type: Function, optional: true },
|
|
24639
|
+
onComposerContentFocused: Function,
|
|
24640
|
+
isDefaultFocus: { type: Boolean, optional: true },
|
|
24612
24641
|
};
|
|
24613
24642
|
|
|
24614
24643
|
const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
|
|
@@ -24642,51 +24671,26 @@
|
|
|
24642
24671
|
class GridComposer extends owl.Component {
|
|
24643
24672
|
static template = "o-spreadsheet-GridComposer";
|
|
24644
24673
|
static components = { Composer };
|
|
24645
|
-
|
|
24646
|
-
|
|
24647
|
-
|
|
24674
|
+
// TODORAR see if we can keep it undefined
|
|
24675
|
+
rect = this.defaultRect;
|
|
24676
|
+
isEditing = false;
|
|
24648
24677
|
isCellReferenceVisible;
|
|
24649
|
-
|
|
24678
|
+
get defaultRect() {
|
|
24679
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
24680
|
+
}
|
|
24650
24681
|
setup() {
|
|
24651
|
-
this.gridComposerRef = owl.useRef("gridComposer");
|
|
24652
|
-
this.composerState = owl.useState({
|
|
24653
|
-
rect: undefined,
|
|
24654
|
-
delimitation: undefined,
|
|
24655
|
-
});
|
|
24656
|
-
const { sheetId, col, row } = this.env.model.getters.getActivePosition();
|
|
24657
|
-
this.zone = this.env.model.getters.expandZone(sheetId, positionToZone({ col, row }));
|
|
24658
|
-
this.rect = this.env.model.getters.getVisibleRect(this.zone);
|
|
24659
|
-
this.isCellReferenceVisible = false;
|
|
24660
|
-
owl.onMounted(() => {
|
|
24661
|
-
const el = this.gridComposerRef.el;
|
|
24662
|
-
this.composerState.rect = {
|
|
24663
|
-
x: this.rect.x,
|
|
24664
|
-
y: this.rect.y,
|
|
24665
|
-
width: el.clientWidth,
|
|
24666
|
-
height: el.clientHeight,
|
|
24667
|
-
};
|
|
24668
|
-
this.composerState.delimitation = {
|
|
24669
|
-
width: this.props.gridDims.width,
|
|
24670
|
-
height: this.props.gridDims.height,
|
|
24671
|
-
};
|
|
24672
|
-
});
|
|
24673
24682
|
owl.onWillUpdateProps(() => {
|
|
24674
|
-
|
|
24675
|
-
|
|
24676
|
-
}
|
|
24677
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
24678
|
-
const zone = this.env.model.getters.getSelectedZone();
|
|
24679
|
-
const rect = this.env.model.getters.getVisibleRect(zone);
|
|
24680
|
-
if (!deepEquals(rect, this.rect) ||
|
|
24681
|
-
sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
|
|
24682
|
-
this.isCellReferenceVisible = true;
|
|
24683
|
-
}
|
|
24683
|
+
this.updateComponentPosition();
|
|
24684
|
+
this.updateCellReferenceVisibility();
|
|
24684
24685
|
});
|
|
24685
24686
|
}
|
|
24686
24687
|
get shouldDisplayCellReference() {
|
|
24687
24688
|
return this.isCellReferenceVisible;
|
|
24688
24689
|
}
|
|
24689
24690
|
get cellReference() {
|
|
24691
|
+
if (!this.env.model.getters.getCurrentEditedCell()) {
|
|
24692
|
+
return "";
|
|
24693
|
+
}
|
|
24690
24694
|
const { col, row, sheetId } = this.env.model.getters.getCurrentEditedCell();
|
|
24691
24695
|
const prefixSheet = sheetId !== this.env.model.getters.getActiveSheetId();
|
|
24692
24696
|
return `${prefixSheet ? getCanonicalSheetName(this.env.model.getters.getSheetName(sheetId)) + "!" : ""}${toXC(col, row)}`;
|
|
@@ -24698,7 +24702,27 @@
|
|
|
24698
24702
|
top: `${top - GRID_CELL_REFERENCE_TOP_OFFSET}px`,
|
|
24699
24703
|
});
|
|
24700
24704
|
}
|
|
24705
|
+
get composerProps() {
|
|
24706
|
+
const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
|
24707
|
+
return {
|
|
24708
|
+
rect: { ...this.rect },
|
|
24709
|
+
delimitation: {
|
|
24710
|
+
width,
|
|
24711
|
+
height,
|
|
24712
|
+
},
|
|
24713
|
+
focus: this.props.focus,
|
|
24714
|
+
isDefaultFocus: true,
|
|
24715
|
+
onComposerContentFocused: this.props.onComposerContentFocused,
|
|
24716
|
+
onComposerCellFocused: this.props.onComposerCellFocused,
|
|
24717
|
+
};
|
|
24718
|
+
}
|
|
24701
24719
|
get containerStyle() {
|
|
24720
|
+
if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
|
|
24721
|
+
return `
|
|
24722
|
+
position: absolute;
|
|
24723
|
+
z-index: -1000;
|
|
24724
|
+
`;
|
|
24725
|
+
}
|
|
24702
24726
|
const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
|
|
24703
24727
|
const cell = this.env.model.getters.getActiveCell();
|
|
24704
24728
|
const position = this.env.model.getters.getActivePosition();
|
|
@@ -24718,6 +24742,8 @@
|
|
|
24718
24742
|
if (!isFormula) {
|
|
24719
24743
|
textAlign = style.align || cell.defaultAlign;
|
|
24720
24744
|
}
|
|
24745
|
+
const maxHeight = this.props.gridDims.height - this.rect.y;
|
|
24746
|
+
const maxWidth = this.props.gridDims.width - this.rect.x;
|
|
24721
24747
|
/**
|
|
24722
24748
|
* min-size is on the container, not the composer element, because we want to have the same size as the cell by default,
|
|
24723
24749
|
* including all the paddings/margins of the composer
|
|
@@ -24729,6 +24755,8 @@
|
|
|
24729
24755
|
top: `${top}px`,
|
|
24730
24756
|
"min-width": `${width + 1}px`,
|
|
24731
24757
|
"min-height": `${height + 1}px`,
|
|
24758
|
+
"max-width": `${maxWidth}px`,
|
|
24759
|
+
"max-height": `${maxHeight}px`,
|
|
24732
24760
|
background,
|
|
24733
24761
|
color,
|
|
24734
24762
|
"font-size": `${fontSizeInPixels(fontSize)}px`,
|
|
@@ -24738,20 +24766,38 @@
|
|
|
24738
24766
|
"text-align": textAlign,
|
|
24739
24767
|
});
|
|
24740
24768
|
}
|
|
24741
|
-
|
|
24742
|
-
const
|
|
24743
|
-
|
|
24744
|
-
|
|
24745
|
-
|
|
24746
|
-
|
|
24747
|
-
|
|
24769
|
+
updateComponentPosition() {
|
|
24770
|
+
const isEditing = this.env.model.getters.getEditionMode() !== "inactive";
|
|
24771
|
+
if (this.isEditing !== isEditing) {
|
|
24772
|
+
this.isEditing = isEditing;
|
|
24773
|
+
if (!isEditing) {
|
|
24774
|
+
this.rect = this.defaultRect;
|
|
24775
|
+
this.env.focusableElement.focus();
|
|
24776
|
+
return;
|
|
24777
|
+
}
|
|
24778
|
+
const position = this.env.model.getters.getActivePosition();
|
|
24779
|
+
const zone = this.env.model.getters.expandZone(position.sheetId, positionToZone(position));
|
|
24780
|
+
this.rect = this.env.model.getters.getVisibleRect(zone);
|
|
24781
|
+
}
|
|
24782
|
+
}
|
|
24783
|
+
updateCellReferenceVisibility() {
|
|
24784
|
+
if (this.isCellReferenceVisible || this.env.model.getters.getEditionMode() === "inactive") {
|
|
24785
|
+
return;
|
|
24786
|
+
}
|
|
24787
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
24788
|
+
const zone = this.env.model.getters.getSelectedZone();
|
|
24789
|
+
const rect = this.env.model.getters.getVisibleRect(zone);
|
|
24790
|
+
if (!deepEquals(rect, this.rect) ||
|
|
24791
|
+
sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
|
|
24792
|
+
this.isCellReferenceVisible = true;
|
|
24793
|
+
}
|
|
24748
24794
|
}
|
|
24749
24795
|
}
|
|
24750
24796
|
GridComposer.props = {
|
|
24751
24797
|
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
24752
|
-
onComposerUnmounted: Function,
|
|
24753
24798
|
onComposerContentFocused: Function,
|
|
24754
24799
|
gridDims: Object,
|
|
24800
|
+
onComposerCellFocused: Function,
|
|
24755
24801
|
};
|
|
24756
24802
|
|
|
24757
24803
|
const CSS$1 = css /* scss */ `
|
|
@@ -25632,7 +25678,6 @@
|
|
|
25632
25678
|
this.props.onCellDoubleClicked(col, row);
|
|
25633
25679
|
}
|
|
25634
25680
|
onContextMenu(ev) {
|
|
25635
|
-
ev.preventDefault();
|
|
25636
25681
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
25637
25682
|
this.props.onCellRightClicked(col, row, { x: ev.clientX, y: ev.clientY });
|
|
25638
25683
|
}
|
|
@@ -26725,7 +26770,6 @@
|
|
|
26725
26770
|
HEADER_WIDTH = HEADER_WIDTH;
|
|
26726
26771
|
menuState;
|
|
26727
26772
|
gridRef;
|
|
26728
|
-
hiddenInput;
|
|
26729
26773
|
onMouseWheel;
|
|
26730
26774
|
canvasPosition;
|
|
26731
26775
|
hoveredCell;
|
|
@@ -26736,17 +26780,16 @@
|
|
|
26736
26780
|
menuItems: [],
|
|
26737
26781
|
});
|
|
26738
26782
|
this.gridRef = owl.useRef("grid");
|
|
26739
|
-
this.hiddenInput = owl.useRef("hiddenInput");
|
|
26740
26783
|
this.canvasPosition = useAbsoluteBoundingRect(this.gridRef);
|
|
26741
26784
|
this.hoveredCell = owl.useState({ col: undefined, row: undefined });
|
|
26742
26785
|
owl.useChildSubEnv({ getPopoverContainerRect: () => this.getGridRect() });
|
|
26743
26786
|
owl.useExternalListener(document.body, "cut", this.copy.bind(this, true));
|
|
26744
26787
|
owl.useExternalListener(document.body, "copy", this.copy.bind(this, false));
|
|
26745
26788
|
owl.useExternalListener(document.body, "paste", this.paste);
|
|
26746
|
-
owl.onMounted(() => this.
|
|
26747
|
-
this.props.exposeFocus(() => this.
|
|
26789
|
+
owl.onMounted(() => this.focusDefaultElement());
|
|
26790
|
+
this.props.exposeFocus(() => this.focusDefaultElement());
|
|
26748
26791
|
useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimensionWithHeaders());
|
|
26749
|
-
owl.useEffect(() => this.
|
|
26792
|
+
owl.useEffect(() => this.focusDefaultElement(), () => [this.env.model.getters.getActiveSheetId()]);
|
|
26750
26793
|
this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
|
|
26751
26794
|
this.moveCanvas(deltaX, deltaY);
|
|
26752
26795
|
this.hoveredCell.col = undefined;
|
|
@@ -26769,7 +26812,7 @@
|
|
|
26769
26812
|
if (this.env.model.getters.hasOpenedPopover()) {
|
|
26770
26813
|
this.closeOpenedPopover();
|
|
26771
26814
|
}
|
|
26772
|
-
this.
|
|
26815
|
+
this.focusDefaultElement();
|
|
26773
26816
|
}
|
|
26774
26817
|
// this map will handle most of the actions that should happen on key down. The arrow keys are managed in the key
|
|
26775
26818
|
// down itself
|
|
@@ -26942,10 +26985,10 @@
|
|
|
26942
26985
|
PAGEUP: () => this.env.model.dispatch("SHIFT_VIEWPORT_UP"),
|
|
26943
26986
|
"CTRL+K": () => INSERT_LINK(this.env),
|
|
26944
26987
|
};
|
|
26945
|
-
|
|
26988
|
+
focusDefaultElement() {
|
|
26946
26989
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
26947
26990
|
this.env.model.getters.getEditionMode() === "inactive") {
|
|
26948
|
-
this.
|
|
26991
|
+
this.env.focusableElement.focus();
|
|
26949
26992
|
}
|
|
26950
26993
|
}
|
|
26951
26994
|
get gridEl() {
|
|
@@ -27089,19 +27132,6 @@
|
|
|
27089
27132
|
return;
|
|
27090
27133
|
}
|
|
27091
27134
|
}
|
|
27092
|
-
onInput(ev) {
|
|
27093
|
-
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
27094
|
-
if (!ev.isComposing && ev.inputType === "insertFromPaste") {
|
|
27095
|
-
return;
|
|
27096
|
-
}
|
|
27097
|
-
if (ev.data) {
|
|
27098
|
-
// if the user types a character on the grid, it means he wants to start composing the selected cell with that
|
|
27099
|
-
// character
|
|
27100
|
-
ev.preventDefault();
|
|
27101
|
-
ev.stopPropagation();
|
|
27102
|
-
this.props.onGridComposerCellFocused(ev.data);
|
|
27103
|
-
}
|
|
27104
|
-
}
|
|
27105
27135
|
// ---------------------------------------------------------------------------
|
|
27106
27136
|
// Context Menu
|
|
27107
27137
|
// ---------------------------------------------------------------------------
|
|
@@ -27214,7 +27244,7 @@
|
|
|
27214
27244
|
}
|
|
27215
27245
|
closeMenu() {
|
|
27216
27246
|
this.menuState.isOpen = false;
|
|
27217
|
-
this.
|
|
27247
|
+
this.focusDefaultElement();
|
|
27218
27248
|
}
|
|
27219
27249
|
}
|
|
27220
27250
|
Grid.props = {
|
|
@@ -30875,8 +30905,16 @@
|
|
|
30875
30905
|
},
|
|
30876
30906
|
},
|
|
30877
30907
|
{
|
|
30878
|
-
description: "
|
|
30908
|
+
description: "Fix datafilter duplication",
|
|
30879
30909
|
from: 12,
|
|
30910
|
+
to: 12.5,
|
|
30911
|
+
applyMigration(data) {
|
|
30912
|
+
return fixOverlappingFilters(data);
|
|
30913
|
+
},
|
|
30914
|
+
},
|
|
30915
|
+
{
|
|
30916
|
+
description: "Change Border description structure",
|
|
30917
|
+
from: 12.5,
|
|
30880
30918
|
to: 13,
|
|
30881
30919
|
applyMigration(data) {
|
|
30882
30920
|
for (const borderId in data.borders) {
|
|
@@ -30907,6 +30945,14 @@
|
|
|
30907
30945
|
return data;
|
|
30908
30946
|
},
|
|
30909
30947
|
},
|
|
30948
|
+
{
|
|
30949
|
+
description: "Fix datafilter duplication (post saas-16.4)",
|
|
30950
|
+
from: 14,
|
|
30951
|
+
to: 14.5,
|
|
30952
|
+
applyMigration(data) {
|
|
30953
|
+
return fixOverlappingFilters(data);
|
|
30954
|
+
},
|
|
30955
|
+
},
|
|
30910
30956
|
];
|
|
30911
30957
|
/**
|
|
30912
30958
|
* This function is used to repair faulty data independently of the migration.
|
|
@@ -31064,6 +31110,26 @@
|
|
|
31064
31110
|
}
|
|
31065
31111
|
return messages;
|
|
31066
31112
|
}
|
|
31113
|
+
function fixOverlappingFilters(data) {
|
|
31114
|
+
for (let sheet of data.sheets || []) {
|
|
31115
|
+
let knownDataFilterZones = [];
|
|
31116
|
+
for (let filterTable of sheet.filterTables || []) {
|
|
31117
|
+
const zone = toZone(filterTable.range);
|
|
31118
|
+
// See commit message of https://github.com/odoo/o-spreadsheet/pull/3632 of more details
|
|
31119
|
+
const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => overlap(knownZone, zone));
|
|
31120
|
+
if (intersectZoneIndex !== -1) {
|
|
31121
|
+
knownDataFilterZones[intersectZoneIndex] = zone;
|
|
31122
|
+
}
|
|
31123
|
+
else {
|
|
31124
|
+
knownDataFilterZones.push(zone);
|
|
31125
|
+
}
|
|
31126
|
+
}
|
|
31127
|
+
sheet.filterTables = knownDataFilterZones.map((zone) => ({
|
|
31128
|
+
range: zoneToXc(zone),
|
|
31129
|
+
}));
|
|
31130
|
+
}
|
|
31131
|
+
return data;
|
|
31132
|
+
}
|
|
31067
31133
|
// -----------------------------------------------------------------------------
|
|
31068
31134
|
// Helpers
|
|
31069
31135
|
// -----------------------------------------------------------------------------
|
|
@@ -31793,9 +31859,9 @@
|
|
|
31793
31859
|
allowDispatch(cmd) {
|
|
31794
31860
|
switch (cmd.type) {
|
|
31795
31861
|
case "UPDATE_CELL":
|
|
31796
|
-
return this.
|
|
31862
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
|
|
31797
31863
|
case "CLEAR_CELL":
|
|
31798
|
-
return this.checkValidations(cmd, this.
|
|
31864
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
|
|
31799
31865
|
default:
|
|
31800
31866
|
return 0 /* CommandResult.Success */;
|
|
31801
31867
|
}
|
|
@@ -31927,10 +31993,6 @@
|
|
|
31927
31993
|
format: cell.format ? getItemId(cell.format, formats) : undefined,
|
|
31928
31994
|
content: cell.content || undefined,
|
|
31929
31995
|
};
|
|
31930
|
-
// if there is a formula but no dependencies (maybe because the cell is in error), no need to recompute the formula text
|
|
31931
|
-
if (cell.isFormula && cell.dependencies.length) {
|
|
31932
|
-
cells[xc].content = this.buildFormulaContent(_sheet.id, cell, cell.dependencies, true);
|
|
31933
|
-
}
|
|
31934
31996
|
}
|
|
31935
31997
|
_sheet.cells = cells;
|
|
31936
31998
|
}
|
|
@@ -32093,10 +32155,7 @@
|
|
|
32093
32155
|
else {
|
|
32094
32156
|
style = before ? before.style : undefined;
|
|
32095
32157
|
}
|
|
32096
|
-
const
|
|
32097
|
-
let format = ("format" in after ? after.format : before && before.format) ||
|
|
32098
|
-
detectDateFormat(afterContent, locale) ||
|
|
32099
|
-
detectNumberFormat(afterContent);
|
|
32158
|
+
const format = "format" in after ? after.format : before && before.format;
|
|
32100
32159
|
/* Read the following IF as:
|
|
32101
32160
|
* we need to remove the cell if it is completely empty, but we can know if it completely empty if:
|
|
32102
32161
|
* - the command says the new content is empty and has no border/format/style
|
|
@@ -32137,12 +32196,11 @@
|
|
|
32137
32196
|
}
|
|
32138
32197
|
createLiteralCell(id, content, format, style) {
|
|
32139
32198
|
const locale = this.getters.getLocale();
|
|
32140
|
-
content = parseLiteral(content, locale).toString();
|
|
32141
32199
|
return {
|
|
32142
32200
|
id,
|
|
32143
|
-
content,
|
|
32201
|
+
content: parseLiteral(content, locale).toString(),
|
|
32144
32202
|
style,
|
|
32145
|
-
format,
|
|
32203
|
+
format: format || detectDateFormat(content, locale) || detectNumberFormat(content),
|
|
32146
32204
|
isFormula: false,
|
|
32147
32205
|
};
|
|
32148
32206
|
}
|
|
@@ -32203,6 +32261,18 @@
|
|
|
32203
32261
|
}
|
|
32204
32262
|
return 0 /* CommandResult.Success */;
|
|
32205
32263
|
}
|
|
32264
|
+
checkUselessUpdateCell(cmd) {
|
|
32265
|
+
const cell = this.getters.getCell(cmd);
|
|
32266
|
+
const hasContent = "content" in cmd || "formula" in cmd;
|
|
32267
|
+
const hasStyle = "style" in cmd;
|
|
32268
|
+
const hasFormat = "format" in cmd;
|
|
32269
|
+
if ((!hasContent || cell?.content === cmd.content) &&
|
|
32270
|
+
(!hasStyle || deepEquals(cell?.style, cmd.style)) &&
|
|
32271
|
+
(!hasFormat || cell?.format === cmd.format)) {
|
|
32272
|
+
return 98 /* CommandResult.NoChanges */;
|
|
32273
|
+
}
|
|
32274
|
+
return 0 /* CommandResult.Success */;
|
|
32275
|
+
}
|
|
32206
32276
|
}
|
|
32207
32277
|
class FormulaCellWithDependencies {
|
|
32208
32278
|
id;
|
|
@@ -36343,7 +36413,15 @@
|
|
|
36343
36413
|
if (!this.rTrees[sheetId]) {
|
|
36344
36414
|
return;
|
|
36345
36415
|
}
|
|
36346
|
-
this.rTrees[sheetId].remove(item,
|
|
36416
|
+
this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
|
|
36417
|
+
}
|
|
36418
|
+
rtreeItemComparer(left, right) {
|
|
36419
|
+
return (left.data == right.data &&
|
|
36420
|
+
left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
36421
|
+
left.boundingBox?.zone.left === right.boundingBox.zone.left &&
|
|
36422
|
+
left.boundingBox?.zone.top === right.boundingBox.zone.top &&
|
|
36423
|
+
left.boundingBox?.zone.right === right.boundingBox.zone.right &&
|
|
36424
|
+
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom);
|
|
36347
36425
|
}
|
|
36348
36426
|
}
|
|
36349
36427
|
/**
|
|
@@ -36421,7 +36499,7 @@
|
|
|
36421
36499
|
const queue = Array.from(ranges).reverse();
|
|
36422
36500
|
while (queue.length > 0) {
|
|
36423
36501
|
const range = queue.pop();
|
|
36424
|
-
visited.
|
|
36502
|
+
visited.addMany(this.encoder.encodeBoundingBox(range));
|
|
36425
36503
|
const impactedPositionIds = this.rTree.search(range).map((dep) => dep.data);
|
|
36426
36504
|
for (const positionId of impactedPositionIds) {
|
|
36427
36505
|
if (!visited.has(positionId)) {
|
|
@@ -36429,7 +36507,7 @@
|
|
|
36429
36507
|
}
|
|
36430
36508
|
}
|
|
36431
36509
|
}
|
|
36432
|
-
visited.
|
|
36510
|
+
visited.deleteMany(ranges.flatMap((r) => this.encoder.encodeBoundingBox(r)));
|
|
36433
36511
|
return visited;
|
|
36434
36512
|
}
|
|
36435
36513
|
}
|
|
@@ -36560,9 +36638,9 @@
|
|
|
36560
36638
|
const cells = positions.map((p) => this.encoder.encode(p));
|
|
36561
36639
|
const cellsToCompute = new JetSet(cells);
|
|
36562
36640
|
const arrayFormulasPositionIds = this.getArrayFormulasImpactedByChangesOf(cells);
|
|
36563
|
-
cellsToCompute.
|
|
36564
|
-
cellsToCompute.
|
|
36565
|
-
cellsToCompute.
|
|
36641
|
+
cellsToCompute.addMany(this.getCellsDependingOn(cells));
|
|
36642
|
+
cellsToCompute.addMany(arrayFormulasPositionIds);
|
|
36643
|
+
cellsToCompute.addMany(this.getCellsDependingOn(arrayFormulasPositionIds));
|
|
36566
36644
|
this.evaluate(cellsToCompute);
|
|
36567
36645
|
}
|
|
36568
36646
|
getArrayFormulasImpactedByChangesOf(positionIds) {
|
|
@@ -36576,7 +36654,7 @@
|
|
|
36576
36654
|
}
|
|
36577
36655
|
if (!content) {
|
|
36578
36656
|
// The previous content could have blocked some array formulas
|
|
36579
|
-
impactedPositionIds.
|
|
36657
|
+
impactedPositionIds.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(positionId));
|
|
36580
36658
|
}
|
|
36581
36659
|
}
|
|
36582
36660
|
return impactedPositionIds;
|
|
@@ -36624,7 +36702,7 @@
|
|
|
36624
36702
|
}
|
|
36625
36703
|
const arrayFormulas = this.spreadingRelations.getFormulaPositionsSpreadingOn(positionId);
|
|
36626
36704
|
const cells = new JetSet(arrayFormulas);
|
|
36627
|
-
cells.
|
|
36705
|
+
cells.addMany(this.getCellsDependingOn(arrayFormulas));
|
|
36628
36706
|
return cells;
|
|
36629
36707
|
}
|
|
36630
36708
|
nextPositionsToUpdate = new JetSet();
|
|
@@ -36775,7 +36853,7 @@
|
|
|
36775
36853
|
this.setEvaluatedCell(positionId, evaluatedCell);
|
|
36776
36854
|
// check if formula dependencies present in the spread zone
|
|
36777
36855
|
// if so, they need to be recomputed
|
|
36778
|
-
this.nextPositionsToUpdate.
|
|
36856
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([positionId]));
|
|
36779
36857
|
};
|
|
36780
36858
|
}
|
|
36781
36859
|
invalidateSpreading(positionId) {
|
|
@@ -36790,8 +36868,8 @@
|
|
|
36790
36868
|
continue;
|
|
36791
36869
|
}
|
|
36792
36870
|
this.evaluatedCells.delete(child);
|
|
36793
|
-
this.nextPositionsToUpdate.
|
|
36794
|
-
this.nextPositionsToUpdate.
|
|
36871
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([child]));
|
|
36872
|
+
this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(child));
|
|
36795
36873
|
}
|
|
36796
36874
|
this.spreadingRelations.removeNode(positionId);
|
|
36797
36875
|
}
|
|
@@ -37151,7 +37229,13 @@
|
|
|
37151
37229
|
const format = newFormat
|
|
37152
37230
|
? getItemId(newFormat, data.formats)
|
|
37153
37231
|
: exportedCellData.format;
|
|
37154
|
-
|
|
37232
|
+
let content;
|
|
37233
|
+
if (formulaCell instanceof FormulaCellWithDependencies) {
|
|
37234
|
+
content = this.getters.buildFormulaContent(exportedSheetData.id, formulaCell, formulaCell.dependencies, true);
|
|
37235
|
+
}
|
|
37236
|
+
else {
|
|
37237
|
+
content = !isExported ? newContent : exportedCellData.content;
|
|
37238
|
+
}
|
|
37155
37239
|
exportedSheetData.cells[xc] = { ...exportedCellData, value, isFormula, content, format };
|
|
37156
37240
|
}
|
|
37157
37241
|
}
|
|
@@ -40974,14 +41058,12 @@
|
|
|
40974
41058
|
break;
|
|
40975
41059
|
case "FOCUS_RANGE":
|
|
40976
41060
|
case "CHANGE_RANGE":
|
|
40977
|
-
|
|
40978
|
-
|
|
40979
|
-
|
|
40980
|
-
|
|
40981
|
-
|
|
40982
|
-
|
|
40983
|
-
this.selection.capture(input, { cell: { col: zone.left, row: zone.top }, zone }, { handleEvent: input.handleEvent.bind(input) });
|
|
40984
|
-
}
|
|
41061
|
+
const input = this.inputs[cmd.id];
|
|
41062
|
+
const range = input.ranges.find((range) => range.id === cmd.rangeId);
|
|
41063
|
+
if (range) {
|
|
41064
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
41065
|
+
const zone = this.getters.getRangeFromSheetXC(sheetId, range?.xc || "A1").zone;
|
|
41066
|
+
this.selection.capture(input, { cell: { col: zone.left, row: zone.top }, zone }, { handleEvent: input.handleEvent.bind(input) });
|
|
40985
41067
|
this.focusedInputId = cmd.id;
|
|
40986
41068
|
}
|
|
40987
41069
|
break;
|
|
@@ -43670,7 +43752,7 @@
|
|
|
43670
43752
|
this.replaceText(ref, this.selectionInitialStart, this.selectionEnd);
|
|
43671
43753
|
}
|
|
43672
43754
|
getZoneReference(zone) {
|
|
43673
|
-
const inputSheetId = this.getters.getCurrentEditedCell().
|
|
43755
|
+
const inputSheetId = this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId();
|
|
43674
43756
|
const sheetId = this.getters.getActiveSheetId();
|
|
43675
43757
|
const range = this.getters.getRangeFromZone(sheetId, zone);
|
|
43676
43758
|
return this.getters.getSelectionRangeString(range, inputSheetId);
|
|
@@ -43684,7 +43766,7 @@
|
|
|
43684
43766
|
_fixedParts.pop();
|
|
43685
43767
|
}
|
|
43686
43768
|
const newRange = range.clone({ parts: _fixedParts });
|
|
43687
|
-
return this.getters.getSelectionRangeString(newRange, this.getters.getCurrentEditedCell().
|
|
43769
|
+
return this.getters.getSelectionRangeString(newRange, this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId());
|
|
43688
43770
|
}
|
|
43689
43771
|
/**
|
|
43690
43772
|
* Replace the current selection by a new text.
|
|
@@ -43717,7 +43799,7 @@
|
|
|
43717
43799
|
if (!this.currentContent.startsWith("=") || this.mode === "inactive") {
|
|
43718
43800
|
return;
|
|
43719
43801
|
}
|
|
43720
|
-
const editionSheetId = this.getters.getCurrentEditedCell().
|
|
43802
|
+
const editionSheetId = this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId();
|
|
43721
43803
|
const XCs = this.getReferencedRanges().map((range) => this.getters.getRangeString(range, editionSheetId));
|
|
43722
43804
|
const colorsToKeep = {};
|
|
43723
43805
|
for (const xc of XCs) {
|
|
@@ -43746,7 +43828,7 @@
|
|
|
43746
43828
|
if (!this.currentContent.startsWith("=") || this.mode === "inactive") {
|
|
43747
43829
|
return [];
|
|
43748
43830
|
}
|
|
43749
|
-
const editionSheetId = this.getters.getCurrentEditedCell().
|
|
43831
|
+
const editionSheetId = this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId();
|
|
43750
43832
|
const rangeColor = (rangeString) => {
|
|
43751
43833
|
const colorIndex = this.colorIndexByRange[rangeString];
|
|
43752
43834
|
return colors$1[colorIndex % colors$1.length];
|
|
@@ -43764,7 +43846,7 @@
|
|
|
43764
43846
|
* Return ranges currently referenced in the composer
|
|
43765
43847
|
*/
|
|
43766
43848
|
getReferencedRanges() {
|
|
43767
|
-
const editionSheetId = this.getters.getCurrentEditedCell().
|
|
43849
|
+
const editionSheetId = this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId();
|
|
43768
43850
|
const referenceRanges = this.currentTokens
|
|
43769
43851
|
.filter((token) => token.type === "REFERENCE")
|
|
43770
43852
|
.map((token) => this.getters.getRangeFromSheetXC(editionSheetId, token.value));
|
|
@@ -45728,6 +45810,16 @@
|
|
|
45728
45810
|
}
|
|
45729
45811
|
}
|
|
45730
45812
|
|
|
45813
|
+
class FocusableElement {
|
|
45814
|
+
focusableElement = undefined;
|
|
45815
|
+
setFocusableElement(element) {
|
|
45816
|
+
this.focusableElement = element;
|
|
45817
|
+
}
|
|
45818
|
+
focus() {
|
|
45819
|
+
this.focusableElement?.focus();
|
|
45820
|
+
}
|
|
45821
|
+
}
|
|
45822
|
+
|
|
45731
45823
|
const RIPPLE_KEY_FRAMES = [
|
|
45732
45824
|
{ transform: "scale(0)" },
|
|
45733
45825
|
{ transform: "scale(0.8)", offset: 0.33 },
|
|
@@ -47770,6 +47862,7 @@
|
|
|
47770
47862
|
_t: Spreadsheet._t,
|
|
47771
47863
|
clipboard: this.env.clipboard || instantiateClipboard(),
|
|
47772
47864
|
startCellEdition: (content) => this.onGridComposerCellFocused(content),
|
|
47865
|
+
focusableElement: new FocusableElement(),
|
|
47773
47866
|
});
|
|
47774
47867
|
owl.useExternalListener(window, "resize", () => this.render(true));
|
|
47775
47868
|
owl.useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
|
|
@@ -47876,17 +47969,18 @@
|
|
|
47876
47969
|
this.model.dispatch("UNFOCUS_SELECTION_INPUT");
|
|
47877
47970
|
this.composer.topBarFocus = "contentFocus";
|
|
47878
47971
|
this.composer.gridFocusMode = "inactive";
|
|
47879
|
-
this.setComposerContent({ selection }
|
|
47972
|
+
this.setComposerContent({ selection });
|
|
47880
47973
|
}
|
|
47881
|
-
onGridComposerContentFocused() {
|
|
47974
|
+
onGridComposerContentFocused(selection) {
|
|
47882
47975
|
if (this.model.getters.isReadonly()) {
|
|
47883
47976
|
return;
|
|
47884
47977
|
}
|
|
47885
47978
|
this.model.dispatch("UNFOCUS_SELECTION_INPUT");
|
|
47886
47979
|
this.composer.topBarFocus = "inactive";
|
|
47887
47980
|
this.composer.gridFocusMode = "contentFocus";
|
|
47888
|
-
this.setComposerContent({});
|
|
47981
|
+
this.setComposerContent({ selection });
|
|
47889
47982
|
}
|
|
47983
|
+
// TODO: either both are defined or none of them. change those args to an object
|
|
47890
47984
|
onGridComposerCellFocused(content, selection) {
|
|
47891
47985
|
if (this.model.getters.isReadonly()) {
|
|
47892
47986
|
return;
|
|
@@ -49298,11 +49392,10 @@
|
|
|
49298
49392
|
* next cluster if the given cell is outside a cluster or at the border of a cluster in the given direction.
|
|
49299
49393
|
*/
|
|
49300
49394
|
getEndOfCluster(startPosition, dim, dir) {
|
|
49301
|
-
const sheet = this.getters.getActiveSheet();
|
|
49302
49395
|
let currentPosition = startPosition;
|
|
49303
49396
|
// If both the current cell and the next cell are not empty, we want to go to the end of the cluster
|
|
49304
49397
|
const nextCellPosition = this.getNextCellPosition(startPosition, dim, dir);
|
|
49305
|
-
let mode = !this.
|
|
49398
|
+
let mode = !this.isEvaluatedCellEmpty(currentPosition) && !this.isEvaluatedCellEmpty(nextCellPosition)
|
|
49306
49399
|
? "endOfCluster"
|
|
49307
49400
|
: "nextCluster";
|
|
49308
49401
|
while (true) {
|
|
@@ -49312,7 +49405,7 @@
|
|
|
49312
49405
|
currentPosition.row === nextCellPosition.row) {
|
|
49313
49406
|
break;
|
|
49314
49407
|
}
|
|
49315
|
-
const isNextCellEmpty = this.
|
|
49408
|
+
const isNextCellEmpty = this.isEvaluatedCellEmpty(nextCellPosition);
|
|
49316
49409
|
if (mode === "endOfCluster" && isNextCellEmpty) {
|
|
49317
49410
|
break;
|
|
49318
49411
|
}
|
|
@@ -49326,10 +49419,20 @@
|
|
|
49326
49419
|
return dim === "cols" ? currentPosition.col : currentPosition.row;
|
|
49327
49420
|
}
|
|
49328
49421
|
/**
|
|
49329
|
-
*
|
|
49330
|
-
* check
|
|
49422
|
+
* Checks if a cell is empty (i.e. does not have a content). If the cell is part of a merge,
|
|
49423
|
+
* the check applies to the main cell of the merge.
|
|
49424
|
+
*/
|
|
49425
|
+
isCellEmpty({ col, row }) {
|
|
49426
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
49427
|
+
const position = this.getters.getMainCellPosition({ sheetId, col, row });
|
|
49428
|
+
return !(this.getters.getCorrespondingFormulaCell(position) || this.getters.getCell(position)?.content);
|
|
49429
|
+
}
|
|
49430
|
+
/**
|
|
49431
|
+
* Checks if a cell evaluated value is empty. If the cell is part of a merge,
|
|
49432
|
+
* the check applies to the main cell of the merge.
|
|
49331
49433
|
*/
|
|
49332
|
-
|
|
49434
|
+
isEvaluatedCellEmpty({ col, row }) {
|
|
49435
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
49333
49436
|
const position = this.getters.getMainCellPosition({ sheetId, col, row });
|
|
49334
49437
|
const cell = this.getters.getEvaluatedCell(position);
|
|
49335
49438
|
return cell.type === CellValueType.empty;
|
|
@@ -51612,9 +51715,9 @@
|
|
|
51612
51715
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
51613
51716
|
|
|
51614
51717
|
|
|
51615
|
-
__info__.version = '16.4.
|
|
51616
|
-
__info__.date = '2024-02-
|
|
51617
|
-
__info__.hash = '
|
|
51718
|
+
__info__.version = '16.4.24';
|
|
51719
|
+
__info__.date = '2024-02-28T12:27:32.683Z';
|
|
51720
|
+
__info__.hash = '90c74d1';
|
|
51618
51721
|
|
|
51619
51722
|
|
|
51620
51723
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|