[FIX] spreadsheet: update o_spreadsheet to latest version
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/bb51d6315 [REL] 17.0.11 https://github.com/odoo/o-spreadsheet/commit/4a419ace3 [PERF] tokenizer: faster tokenize Task: 3735948 https://github.com/odoo/o-spreadsheet/commit/c0ee19701 [PERF] tokenizer: faster parenthesis tokenize Task: 3735948 https://github.com/odoo/o-spreadsheet/commit/c795196e7 [PERF] tokenizer: faster number tokenize Task: 3735948 https://github.com/odoo/o-spreadsheet/commit/bc2fa0472 [PERF] tokenizer: faster symbol tokenize Task: 3735948 https://github.com/odoo/o-spreadsheet/commit/31338a1ec [FIX] Composer: Persistent composition when starting the edition Task: 3685891 https://github.com/odoo/o-spreadsheet/commit/8f138849b [FIX] DataFilter: Fix overlapping filters Task: 3728009 https://github.com/odoo/o-spreadsheet/commit/201aea7ea [FIX] export: unbound formula stays unbound in snapshots https://github.com/odoo/o-spreadsheet/commit/bf4f9bc37 [PERF] cell: remove useless binded function Task: 3721226 https://github.com/odoo/o-spreadsheet/commit/73d8eae56 [PERF] cell: remove range string closure Task: 3721226 https://github.com/odoo/o-spreadsheet/commit/168aff7ea [PERF] cells: transform dependencies without closure Task: 3721226 https://github.com/odoo/o-spreadsheet/commit/55a4d4c2b [FIX] formatting: do not show escape character Task: 3698283 https://github.com/odoo/o-spreadsheet/commit/04be128c8 [REM] composer: remove CTRL+Space shortcut Task: 3504025 https://github.com/odoo/o-spreadsheet/commit/be06aa9e2 [REL] 17.0.10 https://github.com/odoo/o-spreadsheet/commit/7e6810474 [FIX] chart: fix incoherent side_pannel state Task: 3380568 https://github.com/odoo/o-spreadsheet/commit/67a98ca2a [REF] model: preserve default currency format https://github.com/odoo/o-spreadsheet/commit/6acfb3b07 [FIX] export: transform unbound references Task: 3618912 https://github.com/odoo/o-spreadsheet/commit/1ad87cd5a [FIX] export: transform unbound references Task: 3618912 https://github.com/odoo/o-spreadsheet/commit/da02417c7 [FIX] export: remove line returns in formula Task: 3618912 https://github.com/odoo/o-spreadsheet/commit/d8eef54dc [FIX] Grid: Support Mac shortcuts in `Grid` Task: 3707416 closes odoo/odoo#153476 Related: odoo/enterprise#56284 Signed-off-by: Lucas Lefèvre (lul) <lul@odoo.com>
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
/**
|
||||
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
||||
* @see https://github.com/odoo/o-spreadsheet
|
||||
* @version 17.0.9
|
||||
* @date 2024-01-29T15:41:09.261Z
|
||||
* @hash 3c1209a38
|
||||
* @version 17.0.11
|
||||
* @date 2024-02-09T14:36:35.988Z
|
||||
* @hash bb51d6315
|
||||
*/
|
||||
|
||||
(function (exports, owl) {
|
||||
@@ -2889,6 +2889,9 @@
|
||||
function formatValue(value, { format, locale }) {
|
||||
switch (typeof value) {
|
||||
case "string":
|
||||
if (value.includes('\\"')) {
|
||||
return value.replace(/\\"/g, '"');
|
||||
}
|
||||
return value;
|
||||
case "boolean":
|
||||
return value ? "TRUE" : "FALSE";
|
||||
@@ -4933,14 +4936,8 @@
|
||||
: undefined));
|
||||
}
|
||||
}
|
||||
else if (zone.left === zone.right && zone.top === zone.bottom) {
|
||||
// A single cell. If it's only the title, the dataset is not added.
|
||||
if (!dataSetsHaveTitle) {
|
||||
dataSets.push(createDataSet(getters, dataSetSheetId, zone, undefined));
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* 1 row or 1 column */
|
||||
/* 1 cell, 1 row or 1 column */
|
||||
dataSets.push(createDataSet(getters, dataSetSheetId, zone, dataSetsHaveTitle
|
||||
? {
|
||||
top: zone.top,
|
||||
@@ -4989,8 +4986,10 @@
|
||||
}
|
||||
const dataRange = ds.dataRange.clone({ zone: dataZone });
|
||||
return {
|
||||
label: ds.labelCell ? getters.getRangeString(ds.labelCell, "forceSheetReference") : undefined,
|
||||
range: getters.getRangeString(dataRange, "forceSheetReference"),
|
||||
label: ds.labelCell
|
||||
? getters.getRangeString(ds.labelCell, "forceSheetReference", { useFixedReference: true })
|
||||
: undefined,
|
||||
range: getters.getRangeString(dataRange, "forceSheetReference", { useFixedReference: true }),
|
||||
};
|
||||
}
|
||||
function toExcelLabelRange(getters, labelRange, shouldRemoveFirstLabel) {
|
||||
@@ -5003,7 +5002,7 @@
|
||||
zone.top = zone.top + 1;
|
||||
}
|
||||
const range = labelRange.clone({ zone });
|
||||
return getters.getRangeString(range, "forceSheetReference");
|
||||
return getters.getRangeString(range, "forceSheetReference", { useFixedReference: true });
|
||||
}
|
||||
/**
|
||||
* Transform a chart definition which supports dataSets (dataSets and LabelRange)
|
||||
@@ -7384,7 +7383,7 @@
|
||||
while (!chars.isOver()) {
|
||||
let token = tokenizeSpace(chars) ||
|
||||
tokenizeArgsSeparator(chars, locale) ||
|
||||
tokenizeMisc(chars) ||
|
||||
tokenizeParenthesis(chars) ||
|
||||
tokenizeOperator(chars) ||
|
||||
tokenizeString(chars) ||
|
||||
tokenizeDebugger(chars) ||
|
||||
@@ -7405,15 +7404,14 @@
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const misc$1 = {
|
||||
"(": "LEFT_PAREN",
|
||||
")": "RIGHT_PAREN",
|
||||
const parenthesis = {
|
||||
"(": { type: "LEFT_PAREN", value: "(" },
|
||||
")": { type: "RIGHT_PAREN", value: ")" },
|
||||
};
|
||||
function tokenizeMisc(chars) {
|
||||
if (chars.current in misc$1) {
|
||||
function tokenizeParenthesis(chars) {
|
||||
if (chars.current === "(" || chars.current === ")") {
|
||||
const value = chars.shift();
|
||||
const type = misc$1[value];
|
||||
return { type, value };
|
||||
return parenthesis[value];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -7434,7 +7432,12 @@
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const FIRST_POSSIBLE_NUMBER_CHARS = new Set("0123456789");
|
||||
function tokenizeNumber(chars, locale) {
|
||||
if (!FIRST_POSSIBLE_NUMBER_CHARS.has(chars.current) &&
|
||||
chars.current !== locale.decimalSeparator) {
|
||||
return null;
|
||||
}
|
||||
const match = chars.remaining().match(getFormulaNumberRegex(locale.decimalSeparator));
|
||||
if (match) {
|
||||
chars.advanceBy(match[0].length);
|
||||
@@ -7459,7 +7462,7 @@
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const separatorRegexp = /\w|\.|!|\$/;
|
||||
const separatorRegexp = /^[\w\.!\$]+/;
|
||||
/**
|
||||
* A "Symbol" is just basically any word-like element that can appear in a
|
||||
* formula, which is not a string. So:
|
||||
@@ -7499,8 +7502,11 @@
|
||||
};
|
||||
}
|
||||
}
|
||||
while (chars.current && separatorRegexp.test(chars.current)) {
|
||||
result += chars.shift();
|
||||
const match = chars.remaining().match(separatorRegexp);
|
||||
if (match) {
|
||||
const value = match[0];
|
||||
result += value;
|
||||
chars.advanceBy(value.length);
|
||||
}
|
||||
if (result.length) {
|
||||
const value = result;
|
||||
@@ -7562,7 +7568,10 @@
|
||||
return this.text.substring(this.currentIndex);
|
||||
}
|
||||
currentStartsWith(str) {
|
||||
for (let j = 0; j < str.length; j++) {
|
||||
if (this.current !== str[0]) {
|
||||
return false;
|
||||
}
|
||||
for (let j = 1; j < str.length; j++) {
|
||||
if (this.text[this.currentIndex + j] !== str[j]) {
|
||||
return false;
|
||||
}
|
||||
@@ -8593,7 +8602,7 @@
|
||||
return undefined;
|
||||
const dataSets = this.dataSets
|
||||
.map((ds) => toExcelDataset(this.getters, ds))
|
||||
.filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
|
||||
.filter((ds) => ds.range !== "" && ds.range !== INCORRECT_RANGE_STRING);
|
||||
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
||||
return {
|
||||
...this.getDefinition(),
|
||||
@@ -9171,7 +9180,7 @@
|
||||
return undefined;
|
||||
const dataSets = this.dataSets
|
||||
.map((ds) => toExcelDataset(this.getters, ds))
|
||||
.filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
|
||||
.filter((ds) => ds.range !== "" && ds.range !== INCORRECT_RANGE_STRING);
|
||||
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
||||
return {
|
||||
...this.getDefinition(),
|
||||
@@ -9477,7 +9486,7 @@
|
||||
return undefined;
|
||||
const dataSets = this.dataSets
|
||||
.map((ds) => toExcelDataset(this.getters, ds))
|
||||
.filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
|
||||
.filter((ds) => ds.range !== "" && ds.range !== INCORRECT_RANGE_STRING);
|
||||
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
||||
return {
|
||||
...this.getDefinition(),
|
||||
@@ -19920,19 +19929,20 @@
|
||||
const formatNumberCurrency = createFormatActionSpec({
|
||||
name: _t("Currency"),
|
||||
descriptionValue: 1000.12,
|
||||
format: (env) => env.model.config.defaultCurrencyFormat,
|
||||
format: (env) => env.model.config.defaultCurrencyFormat ?? DEFAULT_CURRENCY_FORMAT,
|
||||
});
|
||||
const formatNumberCurrencyRounded = {
|
||||
...createFormatActionSpec({
|
||||
name: _t("Currency rounded"),
|
||||
descriptionValue: 1000,
|
||||
format: (env) => roundFormat(env.model.config.defaultCurrencyFormat),
|
||||
format: (env) => roundFormat(env.model.config.defaultCurrencyFormat ?? DEFAULT_CURRENCY_FORMAT),
|
||||
}),
|
||||
isVisible: (env) => {
|
||||
const currencyFormat = env.model.config.defaultCurrencyFormat;
|
||||
return currencyFormat !== roundFormat(currencyFormat);
|
||||
return currencyFormat !== roundFormat(currencyFormat ?? DEFAULT_CURRENCY_FORMAT);
|
||||
},
|
||||
};
|
||||
const DEFAULT_CURRENCY_FORMAT = "[$$]#,##0.00";
|
||||
const EXAMPLE_DATE = parseLiteral("2023/09/26 10:43:00 PM", DEFAULT_LOCALE);
|
||||
const formatCustomCurrency = {
|
||||
name: _t("Custom currency"),
|
||||
@@ -26500,6 +26510,7 @@
|
||||
static components = { TextValueProvider, FunctionDescriptionProvider };
|
||||
static defaultProps = {
|
||||
inputStyle: "",
|
||||
isDefaultFocus: false,
|
||||
};
|
||||
composerRef = owl.useRef("o_composer");
|
||||
contentHelper = new ContentEditableHelper(this.composerRef.el);
|
||||
@@ -26556,7 +26567,6 @@
|
||||
F2: () => console.warn("Not implemented"),
|
||||
F4: this.processF4Key,
|
||||
Tab: (ev) => this.processTabKey(ev),
|
||||
" ": (ev) => this.processSpaceKey(ev),
|
||||
};
|
||||
keyCodeMapping = {
|
||||
NumpadDecimal: this.processNumpadDecimal,
|
||||
@@ -26564,12 +26574,12 @@
|
||||
setup() {
|
||||
owl.onMounted(() => {
|
||||
const el = this.composerRef.el;
|
||||
if (this.props.isDefaultFocus) {
|
||||
this.env.focusableElement.setFocusableElement(el);
|
||||
}
|
||||
this.contentHelper.updateEl(el);
|
||||
this.processTokenAtCursor();
|
||||
});
|
||||
owl.onWillUnmount(() => {
|
||||
this.props.onComposerUnmounted?.();
|
||||
});
|
||||
owl.useEffect(() => {
|
||||
this.processContent();
|
||||
});
|
||||
@@ -26578,7 +26588,8 @@
|
||||
// Handlers
|
||||
// ---------------------------------------------------------------------------
|
||||
processArrowKeys(ev) {
|
||||
if (this.env.model.getters.isSelectingForComposer()) {
|
||||
if (this.env.model.getters.isSelectingForComposer() ||
|
||||
this.env.model.getters.getEditionMode() === "inactive") {
|
||||
this.functionDescriptionState.showDescription = false;
|
||||
// Prevent the default content editable behavior which moves the cursor
|
||||
ev.preventDefault();
|
||||
@@ -26621,26 +26632,20 @@
|
||||
processTabKey(ev) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
const state = this.autoCompleteState;
|
||||
if (state.showProvider && state.selectedIndex !== undefined) {
|
||||
const autoCompleteValue = this.autoCompleteState.values[state.selectedIndex]?.text;
|
||||
if (autoCompleteValue) {
|
||||
this.autoComplete(autoCompleteValue);
|
||||
return;
|
||||
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
||||
const state = this.autoCompleteState;
|
||||
if (state.showProvider && state.selectedIndex !== undefined) {
|
||||
const autoCompleteValue = this.autoCompleteState.values[state.selectedIndex]?.text;
|
||||
if (autoCompleteValue) {
|
||||
this.autoComplete(autoCompleteValue);
|
||||
return;
|
||||
}
|
||||
}
|
||||
interactiveStopEdition(this.env);
|
||||
}
|
||||
const direction = ev.shiftKey ? "left" : "right";
|
||||
interactiveStopEdition(this.env);
|
||||
this.env.model.selection.moveAnchorCell(direction, 1);
|
||||
}
|
||||
processSpaceKey(ev) {
|
||||
if (ev.ctrlKey) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
this.showFunctionAutocomplete("");
|
||||
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
||||
}
|
||||
}
|
||||
processEnterKey(ev) {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
@@ -26693,6 +26698,9 @@
|
||||
this.compositionActive = false;
|
||||
}
|
||||
onKeydown(ev) {
|
||||
if (this.env.model.getters.getEditionMode() === "inactive") {
|
||||
return;
|
||||
}
|
||||
let handler = this.keyMapping[ev.key] || this.keyCodeMapping[ev.code];
|
||||
if (handler) {
|
||||
handler.call(this, ev);
|
||||
@@ -26701,14 +26709,33 @@
|
||||
ev.stopPropagation();
|
||||
}
|
||||
}
|
||||
onPaste(ev) {
|
||||
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
||||
ev.stopPropagation();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Triggered automatically by the content-editable between the keydown and key up
|
||||
* */
|
||||
onInput(ev) {
|
||||
if (this.props.focus === "inactive" || !this.shouldProcessInputEvents) {
|
||||
if (!this.shouldProcessInputEvents) {
|
||||
return;
|
||||
}
|
||||
let content = this.contentHelper.getText();
|
||||
if (ev.inputType === "insertFromPaste" &&
|
||||
this.env.model.getters.getEditionMode() === "inactive") {
|
||||
return;
|
||||
}
|
||||
ev.stopPropagation();
|
||||
let content;
|
||||
if (this.env.model.getters.getEditionMode() === "inactive") {
|
||||
content = ev.data || "";
|
||||
}
|
||||
else {
|
||||
content = this.contentHelper.getText();
|
||||
}
|
||||
if (this.props.focus === "inactive") {
|
||||
return this.props.onComposerCellFocused?.(content);
|
||||
}
|
||||
let selection = this.contentHelper.getCurrentSelection();
|
||||
if (ev.inputType === "insertParagraph") {
|
||||
const start = Math.min(selection.start, selection.end);
|
||||
@@ -26790,9 +26817,8 @@
|
||||
}
|
||||
const newSelection = this.contentHelper.getCurrentSelection();
|
||||
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
||||
if (this.props.focus === "inactive") {
|
||||
this.props.onComposerContentFocused(newSelection);
|
||||
}
|
||||
this.props.onComposerContentFocused();
|
||||
if (this.props.focus === "inactive") ;
|
||||
this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", newSelection);
|
||||
this.processTokenAtCursor();
|
||||
}
|
||||
@@ -26959,7 +26985,7 @@
|
||||
const highlights = this.env.model.getters.getHighlights();
|
||||
const refSheet = sheetName
|
||||
? this.env.model.getters.getSheetIdByName(sheetName)
|
||||
: this.env.model.getters.getCurrentEditedCell().sheetId;
|
||||
: this.env.model.getters.getCurrentEditedCell()?.sheetId;
|
||||
const highlight = highlights.find((highlight) => {
|
||||
if (highlight.sheetId !== refSheet)
|
||||
return false;
|
||||
@@ -27052,12 +27078,13 @@
|
||||
}
|
||||
}
|
||||
Composer.props = {
|
||||
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
||||
onComposerContentFocused: Function,
|
||||
inputStyle: { type: String, optional: true },
|
||||
rect: { type: Object, optional: true },
|
||||
delimitation: { type: Object, optional: true },
|
||||
onComposerUnmounted: { type: Function, optional: true },
|
||||
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
||||
onComposerCellFocused: { type: Function, optional: true },
|
||||
onComposerContentFocused: Function,
|
||||
isDefaultFocus: { type: Boolean, optional: true },
|
||||
};
|
||||
|
||||
const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
|
||||
@@ -27091,51 +27118,25 @@
|
||||
class GridComposer extends owl.Component {
|
||||
static template = "o-spreadsheet-GridComposer";
|
||||
static components = { Composer };
|
||||
gridComposerRef;
|
||||
zone;
|
||||
rect;
|
||||
rect = this.defaultRect;
|
||||
isEditing = false;
|
||||
isCellReferenceVisible;
|
||||
composerState;
|
||||
get defaultRect() {
|
||||
return { x: 0, y: 0, width: 0, height: 0 };
|
||||
}
|
||||
setup() {
|
||||
this.gridComposerRef = owl.useRef("gridComposer");
|
||||
this.composerState = owl.useState({
|
||||
rect: undefined,
|
||||
delimitation: undefined,
|
||||
});
|
||||
const { sheetId, col, row } = this.env.model.getters.getActivePosition();
|
||||
this.zone = this.env.model.getters.expandZone(sheetId, positionToZone({ col, row }));
|
||||
this.rect = this.env.model.getters.getVisibleRect(this.zone);
|
||||
this.isCellReferenceVisible = false;
|
||||
owl.onMounted(() => {
|
||||
const el = this.gridComposerRef.el;
|
||||
this.composerState.rect = {
|
||||
x: this.rect.x,
|
||||
y: this.rect.y,
|
||||
width: el.clientWidth,
|
||||
height: el.clientHeight,
|
||||
};
|
||||
this.composerState.delimitation = {
|
||||
width: this.props.gridDims.width,
|
||||
height: this.props.gridDims.height,
|
||||
};
|
||||
});
|
||||
owl.onWillUpdateProps(() => {
|
||||
if (this.isCellReferenceVisible) {
|
||||
return;
|
||||
}
|
||||
const sheetId = this.env.model.getters.getActiveSheetId();
|
||||
const zone = this.env.model.getters.getSelectedZone();
|
||||
const rect = this.env.model.getters.getVisibleRect(zone);
|
||||
if (!deepEquals(rect, this.rect) ||
|
||||
sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
|
||||
this.isCellReferenceVisible = true;
|
||||
}
|
||||
this.updateComponentPosition();
|
||||
this.updateCellReferenceVisibility();
|
||||
});
|
||||
}
|
||||
get shouldDisplayCellReference() {
|
||||
return this.isCellReferenceVisible;
|
||||
}
|
||||
get cellReference() {
|
||||
if (!this.env.model.getters.getCurrentEditedCell()) {
|
||||
return "";
|
||||
}
|
||||
const { col, row, sheetId } = this.env.model.getters.getCurrentEditedCell();
|
||||
const prefixSheet = sheetId !== this.env.model.getters.getActiveSheetId();
|
||||
return `${prefixSheet ? getCanonicalSheetName(this.env.model.getters.getSheetName(sheetId)) + "!" : ""}${toXC(col, row)}`;
|
||||
@@ -27147,7 +27148,27 @@
|
||||
top: `${top - GRID_CELL_REFERENCE_TOP_OFFSET}px`,
|
||||
});
|
||||
}
|
||||
get composerProps() {
|
||||
const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
||||
return {
|
||||
rect: { ...this.rect },
|
||||
delimitation: {
|
||||
width,
|
||||
height,
|
||||
},
|
||||
focus: this.props.focus,
|
||||
isDefaultFocus: true,
|
||||
onComposerContentFocused: this.props.onComposerContentFocused,
|
||||
onComposerCellFocused: this.props.onComposerCellFocused,
|
||||
};
|
||||
}
|
||||
get containerStyle() {
|
||||
if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
|
||||
return `
|
||||
position: absolute;
|
||||
z-index: -1000;
|
||||
`;
|
||||
}
|
||||
const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
|
||||
const cell = this.env.model.getters.getActiveCell();
|
||||
const position = this.env.model.getters.getActivePosition();
|
||||
@@ -27167,6 +27188,8 @@
|
||||
if (!isFormula) {
|
||||
textAlign = style.align || cell.defaultAlign;
|
||||
}
|
||||
const maxHeight = this.props.gridDims.height - this.rect.y;
|
||||
const maxWidth = this.props.gridDims.width - this.rect.x;
|
||||
/**
|
||||
* min-size is on the container, not the composer element, because we want to have the same size as the cell by default,
|
||||
* including all the paddings/margins of the composer
|
||||
@@ -27178,6 +27201,8 @@
|
||||
top: `${top}px`,
|
||||
"min-width": `${width + 1}px`,
|
||||
"min-height": `${height + 1}px`,
|
||||
"max-width": `${maxWidth}px`,
|
||||
"max-height": `${maxHeight}px`,
|
||||
background,
|
||||
color,
|
||||
"font-size": `${fontSizeInPixels(fontSize)}px`,
|
||||
@@ -27187,20 +27212,38 @@
|
||||
"text-align": textAlign,
|
||||
});
|
||||
}
|
||||
get composerStyle() {
|
||||
const maxHeight = this.props.gridDims.height - this.rect.y;
|
||||
const maxWidth = this.props.gridDims.width - this.rect.x;
|
||||
return cssPropertiesToCss({
|
||||
"max-width": `${maxWidth}px`,
|
||||
"max-height": `${maxHeight}px`,
|
||||
});
|
||||
updateComponentPosition() {
|
||||
const isEditing = this.env.model.getters.getEditionMode() !== "inactive";
|
||||
if (this.isEditing !== isEditing) {
|
||||
this.isEditing = isEditing;
|
||||
if (!isEditing) {
|
||||
this.rect = this.defaultRect;
|
||||
this.env.focusableElement.focus();
|
||||
return;
|
||||
}
|
||||
const position = this.env.model.getters.getActivePosition();
|
||||
const zone = this.env.model.getters.expandZone(position.sheetId, positionToZone(position));
|
||||
this.rect = this.env.model.getters.getVisibleRect(zone);
|
||||
}
|
||||
}
|
||||
updateCellReferenceVisibility() {
|
||||
if (this.isCellReferenceVisible || this.env.model.getters.getEditionMode() === "inactive") {
|
||||
return;
|
||||
}
|
||||
const sheetId = this.env.model.getters.getActiveSheetId();
|
||||
const zone = this.env.model.getters.getSelectedZone();
|
||||
const rect = this.env.model.getters.getVisibleRect(zone);
|
||||
if (!deepEquals(rect, this.rect) ||
|
||||
sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
|
||||
this.isCellReferenceVisible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
GridComposer.props = {
|
||||
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
||||
onComposerUnmounted: Function,
|
||||
onComposerContentFocused: Function,
|
||||
gridDims: Object,
|
||||
onComposerCellFocused: Function,
|
||||
};
|
||||
|
||||
const CSS$1 = css /* scss */ `
|
||||
@@ -28291,7 +28334,6 @@
|
||||
this.props.onCellDoubleClicked(col, row);
|
||||
}
|
||||
onContextMenu(ev) {
|
||||
ev.preventDefault();
|
||||
const [col, row] = this.getCartesianCoordinates(ev);
|
||||
this.props.onCellRightClicked(col, row, { x: ev.clientX, y: ev.clientY });
|
||||
}
|
||||
@@ -29352,6 +29394,7 @@
|
||||
GROUP_HEADERS: groupHeadersMenuRegistry,
|
||||
UNGROUP_HEADERS: unGroupHeadersMenuRegistry,
|
||||
};
|
||||
const MODIFIER_KEYS = ["Shift", "Control", "Alt", "Meta"];
|
||||
// -----------------------------------------------------------------------------
|
||||
// JS
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -29375,7 +29418,6 @@
|
||||
HEADER_WIDTH = HEADER_WIDTH;
|
||||
menuState;
|
||||
gridRef;
|
||||
hiddenInput;
|
||||
onMouseWheel;
|
||||
canvasPosition;
|
||||
hoveredCell;
|
||||
@@ -29386,17 +29428,16 @@
|
||||
menuItems: [],
|
||||
});
|
||||
this.gridRef = owl.useRef("grid");
|
||||
this.hiddenInput = owl.useRef("hiddenInput");
|
||||
this.canvasPosition = useAbsoluteBoundingRect(this.gridRef);
|
||||
this.hoveredCell = owl.useState({ col: undefined, row: undefined });
|
||||
owl.useChildSubEnv({ getPopoverContainerRect: () => this.getGridRect() });
|
||||
owl.useExternalListener(document.body, "cut", this.copy.bind(this, true));
|
||||
owl.useExternalListener(document.body, "copy", this.copy.bind(this, false));
|
||||
owl.useExternalListener(document.body, "paste", this.paste);
|
||||
owl.onMounted(() => this.focus());
|
||||
this.props.exposeFocus(() => this.focus());
|
||||
owl.onMounted(() => this.focusDefaultElement());
|
||||
this.props.exposeFocus(() => this.focusDefaultElement());
|
||||
useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimensionWithHeaders());
|
||||
owl.useEffect(() => this.focus(), () => [this.env.model.getters.getActiveSheetId()]);
|
||||
owl.useEffect(() => this.focusDefaultElement(), () => [this.env.model.getters.getActiveSheetId()]);
|
||||
this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
|
||||
this.moveCanvas(deltaX, deltaY);
|
||||
this.hoveredCell.col = undefined;
|
||||
@@ -29419,7 +29460,7 @@
|
||||
if (this.env.model.getters.hasOpenedPopover()) {
|
||||
this.closeOpenedPopover();
|
||||
}
|
||||
this.focus();
|
||||
this.focusDefaultElement();
|
||||
}
|
||||
// this map will handle most of the actions that should happen on key down. The arrow keys are managed in the key
|
||||
// down itself
|
||||
@@ -29598,10 +29639,10 @@
|
||||
"ALT+SHIFT+ARROWUP": () => this.processHeaderGroupingKey("up"),
|
||||
"ALT+SHIFT+ARROWDOWN": () => this.processHeaderGroupingKey("down"),
|
||||
};
|
||||
focus() {
|
||||
focusDefaultElement() {
|
||||
if (!this.env.model.getters.getSelectedFigureId() &&
|
||||
this.env.model.getters.getEditionMode() === "inactive") {
|
||||
this.hiddenInput.el?.focus();
|
||||
this.env.focusableElement.focus();
|
||||
}
|
||||
}
|
||||
get gridEl() {
|
||||
@@ -29724,16 +29765,15 @@
|
||||
}
|
||||
}
|
||||
onKeydown(ev) {
|
||||
const eventKey = ev.key.toUpperCase();
|
||||
let keyDownString = "";
|
||||
if (isCtrlKey(ev) && eventKey !== "CTRL")
|
||||
keyDownString += "CTRL+";
|
||||
if (ev.metaKey)
|
||||
keyDownString += "CTRL+";
|
||||
if (ev.altKey && eventKey !== "ALT")
|
||||
keyDownString += "ALT+";
|
||||
if (ev.shiftKey && eventKey !== "SHIFT")
|
||||
keyDownString += "SHIFT+";
|
||||
if (!MODIFIER_KEYS.includes(ev.key)) {
|
||||
if (isCtrlKey(ev))
|
||||
keyDownString += "CTRL+";
|
||||
if (ev.altKey)
|
||||
keyDownString += "ALT+";
|
||||
if (ev.shiftKey)
|
||||
keyDownString += "SHIFT+";
|
||||
}
|
||||
keyDownString += ev.key.toUpperCase();
|
||||
let handler = this.keyDownMapping[keyDownString];
|
||||
if (handler) {
|
||||
@@ -29747,19 +29787,6 @@
|
||||
return;
|
||||
}
|
||||
}
|
||||
onInput(ev) {
|
||||
// the user meant to paste in the sheet, not open the composer with the pasted content
|
||||
if (!ev.isComposing && ev.inputType === "insertFromPaste") {
|
||||
return;
|
||||
}
|
||||
if (ev.data) {
|
||||
// if the user types a character on the grid, it means he wants to start composing the selected cell with that
|
||||
// character
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
this.props.onGridComposerCellFocused(ev.data);
|
||||
}
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Context Menu
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -29874,7 +29901,7 @@
|
||||
}
|
||||
closeMenu() {
|
||||
this.menuState.isOpen = false;
|
||||
this.focus();
|
||||
this.focusDefaultElement();
|
||||
}
|
||||
processHeaderGroupingKey(direction) {
|
||||
if (this.env.model.getters.getSelectedZones().length !== 1) {
|
||||
@@ -33769,6 +33796,31 @@
|
||||
return data;
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Fix datafilter duplication",
|
||||
from: 12,
|
||||
to: 12.5,
|
||||
applyMigration(data) {
|
||||
for (let sheet of data.sheets || []) {
|
||||
let knownDataFilterZones = [];
|
||||
for (let filterTable of sheet.filterTables || []) {
|
||||
const zone = toZone(filterTable.range);
|
||||
// See commit message for the details
|
||||
const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => overlap(knownZone, zone));
|
||||
if (intersectZoneIndex !== -1) {
|
||||
knownDataFilterZones[intersectZoneIndex] = zone;
|
||||
}
|
||||
else {
|
||||
knownDataFilterZones.push(zone);
|
||||
}
|
||||
}
|
||||
sheet.filterTables = knownDataFilterZones.map((zone) => ({
|
||||
range: zoneToXc(zone),
|
||||
}));
|
||||
}
|
||||
return data;
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Change Border description structure",
|
||||
from: 12,
|
||||
@@ -35614,13 +35666,13 @@
|
||||
/*
|
||||
* Reconstructs the original formula string based on a normalized form and its dependencies
|
||||
*/
|
||||
getFormulaCellContent(sheetId, compiledFormula, dependencies) {
|
||||
getFormulaCellContent(sheetId, compiledFormula, dependencies, useFixedReference = false) {
|
||||
const ranges = dependencies || compiledFormula.dependencies;
|
||||
let rangeIndex = 0;
|
||||
return concat(compiledFormula.tokens.map((token) => {
|
||||
if (token.type === "REFERENCE") {
|
||||
const range = ranges[rangeIndex++];
|
||||
return this.getters.getRangeString(range, sheetId);
|
||||
return this.getters.getRangeString(range, sheetId, { useFixedReference });
|
||||
}
|
||||
return token.value;
|
||||
}));
|
||||
@@ -35821,8 +35873,11 @@
|
||||
* being a computed property to rebuild the dependencies XC.
|
||||
*/
|
||||
createFormulaCellWithDependencies(id, compiledFormula, format, style, sheetId) {
|
||||
const dependencies = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
|
||||
return new FormulaCellWithDependencies(id, compiledFormula, format, style, dependencies, sheetId, this.getters.getRangeString.bind(this));
|
||||
const dependencies = [];
|
||||
for (const xc of compiledFormula.dependencies) {
|
||||
dependencies.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
||||
}
|
||||
return new FormulaCellWithDependencies(id, compiledFormula, format, style, dependencies, sheetId, this.getters.getRangeString);
|
||||
}
|
||||
createErrorFormula(id, content, format, style, error) {
|
||||
return {
|
||||
@@ -35876,7 +35931,7 @@
|
||||
const tokens = compiledFormula.tokens.map((token) => {
|
||||
if (token.type === "REFERENCE") {
|
||||
const index = rangeIndex++;
|
||||
return new RangeReferenceToken(() => this.getRangeString(dependencies[index], this.sheetId));
|
||||
return new RangeReferenceToken(dependencies, index, this.sheetId, this.getRangeString);
|
||||
}
|
||||
return token;
|
||||
});
|
||||
@@ -35889,15 +35944,34 @@
|
||||
get content() {
|
||||
return concat(this.compiledFormula.tokens.map((token) => token.value));
|
||||
}
|
||||
get contentWithFixedReferences() {
|
||||
let rangeIndex = 0;
|
||||
return concat(this.compiledFormula.tokens.map((token) => {
|
||||
if (token.type === "REFERENCE") {
|
||||
const index = rangeIndex++;
|
||||
return this.getRangeString(this.compiledFormula.dependencies[index], this.sheetId, {
|
||||
useFixedReference: true,
|
||||
});
|
||||
}
|
||||
return token.value;
|
||||
}));
|
||||
}
|
||||
}
|
||||
class RangeReferenceToken {
|
||||
getValue;
|
||||
ranges;
|
||||
rangeIndex;
|
||||
sheetId;
|
||||
getRangeString;
|
||||
type = "REFERENCE";
|
||||
constructor(getValue) {
|
||||
this.getValue = getValue;
|
||||
constructor(ranges, rangeIndex, sheetId, getRangeString) {
|
||||
this.ranges = ranges;
|
||||
this.rangeIndex = rangeIndex;
|
||||
this.sheetId = sheetId;
|
||||
this.getRangeString = getRangeString;
|
||||
}
|
||||
get value() {
|
||||
return this.getValue();
|
||||
const range = this.ranges[this.rangeIndex];
|
||||
return this.getRangeString(range, this.sheetId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36193,7 +36267,13 @@
|
||||
}
|
||||
}
|
||||
exportForExcel(data) {
|
||||
this.export(data);
|
||||
if (data.sheets) {
|
||||
for (let sheet of data.sheets) {
|
||||
if (this.cfRules[sheet.id]) {
|
||||
sheet.conditionalFormats = this.cfRules[sheet.id].map((rule) => this.mapToConditionalFormat(sheet.id, rule, { useFixedReference: true }));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
// Getters
|
||||
@@ -36258,11 +36338,11 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Private
|
||||
// ---------------------------------------------------------------------------
|
||||
mapToConditionalFormat(sheetId, cf) {
|
||||
mapToConditionalFormat(sheetId, cf, { useFixedReference } = { useFixedReference: false }) {
|
||||
return {
|
||||
...cf,
|
||||
ranges: cf.ranges.map((range) => {
|
||||
return this.getters.getRangeString(range, sheetId);
|
||||
return this.getters.getRangeString(range, sheetId, { useFixedReference });
|
||||
}),
|
||||
};
|
||||
}
|
||||
@@ -38330,8 +38410,10 @@
|
||||
*
|
||||
* @param range the range (received from getRangeFromXC or getRangeFromZone)
|
||||
* @param forSheetId the id of the sheet where the range string is supposed to be used.
|
||||
* @param options
|
||||
* @param options.useFixedReference if true, the range will be returned with fixed row and column
|
||||
*/
|
||||
getRangeString(range, forSheetId) {
|
||||
getRangeString(range, forSheetId, options = { useFixedReference: false }) {
|
||||
if (!range) {
|
||||
return INCORRECT_RANGE_STRING;
|
||||
}
|
||||
@@ -38358,7 +38440,7 @@
|
||||
if (prefixSheet && !sheetName) {
|
||||
return INCORRECT_RANGE_STRING;
|
||||
}
|
||||
let rangeString = this.getRangePartString(rangeImpl, 0);
|
||||
let rangeString = this.getRangePartString(rangeImpl, 0, options);
|
||||
if (rangeImpl.parts && rangeImpl.parts.length === 2) {
|
||||
// this if converts A2:A2 into A2 except if any part of the original range had fixed row or column (with $)
|
||||
if (rangeImpl.zone.top !== rangeImpl.zone.bottom ||
|
||||
@@ -38368,7 +38450,7 @@
|
||||
rangeImpl.parts[1].rowFixed ||
|
||||
rangeImpl.parts[1].colFixed) {
|
||||
rangeString += ":";
|
||||
rangeString += this.getRangePartString(rangeImpl, 1);
|
||||
rangeString += this.getRangePartString(rangeImpl, 1, options);
|
||||
}
|
||||
}
|
||||
return `${prefixSheet ? sheetName + "!" : ""}${rangeString}`;
|
||||
@@ -38409,13 +38491,13 @@
|
||||
/**
|
||||
* Get a Xc string that represent a part of a range
|
||||
*/
|
||||
getRangePartString(range, part) {
|
||||
getRangePartString(range, part, options = { useFixedReference: false }) {
|
||||
const colFixed = range.parts && range.parts[part]?.colFixed ? "$" : "";
|
||||
const col = part === 0 ? numberToLetters(range.zone.left) : numberToLetters(range.zone.right);
|
||||
const rowFixed = range.parts && range.parts[part]?.rowFixed ? "$" : "";
|
||||
const row = part === 0 ? String(range.zone.top + 1) : String(range.zone.bottom + 1);
|
||||
let str = "";
|
||||
if (range.isFullCol) {
|
||||
if (range.isFullCol && !options.useFixedReference) {
|
||||
if (part === 0 && range.unboundedZone.hasHeader) {
|
||||
str = colFixed + col + rowFixed + row;
|
||||
}
|
||||
@@ -38423,7 +38505,7 @@
|
||||
str = colFixed + col;
|
||||
}
|
||||
}
|
||||
else if (range.isFullRow) {
|
||||
else if (range.isFullRow && !options.useFixedReference) {
|
||||
if (part === 0 && range.unboundedZone.hasHeader) {
|
||||
str = colFixed + col + rowFixed + row;
|
||||
}
|
||||
@@ -41428,7 +41510,13 @@
|
||||
const format = newFormat
|
||||
? getItemId(newFormat, data.formats)
|
||||
: exportedCellData.format;
|
||||
const content = !isExported ? newContent : exportedCellData.content;
|
||||
let content;
|
||||
if (formulaCell instanceof FormulaCellWithDependencies) {
|
||||
content = this.getters.getFormulaCellContent(exportedSheetData.id, formulaCell.compiledFormula, formulaCell.compiledFormula.dependencies, true);
|
||||
}
|
||||
else {
|
||||
content = !isExported ? newContent : exportedCellData.content;
|
||||
}
|
||||
exportedSheetData.cells[xc] = { ...exportedCellData, value, isFormula, content, format };
|
||||
}
|
||||
}
|
||||
@@ -50744,6 +50832,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
class FocusableElement {
|
||||
focusableElement = undefined;
|
||||
setFocusableElement(element) {
|
||||
this.focusableElement = element;
|
||||
}
|
||||
focus() {
|
||||
this.focusableElement?.focus();
|
||||
}
|
||||
}
|
||||
|
||||
const RIPPLE_KEY_FRAMES = [
|
||||
{ transform: "scale(0)" },
|
||||
{ transform: "scale(0.8)", offset: 0.33 },
|
||||
@@ -52900,6 +52998,7 @@
|
||||
toggleSidePanel: this.toggleSidePanel.bind(this),
|
||||
clipboard: this.env.clipboard || instantiateClipboard(),
|
||||
startCellEdition: (content) => this.onGridComposerCellFocused(content),
|
||||
focusableElement: new FocusableElement(),
|
||||
});
|
||||
owl.useExternalListener(window, "resize", () => this.render(true));
|
||||
owl.useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
|
||||
@@ -53006,16 +53105,17 @@
|
||||
}
|
||||
this.composer.topBarFocus = "contentFocus";
|
||||
this.composer.gridFocusMode = "inactive";
|
||||
this.setComposerContent({ selection } || {});
|
||||
this.setComposerContent({ selection });
|
||||
}
|
||||
onGridComposerContentFocused() {
|
||||
onGridComposerContentFocused(selection) {
|
||||
if (this.model.getters.isReadonly()) {
|
||||
return;
|
||||
}
|
||||
this.composer.topBarFocus = "inactive";
|
||||
this.composer.gridFocusMode = "contentFocus";
|
||||
this.setComposerContent({});
|
||||
this.setComposerContent({ selection });
|
||||
}
|
||||
// TODO: either both are defined or none of them. change those args to an object
|
||||
onGridComposerCellFocused(content, selection) {
|
||||
if (this.model.getters.isReadonly()) {
|
||||
return;
|
||||
@@ -54950,12 +55050,7 @@
|
||||
attrs.push(["t", "str"]);
|
||||
cycle = escapeXml /*xml*/ `<v>${cell.value}</v>`;
|
||||
}
|
||||
node = escapeXml /*xml*/ `
|
||||
<f>
|
||||
${XlsxFormula}
|
||||
</f>
|
||||
${cycle}
|
||||
`;
|
||||
node = escapeXml /*xml*/ `<f>${XlsxFormula}</f>${cycle}`;
|
||||
return { attrs, node };
|
||||
}
|
||||
function addContent(content, sharedStrings, forceString = false) {
|
||||
@@ -55774,11 +55869,10 @@
|
||||
({ attrs: additionalAttrs, node: cellNode } = addContent(cell.content, construct.sharedStrings, isTableHeader));
|
||||
}
|
||||
attributes.push(...additionalAttrs);
|
||||
cellNodes.push(escapeXml /*xml*/ `
|
||||
<c ${formatAttributes(attributes)}>
|
||||
${cellNode}
|
||||
</c>
|
||||
`);
|
||||
// prettier-ignore
|
||||
cellNodes.push(escapeXml /*xml*/ `<c ${formatAttributes(attributes)}>
|
||||
${cellNode}
|
||||
</c>`);
|
||||
}
|
||||
}
|
||||
if (cellNodes.length || row.size !== DEFAULT_CELL_HEIGHT || row.isHidden) {
|
||||
@@ -56374,7 +56468,6 @@
|
||||
...config,
|
||||
mode: config.mode || "normal",
|
||||
custom: config.custom || {},
|
||||
defaultCurrencyFormat: config.defaultCurrencyFormat || "[$$]#,##0.00",
|
||||
external: this.setupExternalConfig(config.external || {}),
|
||||
transportService,
|
||||
client,
|
||||
@@ -56412,6 +56505,7 @@
|
||||
custom: this.config.custom,
|
||||
uiActions: this.config,
|
||||
session: this.session,
|
||||
defaultCurrencyFormat: this.config.defaultCurrencyFormat,
|
||||
};
|
||||
}
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -56784,9 +56878,9 @@
|
||||
exports.tokenize = tokenize;
|
||||
|
||||
|
||||
__info__.version = "17.0.9";
|
||||
__info__.date = "2024-01-29T15:41:09.261Z";
|
||||
__info__.hash = "3c1209a38";
|
||||
__info__.version = "17.0.11";
|
||||
__info__.date = "2024-02-09T14:36:35.988Z";
|
||||
__info__.hash = "bb51d6315";
|
||||
|
||||
|
||||
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<!--
|
||||
This file is generated by o-spreadsheet build tools. Do not edit it.
|
||||
@see https://github.com/odoo/o-spreadsheet
|
||||
@version 17.0.9
|
||||
@date 2024-01-29T15:41:14.216Z
|
||||
@hash 3c1209a38
|
||||
@version 17.0.11
|
||||
@date 2024-02-09T14:36:37.907Z
|
||||
@hash bb51d6315
|
||||
-->
|
||||
<odoo>
|
||||
<t t-name="o-spreadsheet-ActionButton">
|
||||
@@ -467,7 +467,7 @@
|
||||
t-on-mousedown="onMousedown"
|
||||
t-on-click="onClick"
|
||||
t-on-keyup="onKeyup"
|
||||
t-on-paste.stop=""
|
||||
t-on-paste="onPaste"
|
||||
t-on-compositionstart="onCompositionStart"
|
||||
t-on-compositionend="onCompositionEnd"
|
||||
t-on-dblclick="onDblClick"
|
||||
@@ -565,14 +565,7 @@
|
||||
t-esc="cellReference"
|
||||
/>
|
||||
<div class="o-grid-composer" t-att-style="containerStyle" t-ref="gridComposer">
|
||||
<Composer
|
||||
focus="props.focus"
|
||||
inputStyle="composerStyle"
|
||||
rect="composerState.rect"
|
||||
delimitation="composerState.delimitation"
|
||||
onComposerUnmounted="props.onComposerUnmounted"
|
||||
onComposerContentFocused="props.onComposerContentFocused"
|
||||
/>
|
||||
<Composer t-props="composerProps"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -953,9 +946,10 @@
|
||||
<div
|
||||
class="o-grid w-100 h-100"
|
||||
tabindex="-1"
|
||||
t-on-click="focus"
|
||||
t-on-click="focusDefaultElement"
|
||||
t-on-keydown="onKeydown"
|
||||
t-on-wheel="onMouseWheel"
|
||||
t-on-contextmenu="onInputContextMenu"
|
||||
t-ref="grid">
|
||||
<GridOverlay
|
||||
onCellClicked.bind="onCellClicked"
|
||||
@@ -965,27 +959,15 @@
|
||||
onGridResized.bind="onGridResized"
|
||||
onGridMoved.bind="moveCanvas"
|
||||
gridOverlayDimensions="gridOverlayDimensions"
|
||||
onFigureDeleted.bind="focus"
|
||||
onFigureDeleted.bind="focusDefaultElement"
|
||||
/>
|
||||
<HeadersOverlay onOpenContextMenu="(type, x, y) => this.toggleContextMenu(type, x, y)"/>
|
||||
|
||||
<t t-if="env.model.getters.getEditionMode() !== 'inactive'">
|
||||
<GridComposer
|
||||
onComposerUnmounted="() => this.focus()"
|
||||
onComposerContentFocused="props.onComposerContentFocused"
|
||||
focus="props.focusComposer"
|
||||
gridDims="env.model.getters.getSheetViewDimensionWithHeaders()"
|
||||
/>
|
||||
</t>
|
||||
<t else="1">
|
||||
<input
|
||||
class="position-absolute"
|
||||
style="z-index:-1000;"
|
||||
t-on-input="onInput"
|
||||
t-on-contextmenu="onInputContextMenu"
|
||||
t-ref="hiddenInput"
|
||||
/>
|
||||
</t>
|
||||
<GridComposer
|
||||
focus="props.focusComposer"
|
||||
onComposerContentFocused="props.onComposerContentFocused"
|
||||
onComposerCellFocused="props.onGridComposerCellFocused"
|
||||
gridDims="env.model.getters.getSheetViewDimensionWithHeaders()"
|
||||
/>
|
||||
<canvas t-ref="canvas"/>
|
||||
<t
|
||||
t-foreach="env.model.getters.getClientsToDisplay()"
|
||||
@@ -1065,7 +1047,7 @@
|
||||
t-att-style="style"
|
||||
t-on-mousedown="onMouseDown"
|
||||
t-on-dblclick.self="onDoubleClick"
|
||||
t-on-contextmenu="onContextMenu">
|
||||
t-on-contextmenu.stop.prevent="onContextMenu">
|
||||
<FiguresContainer onFigureDeleted="props.onFigureDeleted"/>
|
||||
<DataValidationOverlay/>
|
||||
<GridAddRowsFooter
|
||||
|
||||
Reference in New Issue
Block a user