Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions packages/core/src/sheets/worksheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,15 @@ export class Worksheet {
return this._spanModel;
}

getStyleDataByHash(hash: string): Nullable<IStyleData> {
const data = this._styles.get(hash);
return { ...data };
}

setStyleData(style: IStyleData): Nullable<string> {
return this._styles.setValue(style);
}

/**
* Get the style of the column.
* @param {number} column The column index
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { APPLY_TYPE, getAutoFillRepeatRange, IAutoFillService, virtualizeDiscret
export class DataValidationAutoFillController extends Disposable {
constructor(
@IAutoFillService private readonly _autoFillService: IAutoFillService,
@Inject(SheetDataValidationModel) private readonly _dataValidationModel: SheetDataValidationModel,
@Inject(SheetDataValidationModel) private readonly _sheetDataValidationModel: SheetDataValidationModel,
@Inject(Injector) private readonly _injector: Injector
) {
super();
Expand All @@ -37,7 +37,7 @@ export class DataValidationAutoFillController extends Disposable {

const generalApplyFunc = (location: IAutoFillLocation, applyType: APPLY_TYPE) => {
const { source: sourceRange, target: targetRange, unitId, subUnitId } = location;
const ruleMatrixCopy = this._dataValidationModel.getRuleObjectMatrix(unitId, subUnitId).clone();
const ruleMatrixCopy = this._sheetDataValidationModel.getRuleObjectMatrix(unitId, subUnitId).clone();

const virtualRange = virtualizeDiscreteRanges([sourceRange, targetRange]);
const [vSourceRange, vTargetRange] = virtualRange.ranges;
Expand Down Expand Up @@ -75,27 +75,26 @@ export class DataValidationAutoFillController extends Disposable {
sourceRange
);
const { row: sourceRow, col: sourceCol } = mapFunc(sourcePositionRange.startRow, sourcePositionRange.startColumn);
const ruleId = this._dataValidationModel.getRuleIdByLocation(unitId, subUnitId, sourceRow, sourceCol);
if (ruleId) {
const targetPositionRange = Rectangle.getPositionRange(
{
startRow: row,
startColumn: col,
endColumn: col,
endRow: row,
},
targetRange
);
const { row: targetRow, col: targetCol } = mapFunc(targetPositionRange.startRow, targetPositionRange.startColumn);
// if ruleId exists, set more dv rules, if not, clear dv rules.
const ruleId = this._sheetDataValidationModel.getRuleIdByLocation(unitId, subUnitId, sourceRow, sourceCol) || '';
const targetPositionRange = Rectangle.getPositionRange(
{
startRow: row,
startColumn: col,
endColumn: col,
endRow: row,
},
targetRange
);
const { row: targetRow, col: targetCol } = mapFunc(targetPositionRange.startRow, targetPositionRange.startColumn);

additionMatrix.setValue(targetRow, targetCol, ruleId);
additionRules.add(ruleId);
}
additionMatrix.setValue(targetRow, targetCol, ruleId);
additionRules.add(ruleId);
});
});
const additions = Array.from(additionRules).map((id) => ({ id, ranges: queryObjectMatrix(additionMatrix, (value) => value === id) }));
ruleMatrixCopy.addRangeRules(additions);
const diffs = ruleMatrixCopy.diff(this._dataValidationModel.getRules(unitId, subUnitId));
const diffs = ruleMatrixCopy.diff(this._sheetDataValidationModel.getRules(unitId, subUnitId));
const { redoMutations, undoMutations } = getDataValidationDiffMutations(unitId, subUnitId, diffs, this._injector, 'patched', applyType === APPLY_TYPE.ONLY_FORMAT);
return {
undos: undoMutations,
Expand All @@ -111,7 +110,7 @@ export class DataValidationAutoFillController extends Disposable {
const { source: sourceRange, unitId, subUnitId } = location;
for (const row of sourceRange.rows) {
for (const col of sourceRange.cols) {
const dv = this._dataValidationModel.getRuleByLocation(unitId, subUnitId, row, col);
const dv = this._sheetDataValidationModel.getRuleByLocation(unitId, subUnitId, row, col);
if (dv && disabledDataVallation.indexOf(dv.type) > -1) {
this._autoFillService.setDisableApplyType(APPLY_TYPE.SERIES, true);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,34 @@ export function getDataValidationDiffMutations(
},
} as IUpdateDataValidationMutationParams,
});
} else {
redoMutations.push({
id: UpdateDataValidationMutation.id,
params: {
unitId,
subUnitId,
ruleId: diff.ruleId,
payload: {
type: UpdateRuleType.RANGE,
payload: diff.newRanges,
},
source,
} as IUpdateDataValidationMutationParams,
});

undoMutations.unshift({
id: UpdateDataValidationMutation.id,
params: {
unitId,
subUnitId,
ruleId: diff.ruleId,
payload: {
type: UpdateRuleType.RANGE,
payload: diff.oldRanges,
},
source,
} as IUpdateDataValidationMutationParams,
});
}
} else {
redoMutations.push({
Expand Down
10 changes: 9 additions & 1 deletion packages/sheets-data-validation/src/utils/formula.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,13 @@ export function isLegalFormulaResult(res: string) {
* Judge if the data-validation's formula need to be offseted by ranges
*/
export function isCustomFormulaType(type: DataValidationType) {
return type !== DataValidationType.LIST && type !== DataValidationType.LIST_MULTIPLE && type !== DataValidationType.CHECKBOX && type !== DataValidationType.ANY;
// types not in this list is formula type
const invalidTypes = [
DataValidationType.LIST,
DataValidationType.LIST_MULTIPLE,
DataValidationType.CHECKBOX,
DataValidationType.ANY,
];

return !invalidTypes.includes(type);
}
36 changes: 18 additions & 18 deletions packages/sheets-ui/src/services/clipboard/clipboard.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@
* limitations under the License.
*/

import type {
ICellData, IDisposable,
IMutationInfo,
IRange,
Nullable, Workbook, Worksheet,
} from '@univerjs/core';
import type { ISetSelectionsOperationParams } from '@univerjs/sheets';
import type { IDiscreteRange } from '../../controllers/utils/range-tools';
import type {
ICellDataWithSpanInfo,
IClipboardPropertyItem,
IPasteTarget,
ISheetClipboardHook,
ISheetDiscreteRangeLocation,
IUniverSheetCopyDataModel,
} from './type';
import {
createIdentifier, Disposable, ErrorService, extractPureTextFromCell, ICommandService,
ILogService,
Expand All @@ -29,43 +45,27 @@ import {
UniverInstanceType,
} from '@univerjs/core';
import { IRenderManagerService } from '@univerjs/engine-render';

import {
getPrimaryForRange,
SetSelectionsOperation,
SheetsSelectionsService,
} from '@univerjs/sheets';
import { HTML_CLIPBOARD_MIME_TYPE, IClipboardInterfaceService, INotificationService, IPlatformService, PLAIN_TEXT_CLIPBOARD_MIME_TYPE } from '@univerjs/ui';
import { BehaviorSubject } from 'rxjs';
import type {
ICellData, IDisposable,
IMutationInfo,
IRange,
Nullable, Workbook, Worksheet,
} from '@univerjs/core';

import type { ISetSelectionsOperationParams } from '@univerjs/sheets';
import { rangeToDiscreteRange, virtualizeDiscreteRanges } from '../../controllers/utils/range-tools';
import { IMarkSelectionService } from '../mark-selection/mark-selection.service';
import { SheetSkeletonManagerService } from '../sheet-skeleton-manager.service';
import { createCopyPasteSelectionStyle } from '../utils/selection-util';
import { CopyContentCache, extractId, genId } from './copy-content-cache';

import { HtmlToUSMService } from './html-to-usm/converter';
import { LarkPastePlugin } from './html-to-usm/paste-plugins/plugin-lark';

import { UniverPastePlugin } from './html-to-usm/paste-plugins/plugin-univer';
import { WordPastePlugin } from './html-to-usm/paste-plugins/plugin-word';
import { COPY_TYPE } from './type';
import { USMToHtmlService } from './usm-to-html/convertor';
import { clipboardItemIsFromExcel, convertTextToTable, discreteRangeContainsRange, mergeSetRangeValues, rangeIntersectWithDiscreteRange } from './utils';
import type { IDiscreteRange } from '../../controllers/utils/range-tools';
import type {
ICellDataWithSpanInfo,
IClipboardPropertyItem,
IPasteTarget,
ISheetClipboardHook,
ISheetDiscreteRangeLocation,
IUniverSheetCopyDataModel,
} from './type';

export const PREDEFINED_HOOK_NAME = {
DEFAULT_COPY: 'default-copy',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { SheetInterceptorService } from '../../services/sheet-interceptor/sheet-
import { InsertRowMutation, InsertRowMutationUndoFactory } from '../mutations/insert-row-col.mutation';
import { RemoveRowMutation } from '../mutations/remove-row-col.mutation';
import { getInsertRangeMutations } from '../utils/handle-range-mutation';
import { followSelectionOperation } from './utils/selection-utils';
import { copyStylesOmitSpecProps, followSelectionOperation } from './utils/selection-utils';
import { getSheetCommandTarget } from './utils/target-util';

export interface InsertRangeMoveDownCommandParams {
Expand Down Expand Up @@ -123,13 +123,14 @@ export const InsertRangeMoveDownCommand: ICommand = {
// to keep style.
const cellValue: IObjectMatrixPrimitiveType<ICellData> = {};
Range.foreach(range, (row, col) => {
const cell = worksheet.getCell(row, col);
let cell = worksheet.getCell(row, col);
if (!cell) {
return;
}
if (!cellValue[row]) {
cellValue[row] = {};
}
cell = copyStylesOmitSpecProps(cell, worksheet, ['bd']);
cellValue[row][col] = { s: cell.s };
});
const insertRangeMutationParams: IInsertRangeMutationParams = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
* limitations under the License.
*/

import type { IAccessor, ICellData, ICommand, IMutationInfo, IObjectMatrixPrimitiveType, IRange } from '@univerjs/core';
import type {
IInsertColMutationParams,
IInsertRangeMutationParams,
IRemoveColMutationParams,
} from '../../basics/interfaces/mutation-interface';

import {
BooleanNumber,
CommandType,
Expand All @@ -26,20 +33,13 @@ import {
Range,
sequenceExecute,
} from '@univerjs/core';
import type { IAccessor, ICellData, ICommand, IMutationInfo, IObjectMatrixPrimitiveType, IRange } from '@univerjs/core';

import { SheetsSelectionsService } from '../../services/selections/selection-manager.service';
import { SheetInterceptorService } from '../../services/sheet-interceptor/sheet-interceptor.service';
import { InsertColMutation, InsertColMutationUndoFactory } from '../mutations/insert-row-col.mutation';
import { RemoveColMutation } from '../mutations/remove-row-col.mutation';
import { getInsertRangeMutations } from '../utils/handle-range-mutation';
import { followSelectionOperation } from './utils/selection-utils';
import { copyStylesOmitSpecProps, followSelectionOperation } from './utils/selection-utils';
import { getSheetCommandTarget } from './utils/target-util';
import type {
IInsertColMutationParams,
IInsertRangeMutationParams,
IRemoveColMutationParams,
} from '../../basics/interfaces/mutation-interface';

export interface InsertRangeMoveRightCommandParams {
range: IRange;
Expand Down Expand Up @@ -124,13 +124,14 @@ export const InsertRangeMoveRightCommand: ICommand = {
// to keep style.
const cellValue: IObjectMatrixPrimitiveType<ICellData> = {};
Range.foreach(range, (row, col) => {
const cell = worksheet.getCell(row, col);
let cell = worksheet.getCell(row, col);
if (!cell || !cell.s) {
return;
}
if (!cellValue[row]) {
cellValue[row] = {};
}
cell = copyStylesOmitSpecProps(cell, worksheet, ['bd']);
cellValue[row][col] = { s: cell.s };
});
const insertRangeMutationParams: IInsertRangeMutationParams = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import {
} from '../mutations/insert-row-col.mutation';
import { RemoveColMutation, RemoveRowMutation } from '../mutations/remove-row-col.mutation';
import { SetRangeValuesMutation } from '../mutations/set-range-values.mutation';
import { copyRangeStyles, followSelectionOperation } from './utils/selection-utils';
import { copyRangeStylesWithoutBorder, followSelectionOperation } from './utils/selection-utils';
import { getSheetCommandTarget } from './utils/target-util';

export interface IInsertRowCommandParams {
Expand Down Expand Up @@ -182,7 +182,7 @@ export const InsertRowBeforeCommand: ICommand = {
endColumn,
},
// copy styles from the row above
cellValue: copyRangeStyles(worksheet, startRow, endRow, startColumn, endColumn, true, startRow - 1),
cellValue: copyRangeStylesWithoutBorder(worksheet, startRow, endRow, startColumn, endColumn, true, startRow - 1),
};

return accessor.get(ICommandService).executeCommand(InsertRowCommand.id, insertRowParams);
Expand Down Expand Up @@ -229,7 +229,7 @@ export const InsertRowAfterCommand: ICommand = {
rangeType: RANGE_TYPE.ROW,
},
// copy styles from the row below
cellValue: copyRangeStyles(worksheet, startRow, endRow, startColumn, endColumn, true, range.endRow),
cellValue: copyRangeStylesWithoutBorder(worksheet, startRow, endRow, startColumn, endColumn, true, range.endRow),
};

return accessor.get(ICommandService).executeCommand(InsertRowCommand.id, insertRowParams);
Expand Down Expand Up @@ -364,8 +364,8 @@ export const InsertColBeforeCommand: ICommand = {
rangeType: RANGE_TYPE.COLUMN,
},

// copy styles from the column before
cellValue: copyRangeStyles(worksheet, startRow, endRow, startColumn, endColumn, false, startColumn - 1),
// copy styles from the left adjacent column
cellValue: copyRangeStylesWithoutBorder(worksheet, startRow, endRow, startColumn, endColumn, false, startColumn - 1),
};

return accessor.get(ICommandService).executeCommand(InsertColCommand.id, insertColParams);
Expand Down Expand Up @@ -409,7 +409,7 @@ export const InsertColAfterCommand: ICommand = {
endRow,
},
// copy styles from the column after
cellValue: copyRangeStyles(worksheet, startRow, endRow, startColumn, endColumn, false, range.endColumn),
cellValue: copyRangeStylesWithoutBorder(worksheet, startRow, endRow, startColumn, endColumn, false, range.endColumn),
};

return accessor.get(ICommandService).executeCommand(InsertColCommand.id, insertColParams);
Expand Down
46 changes: 44 additions & 2 deletions packages/sheets/src/commands/commands/utils/selection-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import type { ICellData, IObjectMatrixPrimitiveType, IRange, ISelectionCell, Nullable, Workbook, Worksheet } from '@univerjs/core';
import type { ICellData, IObjectMatrixPrimitiveType, IRange, ISelectionCell, IStyleData, Nullable, Workbook, Worksheet } from '@univerjs/core';
import type { ISelectionWithStyle } from '../../../basics/selection';

import type { ISetSelectionsOperationParams } from '../../operations/selection.operation';
Expand Down Expand Up @@ -243,7 +243,6 @@ export function createRangeIteratorWithSkipFilteredRows(sheet: Worksheet) {
* @param endColumn
* @param isRow
* @param styleRowOrColumn
* @returns
*/
export function copyRangeStyles(
worksheet: Worksheet,
Expand All @@ -269,3 +268,46 @@ export function copyRangeStyles(
}
return cellValue;
}

export function copyRangeStylesWithoutBorder(
worksheet: Worksheet,
startRow: number,
endRow: number,
startColumn: number,
endColumn: number,
isRow: boolean,
styleRowOrColumn: number
): IObjectMatrixPrimitiveType<ICellData> {
const cellDataMatrix: IObjectMatrixPrimitiveType<ICellData> = {};
for (let row = startRow; row <= endRow; row++) {
for (let column = startColumn; column <= endColumn; column++) {
let cell = isRow ? worksheet.getCell(styleRowOrColumn, column) : worksheet.getCell(row, styleRowOrColumn);
if (!cell || !cell.s) {
continue;
}
if (!cellDataMatrix[row]) {
cellDataMatrix[row] = {};
}

// univer-pro/issues/3016 insert row/column should not reuse border style
cell = copyStylesOmitSpecProps(cell, worksheet, ['bd']);
cellDataMatrix[row][column] = { s: cell.s };
}
}
return cellDataMatrix;
}

export function copyStylesOmitSpecProps(cell: ICellData, worksheet: Worksheet, props: (keyof IStyleData)[]) {
if (typeof cell.s === 'string') {
const styleData = worksheet.getStyleDataByHash(cell.s);
if (styleData) {
props.forEach((prop) => delete styleData[prop]);
cell.s = worksheet.setStyleData(styleData);
}
} else {
const styleData: IStyleData = { ...cell.s };
props.forEach((prop) => delete styleData[prop]);
cell.s = worksheet.setStyleData(styleData);
}
return cell;
}
Loading