@odoo/o-spreadsheet 16.3.0-alpha.2 → 16.3.0-alpha.3
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 +466 -260
- package/dist/o-spreadsheet.d.ts +130 -115
- package/dist/o-spreadsheet.esm.js +466 -260
- package/dist/o-spreadsheet.iife.js +466 -260
- package/dist/o-spreadsheet.iife.min.js +251 -256
- package/package.json +2 -2
|
@@ -114,88 +114,88 @@
|
|
|
114
114
|
const BACKGROUND_HEADER_FILTER_COLOR = "#E6F4EA";
|
|
115
115
|
const BACKGROUND_HEADER_SELECTED_FILTER_COLOR = "#CEEAD6";
|
|
116
116
|
const SEPARATOR_COLOR = "#E0E2E4";
|
|
117
|
-
// Color picker
|
|
117
|
+
// Color picker defaults as upper case HEX to match `toHex`helper
|
|
118
118
|
const COLOR_PICKER_DEFAULTS = [
|
|
119
119
|
"#000000",
|
|
120
120
|
"#434343",
|
|
121
121
|
"#666666",
|
|
122
122
|
"#999999",
|
|
123
|
-
"#
|
|
124
|
-
"#
|
|
125
|
-
"#
|
|
126
|
-
"#
|
|
127
|
-
"#
|
|
128
|
-
"#
|
|
123
|
+
"#B7B7B7",
|
|
124
|
+
"#CCCCCC",
|
|
125
|
+
"#D9D9D9",
|
|
126
|
+
"#EFEFEF",
|
|
127
|
+
"#F3F3F3",
|
|
128
|
+
"#FFFFFF",
|
|
129
129
|
"#980000",
|
|
130
|
-
"#
|
|
131
|
-
"#
|
|
132
|
-
"#
|
|
133
|
-
"#
|
|
134
|
-
"#
|
|
135
|
-
"#
|
|
136
|
-
"#
|
|
137
|
-
"#
|
|
138
|
-
"#
|
|
139
|
-
"#
|
|
140
|
-
"#
|
|
141
|
-
"#
|
|
142
|
-
"#
|
|
143
|
-
"#
|
|
144
|
-
"#
|
|
145
|
-
"#
|
|
146
|
-
"#
|
|
147
|
-
"#
|
|
148
|
-
"#
|
|
149
|
-
"#
|
|
150
|
-
"#
|
|
151
|
-
"#
|
|
152
|
-
"#
|
|
153
|
-
"#
|
|
154
|
-
"#
|
|
155
|
-
"#
|
|
156
|
-
"#
|
|
157
|
-
"#
|
|
158
|
-
"#
|
|
159
|
-
"#
|
|
160
|
-
"#
|
|
161
|
-
"#
|
|
162
|
-
"#
|
|
163
|
-
"#
|
|
164
|
-
"#
|
|
165
|
-
"#
|
|
166
|
-
"#
|
|
167
|
-
"#
|
|
168
|
-
"#
|
|
169
|
-
"#
|
|
170
|
-
"#
|
|
171
|
-
"#
|
|
172
|
-
"#
|
|
173
|
-
"#
|
|
174
|
-
"#
|
|
175
|
-
"#
|
|
176
|
-
"#
|
|
177
|
-
"#
|
|
178
|
-
"#
|
|
179
|
-
"#
|
|
130
|
+
"#FF0000",
|
|
131
|
+
"#FF9900",
|
|
132
|
+
"#FFFF00",
|
|
133
|
+
"#00FF00",
|
|
134
|
+
"#00FFFF",
|
|
135
|
+
"#4A86E8",
|
|
136
|
+
"#0000FF",
|
|
137
|
+
"#9900FF",
|
|
138
|
+
"#FF00FF",
|
|
139
|
+
"#E6B8AF",
|
|
140
|
+
"#F4CCCC",
|
|
141
|
+
"#FCE5CD",
|
|
142
|
+
"#FFF2CC",
|
|
143
|
+
"#D9EAD3",
|
|
144
|
+
"#D0E0E3",
|
|
145
|
+
"#C9DAF8",
|
|
146
|
+
"#CFE2F3",
|
|
147
|
+
"#D9D2E9",
|
|
148
|
+
"#EAD1DC",
|
|
149
|
+
"#DD7E6B",
|
|
150
|
+
"#EA9999",
|
|
151
|
+
"#F9CB9C",
|
|
152
|
+
"#FFE599",
|
|
153
|
+
"#B6D7A8",
|
|
154
|
+
"#A2C4C9",
|
|
155
|
+
"#A4C2F4",
|
|
156
|
+
"#9FC5E8",
|
|
157
|
+
"#B4A7D6",
|
|
158
|
+
"#D5A6BD",
|
|
159
|
+
"#CC4125",
|
|
160
|
+
"#E06666",
|
|
161
|
+
"#F6B26B",
|
|
162
|
+
"#FFD966",
|
|
163
|
+
"#93C47D",
|
|
164
|
+
"#76A5AF",
|
|
165
|
+
"#6D9EEB",
|
|
166
|
+
"#6FA8DC",
|
|
167
|
+
"#8E7CC3",
|
|
168
|
+
"#C27BA0",
|
|
169
|
+
"#A61C00",
|
|
170
|
+
"#CC0000",
|
|
171
|
+
"#E69138",
|
|
172
|
+
"#F1C232",
|
|
173
|
+
"#6AA84F",
|
|
174
|
+
"#45818E",
|
|
175
|
+
"#3C78D8",
|
|
176
|
+
"#3D85C6",
|
|
177
|
+
"#674EA7",
|
|
178
|
+
"#A64D79",
|
|
179
|
+
"#85200C",
|
|
180
180
|
"#990000",
|
|
181
|
-
"#
|
|
182
|
-
"#
|
|
183
|
-
"#
|
|
184
|
-
"#
|
|
185
|
-
"#
|
|
186
|
-
"#
|
|
187
|
-
"#
|
|
188
|
-
"#
|
|
189
|
-
"#
|
|
181
|
+
"#B45F06",
|
|
182
|
+
"#BF9000",
|
|
183
|
+
"#38761D",
|
|
184
|
+
"#134F5C",
|
|
185
|
+
"#1155CC",
|
|
186
|
+
"#0B5394",
|
|
187
|
+
"#351C75",
|
|
188
|
+
"#741B47",
|
|
189
|
+
"#5B0F00",
|
|
190
190
|
"#660000",
|
|
191
|
-
"#
|
|
192
|
-
"#
|
|
193
|
-
"#
|
|
194
|
-
"#
|
|
195
|
-
"#
|
|
191
|
+
"#783F04",
|
|
192
|
+
"#7F6000",
|
|
193
|
+
"#274E13",
|
|
194
|
+
"#0C343D",
|
|
195
|
+
"#1C4587",
|
|
196
196
|
"#073763",
|
|
197
|
-
"#
|
|
198
|
-
"#
|
|
197
|
+
"#20124D",
|
|
198
|
+
"#4C1130",
|
|
199
199
|
];
|
|
200
200
|
// Dimensions
|
|
201
201
|
const MIN_ROW_HEIGHT = 10;
|
|
@@ -224,7 +224,6 @@
|
|
|
224
224
|
const MENU_ITEM_HEIGHT = 28;
|
|
225
225
|
const MENU_SEPARATOR_BORDER_WIDTH = 1;
|
|
226
226
|
const MENU_SEPARATOR_PADDING = 5;
|
|
227
|
-
const MENU_SEPARATOR_HEIGHT = MENU_SEPARATOR_BORDER_WIDTH + 2 * MENU_SEPARATOR_PADDING;
|
|
228
227
|
// Fonts
|
|
229
228
|
const DEFAULT_FONT_WEIGHT = "400";
|
|
230
229
|
const DEFAULT_FONT_SIZE = 10;
|
|
@@ -234,7 +233,7 @@
|
|
|
234
233
|
const DEFAULT_BORDER_DESC = ["thin", "#000"];
|
|
235
234
|
const DEFAULT_FILTER_BORDER_DESC = ["thin", FILTERS_COLOR];
|
|
236
235
|
// DateTimeRegex
|
|
237
|
-
const DATETIME_FORMAT = /[
|
|
236
|
+
const DATETIME_FORMAT = /[ymdhs:]/;
|
|
238
237
|
// Ranges
|
|
239
238
|
const INCORRECT_RANGE_STRING = CellErrorType.InvalidReference;
|
|
240
239
|
// Max Number of history steps kept in memory
|
|
@@ -715,7 +714,7 @@
|
|
|
715
714
|
* '\w' captures [0-9][a-z][A-Z] and _.
|
|
716
715
|
* @param sheetName Name of the sheet
|
|
717
716
|
*/
|
|
718
|
-
function
|
|
717
|
+
function getCanonicalSheetName(sheetName) {
|
|
719
718
|
var _a;
|
|
720
719
|
if (((_a = sheetName.match(/\w/g)) === null || _a === void 0 ? void 0 : _a.length) !== sheetName.length) {
|
|
721
720
|
sheetName = `'${sheetName}'`;
|
|
@@ -736,8 +735,9 @@
|
|
|
736
735
|
return DEFAULT_CELL_HEIGHT;
|
|
737
736
|
}
|
|
738
737
|
const fontSize = computeTextFontSizeInPixels(cell.style);
|
|
739
|
-
|
|
740
|
-
|
|
738
|
+
// the number of lines should be computed from the formula result, but it's not evaluated at this point
|
|
739
|
+
const numberOfLines = cell.isFormula ? 1 : cell.content.split(NEWLINE).length;
|
|
740
|
+
return computeTextLinesHeight(fontSize, numberOfLines) + 2 * PADDING_AUTORESIZE_VERTICAL;
|
|
741
741
|
}
|
|
742
742
|
function computeTextWidth(context, text, style) {
|
|
743
743
|
context.save();
|
|
@@ -1089,6 +1089,8 @@
|
|
|
1089
1089
|
return text;
|
|
1090
1090
|
}
|
|
1091
1091
|
|
|
1092
|
+
const RBA_REGEX = /rgba?\(|\s+|\)/gi;
|
|
1093
|
+
const HEX_MATCH = /^#([A-F\d]{2}){3,4}$/g;
|
|
1092
1094
|
const colors$1 = [
|
|
1093
1095
|
"#eb6d00",
|
|
1094
1096
|
"#0074d9",
|
|
@@ -1114,7 +1116,10 @@
|
|
|
1114
1116
|
}
|
|
1115
1117
|
/**
|
|
1116
1118
|
* Converts any CSS color value to a standardized hex6 value.
|
|
1117
|
-
* Accepts: hex3, hex6, hex8 and
|
|
1119
|
+
* Accepts: hex3, hex6, hex8, rgb[1] and rgba[1].
|
|
1120
|
+
*
|
|
1121
|
+
* [1] under the form rgb(r, g, b, a?) or rgba(r, g, b, a?)
|
|
1122
|
+
* with r,g,b ∈ [0, 255] and a ∈ [0, 1]
|
|
1118
1123
|
*
|
|
1119
1124
|
* toHex("#ABC")
|
|
1120
1125
|
* >> "#AABBCC"
|
|
@@ -1125,27 +1130,31 @@
|
|
|
1125
1130
|
* toHex("rgb(30, 80, 16)")
|
|
1126
1131
|
* >> "#1E5010"
|
|
1127
1132
|
*
|
|
1133
|
+
* * toHex("rgb(30, 80, 16, 0.5)")
|
|
1134
|
+
* >> "#1E501080"
|
|
1135
|
+
*
|
|
1128
1136
|
*/
|
|
1129
1137
|
function toHex(color) {
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
if (color.includes("rgb")) {
|
|
1134
|
-
return rgbToHex6(color);
|
|
1138
|
+
let hexColor = color;
|
|
1139
|
+
if (color.startsWith("rgb")) {
|
|
1140
|
+
hexColor = rgbaStringToHex(color);
|
|
1135
1141
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1142
|
+
else {
|
|
1143
|
+
hexColor = color.replace("#", "").toUpperCase();
|
|
1144
|
+
if (hexColor.length === 3 || hexColor.length === 4) {
|
|
1145
|
+
hexColor = hexColor.split("").reduce((acc, h) => acc + h + h, "");
|
|
1146
|
+
}
|
|
1147
|
+
hexColor = `#${hexColor}`;
|
|
1139
1148
|
}
|
|
1140
|
-
if (
|
|
1141
|
-
throw new Error(
|
|
1149
|
+
if (!hexColor.match(HEX_MATCH)) {
|
|
1150
|
+
throw new Error(`invalid color input: ${color}`);
|
|
1142
1151
|
}
|
|
1143
|
-
return
|
|
1152
|
+
return hexColor;
|
|
1144
1153
|
}
|
|
1145
1154
|
function isColorValid(color) {
|
|
1146
1155
|
try {
|
|
1147
|
-
|
|
1148
|
-
return
|
|
1156
|
+
toHex(color);
|
|
1157
|
+
return true;
|
|
1149
1158
|
}
|
|
1150
1159
|
catch (error) {
|
|
1151
1160
|
return false;
|
|
@@ -1178,15 +1187,29 @@
|
|
|
1178
1187
|
/**
|
|
1179
1188
|
* Convert a CSS rgb color string to a standardized hex6 color value.
|
|
1180
1189
|
*
|
|
1181
|
-
*
|
|
1190
|
+
* rgbaStringToHex("rgb(30, 80, 16)")
|
|
1182
1191
|
* >> "#1E5010"
|
|
1192
|
+
*
|
|
1193
|
+
* rgbaStringToHex("rgba(30, 80, 16, 0.5)")
|
|
1194
|
+
* >> "#1E501080"
|
|
1195
|
+
*
|
|
1196
|
+
* DOES NOT SUPPORT NON INTEGER RGB VALUES
|
|
1183
1197
|
*/
|
|
1184
|
-
function
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1198
|
+
function rgbaStringToHex(color) {
|
|
1199
|
+
const stringVals = color.replace(RBA_REGEX, "").split(",");
|
|
1200
|
+
let alphaHex = 255;
|
|
1201
|
+
if (stringVals.length !== 3 && stringVals.length !== 4) {
|
|
1202
|
+
throw new Error("invalid color");
|
|
1203
|
+
}
|
|
1204
|
+
else if (stringVals.length === 4) {
|
|
1205
|
+
const alpha = parseFloat(stringVals.pop() || "1");
|
|
1206
|
+
alphaHex = Math.round((alpha || 1) * 255);
|
|
1207
|
+
}
|
|
1208
|
+
const vals = stringVals.map((val) => parseInt(val, 10));
|
|
1209
|
+
if (alphaHex !== 255) {
|
|
1210
|
+
vals.push(alphaHex);
|
|
1211
|
+
}
|
|
1212
|
+
return "#" + concat(vals.map((value) => value.toString(16).padStart(2, "0"))).toUpperCase();
|
|
1190
1213
|
}
|
|
1191
1214
|
/**
|
|
1192
1215
|
* RGBA to HEX representation (#RRGGBBAA).
|
|
@@ -1208,7 +1231,7 @@
|
|
|
1208
1231
|
a = "0" + a;
|
|
1209
1232
|
if (a === "ff")
|
|
1210
1233
|
a = "";
|
|
1211
|
-
return "#" + r + g + b + a;
|
|
1234
|
+
return ("#" + r + g + b + a).toUpperCase();
|
|
1212
1235
|
}
|
|
1213
1236
|
/**
|
|
1214
1237
|
* Color string to RGBA representation
|
|
@@ -1329,6 +1352,9 @@
|
|
|
1329
1352
|
s = +(s * 100).toFixed(1);
|
|
1330
1353
|
l = +(l * 100).toFixed(1);
|
|
1331
1354
|
return { a: rgba.a, h, s, l };
|
|
1355
|
+
}
|
|
1356
|
+
function isSameColor(color1, color2) {
|
|
1357
|
+
return isColorValid(color1) && isColorValid(color2) && toHex(color1) === toHex(color2);
|
|
1332
1358
|
}
|
|
1333
1359
|
|
|
1334
1360
|
/** Reference of a cell (eg. A1, $B$5) */
|
|
@@ -1480,7 +1506,7 @@
|
|
|
1480
1506
|
* formula, commas are used to separate arguments
|
|
1481
1507
|
* - it does not support % symbol, in formulas % is an operator
|
|
1482
1508
|
*/
|
|
1483
|
-
const formulaNumberRegexp =
|
|
1509
|
+
const formulaNumberRegexp = /(^-?\d+(\.?\d*(e\d+)?)?|^-?\.\d+)(?!\w|!)/;
|
|
1484
1510
|
const pIntegerAndDecimals = "(\\d+(,\\d{3,})*(\\.\\d*)?)"; // pattern that match integer number with or without decimal digits
|
|
1485
1511
|
const pOnlyDecimals = "(\\.\\d+)"; // pattern that match only expression with decimal digits
|
|
1486
1512
|
const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
|
|
@@ -3089,6 +3115,7 @@
|
|
|
3089
3115
|
const LINE_HEIGHT = 1.2;
|
|
3090
3116
|
css /* scss */ `
|
|
3091
3117
|
div.o-scorecard {
|
|
3118
|
+
font-family: ${DEFAULT_FONT};
|
|
3092
3119
|
user-select: none;
|
|
3093
3120
|
background-color: white;
|
|
3094
3121
|
display: flex;
|
|
@@ -5376,24 +5403,30 @@
|
|
|
5376
5403
|
}
|
|
5377
5404
|
});
|
|
5378
5405
|
}
|
|
5379
|
-
get
|
|
5380
|
-
|
|
5406
|
+
get menuItemsAndSeparators() {
|
|
5407
|
+
const menuItemsAndSeparators = [];
|
|
5408
|
+
for (let i = 0; i < this.props.menuItems.length; i++) {
|
|
5409
|
+
const menuItem = this.props.menuItems[i];
|
|
5410
|
+
if (menuItem.isVisible(this.env)) {
|
|
5411
|
+
menuItemsAndSeparators.push(menuItem);
|
|
5412
|
+
}
|
|
5413
|
+
if (menuItem.separator &&
|
|
5414
|
+
i !== this.props.menuItems.length - 1 && // no separator at the end
|
|
5415
|
+
menuItemsAndSeparators[menuItemsAndSeparators.length - 1] !== "separator" // no double separator
|
|
5416
|
+
) {
|
|
5417
|
+
menuItemsAndSeparators.push("separator");
|
|
5418
|
+
}
|
|
5419
|
+
}
|
|
5420
|
+
if (menuItemsAndSeparators.length === 1 && menuItemsAndSeparators[0] === "separator") {
|
|
5421
|
+
return [];
|
|
5422
|
+
}
|
|
5423
|
+
return menuItemsAndSeparators;
|
|
5381
5424
|
}
|
|
5382
5425
|
get subMenuPosition() {
|
|
5383
5426
|
const position = Object.assign({}, this.subMenu.position);
|
|
5384
5427
|
position.y -= this.subMenu.scrollOffset || 0;
|
|
5385
5428
|
return position;
|
|
5386
5429
|
}
|
|
5387
|
-
get menuHeight() {
|
|
5388
|
-
const menuItems = this.visibleMenuItems;
|
|
5389
|
-
let menuItemsHeight = this.getMenuItemsHeight(menuItems);
|
|
5390
|
-
// We don't display separator at the end of a menu
|
|
5391
|
-
if (menuItems[menuItems.length - 1].separator) {
|
|
5392
|
-
menuItemsHeight -= MENU_SEPARATOR_HEIGHT;
|
|
5393
|
-
}
|
|
5394
|
-
const menuHeight = 2 * MENU_VERTICAL_PADDING + menuItemsHeight;
|
|
5395
|
-
return this.props.maxHeight ? Math.min(menuHeight, this.props.maxHeight) : menuHeight;
|
|
5396
|
-
}
|
|
5397
5430
|
get popoverProps() {
|
|
5398
5431
|
const isRoot = this.props.depth === 1;
|
|
5399
5432
|
return {
|
|
@@ -5407,7 +5440,6 @@
|
|
|
5407
5440
|
verticalOffset: isRoot ? 0 : MENU_VERTICAL_PADDING,
|
|
5408
5441
|
onPopoverHidden: () => this.closeSubMenu(),
|
|
5409
5442
|
onPopoverMoved: () => this.closeSubMenu(),
|
|
5410
|
-
maxHeight: this.menuHeight,
|
|
5411
5443
|
};
|
|
5412
5444
|
}
|
|
5413
5445
|
getColor(menu) {
|
|
@@ -5423,14 +5455,6 @@
|
|
|
5423
5455
|
this.closeSubMenu();
|
|
5424
5456
|
this.props.onClose();
|
|
5425
5457
|
}
|
|
5426
|
-
/**
|
|
5427
|
-
* Return the number of pixels between the top of the menu
|
|
5428
|
-
* and the menu item at a given index.
|
|
5429
|
-
*/
|
|
5430
|
-
subMenuVerticalPosition(menuIndex) {
|
|
5431
|
-
const menusAbove = this.visibleMenuItems.slice(0, menuIndex);
|
|
5432
|
-
return this.position.y + this.getMenuItemsHeight(menusAbove) + MENU_VERTICAL_PADDING;
|
|
5433
|
-
}
|
|
5434
5458
|
onExternalClick(ev) {
|
|
5435
5459
|
// Don't close a root menu when clicked to open the submenus.
|
|
5436
5460
|
const el = this.menuRef.el;
|
|
@@ -5440,10 +5464,6 @@
|
|
|
5440
5464
|
ev.closedMenuId = this.props.menuId;
|
|
5441
5465
|
this.close();
|
|
5442
5466
|
}
|
|
5443
|
-
getMenuItemsHeight(menuItems) {
|
|
5444
|
-
const numberOfSeparators = menuItems.filter((m) => m.separator).length;
|
|
5445
|
-
return MENU_ITEM_HEIGHT * menuItems.length + MENU_SEPARATOR_HEIGHT * numberOfSeparators;
|
|
5446
|
-
}
|
|
5447
5467
|
getName(menu) {
|
|
5448
5468
|
return menu.name(this.env);
|
|
5449
5469
|
}
|
|
@@ -5463,8 +5483,11 @@
|
|
|
5463
5483
|
* If the given menu is not disabled, open it's submenu at the
|
|
5464
5484
|
* correct position according to available surrounding space.
|
|
5465
5485
|
*/
|
|
5466
|
-
openSubMenu(menu, menuIndex) {
|
|
5467
|
-
const
|
|
5486
|
+
openSubMenu(menu, menuIndex, ev) {
|
|
5487
|
+
const parentMenuEl = ev.currentTarget;
|
|
5488
|
+
if (!parentMenuEl)
|
|
5489
|
+
return;
|
|
5490
|
+
const y = parentMenuEl.getBoundingClientRect().top;
|
|
5468
5491
|
this.subMenu.position = {
|
|
5469
5492
|
x: this.position.x + this.props.depth * MENU_WIDTH,
|
|
5470
5493
|
y: y - (this.subMenu.scrollOffset || 0),
|
|
@@ -5481,20 +5504,20 @@
|
|
|
5481
5504
|
this.subMenu.isOpen = false;
|
|
5482
5505
|
this.subMenu.parentMenu = undefined;
|
|
5483
5506
|
}
|
|
5484
|
-
onClickMenu(menu, menuIndex) {
|
|
5507
|
+
onClickMenu(menu, menuIndex, ev) {
|
|
5485
5508
|
if (this.isEnabled(menu)) {
|
|
5486
5509
|
if (this.isRoot(menu)) {
|
|
5487
|
-
this.openSubMenu(menu, menuIndex);
|
|
5510
|
+
this.openSubMenu(menu, menuIndex, ev);
|
|
5488
5511
|
}
|
|
5489
5512
|
else {
|
|
5490
5513
|
this.activateMenu(menu);
|
|
5491
5514
|
}
|
|
5492
5515
|
}
|
|
5493
5516
|
}
|
|
5494
|
-
onMouseOver(menu, position) {
|
|
5517
|
+
onMouseOver(menu, position, ev) {
|
|
5495
5518
|
if (menu.isEnabled(this.env)) {
|
|
5496
5519
|
if (this.isRoot(menu)) {
|
|
5497
|
-
this.openSubMenu(menu, position);
|
|
5520
|
+
this.openSubMenu(menu, position, ev);
|
|
5498
5521
|
}
|
|
5499
5522
|
else {
|
|
5500
5523
|
this.closeSubMenu();
|
|
@@ -6071,8 +6094,8 @@
|
|
|
6071
6094
|
const dataSets = [];
|
|
6072
6095
|
for (const sheetXC of dataSetsString) {
|
|
6073
6096
|
const dataRange = getters.getRangeFromSheetXC(sheetId, sheetXC);
|
|
6074
|
-
const { unboundedZone: zone, sheetId: dataSetSheetId, invalidSheetName } = dataRange;
|
|
6075
|
-
if (invalidSheetName) {
|
|
6097
|
+
const { unboundedZone: zone, sheetId: dataSetSheetId, invalidSheetName, invalidXc } = dataRange;
|
|
6098
|
+
if (invalidSheetName || invalidXc) {
|
|
6076
6099
|
continue;
|
|
6077
6100
|
}
|
|
6078
6101
|
// It's a rectangle. We treat all columns (arbitrary) as different data series.
|
|
@@ -6097,14 +6120,8 @@
|
|
|
6097
6120
|
: undefined));
|
|
6098
6121
|
}
|
|
6099
6122
|
}
|
|
6100
|
-
else if (zone.left === zone.right && zone.top === zone.bottom) {
|
|
6101
|
-
// A single cell. If it's only the title, the dataset is not added.
|
|
6102
|
-
if (!dataSetsHaveTitle) {
|
|
6103
|
-
dataSets.push(createDataSet(getters, dataSetSheetId, zone, undefined));
|
|
6104
|
-
}
|
|
6105
|
-
}
|
|
6106
6123
|
else {
|
|
6107
|
-
/* 1 row or 1 column */
|
|
6124
|
+
/* 1 cell, 1 row or 1 column */
|
|
6108
6125
|
dataSets.push(createDataSet(getters, dataSetSheetId, zone, dataSetsHaveTitle
|
|
6109
6126
|
? {
|
|
6110
6127
|
top: zone.top,
|
|
@@ -6158,6 +6175,18 @@
|
|
|
6158
6175
|
range: getters.getRangeString(dataRange, "forceSheetReference"),
|
|
6159
6176
|
};
|
|
6160
6177
|
}
|
|
6178
|
+
function toExcelLabelRange(getters, labelRange, shouldRemoveFirstLabel) {
|
|
6179
|
+
if (!labelRange)
|
|
6180
|
+
return undefined;
|
|
6181
|
+
let zone = {
|
|
6182
|
+
...labelRange.zone,
|
|
6183
|
+
};
|
|
6184
|
+
if (shouldRemoveFirstLabel && labelRange.zone.bottom > labelRange.zone.top) {
|
|
6185
|
+
zone.top = zone.top + 1;
|
|
6186
|
+
}
|
|
6187
|
+
const range = labelRange.clone({ zone });
|
|
6188
|
+
return getters.getRangeString(range, "forceSheetReference");
|
|
6189
|
+
}
|
|
6161
6190
|
/**
|
|
6162
6191
|
* Transform a chart definition which supports dataSets (dataSets and LabelRange)
|
|
6163
6192
|
* with an executed command
|
|
@@ -6242,6 +6271,20 @@
|
|
|
6242
6271
|
}
|
|
6243
6272
|
return 0 /* CommandResult.Success */;
|
|
6244
6273
|
}
|
|
6274
|
+
function shouldRemoveFirstLabel(labelRange, dataset, dataSetsHaveTitle) {
|
|
6275
|
+
if (!dataSetsHaveTitle)
|
|
6276
|
+
return false;
|
|
6277
|
+
if (!labelRange)
|
|
6278
|
+
return false;
|
|
6279
|
+
if (!dataset)
|
|
6280
|
+
return true;
|
|
6281
|
+
const datasetLength = getZoneArea(dataset.dataRange.zone);
|
|
6282
|
+
const labelLength = getZoneArea(labelRange.zone);
|
|
6283
|
+
if (labelLength < datasetLength) {
|
|
6284
|
+
return false;
|
|
6285
|
+
}
|
|
6286
|
+
return true;
|
|
6287
|
+
}
|
|
6245
6288
|
// ---------------------------------------------------------------------------
|
|
6246
6289
|
// Scorecard
|
|
6247
6290
|
// ---------------------------------------------------------------------------
|
|
@@ -6611,6 +6654,7 @@
|
|
|
6611
6654
|
this.legendPosition = definition.legendPosition;
|
|
6612
6655
|
this.stacked = definition.stacked;
|
|
6613
6656
|
this.aggregated = definition.aggregated;
|
|
6657
|
+
this.dataSetsHaveTitle = definition.dataSetsHaveTitle;
|
|
6614
6658
|
}
|
|
6615
6659
|
static transformDefinition(definition, executed) {
|
|
6616
6660
|
return transformChartDefinitionWithDataSetsWithZone(definition, executed);
|
|
@@ -6678,11 +6722,13 @@
|
|
|
6678
6722
|
const dataSets = this.dataSets
|
|
6679
6723
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
6680
6724
|
.filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
|
|
6725
|
+
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
6681
6726
|
return {
|
|
6682
6727
|
...this.getDefinition(),
|
|
6683
6728
|
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
6684
6729
|
fontColor: toXlsxHexColor(chartFontColor(this.background)),
|
|
6685
6730
|
dataSets,
|
|
6731
|
+
labelRange,
|
|
6686
6732
|
};
|
|
6687
6733
|
}
|
|
6688
6734
|
updateRanges(applyChange) {
|
|
@@ -6750,6 +6796,11 @@
|
|
|
6750
6796
|
const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
|
|
6751
6797
|
let labels = labelValues.formattedValues;
|
|
6752
6798
|
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
|
|
6799
|
+
if (chart.dataSetsHaveTitle &&
|
|
6800
|
+
dataSetsValues[0] &&
|
|
6801
|
+
labels.length > dataSetsValues[0].data.length) {
|
|
6802
|
+
labels.shift();
|
|
6803
|
+
}
|
|
6753
6804
|
({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
|
|
6754
6805
|
if (chart.aggregated) {
|
|
6755
6806
|
({ labels, dataSetsValues } = aggregateDataForLabels(labels, dataSetsValues));
|
|
@@ -7172,6 +7223,7 @@
|
|
|
7172
7223
|
this.labelsAsText = definition.labelsAsText;
|
|
7173
7224
|
this.stacked = definition.stacked;
|
|
7174
7225
|
this.aggregated = definition.aggregated;
|
|
7226
|
+
this.dataSetsHaveTitle = definition.dataSetsHaveTitle;
|
|
7175
7227
|
}
|
|
7176
7228
|
static validateChartDefinition(validator, definition) {
|
|
7177
7229
|
return validator.checkValidations(definition, checkDataset, checkLabelRange);
|
|
@@ -7239,11 +7291,13 @@
|
|
|
7239
7291
|
const dataSets = this.dataSets
|
|
7240
7292
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
7241
7293
|
.filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
|
|
7294
|
+
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
7242
7295
|
return {
|
|
7243
7296
|
...this.getDefinition(),
|
|
7244
7297
|
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
7245
7298
|
fontColor: toXlsxHexColor(chartFontColor(this.background)),
|
|
7246
7299
|
dataSets,
|
|
7300
|
+
labelRange,
|
|
7247
7301
|
};
|
|
7248
7302
|
}
|
|
7249
7303
|
copyForSheetId(sheetId) {
|
|
@@ -7381,6 +7435,11 @@
|
|
|
7381
7435
|
const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
|
|
7382
7436
|
let labels = axisType === "linear" ? labelValues.values : labelValues.formattedValues;
|
|
7383
7437
|
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
|
|
7438
|
+
if (chart.dataSetsHaveTitle &&
|
|
7439
|
+
dataSetsValues[0] &&
|
|
7440
|
+
labels.length > dataSetsValues[0].data.length) {
|
|
7441
|
+
labels.shift();
|
|
7442
|
+
}
|
|
7384
7443
|
({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
|
|
7385
7444
|
if (axisType === "time") {
|
|
7386
7445
|
({ labels, dataSetsValues } = fixEmptyLabelsForDateCharts(labels, dataSetsValues));
|
|
@@ -7439,6 +7498,7 @@
|
|
|
7439
7498
|
this.background = definition.background;
|
|
7440
7499
|
this.legendPosition = definition.legendPosition;
|
|
7441
7500
|
this.aggregated = definition.aggregated;
|
|
7501
|
+
this.dataSetsHaveTitle = definition.dataSetsHaveTitle;
|
|
7442
7502
|
}
|
|
7443
7503
|
static transformDefinition(definition, executed) {
|
|
7444
7504
|
return transformChartDefinitionWithDataSetsWithZone(definition, executed);
|
|
@@ -7502,12 +7562,14 @@
|
|
|
7502
7562
|
const dataSets = this.dataSets
|
|
7503
7563
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
7504
7564
|
.filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
|
|
7565
|
+
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
7505
7566
|
return {
|
|
7506
7567
|
...this.getDefinition(),
|
|
7507
7568
|
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
7508
7569
|
fontColor: toXlsxHexColor(chartFontColor(this.background)),
|
|
7509
7570
|
verticalAxisPosition: "left",
|
|
7510
7571
|
dataSets,
|
|
7572
|
+
labelRange,
|
|
7511
7573
|
};
|
|
7512
7574
|
}
|
|
7513
7575
|
updateRanges(applyChange) {
|
|
@@ -7553,6 +7615,11 @@
|
|
|
7553
7615
|
const labelValues = getChartLabelValues(getters, chart.dataSets, chart.labelRange);
|
|
7554
7616
|
let labels = labelValues.formattedValues;
|
|
7555
7617
|
let dataSetsValues = getChartDatasetValues(getters, chart.dataSets);
|
|
7618
|
+
if (chart.dataSetsHaveTitle &&
|
|
7619
|
+
dataSetsValues[0] &&
|
|
7620
|
+
labels.length > dataSetsValues[0].data.length) {
|
|
7621
|
+
labels.shift();
|
|
7622
|
+
}
|
|
7556
7623
|
({ labels, dataSetsValues } = filterEmptyDataPoints(labels, dataSetsValues));
|
|
7557
7624
|
if (chart.aggregated) {
|
|
7558
7625
|
({ labels, dataSetsValues } = aggregateDataForLabels(labels, dataSetsValues));
|
|
@@ -8188,7 +8255,6 @@
|
|
|
8188
8255
|
labelRangeXc = zoneToXc({
|
|
8189
8256
|
...zone,
|
|
8190
8257
|
right: zone.left,
|
|
8191
|
-
top: dataSetsHaveTitle ? zone.top + 1 : zone.top,
|
|
8192
8258
|
});
|
|
8193
8259
|
}
|
|
8194
8260
|
// Only display legend for several datasets.
|
|
@@ -15106,7 +15172,7 @@
|
|
|
15106
15172
|
cellReference = rowPart + colPart;
|
|
15107
15173
|
}
|
|
15108
15174
|
if (sheet !== undefined) {
|
|
15109
|
-
return `${
|
|
15175
|
+
return `${getCanonicalSheetName(toString(sheet))}!${cellReference}`;
|
|
15110
15176
|
}
|
|
15111
15177
|
return cellReference;
|
|
15112
15178
|
},
|
|
@@ -16931,6 +16997,22 @@
|
|
|
16931
16997
|
aggregated: ev.target.checked,
|
|
16932
16998
|
});
|
|
16933
16999
|
}
|
|
17000
|
+
calculateHeaderPosition() {
|
|
17001
|
+
if (this.isDatasetInvalid || this.isLabelInvalid) {
|
|
17002
|
+
return undefined;
|
|
17003
|
+
}
|
|
17004
|
+
const getters = this.env.model.getters;
|
|
17005
|
+
const sheetId = getters.getActiveSheetId();
|
|
17006
|
+
const labelRange = createRange(getters, sheetId, this.labelRange);
|
|
17007
|
+
const dataSets = createDataSets(getters, this.dataSeriesRanges, sheetId, this.props.definition.dataSetsHaveTitle);
|
|
17008
|
+
if (dataSets.length) {
|
|
17009
|
+
return dataSets[0].dataRange.zone.top + 1;
|
|
17010
|
+
}
|
|
17011
|
+
else if (labelRange) {
|
|
17012
|
+
return labelRange.zone.top + 1;
|
|
17013
|
+
}
|
|
17014
|
+
return undefined;
|
|
17015
|
+
}
|
|
16934
17016
|
}
|
|
16935
17017
|
LineBarPieConfigPanel.template = "o-spreadsheet-LineBarPieConfigPanel";
|
|
16936
17018
|
LineBarPieConfigPanel.components = { SelectionInput };
|
|
@@ -17178,6 +17260,9 @@
|
|
|
17178
17260
|
top,
|
|
17179
17261
|
});
|
|
17180
17262
|
}
|
|
17263
|
+
isSameColor(color1, color2) {
|
|
17264
|
+
return isSameColor(color1, color2);
|
|
17265
|
+
}
|
|
17181
17266
|
}
|
|
17182
17267
|
ColorPicker.template = "o-spreadsheet-ColorPicker";
|
|
17183
17268
|
ColorPicker.defaultProps = {
|
|
@@ -19419,6 +19504,8 @@
|
|
|
19419
19504
|
start = 0;
|
|
19420
19505
|
if (end > textLength)
|
|
19421
19506
|
end = textLength;
|
|
19507
|
+
if (start > textLength)
|
|
19508
|
+
start = textLength;
|
|
19422
19509
|
}
|
|
19423
19510
|
let startNode = this.findChildAtCharacterIndex(start);
|
|
19424
19511
|
let endNode = this.findChildAtCharacterIndex(end);
|
|
@@ -19688,6 +19775,7 @@
|
|
|
19688
19775
|
padding-right: 2px;
|
|
19689
19776
|
|
|
19690
19777
|
box-sizing: border-box;
|
|
19778
|
+
font-family: ${DEFAULT_FONT};
|
|
19691
19779
|
|
|
19692
19780
|
caret-color: black;
|
|
19693
19781
|
padding-left: 3px;
|
|
@@ -20130,7 +20218,7 @@
|
|
|
20130
20218
|
const highlights = this.env.model.getters.getHighlights();
|
|
20131
20219
|
const refSheet = sheetName
|
|
20132
20220
|
? this.env.model.getters.getSheetIdByName(sheetName)
|
|
20133
|
-
: this.env.model.getters.
|
|
20221
|
+
: this.env.model.getters.getCurrentEditedCell().sheetId;
|
|
20134
20222
|
const highlight = highlights.find((highlight) => {
|
|
20135
20223
|
if (highlight.sheetId !== refSheet)
|
|
20136
20224
|
return false;
|
|
@@ -20291,7 +20379,7 @@
|
|
|
20291
20379
|
get cellReference() {
|
|
20292
20380
|
const { col, row, sheetId } = this.env.model.getters.getCurrentEditedCell();
|
|
20293
20381
|
const prefixSheet = sheetId !== this.env.model.getters.getActiveSheetId();
|
|
20294
|
-
return `${prefixSheet ?
|
|
20382
|
+
return `${prefixSheet ? getCanonicalSheetName(this.env.model.getters.getSheetName(sheetId)) + "!" : ""}${toXC(col, row)}`;
|
|
20295
20383
|
}
|
|
20296
20384
|
get cellReferenceStyle() {
|
|
20297
20385
|
const { x: left, y: top } = this.rect;
|
|
@@ -20476,15 +20564,18 @@
|
|
|
20476
20564
|
return { x, y };
|
|
20477
20565
|
}
|
|
20478
20566
|
|
|
20479
|
-
function dragFigureForMove({ x: mouseX, y: mouseY }, { x: mouseInitialX, y: mouseInitialY }, initialFigure, { x: viewportX, y: viewportY }, { scrollX, scrollY }) {
|
|
20567
|
+
function dragFigureForMove({ x: mouseX, y: mouseY }, { x: mouseInitialX, y: mouseInitialY }, initialFigure, { x: viewportX, y: viewportY }, { maxX, maxY }, { scrollX, scrollY }) {
|
|
20480
20568
|
const minX = viewportX ? 0 : -scrollX;
|
|
20481
20569
|
const minY = viewportY ? 0 : -scrollY;
|
|
20482
|
-
|
|
20483
|
-
const newX =
|
|
20484
|
-
|
|
20485
|
-
const newY =
|
|
20570
|
+
const deltaX = mouseX - mouseInitialX;
|
|
20571
|
+
const newX = clamp(initialFigure.x + deltaX, minX, maxX - initialFigure.width - scrollX);
|
|
20572
|
+
const deltaY = mouseY - mouseInitialY;
|
|
20573
|
+
const newY = clamp(initialFigure.y + deltaY, minY, maxY - initialFigure.height - scrollY);
|
|
20486
20574
|
return { ...initialFigure, x: newX, y: newY };
|
|
20487
20575
|
}
|
|
20576
|
+
function clamp(value, min, max) {
|
|
20577
|
+
return Math.min(Math.max(value, min), max);
|
|
20578
|
+
}
|
|
20488
20579
|
function dragFigureForResize(initialFigure, dirX, dirY, { x: mouseX, y: mouseY }, { x: mouseInitialX, y: mouseInitialY }, keepRatio, minFigSize) {
|
|
20489
20580
|
let { x, y, width, height } = initialFigure;
|
|
20490
20581
|
if (keepRatio && dirX != 0 && dirY != 0) {
|
|
@@ -20883,12 +20974,16 @@
|
|
|
20883
20974
|
}
|
|
20884
20975
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
20885
20976
|
const initialMousePosition = { x: ev.clientX, y: ev.clientY };
|
|
20977
|
+
const maxDimensions = {
|
|
20978
|
+
maxX: this.env.model.getters.getColDimensions(sheetId, this.env.model.getters.getNumberCols(sheetId) - 1).end,
|
|
20979
|
+
maxY: this.env.model.getters.getRowDimensions(sheetId, this.env.model.getters.getNumberRows(sheetId) - 1).end,
|
|
20980
|
+
};
|
|
20886
20981
|
const { x, y } = internalFigureToScreen(this.env.model.getters, figure);
|
|
20887
20982
|
const initialFig = { ...figure, x, y };
|
|
20888
20983
|
const onMouseMove = (ev) => {
|
|
20889
20984
|
const getters = this.env.model.getters;
|
|
20890
20985
|
const currentMousePosition = { x: ev.clientX, y: ev.clientY };
|
|
20891
|
-
const draggedFigure = dragFigureForMove(currentMousePosition, initialMousePosition, initialFig, this.env.model.getters.getMainViewportCoordinates(), getters.getActiveSheetScrollInfo());
|
|
20986
|
+
const draggedFigure = dragFigureForMove(currentMousePosition, initialMousePosition, initialFig, this.env.model.getters.getMainViewportCoordinates(), maxDimensions, getters.getActiveSheetScrollInfo());
|
|
20892
20987
|
const otherFigures = this.getOtherFigures(figure.id);
|
|
20893
20988
|
const internalDragged = screenFigureToInternal(getters, draggedFigure);
|
|
20894
20989
|
const snapResult = snapForMove(getters, internalDragged, otherFigures);
|
|
@@ -22582,6 +22677,10 @@
|
|
|
22582
22677
|
}
|
|
22583
22678
|
}
|
|
22584
22679
|
onInput(ev) {
|
|
22680
|
+
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
22681
|
+
if (!ev.isComposing && ev.inputType === "insertFromPaste") {
|
|
22682
|
+
return;
|
|
22683
|
+
}
|
|
22585
22684
|
if (ev.data) {
|
|
22586
22685
|
// if the user types a character on the grid, it means he wants to start composing the selected cell with that
|
|
22587
22686
|
// character
|
|
@@ -23430,6 +23529,70 @@
|
|
|
23430
23529
|
});
|
|
23431
23530
|
}
|
|
23432
23531
|
|
|
23532
|
+
const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/m|\s|-|\/|\.|:)+$/i;
|
|
23533
|
+
/**
|
|
23534
|
+
* Convert excel format to o_spreadsheet format
|
|
23535
|
+
*
|
|
23536
|
+
* Excel format are defined in openXML §18.8.31
|
|
23537
|
+
*/
|
|
23538
|
+
function convertXlsxFormat(numFmtId, formats, warningManager) {
|
|
23539
|
+
var _a, _b, _c;
|
|
23540
|
+
if (numFmtId === 0) {
|
|
23541
|
+
return undefined;
|
|
23542
|
+
}
|
|
23543
|
+
// Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
|
|
23544
|
+
let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || ((_a = formats.find((f) => f.id === numFmtId)) === null || _a === void 0 ? void 0 : _a.format);
|
|
23545
|
+
if (format) {
|
|
23546
|
+
try {
|
|
23547
|
+
let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format
|
|
23548
|
+
convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
|
|
23549
|
+
convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks
|
|
23550
|
+
// Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format
|
|
23551
|
+
const numberOfQuotes = ((_b = convertedFormat.match(/"/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
|
|
23552
|
+
const numberOfOpenBrackets = ((_c = convertedFormat.match(/\[/g)) === null || _c === void 0 ? void 0 : _c.length) || 0;
|
|
23553
|
+
if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) {
|
|
23554
|
+
throw new Error("Multiple escaped blocks in format");
|
|
23555
|
+
}
|
|
23556
|
+
convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]'
|
|
23557
|
+
convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore width of next char for align purposes. Not supported ATM
|
|
23558
|
+
convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM
|
|
23559
|
+
convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces
|
|
23560
|
+
convertedFormat = convertedFormat.replace(/\\./g, (match) => match[1]); // unescape other characters
|
|
23561
|
+
if (isXlsxDateFormat(convertedFormat)) {
|
|
23562
|
+
convertedFormat = convertDateFormat$1(convertedFormat);
|
|
23563
|
+
}
|
|
23564
|
+
if (isFormatSupported(convertedFormat)) {
|
|
23565
|
+
return convertedFormat;
|
|
23566
|
+
}
|
|
23567
|
+
}
|
|
23568
|
+
catch (e) { }
|
|
23569
|
+
}
|
|
23570
|
+
warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
|
|
23571
|
+
return undefined;
|
|
23572
|
+
}
|
|
23573
|
+
function isFormatSupported(format) {
|
|
23574
|
+
try {
|
|
23575
|
+
formatValue(0, format);
|
|
23576
|
+
return true;
|
|
23577
|
+
}
|
|
23578
|
+
catch (e) {
|
|
23579
|
+
return false;
|
|
23580
|
+
}
|
|
23581
|
+
}
|
|
23582
|
+
function isXlsxDateFormat(format) {
|
|
23583
|
+
return format.match(XLSX_DATE_FORMAT_REGEX) !== null;
|
|
23584
|
+
}
|
|
23585
|
+
function convertDateFormat$1(format) {
|
|
23586
|
+
// Some of these aren't defined neither in the OpenXML spec not the Xlsx extension of OpenXML,
|
|
23587
|
+
// but can still occur and are supported by Excel/Google sheets
|
|
23588
|
+
format = format.toLowerCase();
|
|
23589
|
+
format = format.replace(/mmmmm/g, "mmm");
|
|
23590
|
+
format = format.replace(/am\/pm|a\/m/g, "a");
|
|
23591
|
+
format = format.replace(/hhhh/g, "hh");
|
|
23592
|
+
format = format.replace(/\bh\b/g, "hh");
|
|
23593
|
+
return format;
|
|
23594
|
+
}
|
|
23595
|
+
|
|
23433
23596
|
function convertBorders(data, warningManager) {
|
|
23434
23597
|
const borderArray = data.borders.map((border) => {
|
|
23435
23598
|
addBorderWarnings(border, warningManager);
|
|
@@ -23492,41 +23655,6 @@
|
|
|
23492
23655
|
}
|
|
23493
23656
|
return arrayToObject(formats, 1);
|
|
23494
23657
|
}
|
|
23495
|
-
/**
|
|
23496
|
-
* Convert excel format to o_spreadsheet format
|
|
23497
|
-
*
|
|
23498
|
-
* Excel format are defined in openXML §18.8.31
|
|
23499
|
-
*/
|
|
23500
|
-
function convertXlsxFormat(numFmtId, formats, warningManager) {
|
|
23501
|
-
var _a, _b, _c;
|
|
23502
|
-
if (numFmtId === 0) {
|
|
23503
|
-
return undefined;
|
|
23504
|
-
}
|
|
23505
|
-
// Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
|
|
23506
|
-
let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || ((_a = formats.find((f) => f.id === numFmtId)) === null || _a === void 0 ? void 0 : _a.format);
|
|
23507
|
-
if (format) {
|
|
23508
|
-
try {
|
|
23509
|
-
let convertedFormat = format.replace(/(.*?);.*/, "$1"); // only take first part of multi-part format
|
|
23510
|
-
convertedFormat = convertedFormat.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
|
|
23511
|
-
convertedFormat = convertedFormat.replace(/\[\$\]/g, ""); // remove empty bocks
|
|
23512
|
-
// Quotes in format escape sequences of characters. ATM we only support [$...] blocks to escape characters, and only one of them per format
|
|
23513
|
-
const numberOfQuotes = ((_b = convertedFormat.match(/"/g)) === null || _b === void 0 ? void 0 : _b.length) || 0;
|
|
23514
|
-
const numberOfOpenBrackets = ((_c = convertedFormat.match(/\[/g)) === null || _c === void 0 ? void 0 : _c.length) || 0;
|
|
23515
|
-
if (numberOfQuotes / 2 + numberOfOpenBrackets > 1) {
|
|
23516
|
-
throw new Error("Multiple escaped blocks in format");
|
|
23517
|
-
}
|
|
23518
|
-
convertedFormat = convertedFormat.replace(/"(.*)"/g, "[$$$1]"); // replace '"..."' by '[$...]'
|
|
23519
|
-
convertedFormat = convertedFormat.replace(/_.{1}/g, ""); // _ == ignore with of next char for align purposes. Not supported ATM
|
|
23520
|
-
convertedFormat = convertedFormat.replace(/\*.{1}/g, ""); // * == repeat next character enough to fill the line. Not supported ATM
|
|
23521
|
-
convertedFormat = convertedFormat.replace(/\\ /g, " "); // unescape spaces
|
|
23522
|
-
formatValue(0, convertedFormat);
|
|
23523
|
-
return convertedFormat;
|
|
23524
|
-
}
|
|
23525
|
-
catch (e) { }
|
|
23526
|
-
}
|
|
23527
|
-
warningManager.generateNotSupportedWarning(WarningTypes.NumFmtIdNotSupported, format || `nmFmtId ${numFmtId}`);
|
|
23528
|
-
return undefined;
|
|
23529
|
-
}
|
|
23530
23658
|
// ---------------------------------------------------------------------------
|
|
23531
23659
|
// Warnings
|
|
23532
23660
|
// ---------------------------------------------------------------------------
|
|
@@ -24081,16 +24209,18 @@
|
|
|
24081
24209
|
};
|
|
24082
24210
|
}
|
|
24083
24211
|
function convertChartData(chartData) {
|
|
24084
|
-
|
|
24085
|
-
const labelRange =
|
|
24086
|
-
|
|
24212
|
+
const dataSetsHaveTitle = chartData.dataSets[0].label !== undefined;
|
|
24213
|
+
const labelRange = chartData.labelRange
|
|
24214
|
+
? convertExcelRangeToSheetXC(chartData.labelRange, dataSetsHaveTitle)
|
|
24215
|
+
: undefined;
|
|
24216
|
+
let dataSets = chartData.dataSets.map((data) => convertExcelRangeToSheetXC(data.range, dataSetsHaveTitle));
|
|
24087
24217
|
// For doughnut charts, in chartJS first dataset = outer dataset, in excel first dataset = inner dataset
|
|
24088
24218
|
if (chartData.type === "pie") {
|
|
24089
24219
|
dataSets.reverse();
|
|
24090
24220
|
}
|
|
24091
24221
|
return {
|
|
24092
24222
|
dataSets,
|
|
24093
|
-
dataSetsHaveTitle
|
|
24223
|
+
dataSetsHaveTitle,
|
|
24094
24224
|
labelRange,
|
|
24095
24225
|
title: chartData.title || "",
|
|
24096
24226
|
type: chartData.type,
|
|
@@ -24101,6 +24231,28 @@
|
|
|
24101
24231
|
aggregated: false,
|
|
24102
24232
|
labelsAsText: false,
|
|
24103
24233
|
};
|
|
24234
|
+
}
|
|
24235
|
+
function convertExcelRangeToSheetXC(range, dataSetsHaveTitle) {
|
|
24236
|
+
let { sheetName, xc } = splitReference(range);
|
|
24237
|
+
if (sheetName) {
|
|
24238
|
+
sheetName = getCanonicalSheetName(sheetName) + "!";
|
|
24239
|
+
}
|
|
24240
|
+
else {
|
|
24241
|
+
sheetName = "";
|
|
24242
|
+
}
|
|
24243
|
+
let zone = toUnboundedZone(xc);
|
|
24244
|
+
if (dataSetsHaveTitle && zone.bottom !== undefined && zone.right !== undefined) {
|
|
24245
|
+
const height = zone.bottom - zone.top + 1;
|
|
24246
|
+
const width = zone.right - zone.left + 1;
|
|
24247
|
+
if (height === 1) {
|
|
24248
|
+
zone = { ...zone, left: zone.left - 1 };
|
|
24249
|
+
}
|
|
24250
|
+
else if (width === 1) {
|
|
24251
|
+
zone = { ...zone, top: zone.top - 1 };
|
|
24252
|
+
}
|
|
24253
|
+
}
|
|
24254
|
+
const dataXC = zoneToXc(zone);
|
|
24255
|
+
return sheetName + dataXC;
|
|
24104
24256
|
}
|
|
24105
24257
|
|
|
24106
24258
|
/**
|
|
@@ -25168,6 +25320,7 @@
|
|
|
25168
25320
|
title: chartTitle,
|
|
25169
25321
|
type: CHART_TYPE_CONVERSION_MAP[chartType],
|
|
25170
25322
|
dataSets: this.extractChartDatasets(this.querySelector(rootChartElement, `c:${chartType}`)),
|
|
25323
|
+
labelRange: this.extractChildTextContent(rootChartElement, "c:ser c:cat c:f"),
|
|
25171
25324
|
backgroundColor: this.extractChildAttr(rootChartElement, "c:chartSpace > c:spPr a:srgbClr", "val", {
|
|
25172
25325
|
default: "ffffff",
|
|
25173
25326
|
}).asString(),
|
|
@@ -25187,7 +25340,7 @@
|
|
|
25187
25340
|
extractChartDatasets(chartElement) {
|
|
25188
25341
|
return this.mapOnElements({ parent: chartElement, query: "c:ser" }, (chartDataElement) => {
|
|
25189
25342
|
return {
|
|
25190
|
-
label: this.extractChildTextContent(chartDataElement, "c:
|
|
25343
|
+
label: this.extractChildTextContent(chartDataElement, "c:tx c:f"),
|
|
25191
25344
|
range: this.extractChildTextContent(chartDataElement, "c:val c:f", { required: true }),
|
|
25192
25345
|
};
|
|
25193
25346
|
});
|
|
@@ -29104,6 +29257,39 @@
|
|
|
29104
29257
|
case "DELETE_FIGURE":
|
|
29105
29258
|
this.removeFigure(cmd.id, cmd.sheetId);
|
|
29106
29259
|
break;
|
|
29260
|
+
case "REMOVE_COLUMNS_ROWS":
|
|
29261
|
+
this.onRowColDelete(cmd.sheetId, cmd.dimension);
|
|
29262
|
+
}
|
|
29263
|
+
}
|
|
29264
|
+
onRowColDelete(sheetId, dimension) {
|
|
29265
|
+
dimension === "ROW" ? this.onRowDeletion(sheetId) : this.onColDeletion(sheetId);
|
|
29266
|
+
}
|
|
29267
|
+
onRowDeletion(sheetId) {
|
|
29268
|
+
const numHeader = this.getters.getNumberRows(sheetId);
|
|
29269
|
+
let gridHeight = 0;
|
|
29270
|
+
for (let i = 0; i < numHeader; i++) {
|
|
29271
|
+
gridHeight += this.getters.getRowSize(sheetId, i);
|
|
29272
|
+
}
|
|
29273
|
+
const figures = this.getters.getFigures(sheetId);
|
|
29274
|
+
for (const figure of figures) {
|
|
29275
|
+
const newY = Math.min(figure.y, gridHeight - figure.height);
|
|
29276
|
+
if (newY !== figure.y) {
|
|
29277
|
+
this.dispatch("UPDATE_FIGURE", { sheetId, id: figure.id, y: newY });
|
|
29278
|
+
}
|
|
29279
|
+
}
|
|
29280
|
+
}
|
|
29281
|
+
onColDeletion(sheetId) {
|
|
29282
|
+
const numHeader = this.getters.getNumberCols(sheetId);
|
|
29283
|
+
let gridWidth = 0;
|
|
29284
|
+
for (let i = 0; i < numHeader; i++) {
|
|
29285
|
+
gridWidth += this.getters.getColSize(sheetId, i);
|
|
29286
|
+
}
|
|
29287
|
+
const figures = this.getters.getFigures(sheetId);
|
|
29288
|
+
for (const figure of figures) {
|
|
29289
|
+
const newX = Math.min(figure.x, gridWidth - figure.width);
|
|
29290
|
+
if (newX !== figure.x) {
|
|
29291
|
+
this.dispatch("UPDATE_FIGURE", { sheetId, id: figure.id, x: newX });
|
|
29292
|
+
}
|
|
29107
29293
|
}
|
|
29108
29294
|
}
|
|
29109
29295
|
updateFigure(sheetId, figure) {
|
|
@@ -30774,7 +30960,7 @@
|
|
|
30774
30960
|
sheetName = rangeImpl.invalidSheetName;
|
|
30775
30961
|
}
|
|
30776
30962
|
else {
|
|
30777
|
-
sheetName =
|
|
30963
|
+
sheetName = getCanonicalSheetName(this.getters.getSheetName(rangeImpl.sheetId));
|
|
30778
30964
|
}
|
|
30779
30965
|
}
|
|
30780
30966
|
if (prefixSheet && !sheetName) {
|
|
@@ -31825,9 +32011,7 @@
|
|
|
31825
32011
|
// remove duplicates first to check validity on a reduced
|
|
31826
32012
|
// set of colors, then normalize to HEX and remove duplicates
|
|
31827
32013
|
// again
|
|
31828
|
-
[...new Set([...usedColors, ...this.customColors])]
|
|
31829
|
-
.filter(isColorValid)
|
|
31830
|
-
.map((c) => toHex(c).toLowerCase())),
|
|
32014
|
+
[...new Set([...usedColors, ...this.customColors])].filter(isColorValid).map(toHex)),
|
|
31831
32015
|
]).filter((color) => !COLOR_PICKER_DEFAULTS.includes(color));
|
|
31832
32016
|
}
|
|
31833
32017
|
getColorsFromCells(cells) {
|
|
@@ -31888,7 +32072,7 @@
|
|
|
31888
32072
|
return [...chartsColors];
|
|
31889
32073
|
}
|
|
31890
32074
|
tryToAddColor(color) {
|
|
31891
|
-
const formattedColor = toHex(color)
|
|
32075
|
+
const formattedColor = toHex(color);
|
|
31892
32076
|
if (color && !COLOR_PICKER_DEFAULTS.includes(formattedColor)) {
|
|
31893
32077
|
this.customColors.add(formattedColor);
|
|
31894
32078
|
}
|
|
@@ -32903,8 +33087,8 @@
|
|
|
32903
33087
|
this.getters = getters;
|
|
32904
33088
|
this.sheetId = sheetId;
|
|
32905
33089
|
this.boundaries = boundaries;
|
|
32906
|
-
this.
|
|
32907
|
-
this.
|
|
33090
|
+
this.viewportWidth = sizeInGrid.width;
|
|
33091
|
+
this.viewportHeight = sizeInGrid.height;
|
|
32908
33092
|
this.offsetScrollbarX = offsets.x;
|
|
32909
33093
|
this.offsetScrollbarY = offsets.y;
|
|
32910
33094
|
this.canScrollVertically = options.canScrollVertically;
|
|
@@ -32915,6 +33099,10 @@
|
|
|
32915
33099
|
this.adjustViewportOffsetY();
|
|
32916
33100
|
}
|
|
32917
33101
|
// PUBLIC
|
|
33102
|
+
/** Returns the maximum size (in Pixels) of the viewport relative to its allocated client size
|
|
33103
|
+
* When the viewport grid size is smaller than its client width (resp. height), it will return
|
|
33104
|
+
* the client width (resp. height).
|
|
33105
|
+
*/
|
|
32918
33106
|
getMaxSize() {
|
|
32919
33107
|
const lastCol = this.getters.findLastVisibleColRowIndex(this.sheetId, "COL", {
|
|
32920
33108
|
first: this.boundaries.left,
|
|
@@ -32926,20 +33114,24 @@
|
|
|
32926
33114
|
});
|
|
32927
33115
|
const { end: lastColEnd, size: lastColSize } = this.getters.getColDimensions(this.sheetId, lastCol);
|
|
32928
33116
|
const { end: lastRowEnd, size: lastRowSize } = this.getters.getRowDimensions(this.sheetId, lastRow);
|
|
32929
|
-
const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.
|
|
33117
|
+
const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.viewportWidth, 0);
|
|
32930
33118
|
const leftColSize = this.getters.getColSize(this.sheetId, leftColIndex);
|
|
32931
|
-
const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.
|
|
33119
|
+
const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.viewportHeight, 0);
|
|
32932
33120
|
const topRowSize = this.getters.getRowSize(this.sheetId, leftRowIndex);
|
|
32933
|
-
|
|
32934
|
-
|
|
32935
|
-
(
|
|
32936
|
-
|
|
32937
|
-
|
|
32938
|
-
|
|
32939
|
-
|
|
32940
|
-
|
|
32941
|
-
|
|
32942
|
-
|
|
33121
|
+
let width = lastColEnd - this.offsetCorrectionX;
|
|
33122
|
+
if (this.canScrollHorizontally) {
|
|
33123
|
+
width += Math.max(DEFAULT_CELL_WIDTH, // leave some minimal space to let the user know they scrolled all the way
|
|
33124
|
+
Math.min(leftColSize, this.viewportWidth - lastColSize) // Add pixels that allows the snapping at maximum horizontal scroll
|
|
33125
|
+
);
|
|
33126
|
+
width = Math.max(width, this.viewportWidth); // if the viewport grid size is smaller than its client width, return client width
|
|
33127
|
+
}
|
|
33128
|
+
let height = lastRowEnd - this.offsetCorrectionY;
|
|
33129
|
+
if (this.canScrollVertically) {
|
|
33130
|
+
height += Math.max(DEFAULT_CELL_HEIGHT + 5, // leave some space to let the user know they scrolled all the way
|
|
33131
|
+
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
33132
|
+
);
|
|
33133
|
+
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
33134
|
+
}
|
|
32943
33135
|
return { width, height };
|
|
32944
33136
|
}
|
|
32945
33137
|
/**
|
|
@@ -32948,7 +33140,7 @@
|
|
|
32948
33140
|
* It returns -1 if no column is found.
|
|
32949
33141
|
*/
|
|
32950
33142
|
getColIndex(x, absolute = false) {
|
|
32951
|
-
if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.
|
|
33143
|
+
if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.viewportWidth) {
|
|
32952
33144
|
return -1;
|
|
32953
33145
|
}
|
|
32954
33146
|
return this.searchHeaderIndex("COL", x - this.offsetCorrectionX, this.left, absolute);
|
|
@@ -32959,7 +33151,7 @@
|
|
|
32959
33151
|
* It returns -1 if no row is found.
|
|
32960
33152
|
*/
|
|
32961
33153
|
getRowIndex(y, absolute = false) {
|
|
32962
|
-
if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.
|
|
33154
|
+
if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.viewportHeight) {
|
|
32963
33155
|
return -1;
|
|
32964
33156
|
}
|
|
32965
33157
|
return this.searchHeaderIndex("ROW", y - this.offsetCorrectionY, this.top, absolute);
|
|
@@ -32986,7 +33178,7 @@
|
|
|
32986
33178
|
adjustPositionX(col) {
|
|
32987
33179
|
const sheetId = this.sheetId;
|
|
32988
33180
|
const { start, end } = this.getters.getColDimensions(sheetId, col);
|
|
32989
|
-
while (end > this.offsetX + this.offsetCorrectionX + this.
|
|
33181
|
+
while (end > this.offsetX + this.offsetCorrectionX + this.viewportWidth &&
|
|
32990
33182
|
this.offsetX + this.offsetCorrectionX < start) {
|
|
32991
33183
|
this.offsetX = this.getters.getColDimensions(sheetId, this.left).end - this.offsetCorrectionX;
|
|
32992
33184
|
this.offsetScrollbarX = this.offsetX;
|
|
@@ -33008,7 +33200,7 @@
|
|
|
33008
33200
|
adjustPositionY(row) {
|
|
33009
33201
|
const sheetId = this.sheetId;
|
|
33010
33202
|
while (this.getters.getRowDimensions(sheetId, row).end >
|
|
33011
|
-
this.offsetY + this.
|
|
33203
|
+
this.offsetY + this.viewportHeight + this.offsetCorrectionY &&
|
|
33012
33204
|
this.offsetY + this.offsetCorrectionY < this.getters.getRowDimensions(sheetId, row).start) {
|
|
33013
33205
|
this.offsetY = this.getters.getRowDimensions(sheetId, this.top).end - this.offsetCorrectionY;
|
|
33014
33206
|
this.offsetScrollbarY = this.offsetY;
|
|
@@ -33046,8 +33238,8 @@
|
|
|
33046
33238
|
const x = this.getters.getColRowOffset("COL", this.zone.left, targetZone.left) +
|
|
33047
33239
|
this.offsetCorrectionX;
|
|
33048
33240
|
const y = this.getters.getColRowOffset("ROW", this.zone.top, targetZone.top) + this.offsetCorrectionY;
|
|
33049
|
-
const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.
|
|
33050
|
-
const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.
|
|
33241
|
+
const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
|
|
33242
|
+
const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
|
|
33051
33243
|
return {
|
|
33052
33244
|
x,
|
|
33053
33245
|
y,
|
|
@@ -33110,12 +33302,12 @@
|
|
|
33110
33302
|
adjustViewportOffsetX() {
|
|
33111
33303
|
if (this.canScrollHorizontally) {
|
|
33112
33304
|
const { width: viewportWidth } = this.getMaxSize();
|
|
33113
|
-
if (this.
|
|
33114
|
-
this.offsetScrollbarX = Math.max(0, viewportWidth - this.
|
|
33305
|
+
if (this.viewportWidth + this.offsetScrollbarX > viewportWidth) {
|
|
33306
|
+
this.offsetScrollbarX = Math.max(0, viewportWidth - this.viewportWidth);
|
|
33115
33307
|
}
|
|
33116
33308
|
}
|
|
33117
33309
|
this.left = this.getColIndex(this.offsetScrollbarX, true);
|
|
33118
|
-
this.right = this.getColIndex(this.offsetScrollbarX + this.
|
|
33310
|
+
this.right = this.getColIndex(this.offsetScrollbarX + this.viewportWidth, true);
|
|
33119
33311
|
if (this.right === -1) {
|
|
33120
33312
|
this.right = this.boundaries.right;
|
|
33121
33313
|
}
|
|
@@ -33127,12 +33319,12 @@
|
|
|
33127
33319
|
adjustViewportOffsetY() {
|
|
33128
33320
|
if (this.canScrollVertically) {
|
|
33129
33321
|
const { height: paneHeight } = this.getMaxSize();
|
|
33130
|
-
if (this.
|
|
33131
|
-
this.offsetScrollbarY = Math.max(0, paneHeight - this.
|
|
33322
|
+
if (this.viewportHeight + this.offsetScrollbarY > paneHeight) {
|
|
33323
|
+
this.offsetScrollbarY = Math.max(0, paneHeight - this.viewportHeight);
|
|
33132
33324
|
}
|
|
33133
33325
|
}
|
|
33134
33326
|
this.top = this.getRowIndex(this.offsetScrollbarY, true);
|
|
33135
|
-
this.bottom = this.getRowIndex(this.offsetScrollbarY + this.
|
|
33327
|
+
this.bottom = this.getRowIndex(this.offsetScrollbarY + this.viewportWidth, true);
|
|
33136
33328
|
if (this.bottom === -1) {
|
|
33137
33329
|
this.bottom = this.boundaries.bottom;
|
|
33138
33330
|
}
|
|
@@ -33143,7 +33335,7 @@
|
|
|
33143
33335
|
adjustViewportZoneX() {
|
|
33144
33336
|
const sheetId = this.sheetId;
|
|
33145
33337
|
this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
|
|
33146
|
-
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.
|
|
33338
|
+
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
|
|
33147
33339
|
if (this.right === -1) {
|
|
33148
33340
|
this.right = this.getters.getNumberCols(sheetId) - 1;
|
|
33149
33341
|
}
|
|
@@ -33156,7 +33348,7 @@
|
|
|
33156
33348
|
adjustViewportZoneY() {
|
|
33157
33349
|
const sheetId = this.sheetId;
|
|
33158
33350
|
this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
|
|
33159
|
-
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.
|
|
33351
|
+
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
|
|
33160
33352
|
if (this.bottom === -1) {
|
|
33161
33353
|
this.bottom = this.getters.getNumberRows(sheetId) - 1;
|
|
33162
33354
|
}
|
|
@@ -33419,8 +33611,7 @@
|
|
|
33419
33611
|
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
33420
33612
|
}
|
|
33421
33613
|
/**
|
|
33422
|
-
* Return the main viewport maximum size
|
|
33423
|
-
* with some bottom and right padding.
|
|
33614
|
+
* Return the main viewport maximum size relative to the client size.
|
|
33424
33615
|
*/
|
|
33425
33616
|
getMainViewportRect() {
|
|
33426
33617
|
const sheetId = this.getters.getActiveSheetId();
|
|
@@ -33436,8 +33627,8 @@
|
|
|
33436
33627
|
const { width, height } = this.getMainViewportRect();
|
|
33437
33628
|
const viewport = this.getMainInternalViewport(sheetId);
|
|
33438
33629
|
return {
|
|
33439
|
-
maxOffsetX: Math.max(0, width - viewport.
|
|
33440
|
-
maxOffsetY: Math.max(0, height - viewport.
|
|
33630
|
+
maxOffsetX: Math.max(0, width - viewport.viewportWidth + 1),
|
|
33631
|
+
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
33441
33632
|
};
|
|
33442
33633
|
}
|
|
33443
33634
|
getColRowOffsetInViewport(dimension, referenceIndex, index) {
|
|
@@ -35657,7 +35848,7 @@
|
|
|
35657
35848
|
const inputSheetId = this.activeSheet;
|
|
35658
35849
|
const sheetId = this.getters.getActiveSheetId();
|
|
35659
35850
|
const sheetName = this.getters.getSheetName(sheetId);
|
|
35660
|
-
this.add([sheetId === inputSheetId ? xc : `${
|
|
35851
|
+
this.add([sheetId === inputSheetId ? xc : `${getCanonicalSheetName(sheetName)}!${xc}`]);
|
|
35661
35852
|
}
|
|
35662
35853
|
handle(cmd) {
|
|
35663
35854
|
switch (cmd.type) {
|
|
@@ -37904,13 +38095,19 @@
|
|
|
37904
38095
|
*/
|
|
37905
38096
|
paste(target) {
|
|
37906
38097
|
const sheetId = this.getters.getActiveSheetId();
|
|
38098
|
+
const { width, height } = this.copiedFigure;
|
|
38099
|
+
const numCols = this.getters.getNumberCols(sheetId);
|
|
38100
|
+
const numRows = this.getters.getNumberRows(sheetId);
|
|
38101
|
+
const targetX = this.getters.getColDimensions(sheetId, target[0].left).start;
|
|
38102
|
+
const targetY = this.getters.getRowDimensions(sheetId, target[0].top).start;
|
|
38103
|
+
const maxX = this.getters.getColDimensions(sheetId, numCols - 1).end;
|
|
38104
|
+
const maxY = this.getters.getRowDimensions(sheetId, numRows - 1).end;
|
|
37907
38105
|
const position = {
|
|
37908
|
-
x:
|
|
37909
|
-
y:
|
|
38106
|
+
x: maxX < width ? 0 : Math.min(targetX, maxX - width),
|
|
38107
|
+
y: maxY < height ? 0 : Math.min(targetY, maxY - height),
|
|
37910
38108
|
};
|
|
37911
|
-
const size = { height: this.copiedFigure.height, width: this.copiedFigure.width };
|
|
37912
38109
|
const newId = new UuidGenerator().uuidv4();
|
|
37913
|
-
this.copiedFigureContent.paste(sheetId, newId, position,
|
|
38110
|
+
this.copiedFigureContent.paste(sheetId, newId, position, { height, width });
|
|
37914
38111
|
if (this.operation === "CUT") {
|
|
37915
38112
|
this.dispatch("DELETE_FIGURE", {
|
|
37916
38113
|
sheetId: this.copiedFigureContent.sheetId,
|
|
@@ -38276,7 +38473,7 @@
|
|
|
38276
38473
|
return token;
|
|
38277
38474
|
const { xc, sheetName } = splitReference(token.value);
|
|
38278
38475
|
const [left, right] = xc.split(":");
|
|
38279
|
-
const sheetRef = sheetName ? `${
|
|
38476
|
+
const sheetRef = sheetName ? `${getCanonicalSheetName(sheetName)}!` : "";
|
|
38280
38477
|
const updatedLeft = getTokenNextReferenceType(left);
|
|
38281
38478
|
const updatedRight = right ? `:${getTokenNextReferenceType(right)}` : "";
|
|
38282
38479
|
return { ...token, value: sheetRef + updatedLeft + updatedRight };
|
|
@@ -38535,9 +38732,6 @@
|
|
|
38535
38732
|
}
|
|
38536
38733
|
return this.currentContent;
|
|
38537
38734
|
}
|
|
38538
|
-
getEditionSheet() {
|
|
38539
|
-
return this.sheetId;
|
|
38540
|
-
}
|
|
38541
38735
|
getComposerSelection() {
|
|
38542
38736
|
return {
|
|
38543
38737
|
start: this.selectionStart,
|
|
@@ -38821,8 +39015,8 @@
|
|
|
38821
39015
|
getZoneReference(zone, fixedParts = [{ colFixed: false, rowFixed: false }]) {
|
|
38822
39016
|
const sheetId = this.getters.getActiveSheetId();
|
|
38823
39017
|
let selectedXc = this.getters.zoneToXC(sheetId, zone, fixedParts);
|
|
38824
|
-
if (this.getters.
|
|
38825
|
-
const sheetName =
|
|
39018
|
+
if (this.getters.getCurrentEditedCell().sheetId !== this.getters.getActiveSheetId()) {
|
|
39019
|
+
const sheetName = getCanonicalSheetName(this.getters.getSheetName(this.getters.getActiveSheetId()));
|
|
38826
39020
|
selectedXc = `${sheetName}!${selectedXc}`;
|
|
38827
39021
|
}
|
|
38828
39022
|
return selectedXc;
|
|
@@ -38836,7 +39030,7 @@
|
|
|
38836
39030
|
_fixedParts.pop();
|
|
38837
39031
|
}
|
|
38838
39032
|
const newRange = range.clone({ parts: _fixedParts });
|
|
38839
|
-
return this.getters.getSelectionRangeString(newRange, this.getters.
|
|
39033
|
+
return this.getters.getSelectionRangeString(newRange, this.getters.getCurrentEditedCell().sheetId);
|
|
38840
39034
|
}
|
|
38841
39035
|
/**
|
|
38842
39036
|
* Replace the current selection by a new text.
|
|
@@ -38869,7 +39063,7 @@
|
|
|
38869
39063
|
if (!this.currentContent.startsWith("=") || this.mode === "inactive") {
|
|
38870
39064
|
return;
|
|
38871
39065
|
}
|
|
38872
|
-
const editionSheetId = this.getters.
|
|
39066
|
+
const editionSheetId = this.getters.getCurrentEditedCell().sheetId;
|
|
38873
39067
|
const XCs = this.getReferencedRanges().map((range) => this.getters.getRangeString(range, editionSheetId));
|
|
38874
39068
|
const colorsToKeep = {};
|
|
38875
39069
|
for (const xc of XCs) {
|
|
@@ -38898,7 +39092,7 @@
|
|
|
38898
39092
|
if (!this.currentContent.startsWith("=") || this.mode === "inactive") {
|
|
38899
39093
|
return [];
|
|
38900
39094
|
}
|
|
38901
|
-
const editionSheetId = this.getters.
|
|
39095
|
+
const editionSheetId = this.getters.getCurrentEditedCell().sheetId;
|
|
38902
39096
|
const rangeColor = (rangeString) => {
|
|
38903
39097
|
const colorIndex = this.colorIndexByRange[rangeString];
|
|
38904
39098
|
return colors$1[colorIndex % colors$1.length];
|
|
@@ -38916,7 +39110,7 @@
|
|
|
38916
39110
|
* Return ranges currently referenced in the composer
|
|
38917
39111
|
*/
|
|
38918
39112
|
getReferencedRanges() {
|
|
38919
|
-
const editionSheetId = this.getters.
|
|
39113
|
+
const editionSheetId = this.getters.getCurrentEditedCell().sheetId;
|
|
38920
39114
|
return this.currentTokens
|
|
38921
39115
|
.filter((token) => token.type === "REFERENCE")
|
|
38922
39116
|
.map((token) => this.getters.getRangeFromSheetXC(editionSheetId, token.value));
|
|
@@ -38975,7 +39169,6 @@
|
|
|
38975
39169
|
"isSelectingForComposer",
|
|
38976
39170
|
"showSelectionIndicator",
|
|
38977
39171
|
"getCurrentContent",
|
|
38978
|
-
"getEditionSheet",
|
|
38979
39172
|
"getComposerSelection",
|
|
38980
39173
|
"getCurrentTokens",
|
|
38981
39174
|
"getTokenAtCursor",
|
|
@@ -40298,10 +40491,6 @@
|
|
|
40298
40491
|
.o-bottom-bar-arrows {
|
|
40299
40492
|
.o-bottom-bar-arrow {
|
|
40300
40493
|
cursor: pointer;
|
|
40301
|
-
&.o-disabled {
|
|
40302
|
-
opacity: 0.4;
|
|
40303
|
-
cursor: default;
|
|
40304
|
-
}
|
|
40305
40494
|
&:hover:not([class*="o-disabled"]) {
|
|
40306
40495
|
.o-icon {
|
|
40307
40496
|
opacity: 0.9;
|
|
@@ -41139,11 +41328,6 @@
|
|
|
41139
41328
|
margin: 0 6px;
|
|
41140
41329
|
}
|
|
41141
41330
|
|
|
41142
|
-
.o-disabled {
|
|
41143
|
-
opacity: 0.6;
|
|
41144
|
-
cursor: default;
|
|
41145
|
-
}
|
|
41146
|
-
|
|
41147
41331
|
.o-dropdown {
|
|
41148
41332
|
position: relative;
|
|
41149
41333
|
display: flex;
|
|
@@ -41518,10 +41702,12 @@
|
|
|
41518
41702
|
button {
|
|
41519
41703
|
color: #333;
|
|
41520
41704
|
}
|
|
41521
|
-
|
|
41522
|
-
|
|
41523
|
-
|
|
41705
|
+
.o-disabled {
|
|
41706
|
+
opacity: 0.4;
|
|
41707
|
+
pointer: default;
|
|
41708
|
+
pointer-events: none;
|
|
41524
41709
|
}
|
|
41710
|
+
|
|
41525
41711
|
&,
|
|
41526
41712
|
*,
|
|
41527
41713
|
*:before,
|
|
@@ -44890,6 +45076,13 @@
|
|
|
44890
45076
|
* Internal status of the model. Important for command handling coordination
|
|
44891
45077
|
*/
|
|
44892
45078
|
this.status = 0 /* Status.Ready */;
|
|
45079
|
+
/**
|
|
45080
|
+
* Check if a command can be dispatched, and returns a DispatchResult object with the possible
|
|
45081
|
+
* reasons the dispatch failed.
|
|
45082
|
+
*/
|
|
45083
|
+
this.canDispatch = (type, payload) => {
|
|
45084
|
+
return this.checkDispatchAllowed({ ...payload, type });
|
|
45085
|
+
};
|
|
44893
45086
|
/**
|
|
44894
45087
|
* The dispatch method is the only entry point to manipulate data in the model.
|
|
44895
45088
|
* This is through this method that commands are dispatched most of the time
|
|
@@ -45033,7 +45226,10 @@
|
|
|
45033
45226
|
owl.markRaw(this);
|
|
45034
45227
|
}
|
|
45035
45228
|
get handlers() {
|
|
45036
|
-
return [
|
|
45229
|
+
return [...this.coreHandlers, ...this.allUIPlugins, this.history];
|
|
45230
|
+
}
|
|
45231
|
+
get coreHandlers() {
|
|
45232
|
+
return [this.range, ...this.corePlugins];
|
|
45037
45233
|
}
|
|
45038
45234
|
get allUIPlugins() {
|
|
45039
45235
|
return [...this.statefulUIPlugins, ...this.coreViewsPlugins, ...this.featurePlugins];
|
|
@@ -45161,6 +45357,16 @@
|
|
|
45161
45357
|
* Check if the given command is allowed by all the plugins and the history.
|
|
45162
45358
|
*/
|
|
45163
45359
|
checkDispatchAllowed(command) {
|
|
45360
|
+
if (isCoreCommand(command)) {
|
|
45361
|
+
return this.checkDispatchAllowedCoreCommand(command);
|
|
45362
|
+
}
|
|
45363
|
+
return this.checkDispatchAllowedLocalCommand(command);
|
|
45364
|
+
}
|
|
45365
|
+
checkDispatchAllowedCoreCommand(command) {
|
|
45366
|
+
const results = this.coreHandlers.map((handler) => handler.allowDispatch(command));
|
|
45367
|
+
return new DispatchResult(results.flat());
|
|
45368
|
+
}
|
|
45369
|
+
checkDispatchAllowedLocalCommand(command) {
|
|
45164
45370
|
const results = this.handlers.map((handler) => handler.allowDispatch(command));
|
|
45165
45371
|
return new DispatchResult(results.flat());
|
|
45166
45372
|
}
|
|
@@ -45391,9 +45597,9 @@
|
|
|
45391
45597
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
45392
45598
|
|
|
45393
45599
|
|
|
45394
|
-
__info__.version = '16.3.0-alpha.
|
|
45395
|
-
__info__.date = '2023-
|
|
45396
|
-
__info__.hash = '
|
|
45600
|
+
__info__.version = '16.3.0-alpha.3';
|
|
45601
|
+
__info__.date = '2023-04-13T08:30:41.165Z';
|
|
45602
|
+
__info__.hash = '573e679';
|
|
45397
45603
|
|
|
45398
45604
|
|
|
45399
45605
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|