UNPKG

@univerjs/sheets-ui

Version:

Spreadsheet UI layer for Univer Sheets.

846 lines (833 loc) 1.59 MB
import { BreakLineCommand, CoverContentCommand, DOCS_COMPONENT_MAIN_LAYER_INDEX, DOCS_VIEW_KEY, DOC_VERTICAL_PADDING, DeleteLeftCommand, DeleteRightCommand, DocSelectionRenderService, IEditorService, IMEInputCommand, InsertCommand, MoveCursorOperation, MoveSelectionOperation, NodePositionConvertToCursor, ReplaceSnapshotCommand, SetInlineFormatBoldCommand, SetInlineFormatCommand, SetInlineFormatFontFamilyCommand, SetInlineFormatFontSizeCommand, SetInlineFormatItalicCommand, SetInlineFormatStrikethroughCommand, SetInlineFormatSubscriptCommand, SetInlineFormatSuperscriptCommand, SetInlineFormatTextColorCommand, SetInlineFormatUnderlineCommand, VIEWPORT_KEY, convertBodyToHtml, getCanvasOffsetByEngine, getLineBounding } from "@univerjs/docs-ui"; import { AbsoluteRefType, BaselineOffset, BooleanNumber, BorderStyleTypes, CellModeEnum, CellValueType, ColorKit, CommandType, CustomRangeType, DEFAULT_EMPTY_DOCUMENT_VALUE, DEFAULT_STYLES, DEFAULT_WORKSHEET_COLUMN_COUNT, DEFAULT_WORKSHEET_COLUMN_WIDTH, DEFAULT_WORKSHEET_COLUMN_WIDTH_KEY, DEFAULT_WORKSHEET_ROW_COUNT, DEFAULT_WORKSHEET_ROW_HEIGHT, DOCS_FORMULA_BAR_EDITOR_UNIT_ID_KEY, DOCS_NORMAL_EDITOR_UNIT_ID_KEY, DataStreamTreeTokenType, DependentOn, Direction, Disposable, DisposableCollection, DocumentFlavor, EDITOR_ACTIVATED, ErrorService, FOCUSING_COMMENT_EDITOR, FOCUSING_COMMON_DRAWINGS, FOCUSING_EDITOR_BUT_HIDDEN, FOCUSING_EDITOR_INPUT_FORMULA, FOCUSING_EDITOR_STANDALONE, FOCUSING_FX_BAR_EDITOR, FOCUSING_SHAPE_TEXT_EDITOR, FOCUSING_SHEET, FOCUSING_UNIVER_EDITOR, FontItalic, FontWeight, HorizontalAlign, IAuthzIoService, ICommandService, IConfigService, IConfirmService, IContextService, ILogService, IPermissionService, IUndoRedoService, IUniverInstanceService, Inject, Injector, InterceptorEffectEnum, InterceptorManager, LRUMap, LocaleService, LocaleType, NilCommand, ObjectMatrix, Optional, Plugin, PresetListType, Quantity, RANGE_TYPE, Range, Rectangle, RxDisposable, ThemeService, Tools, UndoCommandId, UniverInstanceType, UserManagerService, VerticalAlign, Workbook, WrapStrategy, cloneCellData, cloneCellDataMatrix, cloneCellDataWithSpanAndDisplay, cloneValue, composeStyles, convertCellToRange, createIdentifier, createInterceptorKey, dateKit, debounce, extractPureTextFromCell, fromEventSubject, generateRandomId, get, getEmptyCell, getNumfmtParseValueFilter, getReverseDirection, handleStyleToString, isFormulaString, isNotNullOrUndefined, isRealNum, isSafeUrl, isTextFormat, isValidRange, merge, mergeOverrideWithDependencies, nameCharacterCheck, numfmt, registerDependencies, sequenceExecute, set, skipParseTagNames, sortRules, splitIntoGrid, throttle, toDisposable, touchDependencies, willLoseNumericPrecision } from "@univerjs/core"; import { AnchoredContextMenu, BuiltInUIPart, COLOR_PICKER_COMPONENT, ComponentContainer, ComponentManager, ContextMenuGroup, ContextMenuPosition, CopyCommand, CutCommand, DISABLE_AUTO_FOCUS_KEY, FILE_PNG_CLIPBOARD_MIME_TYPE, FILE__BMP_CLIPBOARD_MIME_TYPE, FILE__JPEG_CLIPBOARD_MIME_TYPE, FILE__WEBP_CLIPBOARD_MIME_TYPE, FONT_FAMILY_COMPONENT, FONT_FAMILY_ITEM_COMPONENT, FONT_SIZE_COMPONENT, FONT_SIZE_LIST, HTML_CLIPBOARD_MIME_TYPE, ICanvasPopupService, IClipboardInterfaceService, IContextMenuService, IDialogService, ILayoutService, IMenuManagerService, IMessageService, INotificationService, IPlatformService, IShortcutService, ISidebarService, IUIPartsService, IZenZoneService, KeyCode, MenuItemType, MetaKeys, PLAIN_TEXT_CLIPBOARD_MIME_TYPE, PasteCommand, RibbonDataGroup, RibbonPosition, RibbonStartGroup, SheetPasteShortKeyCommandName, Slider, ToolbarItem, UI_PLUGIN_CONFIG_KEY, UniverMobileUIPlugin, connectInjector, getMenuHiddenObservable, handleStringToStyle, imageMimeTypeSet, sanitizeParsedHtml, textTrim, useComponentsOfPart, useConfigValue, useDependency, useEvent, useObservable, useSidebarClick, useVirtualList } from "@univerjs/ui"; import { CURSOR_TYPE, DEFAULT_PADDING_DATA, DashedRect, DeviceInputEventType, FIX_ONE_PIXEL_BLUR_OFFSET, Group, IRenderManagerService, Layer, RENDER_CLASS_TYPE, RENDER_RAW_FORMULA_KEY, Rect, RegularPolygon, SHEET_EXTENSION_PREFIX, SHEET_VIEWPORT_KEY, ScrollBar, ScrollTimer, ScrollTimerType, Shape, SheetExtension, Spreadsheet, SpreadsheetColumnHeader, SpreadsheetRowHeader, TRANSFORM_CHANGE_OBSERVABLE_TYPE, Vector2, Viewport, cancelRequestFrame, convertTextRotation, convertTransformToOffsetX, convertTransformToOffsetY, fixLineWidthByScale, getCurrentTypeOfRenderer, getNextWheelZoomRatio, ptToPixel, requestNewFrame, withCurrentTypeOfRenderer } from "@univerjs/engine-render"; import { AUTO_FILL_APPLY_TYPE, AUTO_FILL_HOOK_TYPE, AddMergeUndoMutationFactory, AddRangeProtectionCommand, AddRangeProtectionMutation, AddWorksheetMergeAllCommand, AddWorksheetMergeCommand, AddWorksheetMergeHorizontalCommand, AddWorksheetMergeMutation, AddWorksheetMergeVerticalCommand, AddWorksheetProtectionCommand, AutoClearContentCommand, AutoFillCommand, AutoFillController, BEFORE_CELL_EDIT, BorderStyleManagerService, COMMAND_LISTENER_SKELETON_CHANGE, COMMAND_LISTENER_VALUE_CHANGE, CancelFrozenCommand, CancelMarkDirtyRowAutoHeightOperation, ClearSelectionAllCommand, ClearSelectionContentCommand, ClearSelectionFormatCommand, CopySheetCommand, DeleteRangeMoveLeftCommand, DeleteRangeMoveUpCommand, DeleteRangeProtectionCommand, DeleteRangeProtectionMutation, DeleteWorksheetProtectionCommand, DeltaColumnWidthCommand, DeltaRowHeightCommand, EditStateEnum, IAutoFillService, IExclusiveRangeService, INTERCEPTOR_POINT, INumfmtService, IRefSelectionsService, InsertColBeforeCommand, InsertColCommand, InsertColMutation, InsertDefinedNameCommand, InsertMultiColsLeftCommand, InsertMultiColsRightCommand, InsertMultiRowsAboveCommand, InsertMultiRowsAfterCommand, InsertRangeMoveDownCommand, InsertRangeMoveRightCommand, InsertRowBeforeCommand, InsertRowCommand, InsertRowMutation, InsertSheetCommand, InsertSheetMutation, MAX_CELL_PER_SHEET_KEY, MERGE_CELL_INTERCEPTOR_CHECK, MarkDirtyRowAutoHeightOperation, MergeCellController, MoveColsCommand, MoveColsMutation, MoveRangeCommand, MoveRangeMutation, MoveRowsCommand, MoveRowsMutation, REF_SELECTIONS_ENABLED, RangeProtectionCache, RangeProtectionPermissionEditPoint, RangeProtectionPermissionViewPoint, RangeProtectionRuleModel, RefRangeService, RefSelectionsService, RefillCommand, RemoveColCommand, RemoveColMutation, RemoveDefinedNameCommand, RemoveMergeUndoMutationFactory, RemoveRowCommand, RemoveRowMutation, RemoveSheetCommand, RemoveSheetMutation, RemoveWorksheetMergeCommand, RemoveWorksheetMergeMutation, ResetBackgroundColorCommand, ResetTextColorCommand, SCOPE_WORKBOOK_VALUE_DEFINED_NAME, SELECTIONS_ENABLED, SELECTION_CONTROL_BORDER_BUFFER_COLOR, SELECTION_CONTROL_BORDER_BUFFER_WIDTH, SHEETS_PLUGIN_CONFIG_KEY, ScrollToCellOperation, SelectionMoveType, SetBackgroundColorCommand, SetBoldCommand, SetBorderBasicCommand, SetBorderCommand, SetColHiddenCommand, SetColHiddenMutation, SetColVisibleMutation, SetColWidthCommand, SetDefinedNameCommand, SetFontFamilyCommand, SetFontSizeCommand, SetFrozenCommand, SetFrozenMutation, SetFrozenMutationFactory, SetHorizontalTextAlignCommand, SetItalicCommand, SetProtectionCommand, SetRangeValuesCommand, SetRangeValuesMutation, SetRangeValuesUndoMutationFactory, SetRowHeightCommand, SetRowHiddenCommand, SetRowHiddenMutation, SetRowVisibleMutation, SetSelectedColsVisibleCommand, SetSelectedRowsVisibleCommand, SetSelectionsOperation, SetSpecificColsVisibleCommand, SetSpecificRowsVisibleCommand, SetStrikeThroughCommand, SetStyleCommand, SetTabColorCommand, SetTabColorMutation, SetTextColorCommand, SetTextRotationCommand, SetTextWrapCommand, SetUnderlineCommand, SetVerticalTextAlignCommand, SetWorksheetActivateCommand, SetWorksheetActiveOperation, SetWorksheetColWidthMutation, SetWorksheetColWidthMutationFactory, SetWorksheetHideCommand, SetWorksheetHideMutation, SetWorksheetNameCommand, SetWorksheetNameMutation, SetWorksheetOrderCommand, SetWorksheetOrderMutation, SetWorksheetPermissionPointsCommand, SetWorksheetRowAutoHeightMutation, SetWorksheetRowAutoHeightMutationFactory, SetWorksheetRowHeightMutation, SetWorksheetRowIsAutoHeightCommand, SetWorksheetRowIsAutoHeightMutation, SetWorksheetShowCommand, SheetCopyDownCommand, SheetCopyDownCommand as SheetCopyDownCommand$1, SheetCopyRightCommand, SheetCopyRightCommand as SheetCopyRightCommand$1, SheetInterceptorService, SheetPermissionCheckController, SheetPermissionInitController, SheetSkeletonService, SheetsSelectionsService, TextToNumberCommand, ToggleCellCheckboxCommand, ToggleGridlinesCommand, ToggleGridlinesMutation, UnitAction, UnitObject, UniverSheetsPlugin, ViewStateEnum, WorkbookCopyPermission, WorkbookCreateProtectPermission, WorkbookCreateSheetPermission, WorkbookDeleteColumnPermission, WorkbookDeleteRowPermission, WorkbookDeleteSheetPermission, WorkbookEditablePermission, WorkbookHideSheetPermission, WorkbookInsertColumnPermission, WorkbookInsertRowPermission, WorkbookManageCollaboratorPermission, WorkbookRenameSheetPermission, WorksheetCopyPermission, WorksheetDeleteColumnPermission, WorksheetDeleteProtectionPermission, WorksheetDeleteRowPermission, WorksheetEditPermission, WorksheetInsertColumnPermission, WorksheetInsertRowPermission, WorksheetManageCollaboratorPermission, WorksheetProtectionPointModel, WorksheetProtectionRuleModel, WorksheetSetCellStylePermission, WorksheetSetCellValuePermission, WorksheetSetColumnStylePermission, WorksheetSetRowStylePermission, WorksheetViewPermission, adjustRangeOnMutation, alignToMergedCellsBorders, attachPrimaryWithCoord, attachRangeWithCoord, attachSelectionWithCoord, baseProtectionActions, convertPrimaryWithCoordToPrimary, convertSelectionDataToRange, countCells, defaultLargeSheetOperationConfig, deserializeListOptions, discreteRangeToRange, expandToContinuousRange, getAddMergeMutationRangeByType, getAllWorksheetPermissionPoint, getCellAtRowCol, getClearContentMutationParamsForRanges, getMoveRangeCommandMutations, getPrimaryForRange, getSelectionsService, getSheetCommandTarget, rangeToDiscreteRange, serializeListOptions, setEndForRange, validateDefinedName } from "@univerjs/sheets"; import { BehaviorSubject, EMPTY, Observable, Subject, Subscription, combineLatest, combineLatestWith, distinctUntilChanged, filter, map, merge as merge$1, of, shareReplay, startWith, switchMap, takeUntil, throttleTime, withLatestFrom } from "rxjs"; import { DocSelectionManagerService, DocSkeletonManagerService, RichTextEditingMutation, SetTextSelectionsOperation } from "@univerjs/docs"; import { ObjectScope, UnitAction as UnitAction$1, UnitObject as UnitObject$1, UnitRole } from "@univerjs/protocol"; import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"; import { Avatar, Button, Calendar, CascaderList, ColorPicker, Confirm, Dropdown, DropdownMenu, FormLayout, Input, InputNumber, MessageType, Radio, RadioGroup, Select, Separator, Switch, TimeInput, Tooltip, borderBottomClassName, borderClassName, borderRightClassName, borderTopClassName, clsx, scrollbarClassName } from "@univerjs/design"; import { AutofillDoubleIcon, CheckMarkIcon, CloseIcon, ConvertIcon, DeleteIcon, DropdownIcon, ErrorIcon, EyelashIcon, FxIcon, HideGridlinesDoubleIcon, IncreaseIcon, InfoIcon, LockIcon, MoreDownIcon, MoreIcon, PaintBucketDoubleIcon, PasteSpecialDoubleIcon, PenIcon, ProtectIcon, WarningIcon, WriteIcon } from "@univerjs/icons"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; import { FUNCTION_NAMES_MATH, FUNCTION_NAMES_STATISTICAL, FUNCTION_NAMES_TEXT, FormulaDataModel, IDefinedNamesService, IFunctionService, ISuperTableService, LexerTreeBuilder, NullValueObject, SetFormulaCalculationNotificationMutation, deserializeRangeWithSheet, isReferenceStringWithEffectiveColumn, isReferenceStrings, matchToken, operatorToken, sequenceNodeType, serializeRange, serializeRangeWithSheet } from "@univerjs/engine-formula"; import { ITelemetryService } from "@univerjs/telemetry"; import { debounceTime, filter as filter$1, map as map$1, shareReplay as shareReplay$1, startWith as startWith$1, switchMap as switchMap$1 } from "rxjs/operators"; //#region src/basics/editor/get-editor-object.ts function getEditorObject(unitId, renderManagerService) { if (unitId == null) return; const currentRender = renderManagerService.getRenderById(unitId); if (currentRender == null) return; const { mainComponent, scene, engine, components } = currentRender; return { document: mainComponent, docBackground: components.get(DOCS_VIEW_KEY.BACKGROUND), scene, engine }; } //#endregion //#region src/controllers/shortcuts/utils.ts function whenSheetFocused(contextService) { return contextService.getContextValue(FOCUSING_SHEET); } /** * Requires the currently focused unit to be Workbook and the sheet editor is focused but not activated. * @param contextService * @returns If the sheet editor is focused but not activated. */ function whenSheetEditorFocused(contextService) { return contextService.getContextValue(FOCUSING_SHEET) && contextService.getContextValue(FOCUSING_UNIVER_EDITOR) && !contextService.getContextValue(EDITOR_ACTIVATED) && !contextService.getContextValue(FOCUSING_COMMON_DRAWINGS); } /** * Requires the currently focused unit to be Workbook, regardless of whether the cell editor is activated. * Used by inline-format shortcuts (bold/italic/underline/strikethrough) so they can also fire * inside the cell editor — the corresponding command will route to the docs inline-format command * when EDITOR_ACTIVATED is true. * @param contextService */ function whenSheetFocusedInlineFormat(contextService) { return contextService.getContextValue(FOCUSING_SHEET) && contextService.getContextValue(FOCUSING_UNIVER_EDITOR) && !contextService.getContextValue(FOCUSING_COMMON_DRAWINGS); } function whenSheetEditorFocusedAndFxNotFocused(contextService) { return contextService.getContextValue(FOCUSING_SHEET) && contextService.getContextValue(FOCUSING_UNIVER_EDITOR) && !contextService.getContextValue(EDITOR_ACTIVATED) && !contextService.getContextValue(FOCUSING_FX_BAR_EDITOR) && !contextService.getContextValue(FOCUSING_COMMON_DRAWINGS); } /** * Requires the currently focused unit to be Workbook and the sheet editor is activated. * @param contextService * @returns If the sheet editor is activated. */ function whenSheetEditorActivated(contextService) { return contextService.getContextValue(FOCUSING_SHEET) && contextService.getContextValue(FOCUSING_UNIVER_EDITOR) && contextService.getContextValue(EDITOR_ACTIVATED); } function whenEditorActivated(contextService) { return contextService.getContextValue(FOCUSING_UNIVER_EDITOR) && contextService.getContextValue(EDITOR_ACTIVATED); } /** * Requires the currently focused editor is a formula editor. * @param contextService * @returns If the formula editor is focused. */ function whenFormulaEditorFocused(contextService) { return contextService.getContextValue(FOCUSING_FX_BAR_EDITOR) && contextService.getContextValue(FOCUSING_UNIVER_EDITOR); } /** * Requires the currently focused editor is a formula editor, and it is activated. * @param contextService * @returns If the formula editor is activated. */ function whenFormulaEditorActivated(contextService) { return contextService.getContextValue(FOCUSING_SHEET) && contextService.getContextValue(EDITOR_ACTIVATED) && contextService.getContextValue(FOCUSING_EDITOR_INPUT_FORMULA) && contextService.getContextValue(FOCUSING_UNIVER_EDITOR); } /** * Requires the currently focused editor is not a formula editor, and it is activated. * @param contextService * @returns If the editor is activated and the editor is not the formula editor. */ function whenEditorDidNotInputFormulaActivated(contextService) { return contextService.getContextValue(FOCUSING_SHEET) && contextService.getContextValue(FOCUSING_UNIVER_EDITOR) && contextService.getContextValue(EDITOR_ACTIVATED) && !contextService.getContextValue(FOCUSING_EDITOR_INPUT_FORMULA) && !contextService.getContextValue(FOCUSING_EDITOR_STANDALONE); } //#endregion //#region src/controllers/utils/range-tools.ts function virtualizeDiscreteRanges(ranges) { let totalRows = []; let totalCols = []; const totalRanges = []; ranges.forEach((r) => { totalRows = totalRows.concat(r.rows); totalCols = totalCols.concat(r.cols); }); totalRows = Array.from(new Set(totalRows)).sort((a, b) => a - b); totalCols = Array.from(new Set(totalCols)).sort((a, b) => a - b); ranges.forEach((r) => { totalRanges.push({ startRow: totalRows.findIndex((row) => row === r.rows[0]), endRow: totalRows.findIndex((row) => row === r.rows[r.rows.length - 1]), startColumn: totalCols.findIndex((col) => col === r.cols[0]), endColumn: totalCols.findIndex((col) => col === r.cols[r.cols.length - 1]) }); }); return { ranges: totalRanges, mapFunc: (row, col) => ({ row: totalRows[row], col: totalCols[col] }) }; } //#endregion //#region src/services/selection/const.ts const RANGE_MOVE_PERMISSION_CHECK = createInterceptorKey("rangeMovePermissionCheck"); const RANGE_FILL_PERMISSION_CHECK = createInterceptorKey("rangeFillPermissionCheck"); let SELECTION_SHAPE_DEPTH = /* @__PURE__ */ function(SELECTION_SHAPE_DEPTH) { SELECTION_SHAPE_DEPTH[SELECTION_SHAPE_DEPTH["FORMULA_EDITOR_SHOW"] = 100] = "FORMULA_EDITOR_SHOW"; SELECTION_SHAPE_DEPTH[SELECTION_SHAPE_DEPTH["MARK_SELECTION"] = 1e4] = "MARK_SELECTION"; return SELECTION_SHAPE_DEPTH; }({}); function genNormalSelectionStyle(themeService) { const primaryColor = themeService.getColorFromTheme("primary.600"); const whiteColor = themeService.getColorFromTheme("white"); const fill = new ColorKit(primaryColor).setAlpha(.07).toRgbString(); return { strokeWidth: 1, stroke: primaryColor, fill, widgets: {}, widgetSize: 6, widgetStrokeWidth: 1, widgetStroke: whiteColor, autofillSize: 6, autofillStrokeWidth: 1, autofillStroke: whiteColor, rowHeaderFill: fill, rowHeaderStroke: primaryColor, rowHeaderStrokeWidth: 1, columnHeaderFill: fill, columnHeaderStroke: primaryColor, columnHeaderStrokeWidth: 1, expandCornerSize: 40 }; } //#endregion //#region src/common/keys.ts /** * Copyright 2023-present DreamNum Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ const SHEET_ZOOM_RANGE = [10, 400]; /** * TODO@ggg: To avoid introducing the range-selector of the sheet-formula-ui package into sheet-ui, use a component key for now */ const RANGE_SELECTOR_COMPONENT_KEY = "RANGE_SELECTOR_COMPONENT_KEY"; const EMBEDDING_FORMULA_EDITOR_COMPONENT_KEY = "EMBEDDING_FORMULA_EDITOR_COMPONENT_KEY"; let SHEET_VIEW_KEY = /* @__PURE__ */ function(SHEET_VIEW_KEY) { SHEET_VIEW_KEY["MAIN"] = "__SpreadsheetRender__"; SHEET_VIEW_KEY["ROW"] = "__SpreadsheetRowHeader__"; SHEET_VIEW_KEY["COLUMN"] = "__SpreadsheetColumnHeader__"; SHEET_VIEW_KEY["LEFT_TOP"] = "__SpreadsheetLeftTopPlaceholder__"; return SHEET_VIEW_KEY; }({}); //#endregion //#region \0@oxc-project+runtime@0.133.0/helpers/esm/typeof.js function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) { return typeof o; } : function(o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } //#endregion //#region \0@oxc-project+runtime@0.133.0/helpers/esm/toPrimitive.js function toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } //#endregion //#region \0@oxc-project+runtime@0.133.0/helpers/esm/toPropertyKey.js function toPropertyKey(t) { var i = toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } //#endregion //#region \0@oxc-project+runtime@0.133.0/helpers/esm/defineProperty.js function _defineProperty(e, r, t) { return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } //#endregion //#region src/services/selection/selection-render-model.ts /** * Data model for SelectionControl.model * NOT Same as @univerjs/sheet.WorkbookSelectionModel, that's data model for Workbook */ var SelectionRenderModel = class { constructor() { _defineProperty(this, "_startColumn", -1); _defineProperty(this, "_startRow", -1); _defineProperty(this, "_endColumn", -1); _defineProperty(this, "_endRow", -1); _defineProperty(this, "_startX", 0); _defineProperty(this, "_startY", 0); _defineProperty(this, "_endX", 0); _defineProperty(this, "_endY", 0); _defineProperty(this, "_primary", void 0); _defineProperty(this, "_rangeType", RANGE_TYPE.NORMAL); } get startColumn() { return this._startColumn; } get startRow() { return this._startRow; } get endColumn() { return this._endColumn; } get endRow() { return this._endRow; } get startX() { return this._startX; } get startY() { return this._startY; } get endX() { return this._endX; } get endY() { return this._endY; } get currentCell() { return this._primary; } get rangeType() { return this._rangeType; } /** * @deprecated, Duplicate with `Rectangle` */ isEqual(rangeWithCoord) { const { startColumn, startRow, endColumn, endRow } = this; const { startColumn: newStartColumn, startRow: newStartRow, endColumn: newEndColumn, endRow: newEndRow } = rangeWithCoord; if (startColumn === newStartColumn && startRow === newStartRow && endColumn === newEndColumn && endRow === newEndRow) return true; return false; } highlightToSelection() { if (!this._primary) return; return convertCellToRange(this._primary); } getRange() { return { startColumn: this._startColumn, startRow: this._startRow, endColumn: this._endColumn, endRow: this._endRow, startX: this._startX, startY: this._startY, endX: this._endX, endY: this._endY, rangeType: this.rangeType }; } getCell() { return this._primary; } getRangeType() { return this._rangeType; } setRangeType(rangeType) { this._rangeType = rangeType; } getValue() { return { rangeWithCoord: this.getRange(), primaryWithCoord: this._primary }; } setValue(newSelectionRange, currentCell) { const { startColumn, startRow, endColumn, endRow, startX, startY, endX, endY, rangeType } = newSelectionRange; this._startColumn = startColumn; this._startRow = startRow; this._endColumn = endColumn; this._endRow = endRow; this._startX = startX; this._startY = startY; this._endX = endX; this._endY = endY; if (rangeType !== void 0) this._rangeType = rangeType; if (currentCell !== void 0) this.setCurrentCell(currentCell); } /** * Set primary cell. * @TODO lumixraku there are 3 concepts for same thing, primary and current and highlight * highlight is best. primary sometimes means the actual cell(actual means ignore merge) * @param currentCell */ setCurrentCell(currentCell) { this._primary = currentCell; } clearCurrentCell() { this._primary = null; } }; //#endregion //#region src/commands/commands/headersize-changed.command.ts const SetRowHeaderWidthCommand = { id: "sheet.command.set-row-header-width", type: CommandType.COMMAND, handler: async (accessor, params) => { if (!params) return false; const renderManagerSrv = accessor.get(IRenderManagerService); if (!renderManagerSrv) return false; const { unitId, subUnitId, size } = params; const render = renderManagerSrv.getRenderById(unitId); if (render) { renderManagerSrv.getRenderById(unitId).with(SheetSkeletonManagerService).setRowHeaderSize(render, subUnitId, size); const { components } = render; const renderComponent = components.get("__SpreadsheetRowHeader__"); if (renderComponent) renderComponent.setCustomHeader({ headerStyle: { size } }, subUnitId); } return true; } }; const SetColumnHeaderHeightCommand = { id: "sheet.command.set-col-header-height", type: CommandType.COMMAND, handler: async (accessor, params) => { if (!params) return false; const renderManagerSrv = accessor.get(IRenderManagerService); if (!renderManagerSrv) return false; const { unitId, subUnitId, size } = params; const render = renderManagerSrv.getRenderById(unitId); if (render) { renderManagerSrv.getRenderById(unitId).with(SheetSkeletonManagerService).setColumnHeaderSize(render, subUnitId, size); const { components } = render; const renderComponent = components.get("__SpreadsheetColumnHeader__"); if (renderComponent) renderComponent.setCustomHeader({ headerStyle: { size } }, subUnitId); } return true; } }; //#endregion //#region src/services/selection/selection-layer.ts var SelectionLayer = class extends Layer { render(ctx, isMaxLayer = false) { const startTime = Tools.now(); super.render(ctx, isMaxLayer); this._afterRender(startTime); return this; } _afterRender(startTime) { this.scene.getEngine().renderFrameTimeMetric$.next(["selectionLayer", Tools.now() - startTime]); } }; //#endregion //#region src/services/selection/base-selection-render.service.ts const ISheetSelectionRenderService = createIdentifier("univer.sheet.selection-render-service"); /** * The basic implementation of selection rendering logics. It is designed to be reused for different purposes. */ var BaseSelectionRenderService = class extends Disposable { get selectionMoving() { return this._selectionMoving; } constructor(_injector, _themeService, _shortcutService, _sheetSkeletonManagerService, contextService) { super(); this._injector = _injector; this._themeService = _themeService; this._shortcutService = _shortcutService; this._sheetSkeletonManagerService = _sheetSkeletonManagerService; this.contextService = contextService; _defineProperty(this, "_downObserver", void 0); _defineProperty(this, "_scenePointerMoveSub", void 0); _defineProperty(this, "_scenePointerUpSub", void 0); _defineProperty(this, "_controlFillConfig$", new BehaviorSubject(null)); _defineProperty(this, "controlFillConfig$", this._controlFillConfig$.asObservable()); _defineProperty(this, "_selectionControls", []); _defineProperty(this, "_startRangeWhenPointerDown", { startY: 0, endY: 0, startX: 0, endX: 0, startRow: -1, endRow: -1, startColumn: -1, endColumn: -1 }); _defineProperty(this, "_activeControlIndex", -1); _defineProperty(this, "_startViewportPosX", 0); _defineProperty(this, "_startViewportPosY", 0); _defineProperty(this, "_scrollTimer", void 0); _defineProperty(this, "_cancelDownSubscription", void 0); _defineProperty(this, "_cancelUpSubscription", void 0); _defineProperty(this, "_skeleton", void 0); _defineProperty(this, "_scene", void 0); _defineProperty(this, "_highlightHeader", true); _defineProperty(this, "_rangeType", RANGE_TYPE.NORMAL); _defineProperty(this, "_selectionStyle", void 0); _defineProperty(this, "_remainLastEnabled", false); _defineProperty(this, "_skipLastEnabled", false); _defineProperty(this, "_singleSelectionEnabled", false); _defineProperty(this, "_selectionMoveEnd$", new BehaviorSubject([])); _defineProperty(this, "selectionMoveEnd$", this._selectionMoveEnd$.asObservable()); _defineProperty(this, "_selectionMoving$", new Subject()); _defineProperty(this, "selectionMoving$", this._selectionMoving$.asObservable()); _defineProperty(this, "_selectionMoveStart$", new Subject()); _defineProperty(this, "selectionMoveStart$", this._selectionMoveStart$.asObservable()); _defineProperty(this, "_selectionMoving", false); _defineProperty(this, "_selectionTheme", void 0); _defineProperty(this, "_activeViewport", void 0); _defineProperty(this, "interceptor", new InterceptorManager({ RANGE_MOVE_PERMISSION_CHECK, RANGE_FILL_PERMISSION_CHECK })); _defineProperty(this, "_escapeShortcutDisposable", null); this._initSelectionThemeFromThemeService(); this._initMoving(); } /** * If true, the selector will respond to the range of merged cells and automatically extend the selected range. If false, it will ignore the merged cells. */ get _shouldDetectMergedCells() { return this._rangeType === RANGE_TYPE.NORMAL; } _initMoving() { this.disposeWithMe(this._selectionMoving$.subscribe(() => { this._selectionMoving = true; })); this.disposeWithMe(this._selectionMoveEnd$.subscribe(() => { this._selectionMoving = false; })); } _setSelectionStyle(style) { this._selectionStyle = style; } /** * Reset this._selectionStyle to default normal selection style */ /** @deprecated This should not be provided by the selection render service. */ getViewPort() { return this._activeViewport; } setSingleSelectionEnabled(enabled = false) { this._singleSelectionEnabled = enabled; } newSelectionControl(scene, skeleton, selection) { const zIndex = this.getSelectionControls().length; const { rowHeaderWidth, rowHeaderWidthAndMarginLeft, columnHeaderHeight, columnHeaderHeightAndMarginTop } = skeleton; const control = new SelectionControl(scene, zIndex, this._selectionTheme, { highlightHeader: this._highlightHeader, rowHeaderWidth, columnHeaderHeight, rowHeaderOffsetX: Math.max(0, rowHeaderWidthAndMarginLeft - rowHeaderWidth), columnHeaderOffsetY: Math.max(0, columnHeaderHeightAndMarginTop - columnHeaderHeight) }); this._selectionControls.push(control); const selectionWithCoord = attachSelectionWithCoord(selection, skeleton); control.updateRangeBySelectionWithCoord(selectionWithCoord, skeleton); control.setControlExtension({ skeleton, scene, themeService: this._selectionTheme, injector: this._injector, selectionHooks: { selectionMoveEnd: () => { this._selectionMoveEnd$.next(this.getSelectionDataWithStyle()); } } }); return control; } /** * Update the corresponding selectionControl based on selectionsData from WorkbookSelectionModel * selectionData[i] --> selectionControls[i] * @param selectionsWithStyleList {ISelectionWithStyle[]} selectionsData from WorkbookSelectionModel */ resetSelectionsByModelData(selectionsWithStyleList) { const allSelectionControls = this.getSelectionControls(); const skeleton = this._skeleton; if (!allSelectionControls || !skeleton) return; for (let i = 0, len = selectionsWithStyleList.length; i < len; i++) { const selectionWithStyle = selectionsWithStyleList[i]; const selectionWithCoord = attachSelectionWithCoord(selectionWithStyle, this._skeleton); const control = allSelectionControls[i]; if (control) control.updateRangeBySelectionWithCoord(selectionWithCoord, skeleton); else if (this.isSelectionEnabled()) this.newSelectionControl(this._scene, skeleton, selectionWithStyle); } if (selectionsWithStyleList.length < allSelectionControls.length) allSelectionControls.splice(selectionsWithStyleList.length).forEach((control) => control.dispose()); } refreshSelectionMoveStart() { this._selectionMoveStart$.next(this.getSelectionDataWithStyle()); } refreshSelectionMoveEnd() { this._selectionMoveEnd$.next(this.getSelectionDataWithStyle()); } _initSelectionThemeFromThemeService() { const theme = this._themeService.getCurrentTheme(); this._selectionTheme = new ThemeService(); this._selectionTheme.setTheme(theme); } setSelectionTheme(theme) { this._selectionTheme.setTheme(theme); } _changeRuntime(skeleton, scene, viewport) { this._skeleton = skeleton; this._scene = scene; this._activeViewport = viewport || (scene === null || scene === void 0 ? void 0 : scene.getViewports()[0]); if (!scene.findLayerByZIndex(1)) scene.addLayer(new SelectionLayer(scene, [], 1)); } getSkeleton() { return this._skeleton; } /** * Generate selectionData from this._selectionControls.model . * @returns {ISelectionWithCoord[]} {range, primary, style}[] */ getSelectionDataWithStyle() { const selectionControls = this._selectionControls; if (this._skeleton.worksheet) { const [unitId, sheetId] = this._skeleton.getLocation(); return selectionControls.map((control) => { const v = control.getValue(); v.rangeWithCoord.sheetId = sheetId; v.rangeWithCoord.unitId = unitId; return v; }); } return []; } /** * @TODO lumixraku DO NOT expose private props. */ getSelectionControls() { return this._selectionControls; } /** * Add a selection in spreadsheet, create a new SelectionControl and then update this control by range derives from selection. * @param {ISelectionWithCoord} selectionWithStyle */ _addSelectionControlByModelData(selectionWithStyle) { var _selectionWithStyle$s; const skeleton = this._skeleton; const style = (_selectionWithStyle$s = selectionWithStyle.style) !== null && _selectionWithStyle$s !== void 0 ? _selectionWithStyle$s : genNormalSelectionStyle(this._selectionTheme); const scene = this._scene; selectionWithStyle.style = style; return this.newSelectionControl(scene, skeleton, selectionWithStyle); } _clearAllSelectionControls() { const allSelectionControls = this._selectionControls; for (const control of allSelectionControls) control.dispose(); this._selectionControls.length = 0; } _getFreeze() { var _this$_sheetSkeletonM; return (_this$_sheetSkeletonM = this._sheetSkeletonManagerService.getCurrentParam()) === null || _this$_sheetSkeletonM === void 0 ? void 0 : _this$_sheetSkeletonM.skeleton.getWorksheetConfig().freeze; } _getViewportByCell(row, column) { if (row === void 0 || column === void 0) return null; const freeze = this._getFreeze(); if (!freeze || freeze.startRow <= 0 && freeze.startColumn <= 0) return this._scene.getViewport(SHEET_VIEWPORT_KEY.VIEW_MAIN); if (row > freeze.startRow && column > freeze.startColumn) return this._scene.getViewport(SHEET_VIEWPORT_KEY.VIEW_MAIN); if (row <= freeze.startRow && column <= freeze.startColumn) return this._scene.getViewport(SHEET_VIEWPORT_KEY.VIEW_MAIN_LEFT_TOP); if (row <= freeze.startRow && column > freeze.startColumn) return this._scene.getViewport(SHEET_VIEWPORT_KEY.VIEW_MAIN_TOP); if (row > freeze.startRow && column <= freeze.startColumn) return this._scene.getViewport(SHEET_VIEWPORT_KEY.VIEW_MAIN_LEFT); } /** * Returns the selected range in the active sheet, or null if there is no active range. If multiple ranges are selected this method returns only the last selected range. */ getActiveRange() { const controls = this.getSelectionControls(); const model = controls && controls[controls.length - 1].model; return model && { startRow: model.startRow, startColumn: model.startColumn, endRow: model.endRow, endColumn: model.endColumn }; } setActiveSelectionIndex(index) { this._activeControlIndex = index; } resetActiveSelectionIndex() { this._activeControlIndex = -1; } /** * get active(actually last) selection control * @returns T extends SelectionControl */ getActiveSelectionControl() { const controls = this.getSelectionControls(); if (controls) { if (this._activeControlIndex < 0) return controls[controls.length - 1]; return controls[this._activeControlIndex]; } } endSelection() { var _this$_escapeShortcut; this._clearUpdatingListeners(); this._selectionMoveEnd$.next(this.getSelectionDataWithStyle()); (_this$_escapeShortcut = this._escapeShortcutDisposable) === null || _this$_escapeShortcut === void 0 || _this$_escapeShortcut.dispose(); this._escapeShortcutDisposable = null; } /** * Clear existed selections by workbookSelections.selectionMoveEnd$ */ _reset() { var _this$_downObserver; this._clearAllSelectionControls(); (_this$_downObserver = this._downObserver) === null || _this$_downObserver === void 0 || _this$_downObserver.unsubscribe(); this._downObserver = null; } /** * Init pointer move listener in each pointer down, unbind in each pointer up. * Both cell selections and row-column selections are supported by this method. * @param viewportMain * @param activeSelectionControl * @param rangeType * @param scrollTimerType * @param moveStartPosX * @param moveStartPosY */ _setupPointerMoveListener(viewportMain, activeSelectionControl, rangeType, scrollTimerType = ScrollTimerType.ALL, moveStartPosX, moveStartPosY) { var _viewportMain$left, _viewportMain$top; let xCrossTime = 0; let yCrossTime = 0; let lastX = moveStartPosX; let lastY = moveStartPosY; this._scrollTimer = ScrollTimer.create(this._scene, scrollTimerType); this._scrollTimer.startScroll((_viewportMain$left = viewportMain === null || viewportMain === void 0 ? void 0 : viewportMain.left) !== null && _viewportMain$left !== void 0 ? _viewportMain$left : 0, (_viewportMain$top = viewportMain === null || viewportMain === void 0 ? void 0 : viewportMain.top) !== null && _viewportMain$top !== void 0 ? _viewportMain$top : 0, viewportMain); const scene = this._scene; const startViewport = scene.getActiveViewportByCoord(Vector2.FromArray([moveStartPosX, moveStartPosY])); this._scenePointerMoveSub = scene.onPointerMove$.subscribeEvent((moveEvt) => { var _scene$getActiveViewp; const { offsetX: moveOffsetX, offsetY: moveOffsetY } = moveEvt; const { x: newMoveOffsetX, y: newMoveOffsetY } = scene.getCoordRelativeToViewport(Vector2.FromArray([moveOffsetX, moveOffsetY])); this._movingHandler(newMoveOffsetX, newMoveOffsetY, activeSelectionControl, rangeType); let scrollOffsetX = newMoveOffsetX; let scrollOffsetY = newMoveOffsetY; const currentSelection = this.getActiveSelectionControl(); const freeze = this._getFreeze(); const selection = currentSelection === null || currentSelection === void 0 ? void 0 : currentSelection.model; const endViewport = (_scene$getActiveViewp = scene.getActiveViewportByCoord(Vector2.FromArray([moveOffsetX, moveOffsetY]))) !== null && _scene$getActiveViewp !== void 0 ? _scene$getActiveViewp : this._getViewportByCell(selection === null || selection === void 0 ? void 0 : selection.endRow, selection === null || selection === void 0 ? void 0 : selection.endColumn); const isCrossableViewports = () => { if (!startViewport || !endViewport || !viewportMain) return false; const crossableViewports = [ SHEET_VIEWPORT_KEY.VIEW_MAIN, SHEET_VIEWPORT_KEY.VIEW_MAIN_LEFT_TOP, SHEET_VIEWPORT_KEY.VIEW_MAIN_TOP, SHEET_VIEWPORT_KEY.VIEW_MAIN_LEFT ]; return crossableViewports.includes(startViewport.viewportKey) && crossableViewports.includes(endViewport.viewportKey); }; if (isCrossableViewports()) { if (!startViewport || !endViewport || !viewportMain) return false; const isCrossingX = lastX < viewportMain.left && newMoveOffsetX > viewportMain.left || lastX > viewportMain.left && newMoveOffsetX < viewportMain.left; const isCrossingY = lastY < viewportMain.top && newMoveOffsetY > viewportMain.top || lastY > viewportMain.top && newMoveOffsetY < viewportMain.top; if (isCrossingX) xCrossTime += 1; if (isCrossingY) yCrossTime += 1; const startKey = startViewport.viewportKey; const endKey = endViewport.viewportKey; if (startKey === SHEET_VIEWPORT_KEY.VIEW_ROW_TOP) { var _selection$endRow, _freeze$startRow; if (moveOffsetY < viewportMain.top && ((_selection$endRow = selection === null || selection === void 0 ? void 0 : selection.endRow) !== null && _selection$endRow !== void 0 ? _selection$endRow : 0) < ((_freeze$startRow = freeze === null || freeze === void 0 ? void 0 : freeze.startRow) !== null && _freeze$startRow !== void 0 ? _freeze$startRow : 0)) scrollOffsetY = viewportMain.top; else if (isCrossingY && yCrossTime % 2 === 1) viewportMain.scrollToViewportPos({ viewportScrollY: 0 }); } else if (startKey === SHEET_VIEWPORT_KEY.VIEW_COLUMN_LEFT) { var _selection$endColumn, _freeze$startColumn; if (moveOffsetX < viewportMain.left && ((_selection$endColumn = selection === null || selection === void 0 ? void 0 : selection.endColumn) !== null && _selection$endColumn !== void 0 ? _selection$endColumn : 0) < ((_freeze$startColumn = freeze === null || freeze === void 0 ? void 0 : freeze.startColumn) !== null && _freeze$startColumn !== void 0 ? _freeze$startColumn : 0)) scrollOffsetX = viewportMain.left; else if (isCrossingX && xCrossTime % 2 === 1) viewportMain.scrollToViewportPos({ viewportScrollX: 0 }); } else if (startKey === endKey) { var _selection$endRow2, _freeze$startRow2, _selection$endColumn2, _freeze$startColumn2; let disableX = false; let disableY = false; if (startKey === SHEET_VIEWPORT_KEY.VIEW_MAIN_LEFT_TOP) { disableX = true; disableY = true; } else if (startKey === SHEET_VIEWPORT_KEY.VIEW_MAIN_TOP) disableY = true; else if (startKey === SHEET_VIEWPORT_KEY.VIEW_MAIN_LEFT) disableX = true; if (((_selection$endRow2 = selection === null || selection === void 0 ? void 0 : selection.endRow) !== null && _selection$endRow2 !== void 0 ? _selection$endRow2 : 0) > ((_freeze$startRow2 = freeze === null || freeze === void 0 ? void 0 : freeze.startRow) !== null && _freeze$startRow2 !== void 0 ? _freeze$startRow2 : 0)) disableY = false; if (((_selection$endColumn2 = selection === null || selection === void 0 ? void 0 : selection.endColumn) !== null && _selection$endColumn2 !== void 0 ? _selection$endColumn2 : 0) > ((_freeze$startColumn2 = freeze === null || freeze === void 0 ? void 0 : freeze.startColumn) !== null && _freeze$startColumn2 !== void 0 ? _freeze$startColumn2 : 0)) disableX = false; if (disableX) scrollOffsetX = viewportMain.left; if (disableY) scrollOffsetY = viewportMain.top; } else { const startXY = { x: startViewport.scrollX, y: startViewport.scrollY }; const endXY = { x: endViewport.scrollX, y: endViewport.scrollY }; const shouldResetX = startXY.x !== endXY.x && isCrossingX && xCrossTime % 2 === 1; const shouldResetY = startXY.y !== endXY.y && isCrossingY && yCrossTime % 2 === 1; if (shouldResetX || shouldResetY) { viewportMain.scrollToBarPos({ x: shouldResetX ? startXY.x : void 0, y: shouldResetY ? startXY.y : void 0 }); if (!shouldResetX) scrollOffsetX = viewportMain.left; if (!shouldResetY) scrollOffsetY = viewportMain.top; } if (startKey === SHEET_VIEWPORT_KEY.VIEW_MAIN_LEFT_TOP && endKey === SHEET_VIEWPORT_KEY.VIEW_MAIN_LEFT || endKey === SHEET_VIEWPORT_KEY.VIEW_MAIN_LEFT_TOP && startKey === SHEET_VIEWPORT_KEY.VIEW_MAIN_LEFT) scrollOffsetX = viewportMain.left; if (startKey === SHEET_VIEWPORT_KEY.VIEW_MAIN_LEFT_TOP && endKey === SHEET_VIEWPORT_KEY.VIEW_MAIN_TOP || endKey === SHEET_VIEWPORT_KEY.VIEW_MAIN_LEFT_TOP && startKey === SHEET_VIEWPORT_KEY.VIEW_MAIN_TOP) scrollOffsetY = viewportMain.top; } lastX = newMoveOffsetX; lastY = newMoveOffsetY; } this._scrollTimer.scrolling(scrollOffsetX, scrollOffsetY, () => { this._movingHandler(newMoveOffsetX, newMoveOffsetY, activeSelectionControl, rangeType); }); }); } /** * @deprecated Please use `getCellWithCoordByOffset` instead. */ getSelectionCellByPosition(x, y) { return this.getCellWithCoordByOffset(x, y); } getCellWithCoordByOffset(x, y, skeletonParam) { const scene = this._scene; const skeleton = skeletonParam !== null && skeletonParam !== void 0 ? skeletonParam : this._skeleton; const scrollXY = scene.getViewportScrollXY(scene.getViewport(SHEET_VIEWPORT_KEY.VIEW_MAIN)); const { scaleX, scaleY } = scene.getAncestorScale(); return skeleton.getCellWithCoordByOffset(x - scrollXY.x, y - scrollXY.y, scaleX, scaleY, scrollXY); } /** * When mousedown and mouseup need to go to the coordination and undo stack, when mousemove does not need to go to the coordination and undo stack */ _movingHandler(offsetX, offsetY, activeSelectionControl, rangeType) { var _activeSelectionContr, _activeSelectionContr2, _activeSelectionContr3, _activeSelectionContr4, _this$_getViewportByC; const skeleton = this._skeleton; const scene = this._scene; const [unitId, sheetId] = skeleton.getLocation(); const currSelectionRange = { startRow: (_activeSelectionContr = activeSelectionControl === null || activeSelectionControl === void 0 ? void 0 : activeSelectionControl.model.startRow) !== null && _activeSelectionContr !== void 0 ? _activeSelectionContr : -1, endRow: (_activeSelectionContr2 = activeSelectionControl === null || activeSelectionControl === void 0 ? void 0 : activeSelectionControl.model.endRow) !== null && _activeSelectionContr2 !== void 0 ? _activeSelectionContr2 : -1, startColumn: (_activeSelectionContr3 = activeSelectionControl === null || activeSelectionControl === void 0 ? void 0 : activeSelectionControl.model.startColumn) !== null && _activeSelectionContr3 !== void 0 ? _activeSelectionContr3 : -1, endColumn: (_activeSelectionContr4 = activeSelectionControl === null || activeSelectionControl === void 0 ? void 0 : activeSelectionControl.model.endColumn) !== null && _activeSelectionContr4 !== void 0 ? _activeSelectionContr4 : -1, unitId, sheetId }; const viewportMain = scene.getViewport(SHEET_VIEWPORT_KEY.VIEW_MAIN); const targetViewport = (_this$_getViewportByC = this._getViewportByCell(currSelectionRange.endRow, currSelectionRange.endColumn)) !== null && _this$_getViewportByC !== void 0 ? _this$_getViewportByC : viewportMain; const scrollXY = scene.getScrollXYInfoByViewport(Vector2.FromArray([this._startViewportPosX, this._startViewportPosY]), targetViewport); const { scaleX, scaleY } = scene.getAncestorScale(); if (rangeType === RANGE_TYPE.ROW) offsetX = Number.POSITIVE_INFINITY; else if (rangeType === RANGE_TYPE.COLUMN) offsetY = Number.POSITIVE_INFINITY; const currCell = this._skeleton.getCellByOffset(offsetX, offsetY, scaleX, scaleY, scrollXY); if (!currCell) return; let newSelectionRange = { startRow: Math.min(currCell.startRow, this._startRangeWhenPointerDown.startRow), startColumn: Math.min(currCell.startColumn, this._startRangeWhenPointerDown.startColumn), endRow: Math.max(currCell.endRow, this._startRangeWhenPointerDown.endRow), endColumn: Math.max(currCell.endColumn, this._startRangeWhenPointerDown.endColumn) }; if (this._shouldDetectMergedCells) newSelectionRange = skeleton.expandRangeByMerge(newSelectionRange, this.inRefSelectionMode()); const newSelectionRangeWithCoord = attachSelectionWithCoord({ range: newSelectionRange, primary: void 0, style: null }, skeleton); newSelectionRangeWithCoord.rangeWithCoord.unitId = unitId; newSelectionRangeWithCoord.rangeWithCoord.sheetId = sheetId; newSelectionRangeWithCoord.rangeWithCoord.rangeType = rangeType; const rangeChanged = currSelectionRange.startRow !== newSelectionRange.startRow || currSelectionRange.startColumn !== newSelectionRange.startColumn || currSelectionRange.endRow !== newSelectionRange.endRow || currSelectionRange.endColumn !== newSelectionRange.endColumn; if (activeSelectionControl != null && rangeChanged) { activeSelectionControl.updateRangeBySelectionWithCoord(newSelectionRangeWithCoord); this._selectionMoving$.next(this.getSelectionDataWithStyle()); } } _clearUpdatingListeners() { var _this$_scenePointerMo, _this$_scenePointerUp, _this$_cancelDownSubs, _this$_cancelUpSubscr, _this$_scrollTimer; this._scene.enableObjectsEvent(); (_this$_scenePointerMo = this._scenePointerMoveSub) === null || _this$_scenePointerMo === void 0 || _this$_scenePointerMo.unsubscribe(); this._scenePointerMoveSub = null; (_this$_scenePointerUp = this._scenePointerUpSub) === null || _this$_scenePointerUp === void 0 || _this$_scenePointerUp.unsubscribe(); this._scenePointerUpSub = null; (_this$_cancelDownSubs = this._cancelDownSubscription) === null || _this$_cancelDownSubs === void 0 || _this$_cancelDownSubs.unsubscribe(); this._cancelDownSubscription = null; (_this$_cancelUpSubscr = this._cancelUpSubscription) === null || _this$_cancelUpSubscr === void 0 || _this$_cancelUpSubscr.unsubscribe(); this._cancelUpSubscription = null; (_this$_scrollTimer = this._scrollTimer) === null || _this$_scrollTimer === void 0 || _this$_scrollTimer.dispose(); } _addEndingListeners() { var _scene$getEngine, _this$_cancelDownSubs2, _this$_cancelUpSubscr2; const scene = this._scene; const mainScene = (_scene$getEngine = scene.getEngine()) === null || _scene$getEngine === void 0 ? void 0 : _scene$getEngine.activeScene; if (!mainScene || mainScene === scene) return; (_this$_cancelDownSubs2 = this._cancelDownSubscription) === null || _this$_cancelDownSubs2 === void 0 || _this$_cancelDownSubs2.unsubscribe(); this._cancelDownSubscription = null; (_this$_cancelUpSubscr2 = this._cancelUpSubscription) === null || _this$_cancelUpSubscr2 === void 0 || _this$_cancelUpSubscr2.unsubscribe(); this._cancelUpSubscription = null; this._cancelDownSubscription = mainScene.onPointerDown$.subscribeEvent(() => this._clearUpdatingListeners()); this._cancelUpSubscription = mainScene.onPointerUp$.subscribeEvent(() => this._clearUpdatingListeners()); } /** * Get visible selection range & coord by offset on viewport. Nearly same as skeleton.getCellWithCoordByOffset * Returning selection is only one cell. primary and range are same cell. * * visible selection range means getCellWithCoordByOffset needs first matched row/col in rowHeightAccumulation & colWidthAccumulation. * Original name: _getCellRangeByCursorPosition * * @param offsetX position X in viewport. * @param offsetY * @para