From 5e3140eec3cd3597eef41372b240c3141c31559c Mon Sep 17 00:00:00 2001 From: ybzky Date: Mon, 17 Jun 2024 11:10:06 +0800 Subject: [PATCH] fix(sheets): fix some bugs --- .../formula-clipboard.controller.ts | 8 ++ packages/sheets-ui/src/common/utils.ts | 17 +++-- .../remove-worksheet-merge.command.ts | 73 +++++++++++++++---- .../mutations/set-range-values.mutation.ts | 7 +- packages/ui/src/utils/cell.ts | 11 ++- 5 files changed, 90 insertions(+), 26 deletions(-) diff --git a/packages/sheets-formula/src/controllers/formula-clipboard.controller.ts b/packages/sheets-formula/src/controllers/formula-clipboard.controller.ts index d9cbb0ed3e4..e6c8a3098ad 100644 --- a/packages/sheets-formula/src/controllers/formula-clipboard.controller.ts +++ b/packages/sheets-formula/src/controllers/formula-clipboard.controller.ts @@ -84,6 +84,14 @@ export class FormulaClipboardController extends Disposable { payload: ICopyPastePayload, isSpecialPaste: boolean ) { + const pasteType = payload.pasteType; + if (pasteType === PREDEFINED_HOOK_NAME.SPECIAL_PASTE_VALUE || pasteType === PREDEFINED_HOOK_NAME.SPECIAL_PASTE_FORMAT || pasteType === PREDEFINED_HOOK_NAME.SPECIAL_PASTE_COL_WIDTH) { + return { + undos: [], + redos: [], + }; + } + const copyInfo = { copyType: payload.copyType || COPY_TYPE.COPY, copyRange: pasteFrom?.range, diff --git a/packages/sheets-ui/src/common/utils.ts b/packages/sheets-ui/src/common/utils.ts index 3a8b1979512..b209ab1acab 100644 --- a/packages/sheets-ui/src/common/utils.ts +++ b/packages/sheets-ui/src/common/utils.ts @@ -89,19 +89,22 @@ export function getClearContentMutationParamsForRanges( }; } -export function getClearContentMutationParamForRange( - worksheet: Worksheet, - range: IRange -): ObjectMatrix> { +function getClearContentMutationParamForRange(worksheet: Worksheet, range: IRange): ObjectMatrix> { const { startRow, startColumn, endColumn, endRow } = range; const cellMatrix = worksheet.getMatrixWithMergedCells(startRow, startColumn, endRow, endColumn); const redoMatrix = new ObjectMatrix>(); + let leftTopCellValue: Nullable = null; cellMatrix.forValue((row, col, cellData) => { - if (cellData && (row !== startRow || col !== startColumn)) { + if (cellData) { + if (!leftTopCellValue && cellData.v !== undefined) { + leftTopCellValue = cellData; + } redoMatrix.setValue(row, col, null); } }); + redoMatrix.setValue(startRow, startColumn, leftTopCellValue); + return redoMatrix; } @@ -185,9 +188,9 @@ export function transformPosition2Offset(x: number, y: number, scene: Scene, ske } const freeze = worksheet.getFreeze(); const { startColumn, startRow, xSplit, ySplit } = freeze; - // freeze start + // freeze start const startSheetView = skeleton.getNoMergeCellPositionByIndexWithNoHeader(startRow - ySplit, startColumn - xSplit); - // freeze end + // freeze end const endSheetView = skeleton.getNoMergeCellPositionByIndexWithNoHeader(startRow, startColumn); const { rowHeaderWidth, columnHeaderHeight } = skeleton; const freezeWidth = endSheetView.startX - startSheetView.startX; diff --git a/packages/sheets/src/commands/commands/remove-worksheet-merge.command.ts b/packages/sheets/src/commands/commands/remove-worksheet-merge.command.ts index 043c373251f..66e82879013 100644 --- a/packages/sheets/src/commands/commands/remove-worksheet-merge.command.ts +++ b/packages/sheets/src/commands/commands/remove-worksheet-merge.command.ts @@ -14,8 +14,8 @@ * limitations under the License. */ -import type { ICommand } from '@univerjs/core'; -import { CommandType, ICommandService, IUndoRedoService, IUniverInstanceService, Rectangle, sequenceExecute, Tools } from '@univerjs/core'; +import type { ICellData, ICommand, IMutationInfo, IRange, Nullable, Worksheet } from '@univerjs/core'; +import { CommandType, ICommandService, IUndoRedoService, IUniverInstanceService, ObjectMatrix, Rectangle, sequenceExecute, Tools } from '@univerjs/core'; import type { IAccessor } from '@wendellhu/redi'; import type { @@ -29,11 +29,14 @@ import { RemoveWorksheetMergeMutation, } from '../mutations/remove-worksheet-merge.mutation'; import { SetSelectionsOperation } from '../../commands/operations/selection.operation'; +import type { ISetRangeValuesMutationParams } from '../mutations/set-range-values.mutation'; +import { SetRangeValuesMutation } from '../mutations/set-range-values.mutation'; import { getSheetCommandTarget } from './utils/target-util'; export const RemoveWorksheetMergeCommand: ICommand = { type: CommandType.COMMAND, id: 'sheet.command.remove-worksheet-merge', + // eslint-disable-next-line max-lines-per-function handler: async (accessor: IAccessor) => { const selectionManagerService = accessor.get(SelectionManagerService); const commandService = accessor.get(ICommandService); @@ -53,17 +56,11 @@ export const RemoveWorksheetMergeCommand: ICommand = { ranges: selections, }; - // 范围内没有合并单元格return - let hasMerge = false; const mergeData = worksheet.getConfig().mergeData; - selections.forEach((selection) => { - mergeData.forEach((merge) => { - if (Rectangle.intersects(selection, merge)) { - hasMerge = true; - } - }); + const intersectsMerges = mergeData.filter((merge) => { + return selections.some((selection) => Rectangle.intersects(selection, merge)); }); - if (!hasMerge) return false; + if (!intersectsMerges.length) return false; const undoredoMutationParams: IAddWorksheetMergeMutationParams = RemoveMergeUndoMutationFactory( accessor, @@ -88,21 +85,65 @@ export const RemoveWorksheetMergeCommand: ICommand = { isMergedMainCell: false, }; - const result = sequenceExecute([ + const getSetRangeValuesParams = getSetRangeStyleParamsForRemoveMerge(worksheet, intersectsMerges); + const redoSetRangeValueParams: ISetRangeValuesMutationParams = { + unitId, + subUnitId, + cellValue: getSetRangeValuesParams.redoParams.getMatrix(), + }; + const undoSetRangeValueParams: ISetRangeValuesMutationParams = { + unitId, + subUnitId, + cellValue: getSetRangeValuesParams.undoParams.getMatrix(), + }; + + const redoMutations: IMutationInfo[] = [ { id: RemoveWorksheetMergeMutation.id, params: undoredoMutationParams }, + { id: SetRangeValuesMutation.id, params: redoSetRangeValueParams }, { id: SetSelectionsOperation.id, params: { selections: redoSelections } }, + ]; + + const undoMutations: IMutationInfo[] = [ + { id: AddWorksheetMergeMutation.id, params: undoredoMutationParams }, + { id: SetRangeValuesMutation.id, params: undoSetRangeValueParams }, + { id: SetSelectionsOperation.id, params: { selections: undoSelections } }, + ]; - ], commandService); + const result = sequenceExecute(redoMutations, commandService); if (result) { undoRedoService.pushUndoRedo({ unitID: unitId, - undoMutations: [{ id: AddWorksheetMergeMutation.id, params: undoredoMutationParams }, { id: SetSelectionsOperation.id, params: { selections: undoSelections } }], - // params should be the merged cells to be deleted accurately, rather than the selection - redoMutations: [{ id: RemoveWorksheetMergeMutation.id, params: undoredoMutationParams }, { id: SetSelectionsOperation.id, params: { selections: redoSelections } }], + undoMutations, + redoMutations, }); return true; } return false; }, }; + +function getSetRangeStyleParamsForRemoveMerge(worksheet: Worksheet, ranges: IRange[]) { + const styleRedoMatrix = new ObjectMatrix>(); + const styleUndoMatrix = new ObjectMatrix>(); + + ranges.forEach((range) => { + const { startRow, startColumn, endColumn, endRow } = range; + const cellValue = worksheet.getCellMatrix().getValue(startRow, startColumn); + if (cellValue?.s) { + for (let i = startRow; i <= endRow; i++) { + for (let j = startColumn; j <= endColumn; j++) { + if (i !== startRow || j !== startColumn) { + styleRedoMatrix.setValue(i, j, { s: cellValue.s }); + styleUndoMatrix.setValue(i, j, null); + } + } + } + } + }); + + return { + redoParams: styleRedoMatrix, + undoParams: styleUndoMatrix, + }; +} diff --git a/packages/sheets/src/commands/mutations/set-range-values.mutation.ts b/packages/sheets/src/commands/mutations/set-range-values.mutation.ts index 4c00c6e6856..488874eaac0 100644 --- a/packages/sheets/src/commands/mutations/set-range-values.mutation.ts +++ b/packages/sheets/src/commands/mutations/set-range-values.mutation.ts @@ -242,9 +242,14 @@ export const SetRangeValuesMutation: IMutation) : null); + if (newValueStream === oldVal.p.body?.dataStream) { + mergeRichTextStyle(oldVal.p, newVal.s ? (newVal.s as Nullable) : null); + } else { + delete oldVal.p; + } } } diff --git a/packages/ui/src/utils/cell.ts b/packages/ui/src/utils/cell.ts index 641a3a40dd2..959e06da757 100644 --- a/packages/ui/src/utils/cell.ts +++ b/packages/ui/src/utils/cell.ts @@ -179,8 +179,9 @@ export function handleStringToStyle($dom?: HTMLElement, cssStyle: string = '') { } // font family else if (key === 'font-family') { - const value = textTrim(originStr.substr(originStr.indexOf(':') + 1)); - styleList.ff = value; + const trimValue = textTrim(originStr); + const fontFamily = extractFontFamily(trimValue); + styleList.ff = fontFamily; } // font size else if (key === 'font-size') { @@ -937,3 +938,9 @@ function getPtFontSizeByPx(size: number) { if (ptSize > MAX_FONT_SIZE) return MAX_FONT_SIZE; return ptSize; } + +function extractFontFamily(styleStr: string) { + const regex = /font-family:\s*(?:"([^"]+)"|'([^']+)'|([^;]+))/i; + const matches = styleStr.match(regex); + return matches ? (matches[1] || matches[2] || matches[3]).trim() : null; +}