Skip to content

Commit

Permalink
fix(sheets): fix some bugs (#2536)
Browse files Browse the repository at this point in the history
  • Loading branch information
ybzky committed Jun 17, 2024
1 parent 17130d1 commit 250763e
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
17 changes: 10 additions & 7 deletions packages/sheets-ui/src/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,22 @@ export function getClearContentMutationParamsForRanges(
};
}

export function getClearContentMutationParamForRange(
worksheet: Worksheet,
range: IRange
): ObjectMatrix<Nullable<ICellData>> {
function getClearContentMutationParamForRange(worksheet: Worksheet, range: IRange): ObjectMatrix<Nullable<ICellData>> {
const { startRow, startColumn, endColumn, endRow } = range;
const cellMatrix = worksheet.getMatrixWithMergedCells(startRow, startColumn, endRow, endColumn);
const redoMatrix = new ObjectMatrix<Nullable<ICellData>>();
let leftTopCellValue: Nullable<ICellData> = 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;
}

Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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);
Expand All @@ -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,
Expand All @@ -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<Nullable<ICellData>>();
const styleUndoMatrix = new ObjectMatrix<Nullable<ICellData>>();

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,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,14 @@ export const SetRangeValuesMutation: IMutation<ISetRangeValuesMutationParams, bo
oldVal.s = styles.setValue(merge);
}

const newValueStream = `${newVal.v}\r\n`;
// Only need to copy newValue.s to oldValue.p when you modify the cell style, not when you modify the cell value.
if (!newVal.p && oldVal.p) {
mergeRichTextStyle(oldVal.p, newVal.s ? (newVal.s as Nullable<IStyleData>) : null);
if (newValueStream === oldVal.p.body?.dataStream) {
mergeRichTextStyle(oldVal.p, newVal.s ? (newVal.s as Nullable<IStyleData>) : null);
} else {
delete oldVal.p;
}
}
}

Expand Down
11 changes: 9 additions & 2 deletions packages/ui/src/utils/cell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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') {
Expand Down Expand Up @@ -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;
}

0 comments on commit 250763e

Please sign in to comment.