Skip to content

Commit

Permalink
Merge branch 'dev' into chore/cell-click-lag
Browse files Browse the repository at this point in the history
  • Loading branch information
lumixraku authored Jun 18, 2024
2 parents c00de87 + 4885f4f commit 9e7c1cb
Show file tree
Hide file tree
Showing 13 changed files with 156 additions and 53 deletions.
6 changes: 5 additions & 1 deletion packages/core/src/shared/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
WrapStrategy,
} from '../types/enum';
import { type IRange, RANGE_TYPE } from '../types/interfaces';
import type { ICellData } from '../types/interfaces/i-cell-data';
import type { ICellData, ICellDataForSheetInterceptor } from '../types/interfaces/i-cell-data';
import type { IDocumentData } from '../types/interfaces/i-document-data';
import type { IRangeWithCoord, ISelectionCell, ISelectionCellWithCoord } from '../types/interfaces/i-selection-data';
import type { IColorStyle, IStyleData } from '../types/interfaces/i-style-data';
Expand Down Expand Up @@ -132,6 +132,10 @@ export function isEmptyCell(cell: Nullable<ICellData>) {
return false;
}

export function isCellCoverable(cell: Nullable<ICellDataForSheetInterceptor>) {
return isEmptyCell(cell) && cell?.coverable !== false;
}

export function getColorStyle(color: Nullable<IColorStyle>): Nullable<string> {
if (color) {
if (color.rgb) {
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/types/interfaces/i-cell-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ export interface ICellDataForSheetInterceptor extends ICellData {
markers?: ICellMarks;
customRender?: Nullable<ICellCustomRender[]>;
interceptorAutoHeight?: number;
/**
* can cell be covered when sibling is overflow
*/
coverable?: boolean;
}

export function isICellData(value: any): value is ICellData {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
getColorStyle,
HorizontalAlign,
IContextService,
isEmptyCell,
isCellCoverable,
isNullCell,
isWhiteColor,
LocaleService,
Expand Down Expand Up @@ -1521,7 +1521,7 @@ export class SpreadsheetSkeleton extends Skeleton {
for (let i = startColumn; i >= endColumn; i--) {
const column = i;
const cell = this._worksheet?.getCell(row, column);
if ((!isEmptyCell(cell) && column !== startColumn) || this.intersectMergeRange(row, column)) {
if ((!isCellCoverable(cell) && column !== startColumn) || this.intersectMergeRange(row, column)) {
if (column === startColumn) {
return column;
}
Expand Down Expand Up @@ -1550,7 +1550,7 @@ export class SpreadsheetSkeleton extends Skeleton {
for (let i = startColumn; i <= endColumn; i++) {
const column = i;
const cell = this._worksheet?.getCell(row, column);
if ((!isEmptyCell(cell) && column !== startColumn) || this.intersectMergeRange(row, column)) {
if ((!isCellCoverable(cell) && column !== startColumn) || this.intersectMergeRange(row, column)) {
if (column === startColumn) {
return column;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export class SheetsDataValidationRenderController extends RxDisposable {
INTERCEPTOR_POINT.CELL_CONTENT,
{
priority: 200,
// eslint-disable-next-line max-lines-per-function
// eslint-disable-next-line max-lines-per-function, complexity
handler: (cell, pos, next) => {
const { row, col, unitId, subUnitId, workbook, worksheet } = pos;
const manager = this._dataValidationModel.ensureManager(unitId, subUnitId) as SheetDataValidationManager;
Expand Down Expand Up @@ -340,6 +340,7 @@ export class SheetsDataValidationRenderController extends RxDisposable {
};
return validator?.canvasRender?.calcCellAutoHeight?.(info);
},
coverable: (cell?.coverable ?? true) && !(rule.type === DataValidationType.LIST || rule.type === DataValidationType.LIST_MULTIPLE),
});
},
}
Expand Down
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
2 changes: 2 additions & 0 deletions packages/sheets-hyper-link-ui/src/common/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ export function serializeUrl(urlStr: string) {
) {
return url.hash;
}

return transformedUrl;
}

return urlStr;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
* limitations under the License.
*/

import type { IMutationInfo } from '@univerjs/core';
import { CellValueType, Disposable, IUniverInstanceService, LifecycleStages, ObjectMatrix, OnLifecycle, Range, Tools } from '@univerjs/core';
import type { IMutationInfo, Workbook } from '@univerjs/core';
import { CellValueType, Disposable, IUniverInstanceService, LifecycleStages, ObjectMatrix, OnLifecycle, Range, Tools, UniverInstanceType } from '@univerjs/core';
import { Inject, Injector } from '@wendellhu/redi';
import type { ISetRangeValuesMutationParams } from '@univerjs/sheets';
import { ClearSelectionAllCommand, ClearSelectionContentCommand, getSheetCommandTarget, SelectionManagerService, SetRangeValuesCommand, SetRangeValuesMutation, SetRangeValuesUndoMutationFactory, SheetInterceptorService } from '@univerjs/sheets';
import { ClearSelectionAllCommand, ClearSelectionContentCommand, ClearSelectionFormatCommand, getSheetCommandTarget, SelectionManagerService, SetRangeValuesCommand, SetRangeValuesMutation, SetRangeValuesUndoMutationFactory, SheetInterceptorService } from '@univerjs/sheets';
import type { IAddHyperLinkCommandParams, IUpdateHyperLinkCommandParams } from '@univerjs/sheets-hyper-link';
import { AddHyperLinkCommand, AddHyperLinkMutation, HyperLinkModel, RemoveHyperLinkMutation, UpdateHyperLinkCommand } from '@univerjs/sheets-hyper-link';
import { isLegalLink, serializeUrl } from '../common/util';
Expand Down Expand Up @@ -51,15 +51,17 @@ export class SheetHyperLinkSetRangeController extends Disposable {
if (command.id === AddHyperLinkCommand.id) {
const params = command.params as IAddHyperLinkCommandParams;
const { unitId, subUnitId, link } = params;
const currentCell = this._getCurrentCell(unitId, subUnitId, link.row, link.column);
const redoParams: ISetRangeValuesMutationParams = {
unitId,
subUnitId,
cellValue: {
[link.row]: {
[link.column]: {
v: link.display,
t: CellValueType.STRING,
// t: CellValueType.STRING, // Setting a link to a number is still a number
p: null,
t: currentCell?.t ?? undefined, // Keep force string type
},
},
},
Expand Down Expand Up @@ -211,7 +213,11 @@ export class SheetHyperLinkSetRangeController extends Disposable {
private _initClearSelectionCommandInterceptor() {
this.disposeWithMe(this._sheetInterceptorService.interceptCommand({
getMutations: (command) => {
if (command.id === ClearSelectionContentCommand.id || command.id === ClearSelectionAllCommand.id) {
if (
command.id === ClearSelectionContentCommand.id ||
command.id === ClearSelectionAllCommand.id ||
command.id === ClearSelectionFormatCommand.id
) {
const redos: IMutationInfo[] = [];
const undos: IMutationInfo[] = [];
const selection = this._selectionManagerService.getFirst();
Expand Down Expand Up @@ -254,4 +260,8 @@ export class SheetHyperLinkSetRangeController extends Disposable {
},
}));
}

private _getCurrentCell(unitId: string, subUnitId: string, row: number, col: number) {
return this._univerInstanceService.getUnit<Workbook>(unitId, UniverInstanceType.UNIVER_SHEET)?.getSheetBySheetId(subUnitId)?.getCell(row, col);
}
}
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,17 +14,15 @@
* limitations under the License.
*/

import type { ICellDataForSheetInterceptor, IRange, Workbook } from '@univerjs/core';
import type { Workbook } from '@univerjs/core';
import { DisposableCollection, IPermissionService, IUniverInstanceService, LifecycleStages, OnLifecycle, RxDisposable } from '@univerjs/core';
import { getSheetCommandTarget, RangeProtectionRuleModel } from '@univerjs/sheets';
import { getSheetCommandTarget, RangeProtectionRenderModel, WorksheetViewPermission } from '@univerjs/sheets';
import { Inject, Injector } from '@wendellhu/redi';
import type { IRenderContext, IRenderModule } from '@univerjs/engine-render';
import { UnitAction } from '@univerjs/protocol';
import { NullValueObject } from '@univerjs/engine-formula';
import { StatusBarController } from '../status-bar.controller';

type ICellPermission = Record<UnitAction, boolean> & { ruleId?: string; ranges?: IRange[] };

export const SHEET_PERMISSION_PASTE_PLUGIN = 'SHEET_PERMISSION_PASTE_PLUGIN';

@OnLifecycle(LifecycleStages.Steady, SheetPermissionInterceptorFormulaRenderController)
Expand All @@ -36,8 +34,8 @@ export class SheetPermissionInterceptorFormulaRenderController extends RxDisposa
@Inject(Injector) private readonly _injector: Injector,
@IUniverInstanceService private readonly _univerInstanceService: IUniverInstanceService,
@IPermissionService private readonly _permissionService: IPermissionService,
@Inject(RangeProtectionRuleModel) private _rangeProtectionRuleModel: RangeProtectionRuleModel,
@Inject(StatusBarController) private readonly _statusBarController: StatusBarController
@Inject(StatusBarController) private readonly _statusBarController: StatusBarController,
@Inject(RangeProtectionRenderModel) private _rangeProtectionRenderModel: RangeProtectionRenderModel
) {
super();
this._initStatusBarPermissionInterceptor();
Expand All @@ -52,20 +50,36 @@ export class SheetPermissionInterceptorFormulaRenderController extends RxDisposa
if (!target) {
return defaultValue ?? [];
}
const { worksheet } = target;
originValue.forEach((item) => {
const itemValue = item.getArrayValue();
const startRow = item.getCurrentRow();
const startCol = item.getCurrentColumn();
itemValue.forEach((row, rowIndex) => {
row.forEach((col, colIndex) => {
const permission = (worksheet.getCell(rowIndex + startRow, colIndex + startCol) as (ICellDataForSheetInterceptor & { selectionProtection: ICellPermission[] }))?.selectionProtection?.[0];
if (permission?.[UnitAction.View] === false) {
const { worksheet, unitId, subUnitId } = target;
const sheetViewPermission = this._permissionService.getPermissionPoint(new WorksheetViewPermission(unitId, subUnitId).id)?.value;
if (sheetViewPermission === false) {
originValue.forEach((item) => {
const itemValue = item.getArrayValue();
itemValue.forEach((row, rowIndex) => {
row.forEach((col, colIndex) => {
itemValue[rowIndex][colIndex] = NullValueObject.create();
}
});
});
});
} else {
originValue.forEach((item) => {
const itemValue = item.getArrayValue();
const startRow = item.getCurrentRow();
const startCol = item.getCurrentColumn();
itemValue.forEach((row, rowIndex) => {
row.forEach((col, colIndex) => {
const cellValue = worksheet.getCellRaw(rowIndex + startRow, colIndex + startCol)?.v;
if (cellValue === undefined) {
return;
}
const permission = this._rangeProtectionRenderModel.getCellInfo(unitId, subUnitId, rowIndex + startRow, colIndex + startCol)?.[0];
if (permission?.[UnitAction.View] === false) {
itemValue[rowIndex][colIndex] = NullValueObject.create();
}
});
});
});
});
}
return originValue;
},
})
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,
};
}
Loading

0 comments on commit 9e7c1cb

Please sign in to comment.