refactor(drawing): migrate some logic from sheets-drawing-ui to sheets-drawing package (#6750)

This commit is contained in:
wpxp123456
2026-03-31 17:08:33 +08:00
committed by GitHub
parent e0e8eb03a8
commit 7bee2ab0fd
146 changed files with 3993 additions and 4325 deletions
+1
View File
@@ -70,6 +70,7 @@ import '@univerjs/sheets-hyper-link-ui/facade';
import '@univerjs/sheets-thread-comment/facade';
import '@univerjs/sheets-conditional-formatting/facade';
import '@univerjs/sheets-find-replace/facade';
import '@univerjs/sheets-drawing/facade';
import '@univerjs/sheets-drawing-ui/facade';
import '@univerjs/sheets-zen-editor/facade';
import '@univerjs/sheets-crosshair-highlight/facade';
+2 -2
View File
@@ -45,7 +45,7 @@ export interface IFUniverDocsUIMixin {
getActiveDocument(): FDocument | null;
}
export class FUniverDocsMixin extends FUniver implements IFUniverDocsUIMixin {
export class FUniverDocsUIMixin extends FUniver implements IFUniverDocsUIMixin {
override createUniverDoc(data: Partial<IDocumentData>): FDocument {
const document = this._univerInstanceService.createUnit<IDocumentData, DocumentDataModel>(UniverInstanceType.UNIVER_DOC, data);
return this._injector.createInstance(FDocument, document);
@@ -70,7 +70,7 @@ export class FUniverDocsMixin extends FUniver implements IFUniverDocsUIMixin {
}
}
FUniver.extend(FUniverDocsMixin);
FUniver.extend(FUniverDocsUIMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FUniver extends IFUniverDocsUIMixin {}
@@ -20,7 +20,7 @@ import { CFNumberOperator, CFTimePeriodOperator } from '@univerjs/sheets-conditi
/**
* @ignore
*/
export interface IFSheetsConditionalFormattingEnum {
export interface IFSheetsConditionalFormattingEnumMixin {
/**
* Conditional formatting number operator
*/
@@ -32,19 +32,19 @@ export interface IFSheetsConditionalFormattingEnum {
ConditionFormatTimePeriodOperatorEnum: typeof CFTimePeriodOperator;
}
export class FSheetsConditionalFormattingEnum implements IFSheetsConditionalFormattingEnum {
get ConditionFormatNumberOperatorEnum(): typeof CFNumberOperator {
export class FSheetsConditionalFormattingEnumMixin extends FEnum implements IFSheetsConditionalFormattingEnumMixin {
override get ConditionFormatNumberOperatorEnum(): typeof CFNumberOperator {
return CFNumberOperator;
}
get ConditionFormatTimePeriodOperatorEnum(): typeof CFTimePeriodOperator {
override get ConditionFormatTimePeriodOperatorEnum(): typeof CFTimePeriodOperator {
return CFTimePeriodOperator;
}
}
FEnum.extend(FSheetsConditionalFormattingEnum);
FEnum.extend(FSheetsConditionalFormattingEnumMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
export interface FEnum extends IFSheetsConditionalFormattingEnum {
export interface FEnum extends IFSheetsConditionalFormattingEnumMixin {
}
}
@@ -39,7 +39,7 @@ import { FConditionalFormattingBuilder } from './f-conditional-formatting-builde
/**
* @ignore
*/
export interface IFRangeConditionalFormattingMixin {
export interface IFRangeSheetsConditionalFormattingMixin {
/**
* Gets all the conditional formatting for the current range.
* @returns {IConditionFormattingRule[]} conditional formatting rules for the current range.
@@ -146,7 +146,7 @@ export interface IFRangeConditionalFormattingMixin {
clearConditionalFormatRules(): FRange;
}
export class FRangeConditionalFormattingMixin extends FRange implements IFRangeConditionalFormattingMixin {
export class FRangeSheetsConditionalFormattingMixin extends FRange implements IFRangeSheetsConditionalFormattingMixin {
private _getConditionalFormattingRuleModel(): ConditionalFormattingRuleModel {
return this._injector.get(ConditionalFormattingRuleModel);
}
@@ -213,8 +213,8 @@ export class FRangeConditionalFormattingMixin extends FRange implements IFRangeC
}
}
FRange.extend(FRangeConditionalFormattingMixin);
FRange.extend(FRangeSheetsConditionalFormattingMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FRange extends IFRangeConditionalFormattingMixin { }
interface FRange extends IFRangeSheetsConditionalFormattingMixin { }
}
@@ -19,5 +19,5 @@ import './f-worksheet';
import './f-enum';
export { FConditionalFormattingBuilder } from './f-conditional-formatting-builder';
export type { IFRangeConditionalFormattingMixin } from './f-range';
export type { IFRangeSheetsConditionalFormattingMixin } from './f-range';
export type { IFWorksheetConditionalFormattingMixin } from './f-worksheet';
@@ -0,0 +1,110 @@
/**
* 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.
*/
import type { IEventBase } from '@univerjs/core/facade';
import type { FWorkbook, FWorksheet } from '@univerjs/sheets/facade';
import { FEventName } from '@univerjs/core/facade';
export interface IFSheetsCrosshairHighlightEventNameMixin {
/**
* Triggered when the crosshair highlight is enabled or disabled.
* @see {@link ICrosshairHighlightEnabledChangedEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.CrosshairHighlightEnabledChanged, (params) => {
* const { enabled, workbook, worksheet } = params;
* console.log(params);
* });
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly CrosshairHighlightEnabledChanged: 'CrosshairHighlightEnabledChanged';
/**
* Triggered when the crosshair highlight color is changed.
* @see {@link ICrosshairHighlightColorChangedEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.CrosshairHighlightColorChanged, (params) => {
* const { color, workbook, worksheet } = params;
* console.log(params);
* });
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly CrosshairHighlightColorChanged: 'CrosshairHighlightColorChanged';
}
/**
* @ignore
*/
export class FSheetsCrosshairHighlightEventNameMixin extends FEventName implements IFSheetsCrosshairHighlightEventNameMixin {
override get CrosshairHighlightEnabledChanged(): 'CrosshairHighlightEnabledChanged' {
return 'CrosshairHighlightEnabledChanged';
}
override get CrosshairHighlightColorChanged(): 'CrosshairHighlightColorChanged' {
return 'CrosshairHighlightColorChanged';
}
}
export interface ICrosshairHighlightEnabledChangedEventParams extends IEventBase {
/**
* Whether the crosshair highlight is enabled.
*/
enabled: boolean;
/**
* The workbook that the crosshair highlight is enabled in.
*/
workbook: FWorkbook;
/**
* The worksheet that the crosshair highlight is enabled in.
*/
worksheet: FWorksheet;
}
export interface ICrosshairHighlightColorChangedEventParams extends IEventBase {
/**
* The color of the crosshair highlight.
*/
color: string;
/**
* The workbook that the crosshair highlight is enabled in.
*/
workbook: FWorkbook;
/**
* The worksheet that the crosshair highlight is enabled in.
*/
worksheet: FWorksheet;
}
/**
* @ignore
*/
export interface ISheetsCrosshairHighlightEventParamConfig {
CrosshairHighlightEnabledChanged: ICrosshairHighlightEnabledChangedEventParams;
CrosshairHighlightColorChanged: ICrosshairHighlightColorChangedEventParams;
}
FEventName.extend(FSheetsCrosshairHighlightEventNameMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FEventName extends IFSheetsCrosshairHighlightEventNameMixin { }
interface IEventParamConfig extends ISheetsCrosshairHighlightEventParamConfig { }
}
@@ -51,10 +51,11 @@ vi.mock('@univerjs/sheets-crosshair-highlight', () => ({
describe('crosshair facade', () => {
it('should register mixins and cover event wiring + APIs', async () => {
const module = await import('./f-univer');
const module1 = await import('./f-univer');
const module2 = await import('./f-event');
expect(mocked.extendEvent).toHaveBeenCalledWith(module.FSheetCrosshairHighlightEventMixin);
expect(mocked.extendUniver).toHaveBeenCalledWith(module.FUniverCrosshairHighlightMixin);
expect(mocked.extendEvent).toHaveBeenCalledWith(module2.FSheetsCrosshairHighlightEventNameMixin);
expect(mocked.extendUniver).toHaveBeenCalledWith(module1.FUniverSheetsCrosshairHighlightMixin);
const callbacks: Array<(commandInfo: { id: string }) => void> = [];
const commandService = {
@@ -90,7 +91,7 @@ describe('crosshair facade', () => {
disposeWithMe: vi.fn(),
};
module.FUniverCrosshairHighlightMixin.prototype._initialize.call(
module1.FUniverSheetsCrosshairHighlightMixin.prototype._initialize.call(
thisArg,
{ get: vi.fn(() => commandService) } as never
);
@@ -108,22 +109,22 @@ describe('crosshair facade', () => {
callbacks[0]({ id: mocked.enableId });
callbacks[1]({ id: mocked.setColorId });
const enabledResult = module.FUniverCrosshairHighlightMixin.prototype.setCrosshairHighlightEnabled.call(thisArg, true);
const disabledResult = module.FUniverCrosshairHighlightMixin.prototype.setCrosshairHighlightEnabled.call(thisArg, false);
const enabledResult = module1.FUniverSheetsCrosshairHighlightMixin.prototype.setCrosshairHighlightEnabled.call(thisArg, true);
const disabledResult = module1.FUniverSheetsCrosshairHighlightMixin.prototype.setCrosshairHighlightEnabled.call(thisArg, false);
expect(enabledResult).toBe(thisArg);
expect(disabledResult).toBe(thisArg);
expect(thisArg._commandService.syncExecuteCommand).toHaveBeenCalledWith(mocked.enableId);
expect(thisArg._commandService.syncExecuteCommand).toHaveBeenCalledWith(mocked.disableId);
const colorResult = module.FUniverCrosshairHighlightMixin.prototype.setCrosshairHighlightColor.call(thisArg, '#ff0000');
const colorResult = module1.FUniverSheetsCrosshairHighlightMixin.prototype.setCrosshairHighlightColor.call(thisArg, '#ff0000');
expect(colorResult).toBe(thisArg);
expect(thisArg._commandService.syncExecuteCommand).toHaveBeenCalledWith(mocked.setColorId, { value: '#ff0000' });
expect(module.FUniverCrosshairHighlightMixin.prototype.getCrosshairHighlightEnabled.call(thisArg)).toBe(true);
expect(module.FUniverCrosshairHighlightMixin.prototype.getCrosshairHighlightColor.call(thisArg)).toBe('rgba(1,2,3,0.2)');
expect(module.FUniverCrosshairHighlightMixin.prototype.CROSSHAIR_HIGHLIGHT_COLORS).toBe(mocked.colors);
expect(module1.FUniverSheetsCrosshairHighlightMixin.prototype.getCrosshairHighlightEnabled.call(thisArg)).toBe(true);
expect(module1.FUniverSheetsCrosshairHighlightMixin.prototype.getCrosshairHighlightColor.call(thisArg)).toBe('rgba(1,2,3,0.2)');
expect(module1.FUniverSheetsCrosshairHighlightMixin.prototype.CROSSHAIR_HIGHLIGHT_COLORS).toBe(mocked.colors);
const eventEnum = new module.FSheetCrosshairHighlightEventMixin();
const eventEnum = new module2.FSheetsCrosshairHighlightEventNameMixin();
expect(eventEnum.CrosshairHighlightEnabledChanged).toBe('CrosshairHighlightEnabledChanged');
expect(eventEnum.CrosshairHighlightColorChanged).toBe('CrosshairHighlightColorChanged');
});
@@ -15,103 +15,23 @@
*/
import type { Injector } from '@univerjs/core';
import type { IEventBase } from '@univerjs/core/facade';
import type { ISetCrosshairHighlightColorOperationParams } from '@univerjs/sheets-crosshair-highlight';
import type { FWorkbook, FWorksheet } from '@univerjs/sheets/facade';
import type { ICrosshairHighlightColorChangedEventParams, ICrosshairHighlightEnabledChangedEventParams } from './f-event';
import { ICommandService } from '@univerjs/core';
import { FEventName, FUniver } from '@univerjs/core/facade';
import { CROSSHAIR_HIGHLIGHT_COLORS, DisableCrosshairHighlightOperation, EnableCrosshairHighlightOperation, SetCrosshairHighlightColorOperation, SheetsCrosshairHighlightService, ToggleCrosshairHighlightOperation } from '@univerjs/sheets-crosshair-highlight';
import { FUniver } from '@univerjs/core/facade';
import {
CROSSHAIR_HIGHLIGHT_COLORS,
DisableCrosshairHighlightOperation,
EnableCrosshairHighlightOperation,
SetCrosshairHighlightColorOperation,
SheetsCrosshairHighlightService,
ToggleCrosshairHighlightOperation,
} from '@univerjs/sheets-crosshair-highlight';
/**
* @ignore
*/
export interface IFSheetCrosshairHighlightEventMixin {
/**
* Triggered when the crosshair highlight is enabled or disabled.
* @see {@link ICrosshairHighlightEnabledChangedEvent}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.CrosshairHighlightEnabledChanged, (params) => {
* const { enabled, workbook, worksheet } = params;
* console.log(params);
* });
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly CrosshairHighlightEnabledChanged: 'CrosshairHighlightEnabledChanged';
/**
* Triggered when the crosshair highlight color is changed.
* @see {@link ICrosshairHighlightColorChangedEvent}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.CrosshairHighlightColorChanged, (params) => {
* const { color, workbook, worksheet } = params;
* console.log(params);
* });
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly CrosshairHighlightColorChanged: 'CrosshairHighlightColorChanged';
}
export interface ICrosshairHighlightEnabledChangedEvent extends IEventBase {
/**
* Whether the crosshair highlight is enabled.
*/
enabled: boolean;
/**
* The workbook that the crosshair highlight is enabled in.
*/
workbook: FWorkbook;
/**
* The worksheet that the crosshair highlight is enabled in.
*/
worksheet: FWorksheet;
}
export interface ICrosshairHighlightColorChangedEvent extends IEventBase {
/**
* The color of the crosshair highlight.
*/
color: string;
/**
* The workbook that the crosshair highlight is enabled in.
*/
workbook: FWorkbook;
/**
* The worksheet that the crosshair highlight is enabled in.
*/
worksheet: FWorksheet;
}
/**
* @ignore
*/
export class FSheetCrosshairHighlightEventMixin implements IFSheetCrosshairHighlightEventMixin {
get CrosshairHighlightEnabledChanged(): 'CrosshairHighlightEnabledChanged' {
return 'CrosshairHighlightEnabledChanged';
}
get CrosshairHighlightColorChanged(): 'CrosshairHighlightColorChanged' {
return 'CrosshairHighlightColorChanged';
}
}
/**
* @ignore
*/
export interface ISheetCrosshairHighlightEventConfigs {
CrosshairHighlightEnabledChanged: ICrosshairHighlightEnabledChangedEvent;
CrosshairHighlightColorChanged: ICrosshairHighlightColorChangedEvent;
}
/**
* @ignore
*/
export interface IFUniverCrosshairHighlightMixin {
export interface IFUniverSheetsCrosshairHighlightMixin {
/**
* Enable or disable crosshair highlight.
* @param {boolean} enabled - Whether to enable the crosshair highlight
@@ -165,7 +85,7 @@ export interface IFUniverCrosshairHighlightMixin {
/**
* @ignore
*/
export class FUniverCrosshairHighlightMixin extends FUniver implements IFUniverCrosshairHighlightMixin {
export class FUniverSheetsCrosshairHighlightMixin extends FUniver implements IFUniverSheetsCrosshairHighlightMixin {
/**
* @ignore
*/
@@ -183,10 +103,11 @@ export class FUniverCrosshairHighlightMixin extends FUniver implements IFUniverC
) {
const activeSheet = this.getActiveSheet();
if (!activeSheet) return;
this.fireEvent(this.Event.CrosshairHighlightEnabledChanged, {
const eventParams: ICrosshairHighlightEnabledChangedEventParams = {
enabled: this.getCrosshairHighlightEnabled(),
...activeSheet,
});
};
this.fireEvent(this.Event.CrosshairHighlightEnabledChanged, eventParams);
}
})
)
@@ -199,10 +120,11 @@ export class FUniverCrosshairHighlightMixin extends FUniver implements IFUniverC
if (commandInfo.id === SetCrosshairHighlightColorOperation.id) {
const activeSheet = this.getActiveSheet();
if (!activeSheet) return;
this.fireEvent(this.Event.CrosshairHighlightColorChanged, {
const eventParams: ICrosshairHighlightColorChangedEventParams = {
color: this.getCrosshairHighlightColor(),
...activeSheet,
});
};
this.fireEvent(this.Event.CrosshairHighlightColorChanged, eventParams);
}
})
)
@@ -241,16 +163,8 @@ export class FUniverCrosshairHighlightMixin extends FUniver implements IFUniverC
}
}
FEventName.extend(FSheetCrosshairHighlightEventMixin);
FUniver.extend(FUniverCrosshairHighlightMixin);
FUniver.extend(FUniverSheetsCrosshairHighlightMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FUniver extends IFUniverCrosshairHighlightMixin {}
// eslint-disable-next-line ts/naming-convention
interface FEventName extends IFSheetCrosshairHighlightEventMixin {
}
interface IEventParamConfig extends ISheetCrosshairHighlightEventConfigs {}
interface FUniver extends IFUniverSheetsCrosshairHighlightMixin { }
}
@@ -15,5 +15,7 @@
*/
import './f-univer';
import './f-event';
export type * from './f-event';
export type * from './f-univer';
@@ -23,10 +23,10 @@ import { FEventName } from '@univerjs/core/facade';
/**
* Event interface triggered when a data validation rule is changed
* @interface ISheetDataValidationChangedEvent
* @interface ISheetDataValidationChangedEventParams
* @augments {IEventBase}
*/
export interface ISheetDataValidationChangedEvent extends IEventBase {
export interface ISheetDataValidationChangedEventParams extends IEventBase {
/** The source of the rule change */
origin: IRuleChange;
/** The worksheet containing the validation rule */
@@ -43,10 +43,10 @@ export interface ISheetDataValidationChangedEvent extends IEventBase {
/**
* Event interface triggered when a data validation status changes
* @interface ISheetDataValidatorStatusChangedEvent
* @interface ISheetDataValidatorStatusChangedEventParams
* @augments {IEventBase}
*/
export interface ISheetDataValidatorStatusChangedEvent extends IEventBase {
export interface ISheetDataValidatorStatusChangedEventParams extends IEventBase {
/** The worksheet containing the validation */
worksheet: FWorksheet;
/** The workbook instance */
@@ -63,10 +63,10 @@ export interface ISheetDataValidatorStatusChangedEvent extends IEventBase {
/**
* Event interface triggered before adding a new data validation rule
* @interface IBeforeSheetDataValidationAddEvent
* @interface IBeforeSheetDataValidationAddEventParams
* @augments {IEventBase}
*/
export interface IBeforeSheetDataValidationAddEvent extends IEventBase {
export interface IBeforeSheetDataValidationAddEventParams extends IEventBase {
/** The worksheet to add the validation to */
worksheet: FWorksheet;
/** The workbook instance */
@@ -77,10 +77,10 @@ export interface IBeforeSheetDataValidationAddEvent extends IEventBase {
/**
* Event interface triggered before deleting a data validation rule
* @interface IBeforeSheetDataValidationDeleteEvent
* @interface IBeforeSheetDataValidationDeleteEventParams
* @augments {IEventBase}
*/
export interface IBeforeSheetDataValidationDeleteEvent extends IEventBase {
export interface IBeforeSheetDataValidationDeleteEventParams extends IEventBase {
/** The worksheet containing the validation */
worksheet: FWorksheet;
/** The workbook instance */
@@ -93,10 +93,10 @@ export interface IBeforeSheetDataValidationDeleteEvent extends IEventBase {
/**
* Event interface triggered before updating a data validation rule's criteria
* @interface IBeforeSheetDataValidationCriteriaUpdateEvent
* @interface IBeforeSheetDataValidationCriteriaUpdateEventParams
* @augments {IEventBase}
*/
export interface IBeforeSheetDataValidationCriteriaUpdateEvent extends IEventBase {
export interface IBeforeSheetDataValidationCriteriaUpdateEventParams extends IEventBase {
/** The worksheet containing the validation */
worksheet: FWorksheet;
/** The workbook instance */
@@ -111,10 +111,10 @@ export interface IBeforeSheetDataValidationCriteriaUpdateEvent extends IEventBas
/**
* Event interface triggered before updating a data validation rule's ranges
* @interface IBeforeSheetDataValidationRangeUpdateEvent
* @interface IBeforeSheetDataValidationRangeUpdateEventParams
* @augments {IEventBase}
*/
export interface IBeforeSheetDataValidationRangeUpdateEvent extends IEventBase {
export interface IBeforeSheetDataValidationRangeUpdateEventParams extends IEventBase {
/** The worksheet containing the validation */
worksheet: FWorksheet;
/** The workbook instance */
@@ -129,10 +129,10 @@ export interface IBeforeSheetDataValidationRangeUpdateEvent extends IEventBase {
/**
* Event interface triggered before updating a data validation rule's options
* @interface IBeforeSheetDataValidationOptionsUpdateEvent
* @interface IBeforeSheetDataValidationOptionsUpdateEventParams
* @augments {IEventBase}
*/
export interface IBeforeSheetDataValidationOptionsUpdateEvent extends IEventBase {
export interface IBeforeSheetDataValidationOptionsUpdateEventParams extends IEventBase {
/** The worksheet containing the validation */
worksheet: FWorksheet;
/** The workbook instance */
@@ -147,10 +147,10 @@ export interface IBeforeSheetDataValidationOptionsUpdateEvent extends IEventBase
/**
* Event interface triggered before deleting all data validation rules
* @interface IBeforeSheetDataValidationDeleteAllEvent
* @interface IBeforeSheetDataValidationDeleteAllEventParams
* @augments {IEventBase}
*/
export interface IBeforeSheetDataValidationDeleteAllEvent extends IEventBase {
export interface IBeforeSheetDataValidationDeleteAllEventParams extends IEventBase {
/** The worksheet containing the validations */
worksheet: FWorksheet;
/** The workbook instance */
@@ -163,23 +163,23 @@ export interface IBeforeSheetDataValidationDeleteAllEvent extends IEventBase {
* @ignore
*/
export interface IDataValidationEventParamConfig {
SheetDataValidationChanged: ISheetDataValidationChangedEvent;
SheetDataValidatorStatusChanged: ISheetDataValidatorStatusChangedEvent;
BeforeSheetDataValidationAdd: IBeforeSheetDataValidationAddEvent;
BeforeSheetDataValidationDelete: IBeforeSheetDataValidationDeleteEvent;
BeforeSheetDataValidationDeleteAll: IBeforeSheetDataValidationDeleteAllEvent;
BeforeSheetDataValidationCriteriaUpdate: IBeforeSheetDataValidationCriteriaUpdateEvent;
BeforeSheetDataValidationRangeUpdate: IBeforeSheetDataValidationRangeUpdateEvent;
BeforeSheetDataValidationOptionsUpdate: IBeforeSheetDataValidationOptionsUpdateEvent;
SheetDataValidationChanged: ISheetDataValidationChangedEventParams;
SheetDataValidatorStatusChanged: ISheetDataValidatorStatusChangedEventParams;
BeforeSheetDataValidationAdd: IBeforeSheetDataValidationAddEventParams;
BeforeSheetDataValidationDelete: IBeforeSheetDataValidationDeleteEventParams;
BeforeSheetDataValidationDeleteAll: IBeforeSheetDataValidationDeleteAllEventParams;
BeforeSheetDataValidationCriteriaUpdate: IBeforeSheetDataValidationCriteriaUpdateEventParams;
BeforeSheetDataValidationRangeUpdate: IBeforeSheetDataValidationRangeUpdateEventParams;
BeforeSheetDataValidationOptionsUpdate: IBeforeSheetDataValidationOptionsUpdateEventParams;
}
/**
* @ignore
*/
interface IDataValidationEvent {
interface IFSheetsDataValidationEventNameMixin {
/**
* Event fired when a rule is added, deleted, or modified
* @see {@link ISheetDataValidationChangedEvent}
* @see {@link ISheetDataValidationChangedEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.SheetDataValidationChanged, (params) => {
@@ -194,7 +194,7 @@ interface IDataValidationEvent {
/**
* Event fired when a cell validator status is changed
* @see {@link ISheetDataValidatorStatusChangedEvent}
* @see {@link ISheetDataValidatorStatusChangedEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.SheetDataValidatorStatusChanged, (params) => {
@@ -209,7 +209,7 @@ interface IDataValidationEvent {
/**
* Event fired before a rule is added
* @see {@link IBeforeSheetDataValidationAddEvent}
* @see {@link IBeforeSheetDataValidationAddEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetDataValidationAdd, (params) => {
@@ -227,7 +227,7 @@ interface IDataValidationEvent {
/**
* Event fired before a rule is deleted
* @see {@link IBeforeSheetDataValidationDeleteEvent}
* @see {@link IBeforeSheetDataValidationDeleteEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetDataValidationDelete, (params) => {
@@ -245,7 +245,7 @@ interface IDataValidationEvent {
/**
* Event fired before all rules are deleted
* @see {@link IBeforeSheetDataValidationDeleteAllEvent}
* @see {@link IBeforeSheetDataValidationDeleteAllEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetDataValidationDeleteAll, (params) => {
@@ -263,7 +263,7 @@ interface IDataValidationEvent {
/**
* Event fired before the criteria of a rule are updated
* @see {@link IBeforeSheetDataValidationCriteriaUpdateEvent}
* @see {@link IBeforeSheetDataValidationCriteriaUpdateEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetDataValidationCriteriaUpdate, (params) => {
@@ -281,7 +281,7 @@ interface IDataValidationEvent {
/**
* Event fired before the range of a rule is updated
* @see {@link IBeforeSheetDataValidationRangeUpdateEvent}
* @see {@link IBeforeSheetDataValidationRangeUpdateEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetDataValidationRangeUpdate, (params) => {
@@ -299,7 +299,7 @@ interface IDataValidationEvent {
/**
* Event fired before the options of a rule are updated
* @see {@link IBeforeSheetDataValidationOptionsUpdateEvent}
* @see {@link IBeforeSheetDataValidationOptionsUpdateEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetDataValidationOptionsUpdate, (params) => {
@@ -319,36 +319,36 @@ interface IDataValidationEvent {
/**
* @ignore
*/
export class FDataValidationEvent implements IDataValidationEvent {
get SheetDataValidationChanged(): 'SheetDataValidationChanged' {
export class FSheetsDataValidationEventNameMixin extends FEventName implements IFSheetsDataValidationEventNameMixin {
override get SheetDataValidationChanged(): 'SheetDataValidationChanged' {
return 'SheetDataValidationChanged';
}
get SheetDataValidatorStatusChanged(): 'SheetDataValidatorStatusChanged' {
override get SheetDataValidatorStatusChanged(): 'SheetDataValidatorStatusChanged' {
return 'SheetDataValidatorStatusChanged';
}
get BeforeSheetDataValidationAdd(): 'BeforeSheetDataValidationAdd' {
override get BeforeSheetDataValidationAdd(): 'BeforeSheetDataValidationAdd' {
return 'BeforeSheetDataValidationAdd';
}
get BeforeSheetDataValidationDelete(): 'BeforeSheetDataValidationDelete' {
override get BeforeSheetDataValidationDelete(): 'BeforeSheetDataValidationDelete' {
return 'BeforeSheetDataValidationDelete';
}
get BeforeSheetDataValidationDeleteAll(): 'BeforeSheetDataValidationDeleteAll' {
override get BeforeSheetDataValidationDeleteAll(): 'BeforeSheetDataValidationDeleteAll' {
return 'BeforeSheetDataValidationDeleteAll';
}
get BeforeSheetDataValidationCriteriaUpdate(): 'BeforeSheetDataValidationCriteriaUpdate' {
override get BeforeSheetDataValidationCriteriaUpdate(): 'BeforeSheetDataValidationCriteriaUpdate' {
return 'BeforeSheetDataValidationCriteriaUpdate';
}
get BeforeSheetDataValidationRangeUpdate(): 'BeforeSheetDataValidationRangeUpdate' {
override get BeforeSheetDataValidationRangeUpdate(): 'BeforeSheetDataValidationRangeUpdate' {
return 'BeforeSheetDataValidationRangeUpdate';
}
get BeforeSheetDataValidationOptionsUpdate(): 'BeforeSheetDataValidationOptionsUpdate' {
override get BeforeSheetDataValidationOptionsUpdate(): 'BeforeSheetDataValidationOptionsUpdate' {
return 'BeforeSheetDataValidationOptionsUpdate';
}
}
@@ -356,23 +356,23 @@ export class FDataValidationEvent implements IDataValidationEvent {
/**
* @ignore
*/
export interface IDataValidationEventConfig {
SheetDataValidationChanged: ISheetDataValidationChangedEvent;
SheetDataValidatorStatusChanged: ISheetDataValidatorStatusChangedEvent;
BeforeSheetDataValidationAdd: IBeforeSheetDataValidationAddEvent;
BeforeSheetDataValidationDelete: IBeforeSheetDataValidationDeleteEvent;
BeforeSheetDataValidationDeleteAll: IBeforeSheetDataValidationDeleteAllEvent;
BeforeSheetDataValidationCriteriaUpdate: IBeforeSheetDataValidationCriteriaUpdateEvent;
BeforeSheetDataValidationRangeUpdate: IBeforeSheetDataValidationRangeUpdateEvent;
BeforeSheetDataValidationOptionsUpdate: IBeforeSheetDataValidationOptionsUpdateEvent;
export interface ISheetsDataValidationEventParamConfig {
SheetDataValidationChanged: ISheetDataValidationChangedEventParams;
SheetDataValidatorStatusChanged: ISheetDataValidatorStatusChangedEventParams;
BeforeSheetDataValidationAdd: IBeforeSheetDataValidationAddEventParams;
BeforeSheetDataValidationDelete: IBeforeSheetDataValidationDeleteEventParams;
BeforeSheetDataValidationDeleteAll: IBeforeSheetDataValidationDeleteAllEventParams;
BeforeSheetDataValidationCriteriaUpdate: IBeforeSheetDataValidationCriteriaUpdateEventParams;
BeforeSheetDataValidationRangeUpdate: IBeforeSheetDataValidationRangeUpdateEventParams;
BeforeSheetDataValidationOptionsUpdate: IBeforeSheetDataValidationOptionsUpdateEventParams;
}
FEventName.extend(FDataValidationEvent);
FEventName.extend(FSheetsDataValidationEventNameMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FEventName extends IDataValidationEvent {
interface FEventName extends IFSheetsDataValidationEventNameMixin {
}
interface IEventParamConfig extends IDataValidationEventParamConfig {
interface IEventParamConfig extends ISheetsDataValidationEventParamConfig {
}
}
@@ -25,7 +25,7 @@ import { FDataValidation } from './f-data-validation';
/**
* @ignore
*/
export interface IFRangeDataValidationMixin {
export interface IFRangeSheetsDataValidationMixin {
/**
* Set a data validation rule to current range. if rule is null, clear data validation rule.
* @param {Nullable<FDataValidation>} rule data validation rule, build by `FUniver.newDataValidation`
@@ -166,7 +166,7 @@ export interface IFRangeDataValidationMixin {
/**
* @ignore
*/
export class FRangeDataValidationMixin extends FRange implements IFRangeDataValidationMixin {
export class FRangeSheetsDataValidationMixin extends FRange implements IFRangeSheetsDataValidationMixin {
override setDataValidation(rule: Nullable<FDataValidation>): FRange {
if (!rule) {
this._commandService.syncExecuteCommand(ClearRangeDataValidationCommand.id, {
@@ -298,8 +298,8 @@ export class FRangeDataValidationMixin extends FRange implements IFRangeDataVali
}
}
FRange.extend(FRangeDataValidationMixin);
FRange.extend(FRangeSheetsDataValidationMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FRange extends IFRangeDataValidationMixin { }
interface FRange extends IFRangeSheetsDataValidationMixin { }
}
@@ -23,7 +23,16 @@ import type {
IUpdateSheetDataValidationRangeCommandParams,
IUpdateSheetDataValidationSettingCommandParams,
} from '@univerjs/sheets-data-validation';
import type { IBeforeSheetDataValidationAddEvent, IBeforeSheetDataValidationCriteriaUpdateEvent, IBeforeSheetDataValidationDeleteAllEvent, IBeforeSheetDataValidationDeleteEvent, IBeforeSheetDataValidationOptionsUpdateEvent, IBeforeSheetDataValidationRangeUpdateEvent } from './f-event';
import type {
IBeforeSheetDataValidationAddEventParams,
IBeforeSheetDataValidationCriteriaUpdateEventParams,
IBeforeSheetDataValidationDeleteAllEventParams,
IBeforeSheetDataValidationDeleteEventParams,
IBeforeSheetDataValidationOptionsUpdateEventParams,
IBeforeSheetDataValidationRangeUpdateEventParams,
ISheetDataValidationChangedEventParams,
ISheetDataValidatorStatusChangedEventParams,
} from './f-event';
import { CanceledError, ICommandService } from '@univerjs/core';
import { FUniver } from '@univerjs/core/facade';
import {
@@ -41,7 +50,7 @@ import { FDataValidationBuilder } from './f-data-validation-builder';
/**
* @ignore
*/
export interface IFUnvierDataValidationMixin {
export interface IFUniverSheetsDataValidationMixin {
/**
* Creates a new instance of FDataValidationBuilder
* @returns {FDataValidationBuilder} A new instance of the FDataValidationBuilder class
@@ -66,7 +75,7 @@ export interface IFUnvierDataValidationMixin {
newDataValidation(): FDataValidationBuilder;
}
export class FUnvierDataValidationMixin extends FUniver implements IFUnvierDataValidationMixin {
export class FUniverSheetsDataValidationMixin extends FUniver implements IFUniverSheetsDataValidationMixin {
/**
* @deprecated use `univerAPI.newDataValidation()` as instead.
* @returns {FDataValidationBuilder} A new instance of the FDataValidationBuilder class
@@ -100,16 +109,16 @@ export class FUnvierDataValidationMixin extends FUniver implements IFUnvierDataV
return;
}
const { workbook, worksheet } = target;
const fRule = new FDataValidation(rule, worksheet.getSheet(), this._injector);
this.fireEvent(this.Event.SheetDataValidationChanged, {
const eventParams: ISheetDataValidationChangedEventParams = {
origin: ruleChange,
worksheet,
workbook,
changeType: type,
oldRule,
rule: fRule,
});
};
this.fireEvent(this.Event.SheetDataValidationChanged, eventParams);
});
}
)
@@ -133,14 +142,15 @@ export class FUnvierDataValidationMixin extends FUniver implements IFUnvierDataV
if (!rule) {
return;
}
this.fireEvent(this.Event.SheetDataValidatorStatusChanged, {
const eventParams: ISheetDataValidatorStatusChangedEventParams = {
workbook,
worksheet,
row,
column: col,
rule,
status,
});
};
this.fireEvent(this.Event.SheetDataValidatorStatusChanged, eventParams);
});
}
)
@@ -158,7 +168,7 @@ export class FUnvierDataValidationMixin extends FUniver implements IFUnvierDataV
return;
}
const { workbook, worksheet } = target;
const eventParams: IBeforeSheetDataValidationAddEvent = {
const eventParams: IBeforeSheetDataValidationAddEventParams = {
worksheet,
workbook,
rule: params.rule,
@@ -187,7 +197,7 @@ export class FUnvierDataValidationMixin extends FUniver implements IFUnvierDataV
if (!rule) {
return;
}
const eventParams: IBeforeSheetDataValidationCriteriaUpdateEvent = {
const eventParams: IBeforeSheetDataValidationCriteriaUpdateEventParams = {
worksheet,
workbook,
rule,
@@ -219,7 +229,7 @@ export class FUnvierDataValidationMixin extends FUniver implements IFUnvierDataV
if (!rule) {
return;
}
const eventParams: IBeforeSheetDataValidationRangeUpdateEvent = {
const eventParams: IBeforeSheetDataValidationRangeUpdateEventParams = {
worksheet,
workbook,
rule,
@@ -250,7 +260,7 @@ export class FUnvierDataValidationMixin extends FUniver implements IFUnvierDataV
if (!rule) {
return;
}
const eventParams: IBeforeSheetDataValidationOptionsUpdateEvent = {
const eventParams: IBeforeSheetDataValidationOptionsUpdateEventParams = {
worksheet,
workbook,
rule,
@@ -281,7 +291,7 @@ export class FUnvierDataValidationMixin extends FUniver implements IFUnvierDataV
if (!rule) {
return;
}
const eventParams: IBeforeSheetDataValidationDeleteEvent = {
const eventParams: IBeforeSheetDataValidationDeleteEventParams = {
worksheet,
workbook,
rule,
@@ -307,7 +317,7 @@ export class FUnvierDataValidationMixin extends FUniver implements IFUnvierDataV
return;
}
const { workbook, worksheet } = target;
const eventParams: IBeforeSheetDataValidationDeleteAllEvent = {
const eventParams: IBeforeSheetDataValidationDeleteAllEventParams = {
worksheet,
workbook,
rules: worksheet.getDataValidations(),
@@ -323,7 +333,7 @@ export class FUnvierDataValidationMixin extends FUniver implements IFUnvierDataV
}
}
FUniver.extend(FUnvierDataValidationMixin);
FUniver.extend(FUniverSheetsDataValidationMixin);
declare module '@univerjs/core/facade' {
/**
* @ignore
@@ -338,5 +348,5 @@ declare module '@univerjs/core/facade' {
}
// eslint-disable-next-line ts/naming-convention
interface FUniver extends IFUnvierDataValidationMixin {}
interface FUniver extends IFUniverSheetsDataValidationMixin {}
}
@@ -61,7 +61,7 @@ export interface IDataValidationError {
/**
* @ignore
*/
export interface IFWorkbookDataValidationMixin {
export interface IFWorkbookSheetsDataValidationMixin {
/**
* Get data validation validator status for current workbook.
* @returns A promise that resolves to a matrix of validator status.
@@ -152,7 +152,7 @@ export interface IFWorkbookDataValidationMixin {
/**
* @ignore
*/
export class FWorkbookDataValidationMixin extends FWorkbook implements IFWorkbookDataValidationMixin {
export class FWorkbookSheetsDataValidationMixin extends FWorkbook implements IFWorkbookSheetsDataValidationMixin {
declare _dataValidationModel: SheetDataValidationModel;
override _initialize(): void {
@@ -373,8 +373,8 @@ export class FWorkbookDataValidationMixin extends FWorkbook implements IFWorkboo
}
}
FWorkbook.extend(FWorkbookDataValidationMixin);
FWorkbook.extend(FWorkbookSheetsDataValidationMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FWorkbook extends IFWorkbookDataValidationMixin { }
interface FWorkbook extends IFWorkbookSheetsDataValidationMixin { }
}
@@ -1,162 +0,0 @@
/**
* 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.
*/
import type { ISheetSelectionRenderService, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
import { convertPositionSheetOverGridToAbsolute } from '@univerjs/sheets-ui';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { drawingPositionToTransform, transformToAxisAlignPosition, transformToDrawingPosition } from '../transform-position';
vi.mock('@univerjs/sheets-ui', () => ({
convertPositionSheetOverGridToAbsolute: vi.fn(),
}));
describe('transform-position', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('clips drawing transforms to the current sheet bounds', () => {
vi.mocked(convertPositionSheetOverGridToAbsolute).mockReturnValue({
unitId: 'unit-1',
subUnitId: 'sheet-1',
left: 90,
top: 75,
width: 20,
height: 30,
});
const sheetSkeletonManagerService = {
getCurrent: () => ({ unitId: 'unit-1', sheetId: 'sheet-1' }),
getCurrentSkeleton: () => ({
rowHeaderWidth: 0,
columnHeaderHeight: 0,
columnTotalWidth: 100,
rowTotalHeight: 90,
}),
} as SheetSkeletonManagerService;
const transform = drawingPositionToTransform({
from: { column: 0, row: 0, columnOffset: 0, rowOffset: 0 },
to: { column: 1, row: 1, columnOffset: 0, rowOffset: 0 },
angle: 10,
flipX: true,
}, {} as ISheetSelectionRenderService, sheetSkeletonManagerService);
expect(transform).toEqual({
left: 80,
top: 60,
width: 20,
height: 30,
angle: 10,
flipX: true,
flipY: false,
skewX: 0,
skewY: 0,
});
});
it('converts a transform back to sheet anchors', () => {
const selectionRenderService = {
getCellWithCoordByOffset: vi.fn()
.mockReturnValueOnce({
actualColumn: 1,
actualRow: 2,
startX: 10,
startY: 20,
})
.mockReturnValueOnce({
actualColumn: 3,
actualRow: 4,
startX: 40,
startY: 60,
}),
} as unknown as ISheetSelectionRenderService;
expect(transformToDrawingPosition({
left: 15,
top: 25,
width: 40,
height: 50,
flipY: true,
angle: 25,
}, selectionRenderService)).toEqual({
from: {
column: 1,
columnOffset: 5,
row: 2,
rowOffset: 5,
},
to: {
column: 3,
columnOffset: 15,
row: 4,
rowOffset: 15,
},
flipX: false,
flipY: true,
angle: 25,
skewX: 0,
skewY: 0,
});
});
it('uses swapped bounds for axis-aligned positions when the angle rotates into a major-axis range', () => {
const selectionRenderService = {
getCellWithCoordByOffset: vi.fn()
.mockReturnValueOnce({
actualColumn: 2,
actualRow: 3,
startX: 10,
startY: 40,
})
.mockReturnValueOnce({
actualColumn: 6,
actualRow: 7,
startX: 70,
startY: 80,
}),
} as unknown as ISheetSelectionRenderService;
expect(transformToAxisAlignPosition({
left: 20,
top: 30,
width: 40,
height: 60,
angle: 90,
}, selectionRenderService)).toEqual({
from: {
column: 2,
columnOffset: 0,
row: 3,
rowOffset: 0,
},
to: {
column: 6,
columnOffset: 0,
row: 7,
rowOffset: 0,
},
flipX: false,
flipY: false,
angle: 90,
skewX: 0,
skewY: 0,
});
expect(selectionRenderService.getCellWithCoordByOffset).toHaveBeenNthCalledWith(1, 10, 40);
expect(selectionRenderService.getCellWithCoordByOffset).toHaveBeenNthCalledWith(2, 70, 80);
});
});
@@ -1,186 +0,0 @@
/**
* 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.
*/
import type { ITransformState, Nullable } from '@univerjs/core';
import type { ISheetDrawingPosition } from '@univerjs/sheets-drawing';
import type { ISheetSelectionRenderService, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
import { precisionTo } from '@univerjs/engine-render';
import { convertPositionSheetOverGridToAbsolute } from '@univerjs/sheets-ui';
// eslint-disable-next-line max-lines-per-function
export function drawingPositionToTransform(
position: ISheetDrawingPosition,
selectionRenderService: ISheetSelectionRenderService,
sheetSkeletonManagerService: SheetSkeletonManagerService
): Nullable<ITransformState> {
const { from, to, flipY = false, flipX = false, angle = 0, skewX = 0, skewY = 0 } = position;
const skeletonParam = sheetSkeletonManagerService.getCurrent();
if (skeletonParam == null) {
return;
}
const absolutePosition = convertPositionSheetOverGridToAbsolute(
skeletonParam.unitId,
skeletonParam.sheetId,
{ from, to },
sheetSkeletonManagerService
);
let { left, top, width, height } = absolutePosition;
const skeleton = sheetSkeletonManagerService.getCurrentSkeleton()!;
// const startSelectionCell = attachRangeWithCoord(skeleton, {
// startColumn: fromColumn,
// endColumn: fromColumn,
// startRow: fromRow,
// endRow: fromRow,
// });
// if (startSelectionCell == null) {
// return;
// }
// const endSelectionCell = attachRangeWithCoord(skeleton, {
// startColumn: toColumn,
// endColumn: toColumn,
// startRow: toRow,
// endRow: toRow,
// });
// if (endSelectionCell == null) {
// return;
// }
// const { startX: startSelectionX, startY: startSelectionY } = startSelectionCell;
// const { startX: endSelectionX, startY: endSelectionY } = endSelectionCell;
// let left = precisionTo(startSelectionX + fromColumnOffset, 1);
// let top = precisionTo(startSelectionY + fromRowOffset, 1);
// let width = precisionTo(endSelectionX + toColumnOffset - left, 1);
// let height = precisionTo(endSelectionY + toRowOffset - top, 1);
// if (startSelectionCell.startX === endSelectionCell.endX) {
// width = 0;
// }
// if (startSelectionCell.startY === endSelectionCell.endY) {
// height = 0;
// }
const sheetWidth = skeleton.rowHeaderWidth + skeleton.columnTotalWidth;
const sheetHeight = skeleton.columnHeaderHeight + skeleton.rowTotalHeight;
if ((left + width) > sheetWidth) {
left = sheetWidth - width;
}
if ((top + height) > sheetHeight) {
top = sheetHeight - height;
}
return {
flipY,
flipX,
angle,
skewX,
skewY,
left,
top,
width,
height,
};
}
// use transform and originSize convert to ISheetDrawingPosition
export function transformToDrawingPosition(transform: ITransformState, selectionRenderService: ISheetSelectionRenderService): Nullable<ISheetDrawingPosition> {
const { left = 0, top = 0, width = 0, height = 0, flipY = false, flipX = false, angle = 0, skewX = 0, skewY = 0 } = transform;
const startSelectionCell = selectionRenderService.getCellWithCoordByOffset(left, top);
if (startSelectionCell == null) {
return;
}
const from = {
column: startSelectionCell.actualColumn,
columnOffset: precisionTo(left - startSelectionCell.startX, 1),
row: startSelectionCell.actualRow,
rowOffset: precisionTo(top - startSelectionCell.startY, 1),
};
const endSelectionCell = selectionRenderService.getCellWithCoordByOffset(left + width, top + height);
if (endSelectionCell == null) {
return;
}
const to = {
column: endSelectionCell.actualColumn,
columnOffset: precisionTo(left + width - endSelectionCell.startX, 1),
row: endSelectionCell.actualRow,
rowOffset: precisionTo(top + height - endSelectionCell.startY, 1),
};
return {
flipY,
flipX,
angle,
skewX,
skewY,
from,
to,
};
}
/**
* In excel, the basic drawing with rotate bound use major axis switch, axis-aligned bound will bu used.That means the position bound of drawing element will save as nearly axis-aligned rectangle.
* Here is the rule to convert transform to axis-aligned position:
* [-45°, 45°): use the original bound
* [45°, 135°): rotate the bound 90° clockwise,and the left, top, bottom,right will use the rotated bound.
* [135°, 225°): use the original bound
* [225°, 315°): rotate the bound 90° counterclockwise, and the left, top, bottom, right will use the rotated bound.
* @param transform The transform state of the drawing element.
* @param selectionRenderService
* @return The axis-aligned position of the drawing element.
*/
export function transformToAxisAlignPosition(
transform: ITransformState,
selectionRenderService: ISheetSelectionRenderService
): Nullable<ISheetDrawingPosition> {
const { left = 0, top = 0, width = 0, height = 0, angle = 0 } = transform;
const norm = ((angle % 360) + 360) % 360;
const useSwappedAxis =
(norm >= 45 && norm < 135) ||
(norm >= 225 && norm < 315);
if (!useSwappedAxis) {
return transformToDrawingPosition(transform, selectionRenderService);
}
const rotatedTransform = {
...transform,
left: left + width / 2 - height / 2,
top: top + height / 2 - width / 2,
width: height,
height: width,
};
return transformToDrawingPosition(rotatedTransform, selectionRenderService);
}
@@ -16,10 +16,9 @@
import type { IAccessor } from '@univerjs/core';
import { ICommandService } from '@univerjs/core';
import { ISheetDrawingService } from '@univerjs/sheets-drawing';
import { ISheetDrawingService, RemoveSheetDrawingCommand } from '@univerjs/sheets-drawing';
import { describe, expect, it, vi } from 'vitest';
import { DeleteDrawingsCommand } from '../delete-drawings.command';
import { RemoveSheetDrawingCommand } from '../remove-sheet-drawing.command';
describe('DeleteDrawingsCommand', () => {
it('forwards focused drawings to the remove command', async () => {
@@ -15,19 +15,12 @@
*/
import type { IAccessor } from '@univerjs/core';
import { ArrangeTypeEnum, Direction, DrawingTypeEnum, ICommandService, IUndoRedoService } from '@univerjs/core';
import { ArrangeTypeEnum, DrawingTypeEnum, ICommandService, IUndoRedoService } from '@univerjs/core';
import { IRenderManagerService } from '@univerjs/engine-render';
import { SheetInterceptorService } from '@univerjs/sheets';
import { DrawingApplyType, ISheetDrawingService, SetDrawingApplyMutation } from '@univerjs/sheets-drawing';
import { DrawingApplyType, InsertSheetDrawingCommand, ISheetDrawingService, RemoveSheetDrawingCommand, SetDrawingApplyMutation, SetDrawingArrangeCommand } from '@univerjs/sheets-drawing';
import { ISheetSelectionRenderService } from '@univerjs/sheets-ui';
import { describe, expect, it, vi } from 'vitest';
import { ClearSheetDrawingTransformerOperation } from '../../operations/clear-drawing-transformer.operation';
import { FlipSheetDrawingCommand } from '../flip-drawings.command';
import { InsertSheetDrawingCommand } from '../insert-sheet-drawing.command';
import { MoveDrawingsCommand } from '../move-drawings.command';
import { RemoveSheetDrawingCommand } from '../remove-sheet-drawing.command';
import { SetDrawingArrangeCommand } from '../set-drawing-arrange.command';
import { SetSheetDrawingCommand } from '../set-sheet-drawing.command';
function createSelectionRenderService() {
return {
@@ -151,46 +144,13 @@ describe('sheet drawing commands', () => {
type: DrawingApplyType.REMOVE,
}, undefined);
expect(pushUndoRedo).toHaveBeenCalledWith(expect.objectContaining({
undoMutations: expect.arrayContaining([expect.objectContaining({ id: ClearSheetDrawingTransformerOperation.id })]),
redoMutations: expect.arrayContaining([expect.objectContaining({ id: ClearSheetDrawingTransformerOperation.id })]),
undoMutations: expect.arrayContaining([expect.objectContaining({ id: SetDrawingApplyMutation.id })]),
redoMutations: expect.arrayContaining([expect.objectContaining({ id: SetDrawingApplyMutation.id })]),
}));
});
it('moves focused drawings, recalculates sheet anchors, and clears transformers', () => {
const { accessor, commandService, sheetDrawingService } = createAccessor();
expect(MoveDrawingsCommand.handler(accessor, { direction: Direction.LEFT })).toBe(true);
expect(commandService.syncExecuteCommand).toHaveBeenNthCalledWith(1, SetSheetDrawingCommand.id, {
unitId: 'book-1',
drawings: [expect.objectContaining({
transform: { left: 9, top: 20 },
sheetTransform: {
from: { column: 0, columnOffset: 9, row: 2, rowOffset: 0 },
to: { column: 0, columnOffset: 9, row: 2, rowOffset: 0 },
flipX: false,
flipY: false,
angle: 0,
skewX: 0,
skewY: 0,
},
axisAlignSheetTransform: {
from: { column: 0, columnOffset: 9, row: 2, rowOffset: 0 },
to: { column: 0, columnOffset: 9, row: 2, rowOffset: 0 },
flipX: false,
flipY: false,
angle: 0,
skewX: 0,
skewY: 0,
},
})],
});
expect(commandService.syncExecuteCommand).toHaveBeenNthCalledWith(2, ClearSheetDrawingTransformerOperation.id, ['book-1']);
sheetDrawingService.getFocusDrawings.mockReturnValue([]);
expect(MoveDrawingsCommand.handler(accessor, { direction: Direction.RIGHT })).toBe(false);
});
it('inserts drawings through sheet interceptors and records undo/redo mutations', () => {
const { accessor, commandService, pushUndoRedo, sheetInterceptorService } = createAccessor();
const { accessor, commandService, sheetInterceptorService } = createAccessor();
const params = {
drawings: [{ unitId: 'book-1', subUnitId: 'sheet-1', drawingId: 'shape-2' }],
};
@@ -205,66 +165,7 @@ describe('sheet drawing commands', () => {
objects: ['shape-2'],
type: DrawingApplyType.INSERT,
}, undefined);
expect(pushUndoRedo).toHaveBeenCalledWith(expect.objectContaining({
unitID: 'book-1',
undoMutations: expect.arrayContaining([expect.objectContaining({ id: ClearSheetDrawingTransformerOperation.id, params: ['book-1'] })]),
redoMutations: expect.arrayContaining([expect.objectContaining({ id: ClearSheetDrawingTransformerOperation.id, params: ['book-1'] })]),
}));
expect(InsertSheetDrawingCommand.handler(accessor, undefined)).toBe(false);
});
it('flips drawing transforms, rebuilds anchors, and pushes transformer cleanup', () => {
const { accessor, commandService, pushUndoRedo, sheetDrawingService } = createAccessor();
expect(FlipSheetDrawingCommand.handler(accessor, {
unitId: 'book-1',
drawings: [{ unitId: 'book-1', subUnitId: 'sheet-1', drawingId: 'shape-1' }],
flipH: true,
flipV: true,
})).toBe(true);
expect(sheetDrawingService.getBatchUpdateOp).toHaveBeenCalledWith([
expect.objectContaining({
drawingId: 'shape-1',
drawingType: DrawingTypeEnum.DRAWING_SHAPE,
transform: expect.objectContaining({ left: 10, top: 20, flipX: true, flipY: true }),
sheetTransform: {
from: { column: 1, columnOffset: 0, row: 2, rowOffset: 0 },
to: { column: 1, columnOffset: 0, row: 2, rowOffset: 0 },
flipX: true,
flipY: true,
angle: 0,
skewX: 0,
skewY: 0,
},
axisAlignSheetTransform: {
from: { column: 1, columnOffset: 0, row: 2, rowOffset: 0 },
to: { column: 1, columnOffset: 0, row: 2, rowOffset: 0 },
flipX: true,
flipY: true,
angle: 0,
skewX: 0,
skewY: 0,
},
}),
]);
expect(commandService.syncExecuteCommand).toHaveBeenCalledWith(SetDrawingApplyMutation.id, {
unitId: 'book-1',
subUnitId: 'sheet-1',
op: ['update-redo'],
objects: ['shape-1'],
type: DrawingApplyType.UPDATE,
}, undefined);
expect(pushUndoRedo).toHaveBeenCalledWith(expect.objectContaining({
undoMutations: expect.arrayContaining([expect.objectContaining({ id: ClearSheetDrawingTransformerOperation.id, params: ['book-1'] })]),
redoMutations: expect.arrayContaining([expect.objectContaining({ id: ClearSheetDrawingTransformerOperation.id, params: ['book-1'] })]),
}));
sheetDrawingService.getDrawingData.mockReturnValue({} as never);
expect(FlipSheetDrawingCommand.handler(accessor, {
unitId: 'book-1',
drawings: [{ unitId: 'book-1', subUnitId: 'sheet-1', drawingId: 'missing' }],
flipH: true,
})).toBe(false);
});
});
@@ -15,11 +15,9 @@
*/
import type { IAccessor, ICommand } from '@univerjs/core';
import type { ISheetDrawing } from '@univerjs/sheets-drawing';
import type { IDeleteDrawingCommandParams } from './interfaces';
import type { IDeleteDrawingCommandParams, ISheetDrawing } from '@univerjs/sheets-drawing';
import { CommandType, ICommandService } from '@univerjs/core';
import { ISheetDrawingService } from '@univerjs/sheets-drawing';
import { RemoveSheetDrawingCommand } from './remove-sheet-drawing.command';
import { ISheetDrawingService, RemoveSheetDrawingCommand } from '@univerjs/sheets-drawing';
export const DeleteDrawingsCommand: ICommand = {
id: 'sheet.command.delete-drawing',
@@ -27,9 +27,8 @@ import {
} from '@univerjs/core';
import { getDrawingShapeKeyByDrawingSearch } from '@univerjs/drawing';
import { IRenderManagerService } from '@univerjs/engine-render';
import { DrawingApplyType, ISheetDrawingService, SetDrawingApplyMutation } from '@univerjs/sheets-drawing';
import { ISheetSelectionRenderService } from '@univerjs/sheets-ui';
import { transformToAxisAlignPosition, transformToDrawingPosition } from '../../basics/transform-position';
import { SheetSkeletonService } from '@univerjs/sheets';
import { DrawingApplyType, ISheetDrawingService, SetDrawingApplyMutation, transformToAxisAlignPosition, transformToDrawingPosition } from '@univerjs/sheets-drawing';
import { ClearSheetDrawingTransformerOperation } from '../operations/clear-drawing-transformer.operation';
interface IFlipDrawingCommandParam {
@@ -51,21 +50,18 @@ export const FlipSheetDrawingCommand: ICommand = {
type: CommandType.COMMAND,
// eslint-disable-next-line max-lines-per-function, complexity
handler: (accessor: IAccessor, params?: IFlipSheetDrawingCommandParams) => {
const commandService = accessor.get(ICommandService);
const undoRedoService = accessor.get(IUndoRedoService);
const sheetDrawingService = accessor.get(ISheetDrawingService);
const renderManagerService = accessor.get(IRenderManagerService);
if (!params) return false;
const { drawings } = params;
const commandService = accessor.get(ICommandService);
const undoRedoService = accessor.get(IUndoRedoService);
const sheetDrawingService = accessor.get(ISheetDrawingService);
const sheetSkeletonService = accessor.get(SheetSkeletonService);
const { drawings } = params;
const flipH = params.flipH;
const flipV = params.flipV;
const unitIds: string[] = [];
const updateParams: any[] = [];
for (const param of drawings) {
@@ -78,6 +74,11 @@ export const FlipSheetDrawingCommand: ICommand = {
continue;
}
const skeleton = sheetSkeletonService.getSkeleton(unitId, subUnitId);
if (!skeleton) {
continue;
}
const transform = { ...existing.transform } as ITransformState;
if (flipH) {
@@ -87,14 +88,8 @@ export const FlipSheetDrawingCommand: ICommand = {
transform.flipY = !transform.flipY;
}
const render = renderManagerService.getRenderById(unitId);
const selectionRenderService = render?.with(ISheetSelectionRenderService);
if (!selectionRenderService) {
continue;
}
const sheetTransform = transformToDrawingPosition(transform, selectionRenderService);
const axisAlignSheetTransform = transformToAxisAlignPosition(transform, selectionRenderService) as ISheetDrawingPosition;
const sheetTransform = transformToDrawingPosition(transform, skeleton);
const axisAlignSheetTransform = transformToAxisAlignPosition(transform, skeleton) as ISheetDrawingPosition;
const updateParamItem: any = {
unitId,
@@ -15,15 +15,11 @@
*/
import type { IAccessor, ICommand } from '@univerjs/core';
import type { ISheetDrawing } from '@univerjs/sheets-drawing';
import type { ISetDrawingCommandParams } from './interfaces';
import type { ISetDrawingCommandParams, ISheetDrawing } from '@univerjs/sheets-drawing';
import { CommandType, Direction, ICommandService } from '@univerjs/core';
import { ISheetDrawingService } from '@univerjs/sheets-drawing';
import { ISheetSelectionRenderService } from '@univerjs/sheets-ui';
import { transformToAxisAlignPosition, transformToDrawingPosition } from '../../basics/transform-position';
import { SheetSkeletonService } from '@univerjs/sheets';
import { ISheetDrawingService, SetSheetDrawingCommand, transformToAxisAlignPosition, transformToDrawingPosition } from '@univerjs/sheets-drawing';
import { ClearSheetDrawingTransformerOperation } from '../operations/clear-drawing-transformer.operation';
import { SetSheetDrawingCommand } from './set-sheet-drawing.command';
export interface IMoveDrawingsCommandParams {
direction: Direction;
@@ -35,7 +31,7 @@ export const MoveDrawingsCommand: ICommand = {
handler: (accessor: IAccessor, params: IMoveDrawingsCommandParams) => {
const commandService = accessor.get(ICommandService);
const drawingManagerService = accessor.get(ISheetDrawingService);
const selectionRenderService = accessor.get(ISheetSelectionRenderService);
const sheetSkeletonService = accessor.get(SheetSkeletonService);
const { direction } = params;
@@ -48,12 +44,13 @@ export const MoveDrawingsCommand: ICommand = {
const unitId = drawings[0].unitId;
const newDrawings = drawings.map((drawing) => {
const { transform } = drawing as ISheetDrawing;
if (transform == null) {
const { transform, unitId, subUnitId } = drawing as ISheetDrawing;
const skeleton = sheetSkeletonService.getSkeleton(unitId, subUnitId);
if (!transform || !skeleton) {
return null;
}
const newTransform = { ...transform };
const newTransform = { ...transform };
const { left = 0, top = 0 } = transform;
if (direction === Direction.UP) {
@@ -69,8 +66,8 @@ export const MoveDrawingsCommand: ICommand = {
return {
...drawing,
transform: newTransform,
sheetTransform: transformToDrawingPosition(newTransform, selectionRenderService),
axisAlignSheetTransform: transformToAxisAlignPosition(newTransform, selectionRenderService),
sheetTransform: transformToDrawingPosition(newTransform, skeleton),
axisAlignSheetTransform: transformToAxisAlignPosition(newTransform, skeleton),
} as ISheetDrawing;
}).filter((drawing) => drawing != null) as ISheetDrawing[];
@@ -17,17 +17,15 @@
import type { IRenderContext, IRenderModule } from '@univerjs/engine-render';
import { Disposable, Inject } from '@univerjs/core';
import { IDrawingManagerService } from '@univerjs/drawing';
import { ISheetDrawingService } from '@univerjs/sheets-drawing';
import { ISheetSelectionRenderService, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
import { drawingPositionToTransform } from '../../basics/transform-position';
import { SheetSkeletonService } from '@univerjs/sheets';
import { drawingPositionToTransform, ISheetDrawingService } from '@univerjs/sheets-drawing';
export class SheetsDrawingRenderController extends Disposable implements IRenderModule {
constructor(
private _context: IRenderContext,
@ISheetDrawingService private readonly _sheetDrawingService: ISheetDrawingService,
@IDrawingManagerService private readonly _drawingManagerService: IDrawingManagerService,
@Inject(ISheetSelectionRenderService) private _sheetSelectionRenderService: ISheetSelectionRenderService,
@Inject(SheetSkeletonManagerService) private _sheetSkeletonManagerService: SheetSkeletonManagerService
@Inject(SheetSkeletonService) private readonly _sheetSkeletonService: SheetSkeletonService
) {
super();
@@ -46,8 +44,11 @@ export class SheetsDrawingRenderController extends Disposable implements IRender
const subUnitData = data[subUnit];
for (const drawingId in subUnitData.data) {
const drawingData = subUnitData.data[drawingId];
if (drawingData.sheetTransform) {
drawingData.transform = drawingPositionToTransform(drawingData.sheetTransform, this._sheetSelectionRenderService, this._sheetSkeletonManagerService);
const { unitId, subUnitId } = drawingData;
const skeletonParam = this._sheetSkeletonService.getSkeletonParam(unitId, subUnitId);
if (skeletonParam && drawingData.sheetTransform) {
drawingData.transform = drawingPositionToTransform(drawingData.sheetTransform, skeletonParam);
}
}
}
@@ -17,26 +17,21 @@
import type { IMutationInfo, IRange, Nullable } from '@univerjs/core';
import type { IDrawingJsonUndo1 } from '@univerjs/drawing';
import type { IDiscreteRange } from '@univerjs/sheets';
import type { ISheetDrawing, ISheetImage } from '@univerjs/sheets-drawing';
import type { IDeleteDrawingCommandParams, ISheetDrawing, ISheetImage } from '@univerjs/sheets-drawing';
import type { IPasteHookValueType, ISheetDiscreteRangeLocation } from '@univerjs/sheets-ui';
import type { IDeleteDrawingCommandParams } from '../commands/commands/interfaces';
import { Disposable, DrawingTypeEnum, generateRandomId, ICommandService } from '@univerjs/core';
import { Disposable, DrawingTypeEnum, generateRandomId, ICommandService, Inject } from '@univerjs/core';
import { IDrawingManagerService, ImageSourceType } from '@univerjs/drawing';
import { IRenderManagerService } from '@univerjs/engine-render';
import { discreteRangeToRange } from '@univerjs/sheets';
import { DrawingApplyType, SetDrawingApplyMutation, SheetDrawingAnchorType } from '@univerjs/sheets-drawing';
import { attachRangeWithCoord, discreteRangeToRange, SheetSkeletonService } from '@univerjs/sheets';
import { DrawingApplyType, RemoveSheetDrawingCommand, SetDrawingApplyMutation, SheetDrawingAnchorType, transformToAxisAlignPosition, transformToDrawingPosition } from '@univerjs/sheets-drawing';
import {
COPY_TYPE,
ISheetClipboardService,
ISheetSelectionRenderService,
PREDEFINED_HOOK_NAME_PASTE,
SheetSkeletonManagerService,
virtualizeDiscreteRanges,
} from '@univerjs/sheets-ui';
import { IClipboardInterfaceService } from '@univerjs/ui';
import { transformToAxisAlignPosition, transformToDrawingPosition } from '../basics/transform-position';
import { InsertFloatImageCommand } from '../commands/commands/insert-image.command';
import { RemoveSheetDrawingCommand } from '../commands/commands/remove-sheet-drawing.command';
const IMAGE_PNG_MIME_TYPE = 'image/png';
@@ -103,6 +98,7 @@ export class SheetsDrawingCopyPasteController extends Disposable {
constructor(
@ISheetClipboardService private _sheetClipboardService: ISheetClipboardService,
@IRenderManagerService private readonly _renderManagerService: IRenderManagerService,
@Inject(SheetSkeletonService) private readonly _sheetSkeletonService: SheetSkeletonService,
@IDrawingManagerService private readonly _drawingService: IDrawingManagerService,
@IClipboardInterfaceService private readonly _clipboardInterfaceService: IClipboardInterfaceService,
@ICommandService private readonly _commandService: ICommandService
@@ -173,11 +169,14 @@ export class SheetsDrawingCopyPasteController extends Disposable {
}
const { copyType = COPY_TYPE.COPY, pasteType } = payload;
const { range: copyRange } = pasteFrom || {};
const { range: pasteRange, unitId, subUnitId } = pasteTo;
const { range: copyRange, unitId: fromUnitId, subUnitId: fromSubUnitId } = pasteFrom || {};
const { range: pasteRange, unitId: toUnitId, subUnitId: toSubUnitId } = pasteTo;
const mutations = this._copyInfo.copyRange
? this._generateRangeDrawingsPasteMutations({ pasteType, unitId, subUnitId, pasteRange }, { copyRange, copyType })
? this._generateRangeDrawingsPasteMutations(
{ unitId: toUnitId, subUnitId: toSubUnitId, pasteRange, pasteType },
{ unitId: fromUnitId, subUnitId: fromSubUnitId, copyType, copyRange }
)
: this._generateSingleDrawingPasteMutations({ pasteTo, pasteType }, COPY_TYPE.COPY);
return mutations;
@@ -220,13 +219,11 @@ export class SheetsDrawingCopyPasteController extends Disposable {
}
private _createDrawingsCopyInfoByRange(unitId: string, subUnitId: string, range: IRange) {
const skeletonManagerService = this._renderManagerService.getRenderById(unitId)?.with(SheetSkeletonManagerService);
if (!skeletonManagerService) return;
const skeleton = this._sheetSkeletonService.getSkeleton(unitId, subUnitId);
if (!skeleton) return;
const selectionRect = skeletonManagerService.attachRangeWithCoord(range);
if (!selectionRect) {
return;
}
const selectionRect = attachRangeWithCoord(skeleton, range);
if (!selectionRect) return;
const { startX, endX, startY, endY } = selectionRect;
const drawings = this._drawingService.getDrawingData(unitId, subUnitId);
@@ -279,18 +276,13 @@ export class SheetsDrawingCopyPasteController extends Disposable {
}
const { unitId, subUnitId, range } = pasteTo;
const render = this._renderManagerService.getRenderById(unitId);
const skeletonManagerService = render?.with(SheetSkeletonManagerService);
const selectionRenderService = render?.with(ISheetSelectionRenderService);
const copyInfo = this._copyInfo!;
if (!skeletonManagerService || !selectionRenderService) {
const pasteToSkeleton = this._sheetSkeletonService.getSkeleton(unitId, subUnitId);
if (!pasteToSkeleton) {
return { redos: [], undos: [] };
}
const copyInfo = this._copyInfo!;
const { drawings } = copyInfo;
const pasteRange = discreteRangeToRange(range);
return this._generateMutations(drawings, {
@@ -298,7 +290,7 @@ export class SheetsDrawingCopyPasteController extends Disposable {
subUnitId,
isCut: copyType === COPY_TYPE.CUT,
getTransform: (transform, sheetTransform) => {
const pasteRect = skeletonManagerService.attachRangeWithCoord({
const pasteRect = attachRangeWithCoord(pasteToSkeleton, {
startRow: pasteRange.startRow,
endRow: pasteRange.endRow,
startColumn: pasteRange.startColumn,
@@ -313,8 +305,8 @@ export class SheetsDrawingCopyPasteController extends Disposable {
return {
transform: newTransform,
sheetTransform: transformToDrawingPosition(newTransform, selectionRenderService) ?? sheetTransform,
axisAlignSheetTransform: transformToAxisAlignPosition(newTransform, selectionRenderService) ?? sheetTransform,
sheetTransform: transformToDrawingPosition(newTransform, pasteToSkeleton) ?? sheetTransform,
axisAlignSheetTransform: transformToAxisAlignPosition(newTransform, pasteToSkeleton) ?? sheetTransform,
};
},
});
@@ -399,29 +391,25 @@ export class SheetsDrawingCopyPasteController extends Disposable {
pasteType: IPasteHookValueType;
},
copyContext: {
copyType: COPY_TYPE;
unitId?: string;
subUnitId?: string;
copyRange?: IDiscreteRange;
copyType: COPY_TYPE;
}
) {
const {
unitId,
subUnitId,
pasteType,
pasteRange,
} = pasteContext;
if (!this._copyInfo) {
return { redos: [], undos: [] };
}
const {
copyRange,
copyType,
} = copyContext;
const { unitId: toUnitId, subUnitId: toSubUnitId, pasteRange, pasteType } = pasteContext;
const { unitId: fromUnitId, subUnitId: fromSubUnitId, copyRange, copyType } = copyContext;
if (specialPastes.includes(pasteType)) {
return { redos: [], undos: [] };
}
const skeletonManagerService = this._renderManagerService.getRenderById(unitId)?.with(SheetSkeletonManagerService);
if (!skeletonManagerService || !this._copyInfo) {
const toSkeleton = this._sheetSkeletonService.getSkeleton(toUnitId, toSubUnitId);
if (!toSkeleton) {
return { redos: [], undos: [] };
}
@@ -429,29 +417,34 @@ export class SheetsDrawingCopyPasteController extends Disposable {
if (!copyRange) {
return this._generateSingleDrawingPasteMutations({
pasteTo: { unitId, subUnitId, range: discreteRangeToRange(pasteRange) as unknown as IDiscreteRange },
pasteTo: { unitId: toUnitId, subUnitId: toSubUnitId, range: discreteRangeToRange(pasteRange) as unknown as IDiscreteRange },
pasteType,
}, copyType);
}
const fromSkeleton = this._sheetSkeletonService.getSkeleton(fromUnitId!, fromSubUnitId!);
if (!fromSkeleton) {
return { redos: [], undos: [] };
}
const { ranges: [vCopyRange, vPastedRange], mapFunc } = virtualizeDiscreteRanges([copyRange, pasteRange]);
const { row: copyRow, col: copyCol } = mapFunc(vCopyRange.startRow, vCopyRange.startColumn);
const { row: pasteRow, col: pasteCol } = mapFunc(vPastedRange.startRow, vPastedRange.startColumn);
const copyRect = skeletonManagerService.attachRangeWithCoord({
const copyRect = attachRangeWithCoord(fromSkeleton, {
startRow: copyRow,
endRow: copyRow,
startColumn: copyCol,
endColumn: copyCol,
});
const pasteRect = skeletonManagerService.attachRangeWithCoord({
const pasteRect = attachRangeWithCoord(toSkeleton, {
startRow: pasteRow,
endRow: pasteRow,
startColumn: pasteCol,
endColumn: pasteCol,
});
if (!copyRect || !pasteRect || !this._copyInfo) {
if (!copyRect || !pasteRect) {
return { redos: [], undos: [] };
}
@@ -461,49 +454,14 @@ export class SheetsDrawingCopyPasteController extends Disposable {
const columnOffset = pasteCol - copyCol;
return this._generateMutations(drawings, {
unitId,
subUnitId,
unitId: toUnitId,
subUnitId: toSubUnitId,
getTransform: (transform, sheetTransform) => {
const newTransform = {
...transform,
left: (transform?.left ?? 0) + leftOffset,
top: (transform?.top ?? 0) + topOffset,
};
const render = this._renderManagerService.getRenderById(unitId);
const selectionRenderService = render?.with(ISheetSelectionRenderService);
if (!selectionRenderService) {
// todo : if rotate has the angle, the axisAlignSheetTransform is not equal to sheetTransform, need to calculate the new axisAlignSheetTransform based on the new transform
return {
transform: newTransform,
sheetTransform: {
...sheetTransform,
to: {
...sheetTransform.to,
row: sheetTransform.to.row + rowOffset,
column: sheetTransform.to.column + columnOffset,
},
from: {
...sheetTransform.from,
row: sheetTransform.from.row + rowOffset,
column: sheetTransform.from.column + columnOffset,
},
},
axisAlignSheetTransform: {
...sheetTransform,
to: {
...sheetTransform.to,
row: sheetTransform.to.row + rowOffset,
column: sheetTransform.to.column + columnOffset,
},
from: {
...sheetTransform.from,
row: sheetTransform.from.row + rowOffset,
column: sheetTransform.from.column + columnOffset,
},
},
};
}
return {
transform: newTransform,
@@ -520,7 +478,7 @@ export class SheetsDrawingCopyPasteController extends Disposable {
column: sheetTransform.from.column + columnOffset,
},
},
axisAlignSheetTransform: transformToAxisAlignPosition(newTransform, selectionRenderService) ?? sheetTransform,
axisAlignSheetTransform: transformToAxisAlignPosition(newTransform, toSkeleton) ?? sheetTransform,
};
},
isCut: copyType === COPY_TYPE.CUT,
@@ -18,18 +18,12 @@ import type { IDrawingGroupNestedParam, IMutationInfo, Nullable } from '@univerj
import type { IDrawingJsonUndo1 } from '@univerjs/drawing';
import type { ISheetDrawing } from '@univerjs/sheets-drawing';
import type { IPasteHookValueType, ISheetDiscreteRangeLocation } from '@univerjs/sheets-ui';
import { Disposable, DrawingTypeEnum } from '@univerjs/core';
import { Disposable, DrawingTypeEnum, Inject } from '@univerjs/core';
import { IDrawingManagerService } from '@univerjs/drawing';
import { IRenderManagerService } from '@univerjs/engine-render';
import { discreteRangeToRange } from '@univerjs/sheets';
import { DrawingApplyType, ISheetDrawingService, SetDrawingApplyMutation } from '@univerjs/sheets-drawing';
import {
ISheetClipboardService,
ISheetSelectionRenderService,
PREDEFINED_HOOK_NAME_PASTE,
SheetSkeletonManagerService,
} from '@univerjs/sheets-ui';
import { transformToAxisAlignPosition, transformToDrawingPosition } from '../basics/transform-position';
import { attachRangeWithCoord, discreteRangeToRange, SheetSkeletonService } from '@univerjs/sheets';
import { DrawingApplyType, ISheetDrawingService, SetDrawingApplyMutation, transformToAxisAlignPosition, transformToDrawingPosition } from '@univerjs/sheets-drawing';
import { ISheetClipboardService, PREDEFINED_HOOK_NAME_PASTE } from '@univerjs/sheets-ui';
import { cloneGroupParams } from '../commands/commands/utils';
export interface IGroupFeaturePasteHookParams {
@@ -68,6 +62,7 @@ export class SheetsDrawingGroupCopyPasteController extends Disposable {
constructor(
@ISheetClipboardService private readonly _sheetClipboardService: ISheetClipboardService,
@IRenderManagerService private readonly _renderManagerService: IRenderManagerService,
@Inject(SheetSkeletonService) private readonly _sheetSkeletonService: SheetSkeletonService,
@ISheetDrawingService private readonly _sheetDrawingService: ISheetDrawingService,
@IDrawingManagerService private readonly _drawingManagerService: IDrawingManagerService
) {
@@ -139,12 +134,13 @@ export class SheetsDrawingGroupCopyPasteController extends Disposable {
}
private _generateGroupPasteMutations(pasteTo: ISheetDiscreteRangeLocation): { redos: IMutationInfo[]; undos: IMutationInfo[] } {
const { unitId, subUnitId, range } = pasteTo;
const render = this._renderManagerService.getRenderById(unitId);
const skeletonManagerService = render?.with(SheetSkeletonManagerService);
const selectionRenderService = render?.with(ISheetSelectionRenderService);
if (!this._copyInfo) {
return { redos: [], undos: [] };
}
if (!skeletonManagerService || !selectionRenderService || !this._copyInfo) {
const { unitId, subUnitId, range } = pasteTo;
const pasteToSkeleton = this._sheetSkeletonService.getSkeleton(unitId, subUnitId);
if (!pasteToSkeleton) {
return { redos: [], undos: [] };
}
@@ -158,7 +154,7 @@ export class SheetsDrawingGroupCopyPasteController extends Disposable {
// Resolve the paste destination rectangle.
const pasteRange = discreteRangeToRange(range);
const pasteRect = skeletonManagerService.attachRangeWithCoord({
const pasteRect = attachRangeWithCoord(pasteToSkeleton, {
startRow: pasteRange.startRow,
endRow: pasteRange.endRow,
startColumn: pasteRange.startColumn,
@@ -181,8 +177,8 @@ export class SheetsDrawingGroupCopyPasteController extends Disposable {
unitId,
subUnitId,
transform: newTransform,
sheetTransform: transformToDrawingPosition(newTransform, selectionRenderService) ?? origRootGroup.sheetTransform,
axisAlignSheetTransform: transformToAxisAlignPosition(newTransform, selectionRenderService) ?? origRootGroup.sheetTransform,
sheetTransform: transformToDrawingPosition(newTransform, pasteToSkeleton) ?? origRootGroup.sheetTransform,
axisAlignSheetTransform: transformToAxisAlignPosition(newTransform, pasteToSkeleton) ?? origRootGroup.sheetTransform,
} as ISheetDrawing;
}),
];
@@ -16,26 +16,60 @@
import type { IAccessor, IDrawingParam, IRange, Nullable, Workbook } from '@univerjs/core';
import type { IImageData, IImageIoServiceParam } from '@univerjs/drawing';
import type { IRenderContext, IRenderModule } from '@univerjs/engine-render';
import type { IRenderContext, IRenderModule, SpreadsheetSkeleton } from '@univerjs/engine-render';
import type { ISheetLocationBase, WorkbookSelectionModel } from '@univerjs/sheets';
import type { ISheetDrawing, ISheetDrawingPosition } from '@univerjs/sheets-drawing';
import type { IInsertDrawingCommandParams, ISetDrawingCommandParams } from '../commands/commands/interfaces';
import type { ISetDrawingArrangeCommandParams } from '../commands/commands/set-drawing-arrange.command';
import { BooleanNumber, BuildTextUtils, createDocumentModelWithStyle, Disposable, DrawingTypeEnum, FOCUSING_COMMON_DRAWINGS, generateRandomId, ICommandService, IContextService, ImageSourceType, Inject, Injector, IURLImageService, LocaleService, ObjectRelativeFromH, ObjectRelativeFromV, PositionedObjectLayoutType, WrapTextType } from '@univerjs/core';
import type { IDeleteDrawingCommandParams, IInsertDrawingCommandParams, ISetDrawingArrangeCommandParams, ISetDrawingCommandParams, ISheetDrawing, ISheetDrawingPosition } from '@univerjs/sheets-drawing';
import {
BooleanNumber,
BuildTextUtils,
createDocumentModelWithStyle,
Disposable,
DrawingTypeEnum,
FOCUSING_COMMON_DRAWINGS,
generateRandomId,
ICommandService,
IContextService,
ImageSourceType,
Inject,
Injector,
IURLImageService,
LocaleService,
ObjectRelativeFromH,
ObjectRelativeFromV,
PositionedObjectLayoutType,
WrapTextType,
} from '@univerjs/core';
import { MessageType } from '@univerjs/design';
import { docDrawingPositionToTransform } from '@univerjs/docs-ui';
import { DRAWING_IMAGE_ALLOW_IMAGE_LIST, DRAWING_IMAGE_ALLOW_SIZE, DRAWING_IMAGE_COUNT_LIMIT, DRAWING_IMAGE_HEIGHT_LIMIT, DRAWING_IMAGE_WIDTH_LIMIT, getImageSize, IDrawingManagerService, IImageIoService, ImageUploadStatusType, SetDrawingSelectedOperation } from '@univerjs/drawing';
import {
DRAWING_IMAGE_ALLOW_IMAGE_LIST,
DRAWING_IMAGE_ALLOW_SIZE,
DRAWING_IMAGE_COUNT_LIMIT,
DRAWING_IMAGE_HEIGHT_LIMIT,
DRAWING_IMAGE_WIDTH_LIMIT,
getImageSize,
IDrawingManagerService,
IImageIoService,
ImageUploadStatusType,
SetDrawingSelectedOperation,
} from '@univerjs/drawing';
import { IRenderManagerService } from '@univerjs/engine-render';
import { SetRangeValuesCommand, SheetsSelectionsService } from '@univerjs/sheets';
import { ISheetDrawingService } from '@univerjs/sheets-drawing';
import { attachRangeWithCoord, ISheetSelectionRenderService, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
import { attachRangeWithCoord, SetRangeValuesCommand, SheetInterceptorService, SheetSkeletonService, SheetsSelectionsService } from '@univerjs/sheets';
import {
drawingPositionToTransform,
InsertSheetDrawingCommand,
ISheetDrawingService,
RemoveSheetDrawingCommand,
SetDrawingArrangeCommand,
SetSheetDrawingCommand,
transformToAxisAlignPosition,
transformToDrawingPosition,
} from '@univerjs/sheets-drawing';
import { ISheetSelectionRenderService, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
import { ILocalFileService, IMessageService } from '@univerjs/ui';
import { drawingPositionToTransform, transformToAxisAlignPosition, transformToDrawingPosition } from '../basics/transform-position';
import { GroupSheetDrawingCommand } from '../commands/commands/group-sheet-drawing.command';
import { InsertSheetDrawingCommand } from '../commands/commands/insert-sheet-drawing.command';
import { SetDrawingArrangeCommand } from '../commands/commands/set-drawing-arrange.command';
import { SetSheetDrawingCommand } from '../commands/commands/set-sheet-drawing.command';
import { UngroupSheetDrawingCommand } from '../commands/commands/ungroup-sheet-drawing.command';
import { ClearSheetDrawingTransformerOperation } from '../commands/operations/clear-drawing-transformer.operation';
/**
* Calculate the bounding box after rotation
@@ -97,8 +131,8 @@ export class SheetDrawingUpdateController extends Disposable implements IRenderM
private readonly _workbookSelections: WorkbookSelectionModel;
constructor(
private readonly _context: IRenderContext<Workbook>,
@Inject(SheetSkeletonManagerService) private readonly _skeletonManagerService: SheetSkeletonManagerService,
@ICommandService private readonly _commandService: ICommandService,
@Inject(SheetInterceptorService) private readonly _sheetInterceptorService: SheetInterceptorService,
@ISheetSelectionRenderService private readonly _selectionRenderService: ISheetSelectionRenderService,
@IImageIoService private readonly _imageIoService: IImageIoService,
@ILocalFileService private readonly _fileOpenerService: ILocalFileService,
@@ -108,6 +142,7 @@ export class SheetDrawingUpdateController extends Disposable implements IRenderM
@IMessageService private readonly _messageService: IMessageService,
@Inject(LocaleService) private readonly _localeService: LocaleService,
@Inject(SheetsSelectionsService) selectionManagerService: SheetsSelectionsService,
@Inject(SheetSkeletonService) private readonly _sheetSkeletonService: SheetSkeletonService,
@Inject(Injector) private readonly _injector: Injector,
@IURLImageService private readonly _urlImageService: IURLImageService
) {
@@ -115,6 +150,7 @@ export class SheetDrawingUpdateController extends Disposable implements IRenderM
this._workbookSelections = selectionManagerService.getWorkbookSelections(this._context.unitId);
this._setDrawingListener();
this._updateDrawingListener();
this._updateOrderListener();
this._groupDrawingListener();
@@ -203,13 +239,16 @@ export class SheetDrawingUpdateController extends Disposable implements IRenderM
scale = Math.max(scaleWidth, scaleHeight);
}
const sheetTransform = this._getImagePosition(width * scale, height * scale, sceneWidth, sceneHeight);
const sheetSkeletonParam = this._sheetSkeletonService.getSkeletonParam(unitId, subUnitId);
if (!sheetSkeletonParam) return;
if (sheetTransform == null) {
return;
}
const { skeleton } = sheetSkeletonParam;
const sheetTransform = this._getImagePosition(width * scale, height * scale, sceneWidth, sceneHeight, skeleton);
if (!sheetTransform) return;
const newTransform = drawingPositionToTransform(sheetTransform, sheetSkeletonParam);
if (!newTransform) return;
const newTransform = drawingPositionToTransform(sheetTransform, this._selectionRenderService, this._skeletonManagerService)!;
const sheetDrawingParam: ISheetDrawing = {
unitId,
subUnitId,
@@ -219,7 +258,7 @@ export class SheetDrawingUpdateController extends Disposable implements IRenderM
source,
transform: newTransform,
sheetTransform,
axisAlignSheetTransform: transformToAxisAlignPosition(newTransform, this._selectionRenderService) ?? sheetTransform,
axisAlignSheetTransform: transformToAxisAlignPosition(newTransform, skeleton) ?? sheetTransform,
};
return this._commandService.executeCommand(InsertSheetDrawingCommand.id, {
@@ -461,7 +500,7 @@ export class SheetDrawingUpdateController extends Disposable implements IRenderM
};
}
private _getImagePosition(imageWidth: number, imageHeight: number, sceneWidth: number, sceneHeight: number): Nullable<ISheetDrawingPosition> {
private _getImagePosition(imageWidth: number, imageHeight: number, sceneWidth: number, sceneHeight: number, skeleton: SpreadsheetSkeleton): Nullable<ISheetDrawingPosition> {
const selections = this._workbookSelections.getCurrentSelections();
let range: IRange = {
startRow: 0,
@@ -473,7 +512,7 @@ export class SheetDrawingUpdateController extends Disposable implements IRenderM
range = selections[selections.length - 1].range;
}
const rangeWithCoord = attachRangeWithCoord(this._skeletonManagerService.getCurrent()!.skeleton, range);
const rangeWithCoord = attachRangeWithCoord(skeleton, range);
if (rangeWithCoord == null) {
return;
}
@@ -553,52 +592,68 @@ export class SheetDrawingUpdateController extends Disposable implements IRenderM
}));
}
private _setDrawingListener() {
this.disposeWithMe(
this._sheetInterceptorService.interceptCommand({
getMutations: (commandInfo) => {
if (commandInfo.id === SetSheetDrawingCommand.id || InsertSheetDrawingCommand.id || commandInfo.id === RemoveSheetDrawingCommand.id) {
const params = commandInfo.params as ISetDrawingCommandParams | IInsertDrawingCommandParams | IDeleteDrawingCommandParams;
const { unitId } = params;
const redos = [
{
id: ClearSheetDrawingTransformerOperation.id,
params: [unitId],
},
];
const undos = [
{
id: ClearSheetDrawingTransformerOperation.id,
params: [unitId],
},
];
return { redos, undos };
}
return { redos: [], undos: [] };
},
})
);
}
private _updateDrawingListener() {
this.disposeWithMe(this._drawingManagerService.featurePluginUpdate$.subscribe((params) => {
const drawings: Partial<ISheetDrawing>[] = [];
const groupChildParams: IDrawingParam[] = [];
if (params.length === 0) {
return;
}
(params as IImageData[]).forEach((param) => {
const { unitId, subUnitId, drawingId, drawingType, transform } = param;
if (transform == null) {
const { unitId, subUnitId, drawingId, transform } = param;
const sheetSkeletonParam = this._sheetSkeletonService.getSkeletonParam(unitId, subUnitId);
if (!transform || !sheetSkeletonParam) {
return;
}
const { skeleton } = sheetSkeletonParam;
const sheetDrawing = this._sheetDrawingService.getDrawingByParam({ unitId, subUnitId, drawingId });
// const imageDrawing = this._drawingManagerService.getDrawingByParam({ unitId, subUnitId, drawingId });
if (sheetDrawing == null || sheetDrawing.unitId !== this._context.unitId) {
return;
}
const sheetTransform = transformToDrawingPosition({ ...sheetDrawing.transform, ...transform }, this._selectionRenderService);
const axisAlignSheetTransform = transformToAxisAlignPosition({ ...sheetDrawing.transform, ...transform }, this._selectionRenderService);
const sheetTransform = transformToDrawingPosition({ ...sheetDrawing.transform, ...transform }, skeleton);
const axisAlignSheetTransform = transformToAxisAlignPosition({ ...sheetDrawing.transform, ...transform }, skeleton);
if (sheetTransform == null || axisAlignSheetTransform == null) {
return;
}
// const oldDrawing: Partial<ISheetDrawing> = {
// ...sheetDrawing,
// };
const newDrawing: Partial<ISheetDrawing> = {
...param,
transform: { ...sheetDrawing.transform, ...transform, ...drawingPositionToTransform(sheetTransform, this._selectionRenderService, this._skeletonManagerService) },
transform: { ...sheetDrawing.transform, ...transform, ...drawingPositionToTransform(sheetTransform, sheetSkeletonParam) },
sheetTransform: { ...sheetTransform },
axisAlignSheetTransform: { ...axisAlignSheetTransform },
};
// if (newDrawing.drawingType === DrawingTypeEnum.DRAWING_GROUP) {
// }
drawings.push(newDrawing);
});
@@ -616,9 +671,11 @@ export class SheetDrawingUpdateController extends Disposable implements IRenderM
axisAlignSheetTransform: ISheetDrawingPosition;
}> {
const { unitId, subUnitId, drawingId, transform } = param;
if (transform == null) {
const skeleton = this._sheetSkeletonService.getSkeleton(unitId, subUnitId);
if (!transform || !skeleton) {
return null;
}
const sheetDrawing = this._sheetDrawingService.getDrawingByParam({ unitId, subUnitId, drawingId });
let sheetDrawingTransform = sheetDrawing?.transform;
@@ -626,16 +683,17 @@ export class SheetDrawingUpdateController extends Disposable implements IRenderM
sheetDrawingTransform = {};
}
if (!isCreate && (sheetDrawing == null || sheetDrawing.unitId !== this._context.unitId)) {
if (!isCreate && (!sheetDrawing || sheetDrawing.unitId !== this._context.unitId)) {
return null;
}
const sheetTransform = transformToDrawingPosition({ ...sheetDrawingTransform, ...transform }, this._selectionRenderService);
const axisAlignSheetTransform = transformToAxisAlignPosition({ ...sheetDrawingTransform, ...transform }, this._selectionRenderService);
const sheetTransform = transformToDrawingPosition({ ...sheetDrawingTransform, ...transform }, skeleton);
const axisAlignSheetTransform = transformToAxisAlignPosition({ ...sheetDrawingTransform, ...transform }, skeleton);
if (sheetTransform == null || axisAlignSheetTransform == null) {
if (!sheetTransform || !axisAlignSheetTransform) {
return null;
}
return { sheetTransform, axisAlignSheetTransform };
}
@@ -15,19 +15,13 @@
*/
import { Disposable, ICommandService, Inject } from '@univerjs/core';
import { IDrawingManagerService } from '@univerjs/drawing';
import { SheetsSelectionsService } from '@univerjs/sheets';
import { ComponentManager, IMenuManagerService, IShortcutService } from '@univerjs/ui';
import { DeleteDrawingsCommand } from '../commands/commands/delete-drawings.command';
import { FlipSheetDrawingCommand } from '../commands/commands/flip-drawings.command';
import { GroupSheetDrawingCommand } from '../commands/commands/group-sheet-drawing.command';
import { InsertCellImageCommand, InsertFloatImageCommand } from '../commands/commands/insert-image.command';
import { InsertSheetDrawingCommand } from '../commands/commands/insert-sheet-drawing.command';
import { MoveDrawingsCommand } from '../commands/commands/move-drawings.command';
import { RemoveSheetDrawingCommand } from '../commands/commands/remove-sheet-drawing.command';
import { SaveCellImagesCommand } from '../commands/commands/save-cell-images.command';
import { SetDrawingArrangeCommand } from '../commands/commands/set-drawing-arrange.command';
import { SetSheetDrawingCommand } from '../commands/commands/set-sheet-drawing.command';
import { UngroupSheetDrawingCommand } from '../commands/commands/ungroup-sheet-drawing.command';
import { ClearSheetDrawingTransformerOperation } from '../commands/operations/clear-drawing-transformer.operation';
import { EditSheetDrawingOperation } from '../commands/operations/edit-sheet-drawing.operation';
@@ -43,9 +37,7 @@ export class SheetDrawingUIController extends Disposable {
@Inject(ComponentManager) private readonly _componentManager: ComponentManager,
@IMenuManagerService private readonly _menuManagerService: IMenuManagerService,
@ICommandService private readonly _commandService: ICommandService,
@IShortcutService private readonly _shortcutService: IShortcutService,
@IDrawingManagerService private readonly _drawingManagerService: IDrawingManagerService,
@Inject(SheetsSelectionsService) private readonly _sheetsSelectionsService: SheetsSelectionsService
@IShortcutService private readonly _shortcutService: IShortcutService
) {
super();
@@ -66,9 +58,6 @@ export class SheetDrawingUIController extends Disposable {
[
InsertFloatImageCommand,
InsertCellImageCommand,
InsertSheetDrawingCommand,
RemoveSheetDrawingCommand,
SetSheetDrawingCommand,
SidebarSheetDrawingOperation,
ClearSheetDrawingTransformerOperation,
EditSheetDrawingOperation,
@@ -76,7 +65,6 @@ export class SheetDrawingUIController extends Disposable {
UngroupSheetDrawingCommand,
MoveDrawingsCommand,
DeleteDrawingsCommand,
SetDrawingArrangeCommand,
SaveCellImagesCommand,
FlipSheetDrawingCommand,
].forEach((command) => this.disposeWithMe(this._commandService.registerCommand(command)));
+25 -315
View File
@@ -14,20 +14,18 @@
* limitations under the License.
*/
import type { IDrawingSearch } from '@univerjs/core';
import type { IEventBase } from '@univerjs/core/facade';
import type { ISheetFloatDom, ISheetImage } from '@univerjs/sheets-drawing';
import type { ISheetFloatDom } from '@univerjs/sheets-drawing';
import type { FWorkbook } from '@univerjs/sheets/facade';
import type { FOverGridImage } from './f-over-grid-image';
import { FEventName } from '@univerjs/core/facade';
/**
* @ignore
*/
interface IFDrawingEventNameMixin {
interface IFSheetsDrawingUIEventNameMixin {
/**
* Triggered before float dom insertion.
* @see {@link IBeforeFloatDomAddParam}
* @see {@link IBeforeFloatDomAddEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeFloatDomAdd, (params) => {
@@ -45,7 +43,7 @@ interface IFDrawingEventNameMixin {
/**
* Triggered after float dom insertion.
* @see {@link IFloatDomAddedParam}
* @see {@link IFloatDomAddedEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.FloatDomAdded, (params) => {
@@ -61,7 +59,7 @@ interface IFDrawingEventNameMixin {
/**
* Triggered before float dom update.
* @see {@link IBeforeFloatDomUpdateParam}
* @see {@link IBeforeFloatDomUpdateEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeFloatDomUpdate, (params) => {
@@ -79,7 +77,7 @@ interface IFDrawingEventNameMixin {
/**
* Triggered after float dom update.
* @see {@link IFloatDomUpdatedParam}
* @see {@link IFloatDomUpdatedEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.FloatDomUpdated, (params) => {
@@ -95,7 +93,7 @@ interface IFDrawingEventNameMixin {
/**
* Triggered before float dom deletion.
* @see {@link IBeforeFloatDomDeleteParam}
* @see {@link IBeforeFloatDomDeleteEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeFloatDomDelete, (params) => {
@@ -113,7 +111,7 @@ interface IFDrawingEventNameMixin {
/**
* Triggered after float dom deletion.
* @see {@link IFloatDomDeletedParam}
* @see {@link IFloatDomDeletedEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.FloatDomDeleted, (params) => {
@@ -126,145 +124,9 @@ interface IFDrawingEventNameMixin {
* ```
*/
readonly FloatDomDeleted: 'FloatDomDeleted';
/**
* Triggered before floating image insertion.
* @see {@link IBeforeOverGridImageInsertParam}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeOverGridImageInsert, (params) => {
* console.log(params);
* // do something
* const { workbook, insertImageParams } = params;
* // Cancel the insertion operation
* params.cancel = true;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly BeforeOverGridImageInsert: 'BeforeOverGridImageInsert';
/**
* Triggered after floating image insertion.
* @see {@link IOverGridImageInsertedParam}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.OverGridImageInserted, (params) => {
* console.log(params);
* // do something
* const { workbook, images } = params;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly OverGridImageInserted: 'OverGridImageInserted';
/**
* Triggered before floating image removal.
* @see {@link IBeforeOverGridImageRemoveParam}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeOverGridImageRemove, (params) => {
* console.log(params);
* // do something
* const { workbook, images } = params;
* // Cancel the removal operation
* params.cancel = true;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly BeforeOverGridImageRemove: 'BeforeOverGridImageRemove';
/**
* Triggered after floating image removal.
* @see {@link IOverGridImageRemovedParam}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.OverGridImageRemoved, (params) => {
* console.log(params);
* // do something
* const { workbook, removeImageParams } = params;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly OverGridImageRemoved: 'OverGridImageRemoved';
/**
* Triggered before floating image change.
* @see {@link IBeforeOverGridImageChangeParam}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeOverGridImageChange, (params) => {
* console.log(params);
* // do something
* const { workbook, images } = params;
* // Cancel the image change
* params.cancel = true;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly BeforeOverGridImageChange: 'BeforeOverGridImageChange';
/**
* Triggered after floating image change.
* @see {@link IOverGridImageChangedParam}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.OverGridImageChanged, (params) => {
* console.log(params);
* // do something
* const { workbook, images } = params;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly OverGridImageChanged: 'OverGridImageChanged';
/**
* Triggered before floating image selection.
* @see {@link IBeforeOverGridImageSelectParam}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeOverGridImageSelect, (params) => {
* console.log(params);
* // do something
* const { workbook, selectedImages, oldSelectedImages } = params;
* // cancel the selection operation
* params.cancel = true;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly BeforeOverGridImageSelect: 'BeforeOverGridImageSelect';
/**
* Triggered after floating image selection.
* @see {@link IOverGridImageSelectedParam}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.OverGridImageSelected, (params) => {
* console.log(params);
* // do something
* const { workbook, selectedImages } = params;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly OverGridImageSelected: 'OverGridImageSelected';
}
export class FDrawingEventNameMixin extends FEventName implements IFDrawingEventNameMixin {
export class FSheetsDrawingUIEventNameMixin extends FEventName implements IFSheetsDrawingUIEventNameMixin {
override get BeforeFloatDomAdd(): 'BeforeFloatDomAdd' {
return 'BeforeFloatDomAdd' as const;
}
@@ -288,152 +150,12 @@ export class FDrawingEventNameMixin extends FEventName implements IFDrawingEvent
override get FloatDomDeleted(): 'FloatDomDeleted' {
return 'FloatDomDeleted' as const;
}
override get BeforeOverGridImageChange(): 'BeforeOverGridImageChange' {
return 'BeforeOverGridImageChange' as const;
}
override get OverGridImageChanged(): 'OverGridImageChanged' {
return 'OverGridImageChanged' as const;
}
override get BeforeOverGridImageInsert(): 'BeforeOverGridImageInsert' {
return 'BeforeOverGridImageInsert' as const;
}
override get OverGridImageInserted(): 'OverGridImageInserted' {
return 'OverGridImageInserted' as const;
}
override get BeforeOverGridImageRemove(): 'BeforeOverGridImageRemove' {
return 'BeforeOverGridImageRemove' as const;
}
override get OverGridImageRemoved(): 'OverGridImageRemoved' {
return 'OverGridImageRemoved' as const;
}
override get BeforeOverGridImageSelect(): 'BeforeOverGridImageSelect' {
return 'BeforeOverGridImageSelect' as const;
}
override get OverGridImageSelected(): 'OverGridImageSelected' {
return 'OverGridImageSelected' as const;
}
}
export interface IBeforeOverGridImageChangeParamObject {
/**
* Parameters of the image to be updated. {@link ISheetImage}
*/
changeParam: Partial<ISheetImage>;
/**
* Instance of the image to be updated. {@link FOverGridImage}
*/
image: FOverGridImage;
}
export interface IBeforeOverGridImageChangeParam extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* Collection of parameters of the images to be updated, there may be multiple images to be updated. {@link IBeforeOverGridImageChangeParamObject}
*/
images: IBeforeOverGridImageChangeParamObject[];
}
export interface IOverGridImageChangedParam extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* Instances of the images after the update. {@link FOverGridImage}
*/
images: FOverGridImage[];
}
export interface IBeforeOverGridImageInsertParam extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* Collection of parameters of the images to be inserted. {@link ISheetImage}
*/
insertImageParams: ISheetImage[];
}
export interface IOverGridImageInsertedParam extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* Collection of instances of the images after insertion. {@link FOverGridImage}
*/
images: FOverGridImage[];
}
export interface IBeforeOverGridImageRemoveParam extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* Collection of instances of the images to be removed. {@link FOverGridImage}
*/
images: FOverGridImage[];
}
export interface IOverGridImageRemovedParam extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* Collection of parameters of the images after removal. {@link ISheetImage}
*/
removeImageParams: IDrawingSearch[];
}
export interface IBeforeOverGridImageSelectParam extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* The images before selection. {@link FOverGridImage}
*/
oldSelectedImages: FOverGridImage[];
selectedImages: FOverGridImage[];
}
export interface IOverGridImageSelectedParam extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* The selected images. {@link FOverGridImage}
*/
selectedImages: FOverGridImage[];
}
/**
* @ignore
*/
export interface IBeforeFloatDomAddParam extends IEventBase {
export interface IBeforeFloatDomAddEventParams extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
@@ -445,7 +167,7 @@ export interface IBeforeFloatDomAddParam extends IEventBase {
drawings: ISheetFloatDom[];
}
export interface IFloatDomAddedParam extends IEventBase {
export interface IFloatDomAddedEventParams extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
@@ -457,7 +179,7 @@ export interface IFloatDomAddedParam extends IEventBase {
drawings: ISheetFloatDom[];
}
export interface IBeforeFloatDomUpdateParam extends IEventBase {
export interface IBeforeFloatDomUpdateEventParams extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
@@ -469,7 +191,7 @@ export interface IBeforeFloatDomUpdateParam extends IEventBase {
drawings: ISheetFloatDom[];
}
export interface IFloatDomUpdatedParam extends IEventBase {
export interface IFloatDomUpdatedEventParams extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
@@ -481,7 +203,7 @@ export interface IFloatDomUpdatedParam extends IEventBase {
drawings: ISheetFloatDom[];
}
export interface IBeforeFloatDomDeleteParam extends IEventBase {
export interface IBeforeFloatDomDeleteEventParams extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
@@ -493,7 +215,7 @@ export interface IBeforeFloatDomDeleteParam extends IEventBase {
drawings: ISheetFloatDom[];
}
export interface IFloatDomDeletedParam extends IEventBase {
export interface IFloatDomDeletedEventParams extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
@@ -505,32 +227,20 @@ export interface IFloatDomDeletedParam extends IEventBase {
drawings: string[];
}
interface IFSheetsUIEventParamConfig {
BeforeOverGridImageChange: IBeforeOverGridImageChangeParam;
OverGridImageChanged: IOverGridImageChangedParam;
interface ISheetsDrawingUIEventParamConfig {
BeforeFloatDomAdd: IBeforeFloatDomAddEventParams;
FloatDomAdded: IFloatDomAddedEventParams;
BeforeOverGridImageInsert: IBeforeOverGridImageInsertParam;
OverGridImageInserted: IOverGridImageInsertedParam;
BeforeFloatDomUpdate: IBeforeFloatDomUpdateEventParams;
FloatDomUpdated: IFloatDomUpdatedEventParams;
BeforeOverGridImageRemove: IBeforeOverGridImageRemoveParam;
OverGridImageRemoved: IOverGridImageRemovedParam;
BeforeOverGridImageSelect: IBeforeOverGridImageSelectParam;
OverGridImageSelected: IOverGridImageSelectedParam;
BeforeFloatDomAdd: IBeforeFloatDomAddParam;
FloatDomAdded: IFloatDomAddedParam;
BeforeFloatDomUpdate: IBeforeFloatDomUpdateParam;
FloatDomUpdated: IFloatDomUpdatedParam;
BeforeFloatDomDelete: IBeforeFloatDomDeleteParam;
FloatDomDeleted: IFloatDomDeletedParam;
BeforeFloatDomDelete: IBeforeFloatDomDeleteEventParams;
FloatDomDeleted: IFloatDomDeletedEventParams;
}
FEventName.extend(FDrawingEventNameMixin);
FEventName.extend(FSheetsDrawingUIEventNameMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FEventName extends IFDrawingEventNameMixin { }
interface IEventParamConfig extends IFSheetsUIEventParamConfig { }
interface FEventName extends IFSheetsDrawingUIEventNameMixin { }
interface IEventParamConfig extends ISheetsDrawingUIEventParamConfig { }
}
@@ -35,7 +35,7 @@ export interface ISaveCellImagesOptions {
useColumnIndex?: number;
}
export interface IFRangeSheetDrawingMixin {
export interface IFRangeSheetsDrawingUIMixin {
/**
* Inserts an image into the current cell.
*
@@ -81,7 +81,7 @@ export interface IFRangeSheetDrawingMixin {
saveCellImagesAsync(options?: ISaveCellImagesOptions): Promise<boolean>;
}
export class FRangeSheetDrawingUI extends FRange implements IFRangeSheetDrawingMixin {
export class FRangeSheetsDrawingUIMixin extends FRange implements IFRangeSheetsDrawingUIMixin {
override async insertCellImageAsync(file: File | string): Promise<boolean> {
const renderManagerService = this._injector.get(IRenderManagerService);
const controller = getCurrentTypeOfRenderer(UniverInstanceType.UNIVER_SHEET, this._injector.get(IUniverInstanceService), renderManagerService)
@@ -157,8 +157,8 @@ export class FRangeSheetDrawingUI extends FRange implements IFRangeSheetDrawingM
}
}
FRange.extend(FRangeSheetDrawingUI);
FRange.extend(FRangeSheetsDrawingUIMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FRange extends IFRangeSheetDrawingMixin { }
interface FRange extends IFRangeSheetsDrawingUIMixin { }
}
+18 -282
View File
@@ -15,44 +15,14 @@
*/
import type { IDisposable, IDrawingSearch, Injector } from '@univerjs/core';
import type { IEventBase } from '@univerjs/core/facade';
import type { ISheetFloatDom, ISheetImage } from '@univerjs/sheets-drawing';
import type { IDeleteDrawingCommandParams, IInsertDrawingCommandParams, ISetDrawingCommandParams } from '@univerjs/sheets-drawing-ui';
import type { FWorkbook } from '@univerjs/sheets/facade';
import type {
IBeforeFloatDomAddParam,
IBeforeFloatDomDeleteParam,
IBeforeFloatDomUpdateParam,
IBeforeOverGridImageChangeParamObject,
} from './f-event';
import type { IDeleteDrawingCommandParams, IInsertDrawingCommandParams, ISetDrawingCommandParams, ISheetFloatDom } from '@univerjs/sheets-drawing';
import type { IBeforeFloatDomAddEventParams, IBeforeFloatDomDeleteEventParams, IBeforeFloatDomUpdateEventParams, IFloatDomAddedEventParams, IFloatDomDeletedEventParams, IFloatDomUpdatedEventParams } from './f-event';
import { CanceledError, DrawingTypeEnum, ICommandService, IURLImageService } from '@univerjs/core';
import { FUniver } from '@univerjs/core/facade';
import { IDrawingManagerService, SetDrawingSelectedOperation } from '@univerjs/drawing';
import { InsertSheetDrawingCommand, RemoveSheetDrawingCommand, SetSheetDrawingCommand } from '@univerjs/sheets-drawing-ui';
import { FOverGridImage } from './f-over-grid-image';
import { IDrawingManagerService } from '@univerjs/drawing';
import { InsertSheetDrawingCommand, RemoveSheetDrawingCommand, SetSheetDrawingCommand } from '@univerjs/sheets-drawing';
interface IBeforeOverGridImageInsertParam extends IEventBase {
workbook: FWorkbook;
insertImageParams: ISheetImage[];
}
interface IBeforeOverGridImageRemoveParam extends IEventBase {
workbook: FWorkbook;
images: FOverGridImage[];
}
interface IBeforeOverGridImageChangeParam extends IEventBase {
workbook: FWorkbook;
images: IBeforeOverGridImageChangeParamObject[];
}
interface IBeforeOverGridImageSelectParam extends IEventBase {
workbook: FWorkbook;
selectedImages: FOverGridImage[];
oldSelectedImages: FOverGridImage[];
}
export interface IFUniverDrawingUIMixin {
export interface IFUniverSheetsDrawingUIMixin {
/**
* Register a custom image downloader for URL images
* @param downloader The downloader function that takes a URL and returns a base64 string
@@ -77,7 +47,7 @@ export interface IFUniverDrawingUIMixin {
/**
* @ignore
*/
export class FUniverDrawingUIMixin extends FUniver implements IFUniverDrawingUIMixin {
export class FUniverSheetsDrawingUIMixin extends FUniver implements IFUniverSheetsDrawingUIMixin {
/**
* @ignore
*/
@@ -107,7 +77,7 @@ export class FUniverDrawingUIMixin extends FUniver implements IFUniverDrawingUIM
return;
}
const eventParams: IBeforeFloatDomAddParam = {
const eventParams: IBeforeFloatDomAddEventParams = {
workbook,
drawings: floatDomDrawings,
};
@@ -142,113 +112,11 @@ export class FUniverDrawingUIMixin extends FUniver implements IFUniverDrawingUIM
return;
}
this.fireEvent(this.Event.FloatDomAdded, {
const eventParams: IFloatDomAddedEventParams = {
workbook,
drawings: floatDomDrawings,
});
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.BeforeOverGridImageInsert,
() => commandService.beforeCommandExecuted((commandInfo) => {
if (commandInfo.id !== InsertSheetDrawingCommand.id) return;
const params = commandInfo.params as IInsertDrawingCommandParams;
const workbook = this.getActiveWorkbook();
if (workbook == null || params == null) {
return;
}
const { drawings } = params;
const eventParams: IBeforeOverGridImageInsertParam = {
workbook,
insertImageParams: drawings as ISheetImage[],
};
this.fireEvent(this.Event.BeforeOverGridImageInsert, eventParams);
if (eventParams.cancel) {
throw new CanceledError();
}
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.BeforeOverGridImageRemove,
() => commandService.beforeCommandExecuted((commandInfo) => {
if (commandInfo.id !== RemoveSheetDrawingCommand.id) return;
const params = commandInfo.params as IDeleteDrawingCommandParams;
const workbook = this.getActiveWorkbook();
if (workbook == null || params == null) {
return;
}
const drawingManagerService = injector.get(IDrawingManagerService);
const { drawings } = params;
const willRemoveDrawings = drawings.map((drawing) => {
return drawingManagerService.getDrawingByParam(drawing);
}) as ISheetImage[];
const eventParams: IBeforeOverGridImageRemoveParam = {
workbook,
images: this._createFOverGridImage(willRemoveDrawings),
};
this.fireEvent(this.Event.BeforeOverGridImageRemove, eventParams);
if (eventParams.cancel) {
throw new CanceledError();
}
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.BeforeOverGridImageChange,
() => commandService.beforeCommandExecuted((commandInfo) => {
if (commandInfo.id !== SetSheetDrawingCommand.id) return;
const params = commandInfo.params as ISetDrawingCommandParams;
const workbook = this.getActiveWorkbook();
if (workbook == null || params == null) {
return;
}
const { drawings } = params;
const drawingManagerService = injector.get(IDrawingManagerService);
const images: IBeforeOverGridImageChangeParamObject[] = [];
drawings.forEach((drawing) => {
const image = drawingManagerService.getDrawingByParam(drawing as IDrawingSearch) as ISheetImage;
if (image == null) {
return;
}
images.push({
changeParam: drawing,
image: this._injector.createInstance(FOverGridImage, image),
});
});
const eventParams: IBeforeOverGridImageChangeParam = {
workbook,
images,
};
this.fireEvent(this.Event.BeforeOverGridImageChange, eventParams);
if (eventParams.cancel) {
drawingManagerService.updateNotification(drawings as IDrawingSearch[]);
throw new CanceledError();
}
this.fireEvent(this.Event.FloatDomAdded, eventParams);
})
)
);
@@ -281,7 +149,7 @@ export class FUniverDrawingUIMixin extends FUniver implements IFUniverDrawingUIM
return;
}
const eventParams: IBeforeFloatDomUpdateParam = {
const eventParams: IBeforeFloatDomUpdateEventParams = {
workbook,
drawings: floatDomDrawings,
};
@@ -324,10 +192,11 @@ export class FUniverDrawingUIMixin extends FUniver implements IFUniverDrawingUIM
return;
}
this.fireEvent(this.Event.FloatDomUpdated, {
const eventParams: IFloatDomUpdatedEventParams = {
workbook,
drawings: floatDomDrawings,
});
};
this.fireEvent(this.Event.FloatDomUpdated, eventParams);
})
)
);
@@ -358,7 +227,7 @@ export class FUniverDrawingUIMixin extends FUniver implements IFUniverDrawingUIM
return;
}
const eventParams: IBeforeFloatDomDeleteParam = {
const eventParams: IBeforeFloatDomDeleteEventParams = {
workbook,
drawings: floatDomDrawings,
};
@@ -385,147 +254,14 @@ export class FUniverDrawingUIMixin extends FUniver implements IFUniverDrawingUIM
}
const { drawings } = params;
this.fireEvent(this.Event.FloatDomDeleted, {
const eventParams: IFloatDomDeletedEventParams = {
workbook,
drawings: drawings.filter((i) => i.drawingType === DrawingTypeEnum.DRAWING_DOM).map((i) => i.drawingId),
});
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.BeforeOverGridImageSelect,
() => commandService.beforeCommandExecuted((commandInfo) => {
if (commandInfo.id !== SetDrawingSelectedOperation.id) return;
const drawings = commandInfo.params as IDrawingSearch[];
const workbook = this.getActiveWorkbook();
if (workbook == null) {
return;
}
const drawingManagerService = injector.get(IDrawingManagerService);
const oldSelectedDrawings = drawingManagerService.getFocusDrawings() as ISheetImage[];
const selectedDrawings = drawings.map((drawing) => {
return drawingManagerService.getDrawingByParam(drawing);
}) as ISheetImage[];
const eventParams: IBeforeOverGridImageSelectParam = {
workbook,
selectedImages: this._createFOverGridImage(selectedDrawings),
oldSelectedImages: this._createFOverGridImage(oldSelectedDrawings),
};
this.fireEvent(this.Event.BeforeOverGridImageSelect, eventParams);
if (eventParams.cancel) {
throw new CanceledError();
}
this.fireEvent(this.Event.FloatDomDeleted, eventParams);
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.OverGridImageInserted,
() => commandService.onCommandExecuted((commandInfo) => {
if (commandInfo.id !== InsertSheetDrawingCommand.id) return;
const params = commandInfo.params as IInsertDrawingCommandParams;
const workbook = this.getActiveWorkbook();
if (workbook == null || params == null) {
return;
}
const { drawings } = params;
this.fireEvent(this.Event.OverGridImageInserted, {
workbook,
images: this._createFOverGridImage(drawings as ISheetImage[]),
});
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.OverGridImageRemoved,
() => commandService.onCommandExecuted((commandInfo) => {
if (commandInfo.id !== RemoveSheetDrawingCommand.id) return;
const params = commandInfo.params as IDeleteDrawingCommandParams;
const workbook = this.getActiveWorkbook();
if (workbook == null || params == null) {
return;
}
const { drawings } = params;
this.fireEvent(this.Event.OverGridImageRemoved, {
workbook,
removeImageParams: drawings,
});
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.OverGridImageChanged,
() => commandService.onCommandExecuted((commandInfo) => {
if (commandInfo.id !== SetSheetDrawingCommand.id) return;
const params = commandInfo.params as ISetDrawingCommandParams;
const workbook = this.getActiveWorkbook();
if (workbook == null || params == null) {
return;
}
const { drawings } = params;
const drawingManagerService = injector.get(IDrawingManagerService);
const images = drawings.map((drawing) => {
return this._injector.createInstance(FOverGridImage, drawingManagerService.getDrawingByParam(drawing as IDrawingSearch) as ISheetImage);
});
this.fireEvent(this.Event.OverGridImageChanged, {
workbook,
images,
});
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.OverGridImageSelected,
() => commandService.onCommandExecuted((commandInfo) => {
if (commandInfo.id !== SetDrawingSelectedOperation.id) return;
const drawings = commandInfo.params as IDrawingSearch[];
const workbook = this.getActiveWorkbook();
if (workbook == null) {
return;
}
const drawingManagerService = injector.get(IDrawingManagerService);
const selectedDrawings = drawings.map((drawing) => {
return drawingManagerService.getDrawingByParam(drawing);
}) as ISheetImage[];
this.fireEvent(this.Event.OverGridImageSelected, {
workbook,
selectedImages: this._createFOverGridImage(selectedDrawings as ISheetImage[]),
});
})
)
);
}
private _createFOverGridImage(drawings: ISheetImage[]): FOverGridImage[] {
return drawings.map((drawing) => {
return this._injector.createInstance(FOverGridImage, drawing);
});
}
override registerURLImageDownloader(downloader: (url: string) => Promise<string>): IDisposable {
@@ -534,8 +270,8 @@ export class FUniverDrawingUIMixin extends FUniver implements IFUniverDrawingUIM
}
}
FUniver.extend(FUniverDrawingUIMixin);
FUniver.extend(FUniverSheetsDrawingUIMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FUniver extends IFUniverDrawingUIMixin { }
interface FUniver extends IFUniverSheetsDrawingUIMixin { }
}
@@ -14,22 +14,18 @@
* limitations under the License.
*/
import type { IDisposable, ITransformState, Nullable } from '@univerjs/core';
import type { IFBlobSource } from '@univerjs/core/facade';
import type { ISheetFloatDom, ISheetImage } from '@univerjs/sheets-drawing';
import type { ITransformState, Nullable } from '@univerjs/core';
import type { ISheetFloatDom } from '@univerjs/sheets-drawing';
import type { ICanvasFloatDom, ICanvasFloatDomInfo, IDOMAnchor } from '@univerjs/sheets-drawing-ui';
import type { IFComponentKey } from '@univerjs/sheets-ui/facade';
import type { FRange } from '@univerjs/sheets/facade';
import type { ISaveCellImagesOptions } from './f-range';
import { DrawingTypeEnum, ImageSourceType, toDisposable } from '@univerjs/core';
import { IRenderManagerService } from '@univerjs/engine-render';
import { ISheetDrawingService } from '@univerjs/sheets-drawing';
import { FileNamePart, IBatchSaveImagesService, InsertSheetDrawingCommand, RemoveSheetDrawingCommand, SetSheetDrawingCommand, SheetCanvasFloatDomManagerService, transformToAxisAlignPosition, transformToDrawingPosition } from '@univerjs/sheets-drawing-ui';
import { ISheetSelectionRenderService } from '@univerjs/sheets-ui';
import { SheetSkeletonService } from '@univerjs/sheets';
import { ISheetDrawingService, RemoveSheetDrawingCommand, SetSheetDrawingCommand, transformToAxisAlignPosition, transformToDrawingPosition } from '@univerjs/sheets-drawing';
import { FileNamePart, IBatchSaveImagesService, SheetCanvasFloatDomManagerService } from '@univerjs/sheets-drawing-ui';
import { transformComponentKey } from '@univerjs/sheets-ui/facade';
import { FWorksheet } from '@univerjs/sheets/facade';
import { ComponentManager } from '@univerjs/ui';
import { FOverGridImage, FOverGridImageBuilder } from './f-over-grid-image';
// why omit this key? if componentKey is missing, then which component should be used?
export interface IFICanvasFloatDom extends Omit<ICanvasFloatDom, 'componentKey' | 'unitId' | 'subUnitId'>, IFComponentKey { }
@@ -44,7 +40,7 @@ export interface IFCanvasFloatDomResult extends Omit<ICanvasFloatDom, 'component
/**
* @ignore
*/
export interface IFWorksheetLegacy {
export interface IFWorksheetDrawingUIMixin {
/**
* Get float dom by id
* @param {string} id - float dom id
@@ -386,210 +382,6 @@ export interface IFWorksheetLegacy {
dispose: () => void;
}>;
/**
* Insert an image to the sheet
* @param {string} url - The image url
* @returns true if the image is inserted successfully
* @example
* ```ts
* // Insert an image to the sheet, default position is A1
* const fWorksheet = univerAPI.getActiveWorkbook().getActiveSheet();
* const result = await fWorksheet.insertImage('https://avatars.githubusercontent.com/u/61444807?s=48&v=4');
* console.log(result);
* ```
*/
insertImage(url: string): Promise<boolean>;
/**
* @param {string} url - The image url
* @param {number} column - The column index to insert the image
* @param {number} row - The row index to insert the image
* @returns True if the image is inserted successfully
* @example
* ```ts
* // Insert an image to the sheet, position is F6
* const fWorksheet = univerAPI.getActiveWorkbook().getActiveSheet();
* const result = await fWorksheet.insertImage('https://avatars.githubusercontent.com/u/61444807?s=48&v=4', 5, 5);
* console.log(result);
* ```
*/
insertImage(url: string, column: number, row: number): Promise<boolean>;
/**
* @param {string} url - The image url
* @param {number} column - The column index to insert the image
* @param {number} row - The row index to insert the image
* @param {number} offsetX - The column offset, pixel unit
* @param {number} offsetY - The row offset, pixel unit
* @returns True if the image is inserted successfully
* @example
* ```ts
* // Insert an image to the sheet, position is F6, offset is 10px
* const fWorksheet = univerAPI.getActiveWorkbook().getActiveSheet();
* const result = await fWorksheet.insertImage('https://avatars.githubusercontent.com/u/61444807?s=48&v=4', 5, 5, 10, 10);
* console.log(result);
* ```
*/
insertImage(url: string, column: number, row: number, offsetX: number, offsetY: number): Promise<boolean>;
insertImage(url: IFBlobSource): Promise<boolean>;
insertImage(url: IFBlobSource, column: number, row: number): Promise<boolean>;
insertImage(url: IFBlobSource, column: number, row: number, offsetX: number, offsetY: number): Promise<boolean>;
insertImage(url: IFBlobSource | string, column: number, row: number, offsetX: number, offsetY: number): Promise<boolean>;
/**
* Insert images to the sheet
* @param {ISheetImage[]} sheetImages - The images to insert
* @returns {FWorksheet} The FWorksheet instance for chaining
* @example
* ```ts
* // create a new image builder and set image source.
* // then build `ISheetImage` and insert it into the sheet, position is start from F6 cell, width is 500px, height is 300px
* const fWorkbook = univerAPI.getActiveWorkbook();
* const fWorksheet = fWorkbook.getActiveSheet();
* const image = await fWorksheet.newOverGridImage()
* .setSource('https://avatars.githubusercontent.com/u/61444807?s=48&v=4', univerAPI.Enum.ImageSourceType.URL)
* .setColumn(5)
* .setRow(5)
* .setWidth(500)
* .setHeight(300)
* .buildAsync();
* fWorksheet.insertImages([image]);
*
* // update the image width to 100px and height to 50px
* setTimeout(async () => {
* const imageBuilder = fWorksheet.getImageById(image.drawingId).toBuilder();
* const newImage = await imageBuilder.setWidth(100).setHeight(50).buildAsync();
* fWorksheet.updateImages([newImage]);
* }, 4000);
* ```
*/
insertImages(sheetImages: ISheetImage[]): FWorksheet;
/**
* Get all images of the sheet.
* @returns {FOverGridImage[]} The FOverGridImage instances
* @example
* ```ts
* const fWorksheet = univerAPI.getActiveWorkbook().getActiveSheet();
* const images = fWorksheet.getImages();
* images.forEach((image) => {
* console.log(image, image.getId());
* });
* ```
*/
getImages(): FOverGridImage[];
/**
* Get image by drawing id
* @param {string} id - The drawing id of the image
* @returns {FOverGridImage | null} The FOverGridImage instance
* @example
* ```ts
* const fWorksheet = univerAPI.getActiveWorkbook().getActiveSheet();
* const image = fWorksheet.getImageById('xxxx');
* console.log(image);
* ```
*/
getImageById(id: string): FOverGridImage | null;
/**
* Delete images from the sheet
* @param {FOverGridImage[]} sheetImages - The images to delete
* @returns {FWorksheet} The FWorksheet instance for chaining
* @example
* ```ts
* const fWorksheet = univerAPI.getActiveWorkbook().getActiveSheet();
* const image = fWorksheet.getImages()[0];
*
* // Delete the first image of the sheet
* fWorksheet.deleteImages([image]);
* ```
*/
deleteImages(sheetImages: FOverGridImage[]): FWorksheet;
/**
* Update images to the sheet
* @param {ISheetImage[]} sheetImages - The images to update
* @returns {FWorksheet} The FWorksheet instance for chaining
* @example
* ```ts
* // create a new image builder and set image source.
* // then build `ISheetImage` and insert it into the sheet, position is start from F6 cell, width is 500px, height is 300px
* const fWorkbook = univerAPI.getActiveWorkbook();
* const fWorksheet = fWorkbook.getActiveSheet();
* const image = await fWorksheet.newOverGridImage()
* .setSource('https://avatars.githubusercontent.com/u/61444807?s=48&v=4', univerAPI.Enum.ImageSourceType.URL)
* .setColumn(5)
* .setRow(5)
* .setWidth(500)
* .setHeight(300)
* .buildAsync();
* fWorksheet.insertImages([image]);
*
* // update the image width to 100px and height to 50px after 4 seconds
* setTimeout(async () => {
* const imageBuilder = fWorksheet.getImageById(image.drawingId).toBuilder();
* const newImage = await imageBuilder.setWidth(100).setHeight(50).buildAsync();
* fWorksheet.updateImages([newImage]);
* }, 4000);
* ```
*/
updateImages(sheetImages: ISheetImage[]): FWorksheet;
/**
* Get the current selected images.
* @returns {FOverGridImage[]} The FOverGridImage instances
* @example
* ```ts
* const fWorksheet = univerAPI.getActiveWorkbook().getActiveSheet();
* const images = fWorksheet.getActiveImages();
* images.forEach((image) => {
* console.log(image, image.getId());
* });
* ```
*/
getActiveImages(): FOverGridImage[];
/**
* Hook when a image is inserted.
* @param {function(FOverGridImage[]: void)} callback - The callback function when a image is inserted.
* @deprecated use `univerAPI.addEvent(univerAPI.Event.OverGridImageInserted, (params) => {})` as instead
*/
onImageInserted(callback: (images: FOverGridImage[]) => void): IDisposable;
/**
* Hook when a image is deleted.
* @param {function(FOverGridImage[]: void)} callback - The callback function when a image is deleted.
* @deprecated use `univerAPI.addEvent(univerAPI.Event.OverGridImageRemoved, (params) => {})` as instead
*/
onImageDeleted(callback: (images: FOverGridImage[]) => void): IDisposable;
/**
* Hook when a image is changed.
* @param {function(FOverGridImage[]: void)} callback - The callback function when a image is changed.
* @deprecated use `univerAPI.addEvent(univerAPI.Event.OverGridImageChanged, (params) => {})` as instead
*/
onImageChanged(callback: (images: FOverGridImage[]) => void): IDisposable;
/**
* Create a new over grid image builder.
* @returns {FOverGridImageBuilder} The FOverGridImageBuilder instance
* @example
* ```ts
* // create a new image builder and set image source.
* // then build `ISheetImage` and insert it into the sheet, position is start from F6 cell, width is 500px, height is 300px
* const fWorkbook = univerAPI.getActiveWorkbook();
* const fWorksheet = fWorkbook.getActiveSheet();
* const image = await fWorksheet.newOverGridImage()
* .setSource('https://avatars.githubusercontent.com/u/61444807?s=48&v=4', univerAPI.Enum.ImageSourceType.URL)
* .setColumn(5)
* .setRow(5)
* .setWidth(500)
* .setHeight(300)
* .buildAsync();
* fWorksheet.insertImages([image]);
* ```
*/
newOverGridImage(): FOverGridImageBuilder;
/**
* Save all cell images from specified ranges to the file system.
* This method will open a directory picker dialog and save all images to the selected directory.
@@ -619,7 +411,7 @@ export interface IFWorksheetLegacy {
saveCellImagesAsync(options?: ISaveCellImagesOptions, ranges?: FRange[]): Promise<boolean>;
}
export class FWorksheetLegacy extends FWorksheet implements IFWorksheetLegacy {
export class FWorksheetDrawingUIMixin extends FWorksheet implements IFWorksheetDrawingUIMixin {
override getFloatDomById(id: string): Nullable<IFCanvasFloatDomResult> {
const floatDomService = this._injector.get(SheetCanvasFloatDomManagerService);
const info = floatDomService.getFloatDomInfo(id);
@@ -693,11 +485,14 @@ export class FWorksheetLegacy extends FWorksheet implements IFWorksheetLegacy {
}
override updateFloatDom(id: string, config: Partial<Omit<IFCanvasFloatDomResult, 'id'>>): this {
const sheetSkeletonService = this._injector.get(SheetSkeletonService);
const floatDomService = this._injector.get(SheetCanvasFloatDomManagerService);
const info = floatDomService.getFloatDomInfo(id);
if (!info) return this;
const { unitId, subUnitId } = info;
const skeleton = sheetSkeletonService.getSkeleton(unitId, subUnitId);
if (!skeleton) return this;
const drawingParm = this._injector.get(ISheetDrawingService).getDrawingByParam({
unitId,
@@ -705,50 +500,34 @@ export class FWorksheetLegacy extends FWorksheet implements IFWorksheetLegacy {
drawingId: id,
})! as ISheetFloatDom;
const renderManagerService = this._injector.get(IRenderManagerService);
const render = renderManagerService.getRenderById(unitId);
if (!render) return this;
const skeleton = this.getSkeleton();
if (!skeleton) return this;
const selectionRenderService = renderManagerService.getRenderById(this.getWorkbook().getUnitId())?.with(ISheetSelectionRenderService);
if (!selectionRenderService) return this;
const newParam: ISheetFloatDom = {
...drawingParm,
componentKey: config.componentKey || drawingParm.componentKey,
allowTransform: config.allowTransform !== undefined ? config.allowTransform : drawingParm.allowTransform,
data: config.data || drawingParm.data,
sheetTransform: config.position
? transformToDrawingPosition(
config.position,
selectionRenderService
) ?? drawingParm.sheetTransform
? transformToDrawingPosition(config.position, skeleton) ?? drawingParm.sheetTransform
: drawingParm.sheetTransform,
transform: {
...drawingParm.transform,
...config.position, // Merge with existing transform
},
axisAlignSheetTransform: config.position
? transformToAxisAlignPosition(
config.position,
selectionRenderService
) ?? drawingParm.sheetTransform
? transformToAxisAlignPosition(config.position, skeleton) ?? drawingParm.sheetTransform
: drawingParm.sheetTransform,
};
const res = this._commandService.syncExecuteCommand(SetSheetDrawingCommand.id, { unitId, subUnitId, drawings: [newParam] });
if (!res) {
throw new Error('updateFloatDom failed');
}
return this;
}
override batchUpdateFloatDoms(updates: Array<{ id: string; config: Partial<Omit<IFCanvasFloatDomResult, 'id'>> }>): this {
const floatDomService = this._injector.get(SheetCanvasFloatDomManagerService);
const drawingService = this._injector.get(ISheetDrawingService);
const renderManagerService = this._injector.get(IRenderManagerService);
const sheetSkeletonService = this._injector.get(SheetSkeletonService);
const drawings: ISheetFloatDom[] = [];
@@ -757,6 +536,9 @@ export class FWorksheetLegacy extends FWorksheet implements IFWorksheetLegacy {
if (!info) continue;
const { unitId, subUnitId } = info;
const skeleton = sheetSkeletonService.getSkeleton(unitId, subUnitId);
if (!skeleton) continue;
const drawingParm = drawingService.getDrawingByParam({
unitId,
subUnitId,
@@ -764,35 +546,20 @@ export class FWorksheetLegacy extends FWorksheet implements IFWorksheetLegacy {
}) as ISheetFloatDom;
if (!drawingParm) continue;
const render = renderManagerService.getRenderById(unitId);
if (!render) continue;
const skeleton = this.getSkeleton();
if (!skeleton) continue;
const selectionRenderService = render.with(ISheetSelectionRenderService);
if (!selectionRenderService) return this;
const newParam: ISheetFloatDom = {
...drawingParm,
componentKey: update.config.componentKey || drawingParm.componentKey,
allowTransform: update.config.allowTransform !== undefined ? update.config.allowTransform : drawingParm.allowTransform,
data: update.config.data || drawingParm.data,
sheetTransform: update.config.position
? transformToDrawingPosition(
update.config.position,
selectionRenderService
) ?? drawingParm.sheetTransform
? transformToDrawingPosition(update.config.position, skeleton) ?? drawingParm.sheetTransform
: drawingParm.sheetTransform,
transform: {
...drawingParm.transform,
...update.config.position, // Merge with existing transform
},
axisAlignSheetTransform: update.config.position
? transformToAxisAlignPosition(
update.config.position,
selectionRenderService
) ?? drawingParm.sheetTransform
? transformToAxisAlignPosition(update.config.position, skeleton) ?? drawingParm.sheetTransform
: drawingParm.sheetTransform,
};
@@ -913,146 +680,6 @@ export class FWorksheetLegacy extends FWorksheet implements IFWorksheetLegacy {
return null;
}
override async insertImage(url: IFBlobSource | string, column?: number, row?: number, offsetX?: number, offsetY?: number): Promise<boolean> {
const imageBuilder = this.newOverGridImage();
if (typeof url === 'string') {
imageBuilder.setSource(url);
} else {
const blobSource = url.getBlob();
const base64 = await blobSource.getDataAsString();
imageBuilder.setSource(base64, ImageSourceType.BASE64);
}
if (column !== undefined) {
imageBuilder.setColumn(column);
} else {
imageBuilder.setColumn(0);
}
if (row !== undefined) {
imageBuilder.setRow(row);
} else {
imageBuilder.setRow(0);
}
if (offsetX !== undefined) {
imageBuilder.setColumnOffset(offsetX);
} else {
imageBuilder.setColumnOffset(0);
}
if (offsetY !== undefined) {
imageBuilder.setRowOffset(offsetY);
} else {
imageBuilder.setRowOffset(0);
}
const param = await imageBuilder.buildAsync();
// param.drawingId
return this._commandService.syncExecuteCommand(InsertSheetDrawingCommand.id, { unitId: this._fWorkbook.getId(), drawings: [param] });
}
override insertImages(sheetImages: ISheetImage[]): FWorksheet {
const param = sheetImages.map((image) => {
image.unitId = this._fWorkbook.getId();
image.subUnitId = this.getSheetId();
return image;
});
this._commandService.syncExecuteCommand(InsertSheetDrawingCommand.id, { unitId: this._fWorkbook.getId(), drawings: param });
return this;
}
override deleteImages(sheetImages: FOverGridImage[]): FWorksheet {
const drawings = sheetImages.map((image) => {
return {
unitId: this._fWorkbook.getId(),
drawingId: image.getId(),
subUnitId: this.getSheetId(),
drawingType: image.getType(),
};
});
this._commandService.syncExecuteCommand(RemoveSheetDrawingCommand.id, { unitId: this._fWorkbook.getId(), drawings });
return this;
}
override getImages(): FOverGridImage[] {
const sheetDrawingService = this._injector.get(ISheetDrawingService);
const drawingData = sheetDrawingService.getDrawingData(this._fWorkbook.getId(), this.getSheetId());
const images: FOverGridImage[] = [];
for (const drawingId in drawingData) {
const drawing = drawingData[drawingId];
if (drawing.drawingType !== DrawingTypeEnum.DRAWING_IMAGE) {
continue;
}
images.push(this._injector.createInstance(FOverGridImage, drawing as ISheetImage));
}
return images;
}
override getImageById(id: string): FOverGridImage | null {
const sheetDrawingService = this._injector.get(ISheetDrawingService);
const drawing = sheetDrawingService.getDrawingByParam({ unitId: this._fWorkbook.getId(), subUnitId: this.getSheetId(), drawingId: id });
if (drawing && drawing.drawingType === DrawingTypeEnum.DRAWING_IMAGE) {
return this._injector.createInstance(FOverGridImage, drawing as ISheetImage);
}
return null;
}
override getActiveImages(): FOverGridImage[] {
const sheetDrawingService = this._injector.get(ISheetDrawingService);
const drawingData = sheetDrawingService.getFocusDrawings();
const images: FOverGridImage[] = [];
for (const drawingId in drawingData) {
const drawing = drawingData[drawingId];
images.push(this._injector.createInstance(FOverGridImage, drawing as ISheetImage));
}
return images;
}
override updateImages(sheetImages: ISheetImage[]): FWorksheet {
this._commandService.syncExecuteCommand(SetSheetDrawingCommand.id, { unitId: this._fWorkbook.getId(), drawings: sheetImages });
return this;
}
override onImageInserted(callback: (images: FOverGridImage[]) => void): IDisposable {
const sheetDrawingService = this._injector.get(ISheetDrawingService);
return toDisposable(sheetDrawingService.add$.subscribe((drawingSearches) => {
const drawings = drawingSearches.map(
(drawingSearch) => this._injector.createInstance(FOverGridImage, sheetDrawingService.getDrawingByParam(drawingSearch) as ISheetImage)
);
callback(drawings);
}));
}
override onImageDeleted(callback: (images: FOverGridImage[]) => void): IDisposable {
const sheetDrawingService = this._injector.get(ISheetDrawingService);
return toDisposable(sheetDrawingService.remove$.subscribe((drawingSearches) => {
const drawings = drawingSearches.map(
(drawingSearch) => this._injector.createInstance(FOverGridImage, sheetDrawingService.getDrawingByParam(drawingSearch) as ISheetImage)
);
callback(drawings);
}));
}
override onImageChanged(callback: (images: FOverGridImage[]) => void): IDisposable {
const sheetDrawingService = this._injector.get(ISheetDrawingService);
return toDisposable(sheetDrawingService.update$.subscribe((drawingSearches) => {
const drawings = drawingSearches.map(
(drawingSearch) => this._injector.createInstance(FOverGridImage, sheetDrawingService.getDrawingByParam(drawingSearch) as ISheetImage)
);
callback(drawings);
}));
}
override newOverGridImage(): FOverGridImageBuilder {
const unitId = this._fWorkbook.getId();
const subUnitId = this.getSheetId();
return this._injector.createInstance(FOverGridImageBuilder, unitId, subUnitId);
}
override async saveCellImagesAsync(options?: ISaveCellImagesOptions, ranges?: FRange[]): Promise<boolean> {
const batchSaveService = this._injector.get(IBatchSaveImagesService);
const unitId = this._fWorkbook.getId();
@@ -1109,8 +736,8 @@ export class FWorksheetLegacy extends FWorksheet implements IFWorksheetLegacy {
}
}
FWorksheet.extend(FWorksheetLegacy);
FWorksheet.extend(FWorksheetDrawingUIMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FWorksheet extends IFWorksheetLegacy { }
interface FWorksheet extends IFWorksheetDrawingUIMixin { }
}
@@ -14,16 +14,12 @@
* limitations under the License.
*/
import './f-over-grid-image';
import './f-worksheet';
import './f-enum';
import './f-event';
import './f-univer';
import './f-range';
export type * from './f-enum';
export type * from './f-event';
export type * from './f-over-grid-image';
export type * from './f-range';
export type * from './f-univer';
export type * from './f-worksheet';
-6
View File
@@ -16,17 +16,11 @@
import './global.css';
export { drawingPositionToTransform, transformToAxisAlignPosition, transformToDrawingPosition } from './basics/transform-position';
export { DeleteDrawingsCommand } from './commands/commands/delete-drawings.command';
export { GroupSheetDrawingCommand } from './commands/commands/group-sheet-drawing.command';
export { type IInsertImageCommandParams, InsertFloatImageCommand } from './commands/commands/insert-image.command';
export { InsertSheetDrawingCommand } from './commands/commands/insert-sheet-drawing.command';
export type { IDeleteDrawingCommandParams, IInsertDrawingCommandParams, ISetDrawingCommandParams } from './commands/commands/interfaces';
export { MoveDrawingsCommand } from './commands/commands/move-drawings.command';
export { RemoveSheetDrawingCommand } from './commands/commands/remove-sheet-drawing.command';
export { SaveCellImagesCommand } from './commands/commands/save-cell-images.command';
export { SetDrawingArrangeCommand } from './commands/commands/set-drawing-arrange.command';
export { SetSheetDrawingCommand } from './commands/commands/set-sheet-drawing.command';
export { UngroupSheetDrawingCommand } from './commands/commands/ungroup-sheet-drawing.command';
export { ClearSheetDrawingTransformerOperation } from './commands/operations/clear-drawing-transformer.operation';
export { EditSheetDrawingOperation } from './commands/operations/edit-sheet-drawing.operation';
@@ -23,10 +23,10 @@ import { MessageType } from '@univerjs/design';
import { IDrawingManagerService, SetDrawingSelectedOperation } from '@univerjs/drawing';
import { COMPONENT_IMAGE_POPUP_MENU, ImageCropperObject, ImageResetSizeOperation, OpenImageCropOperation } from '@univerjs/drawing-ui';
import { IRenderManagerService } from '@univerjs/engine-render';
import { RemoveSheetDrawingCommand } from '@univerjs/sheets-drawing';
import { SheetCanvasPopManagerService } from '@univerjs/sheets-ui';
import { IMessageService } from '@univerjs/ui';
import { FlipSheetDrawingCommand } from '../commands/commands/flip-drawings.command';
import { RemoveSheetDrawingCommand } from '../commands/commands/remove-sheet-drawing.command';
import { EditSheetDrawingOperation } from '../commands/operations/edit-sheet-drawing.operation';
export class DrawingPopupMenuController extends RxDisposable {
@@ -18,18 +18,16 @@ import type { IDisposable, IDrawingSearch, IPosition, IRange, ITransformState, N
import type { IDrawingJsonUndo1 } from '@univerjs/drawing';
import type { BaseObject, IBoundRectNoAngle, IRectProps, IRender, Scene, SpreadsheetSkeleton } from '@univerjs/engine-render';
import type { ISetFrozenMutationParams, ISetSelectionsOperationParams, ISetWorksheetRowAutoHeightMutationParams } from '@univerjs/sheets';
import type { IFloatDomData, ISheetDrawingPosition, ISheetFloatDom } from '@univerjs/sheets-drawing';
import type { IFloatDomData, IInsertDrawingCommandParams, ISheetDrawingPosition, ISheetFloatDom } from '@univerjs/sheets-drawing';
import type { IFloatDom, IFloatDomLayout } from '@univerjs/ui';
import type { IInsertDrawingCommandParams } from '../commands/commands/interfaces';
import { Disposable, DisposableCollection, DrawingTypeEnum, fromEventSubject, generateRandomId, ICommandService, Inject, IUniverInstanceService, LifecycleService, LifecycleStages, Tools, UniverInstanceType } from '@univerjs/core';
import { getDrawingShapeKeyByDrawingSearch, IDrawingManagerService } from '@univerjs/drawing';
import { DRAWING_OBJECT_LAYER_INDEX, IRenderManagerService, ObjectType, Rect, SHEET_VIEWPORT_KEY } from '@univerjs/engine-render';
import { COMMAND_LISTENER_SKELETON_CHANGE, getSheetCommandTarget, SetFrozenMutation, SetSelectionsOperation, SetWorksheetRowAutoHeightMutation } from '@univerjs/sheets';
import { DrawingApplyType, ISheetDrawingService, SetDrawingApplyMutation } from '@univerjs/sheets-drawing';
import { DrawingApplyType, InsertSheetDrawingCommand, ISheetDrawingService, SetDrawingApplyMutation } from '@univerjs/sheets-drawing';
import { ISheetSelectionRenderService, SetScrollOperation, SetZoomRatioOperation, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
import { CanvasFloatDomService } from '@univerjs/ui';
import { BehaviorSubject, filter, map, of, Subject, switchMap, take } from 'rxjs';
import { InsertSheetDrawingCommand } from '../commands/commands/insert-sheet-drawing.command';
export interface ICanvasFloatDom {
/**
@@ -761,7 +759,7 @@ export class SheetCanvasFloatDomManagerService extends Disposable {
if (!renderObject) return;
const currentRender = this._renderManagerService.getRenderById(unitId);
if (!currentRender) return;
const skeletonParam = this._renderManagerService.getRenderById(unitId)?.with(SheetSkeletonManagerService).getWorksheetSkeleton(subUnitId);
const skeletonParam = this._renderManagerService.getRenderById(unitId)?.with(SheetSkeletonManagerService).getSkeletonParam(subUnitId);
if (!skeletonParam) return;
const { componentKey, data, allowTransform = true } = config;
@@ -815,7 +813,7 @@ export class SheetCanvasFloatDomManagerService extends Disposable {
if (!skMangerService) {
return;
}
const skeletonParam = skMangerService.getWorksheetSkeleton(subUnitId);
const skeletonParam = skMangerService.getSkeletonParam(subUnitId);
if (!skeletonParam) {
return;
}
@@ -1011,7 +1009,7 @@ export class SheetCanvasFloatDomManagerService extends Disposable {
if (!renderObject) return;
const currentRender = this._renderManagerService.getRenderById(unitId);
if (!currentRender) return;
const skeletonParam = this._renderManagerService.getRenderById(unitId)?.with(SheetSkeletonManagerService).getWorksheetSkeleton(subUnitId);
const skeletonParam = this._renderManagerService.getRenderById(unitId)?.with(SheetSkeletonManagerService).getSkeletonParam(subUnitId);
if (!skeletonParam) return;
const { componentKey, data, allowTransform = true } = config;
@@ -1071,7 +1069,7 @@ export class SheetCanvasFloatDomManagerService extends Disposable {
if (!skMangerService) {
return;
}
const skeleton = skMangerService.getWorksheetSkeleton(subUnitId);
const skeleton = skMangerService.getSkeletonParam(subUnitId);
if (!skeleton) {
return;
}
@@ -21,10 +21,9 @@ import { ICommandService, LocaleService } from '@univerjs/core';
import { clsx, Radio, RadioGroup } from '@univerjs/design';
import { IDrawingManagerService } from '@univerjs/drawing';
import { IRenderManagerService } from '@univerjs/engine-render';
import { SheetDrawingAnchorType } from '@univerjs/sheets-drawing';
import { SetSheetDrawingCommand, SheetDrawingAnchorType } from '@univerjs/sheets-drawing';
import { useDependency } from '@univerjs/ui';
import { useEffect, useState } from 'react';
import { SetSheetDrawingCommand } from '../../commands/commands/set-sheet-drawing.command';
export interface ISheetDrawingAnchorProps {
drawings: IDrawingParam[];
+13 -1
View File
@@ -20,7 +20,8 @@
"keywords": [],
"exports": {
".": "./src/index.ts",
"./*": "./src/*"
"./*": "./src/*",
"./facade": "./src/facade/index.ts"
},
"main": "./src/index.ts",
"types": "./lib/types/index.d.ts",
@@ -39,6 +40,16 @@
"require": "./lib/cjs/*",
"types": "./lib/types/index.d.ts"
},
"./facade": {
"import": "./lib/es/facade.js",
"require": "./lib/cjs/facade.js",
"types": "./lib/types/facade/index.d.ts"
},
"./lib/facade": {
"import": "./lib/es/facade.js",
"require": "./lib/cjs/facade.js",
"types": "./lib/types/facade/index.d.ts"
},
"./lib/*": "./lib/*"
}
},
@@ -60,6 +71,7 @@
"dependencies": {
"@univerjs/core": "workspace:*",
"@univerjs/drawing": "workspace:*",
"@univerjs/engine-render": "workspace:*",
"@univerjs/sheets": "workspace:*"
},
"devDependencies": {
@@ -0,0 +1,103 @@
/**
* 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.
*/
import type { ITransformState, Nullable } from '@univerjs/core';
import type { SpreadsheetSkeleton } from '@univerjs/engine-render';
import type { ISheetSkeletonManagerParam } from '@univerjs/sheets';
import type { ISheetDrawingPosition } from '../services/sheet-drawing.service';
import { convertPositionSheetOverGridToAbsolute } from '@univerjs/sheets';
export function drawingPositionToTransform(position: ISheetDrawingPosition, sheetSkeletonParam: Nullable<ISheetSkeletonManagerParam>): Nullable<ITransformState> {
if (!sheetSkeletonParam) return;
const { unitId, sheetId, skeleton } = sheetSkeletonParam;
const { from, to, flipY = false, flipX = false, angle = 0, skewX = 0, skewY = 0 } = position;
const absolutePosition = convertPositionSheetOverGridToAbsolute(unitId, sheetId, { from, to }, skeleton);
let { left, top, width, height } = absolutePosition;
const sheetWidth = skeleton.rowHeaderWidth + skeleton.columnTotalWidth;
const sheetHeight = skeleton.columnHeaderHeight + skeleton.rowTotalHeight;
if ((left + width) > sheetWidth) {
left = sheetWidth - width;
}
if ((top + height) > sheetHeight) {
top = sheetHeight - height;
}
return {
flipY,
flipX,
angle,
skewX,
skewY,
left,
top,
width,
height,
};
}
// use transform and originSize convert to ISheetDrawingPosition
export function transformToDrawingPosition(transform: ITransformState, skeleton: SpreadsheetSkeleton): ISheetDrawingPosition {
const { left = 0, top = 0, width = 0, height = 0, flipY = false, flipX = false, angle = 0, skewX = 0, skewY = 0 } = transform;
const startSelectionCell = skeleton.getOffsetRelativeToRowCol(left, top);
const endSelectionCell = skeleton.getOffsetRelativeToRowCol(left + width, top + height);
return {
flipY,
flipX,
angle,
skewX,
skewY,
from: startSelectionCell,
to: endSelectionCell,
};
}
/**
* In excel, the basic drawing with rotate bound use major axis switch, axis-aligned bound will bu used.That means the position bound of drawing element will save as nearly axis-aligned rectangle.
* Here is the rule to convert transform to axis-aligned position:
* [-45°, 45°): use the original bound
* [45°, 135°): rotate the bound 90° clockwise,and the left, top, bottom,right will use the rotated bound.
* [135°, 225°): use the original bound
* [225°, 315°): rotate the bound 90° counterclockwise, and the left, top, bottom, right will use the rotated bound.
* @return The axis-aligned position of the drawing element.
*/
export function transformToAxisAlignPosition(transform: ITransformState, skeleton: SpreadsheetSkeleton): ISheetDrawingPosition {
const { left = 0, top = 0, width = 0, height = 0, angle = 0 } = transform;
const norm = ((angle % 360) + 360) % 360;
const useSwappedAxis =
(norm >= 45 && norm < 135) ||
(norm >= 225 && norm < 315);
if (!useSwappedAxis) {
return transformToDrawingPosition(transform, skeleton);
}
const rotatedTransform = {
...transform,
left: left + width / 2 - height / 2,
top: top + height / 2 - width / 2,
width: height,
height: width,
};
return transformToDrawingPosition(rotatedTransform, skeleton);
}
@@ -16,8 +16,7 @@
import type { IAccessor, ICommand } from '@univerjs/core';
import type { IDrawingJsonUndo1 } from '@univerjs/drawing';
import type { IInsertDrawingCommandParams } from './interfaces';
import type { ISheetDrawing } from '../../services/sheet-drawing.service';
import {
CommandType,
ICommandService,
@@ -25,33 +24,27 @@ import {
sequenceExecute,
} from '@univerjs/core';
import { SheetInterceptorService } from '@univerjs/sheets';
import { DrawingApplyType, ISheetDrawingService, SetDrawingApplyMutation } from '@univerjs/sheets-drawing';
import { ClearSheetDrawingTransformerOperation } from '../operations/clear-drawing-transformer.operation';
import { ISheetDrawingService } from '../../services/sheet-drawing.service';
import { DrawingApplyType, SetDrawingApplyMutation } from '../mutations/set-drawing-apply.mutation';
export interface IInsertDrawingCommandParams {
unitId: string;
drawings: ISheetDrawing[];
}
/**
* The command to insert new defined name
*/
export const InsertSheetDrawingCommand: ICommand = {
id: 'sheet.command.insert-sheet-image',
type: CommandType.COMMAND,
handler: (accessor: IAccessor, params?: IInsertDrawingCommandParams) => {
if (!params) return false;
const commandService = accessor.get(ICommandService);
const undoRedoService = accessor.get(IUndoRedoService);
const sheetDrawingService = accessor.get(ISheetDrawingService);
const sheetInterceptorService = accessor.get(SheetInterceptorService);
if (!params) return false;
// const { drawingParam, imageParam } = params;
const drawings = params.drawings;
// const sheetDrawingParams = drawings.map((param) => param.sheetDrawingParam);
const unitIds: string[] = drawings.map((param) => param.unitId);
// execute do mutations and add undo mutations to undo stack if completed
const jsonOp = sheetDrawingService.getBatchAddOp(drawings) as IDrawingJsonUndo1;
const { unitId, subUnitId, undo, redo, objects } = jsonOp;
const intercepted = sheetInterceptorService.onCommandExecute({ id: InsertSheetDrawingCommand.id, params });
@@ -68,13 +61,11 @@ export const InsertSheetDrawingCommand: ICommand = {
...(intercepted.preUndos ?? []),
undoInsertMutation,
...(intercepted.undos),
{ id: ClearSheetDrawingTransformerOperation.id, params: unitIds },
],
redoMutations: [
...(intercepted.preRedos ?? []),
insertMutation,
...intercepted.redos,
{ id: ClearSheetDrawingTransformerOperation.id, params: unitIds },
],
});
@@ -14,9 +14,8 @@
* limitations under the License.
*/
import type { IAccessor, ICommand } from '@univerjs/core';
import type { DrawingTypeEnum, IAccessor, ICommand } from '@univerjs/core';
import type { IDrawingJsonUndo1 } from '@univerjs/drawing';
import type { IDeleteDrawingCommandParams } from './interfaces';
import {
CommandType,
ICommandService,
@@ -24,40 +23,38 @@ import {
sequenceExecute,
} from '@univerjs/core';
import { SheetInterceptorService } from '@univerjs/sheets';
import { DrawingApplyType, ISheetDrawingService, SetDrawingApplyMutation } from '@univerjs/sheets-drawing';
import { ClearSheetDrawingTransformerOperation } from '../operations/clear-drawing-transformer.operation';
import { ISheetDrawingService } from '../../services/sheet-drawing.service';
import { DrawingApplyType, SetDrawingApplyMutation } from '../mutations/set-drawing-apply.mutation';
export interface IDeleteDrawingCommandParam {
unitId: string;
subUnitId: string;
drawingId: string;
drawingType: DrawingTypeEnum;
}
export interface IDeleteDrawingCommandParams {
unitId: string;
drawings: IDeleteDrawingCommandParam[];
}
/**
* The command to remove new sheet image
*/
export const RemoveSheetDrawingCommand: ICommand = {
id: 'sheet.command.remove-sheet-image',
type: CommandType.COMMAND,
handler: (accessor: IAccessor, params?: IDeleteDrawingCommandParams) => {
if (!params) return false;
const commandService = accessor.get(ICommandService);
const undoRedoService = accessor.get(IUndoRedoService);
const sheetInterceptorService = accessor.get(SheetInterceptorService);
const sheetDrawingService = accessor.get(ISheetDrawingService);
if (!params) return false;
const { drawings } = params;
const unitIds: string[] = [];
drawings.forEach((param) => {
const { unitId } = param;
unitIds.push(unitId);
});
const jsonOp = sheetDrawingService.getBatchRemoveOp(drawings) as IDrawingJsonUndo1;
const { unitId, subUnitId, undo, redo, objects } = jsonOp;
const intercepted = sheetInterceptorService.onCommandExecute({ id: RemoveSheetDrawingCommand.id, params });
// execute do mutations and add undo mutations to undo stack if completed
const removeMutation = { id: SetDrawingApplyMutation.id, params: { unitId, subUnitId, op: redo, objects, type: DrawingApplyType.REMOVE } };
const undoRemoveMutation = { id: SetDrawingApplyMutation.id, params: { unitId, subUnitId, op: undo, objects, type: DrawingApplyType.INSERT } };
@@ -70,13 +67,11 @@ export const RemoveSheetDrawingCommand: ICommand = {
...(intercepted.preUndos ?? []),
undoRemoveMutation,
...intercepted.undos,
{ id: ClearSheetDrawingTransformerOperation.id, params: unitIds },
],
redoMutations: [
...(intercepted.preRedos ?? []),
removeMutation,
...intercepted.redos,
{ id: ClearSheetDrawingTransformerOperation.id, params: unitIds },
],
});
@@ -22,15 +22,13 @@ import {
ICommandService,
IUndoRedoService,
} from '@univerjs/core';
import { DrawingApplyType, ISheetDrawingService, SetDrawingApplyMutation } from '@univerjs/sheets-drawing';
import { ISheetDrawingService } from '../../services/sheet-drawing.service';
import { DrawingApplyType, SetDrawingApplyMutation } from '../mutations/set-drawing-apply.mutation';
export interface ISetDrawingArrangeCommandParams extends IDrawingOrderMapParam {
arrangeType: ArrangeTypeEnum;
}
/**
* The command to insert new defined name
*/
export const SetDrawingArrangeCommand: ICommand = {
id: 'sheet.command.set-drawing-arrange',
type: CommandType.COMMAND,
@@ -14,11 +14,9 @@
* limitations under the License.
*/
import type { IAccessor, ICommand } from '@univerjs/core';
import type { ICommand } from '@univerjs/core';
import type { IDrawingJsonUndo1 } from '@univerjs/drawing';
import type { ISheetDrawing } from '@univerjs/sheets-drawing';
import type { ISetDrawingCommandParams } from './interfaces';
import type { ISheetDrawing } from '../../services/sheet-drawing.service';
import {
CommandType,
ICommandService,
@@ -26,30 +24,27 @@ import {
sequenceExecute,
} from '@univerjs/core';
import { SheetInterceptorService } from '@univerjs/sheets';
import { DrawingApplyType, ISheetDrawingService, SetDrawingApplyMutation } from '@univerjs/sheets-drawing';
import { ClearSheetDrawingTransformerOperation } from '../operations/clear-drawing-transformer.operation';
import { ISheetDrawingService } from '../../services/sheet-drawing.service';
import { DrawingApplyType, SetDrawingApplyMutation } from '../mutations/set-drawing-apply.mutation';
/**
* The command to update defined name
*/
export const SetSheetDrawingCommand: ICommand = {
export interface ISetDrawingCommandParams {
unitId: string;
drawings: Partial<ISheetDrawing>[];
}
export const SetSheetDrawingCommand: ICommand<ISetDrawingCommandParams> = {
id: 'sheet.command.set-sheet-image',
type: CommandType.COMMAND,
handler: (accessor: IAccessor, params?: ISetDrawingCommandParams) => {
handler: (accessor, params) => {
if (!params) return false;
const commandService = accessor.get(ICommandService);
const undoRedoService = accessor.get(IUndoRedoService);
const sheetDrawingService = accessor.get(ISheetDrawingService);
const sheetInterceptorService = accessor.get(SheetInterceptorService);
if (!params) return false;
const { drawings } = params;
// const newSheetDrawingParams = drawings.map((param) => param.newDrawing);
// const oldSheetDrawingParams = drawings.map((param) => param.oldDrawing);
const jsonOp = sheetDrawingService.getBatchUpdateOp(drawings as ISheetDrawing[]) as IDrawingJsonUndo1;
const { unitId, subUnitId, undo, redo, objects } = jsonOp;
const intercepted = sheetInterceptorService.onCommandExecute({ id: SetSheetDrawingCommand.id, params });
@@ -57,19 +52,13 @@ export const SetSheetDrawingCommand: ICommand = {
...(intercepted.preRedos ?? []),
{ id: SetDrawingApplyMutation.id, params: { unitId, subUnitId, op: redo, objects, type: DrawingApplyType.UPDATE } },
...intercepted.redos,
{ id: ClearSheetDrawingTransformerOperation.id, params: [unitId] },
];
const undoMutations = [
...(intercepted.preUndos ?? []),
{ id: SetDrawingApplyMutation.id, params: { unitId, subUnitId, op: undo, objects, type: DrawingApplyType.UPDATE } },
...intercepted.undos,
{ id: ClearSheetDrawingTransformerOperation.id, params: [unitId] },
];
// execute do mutations and add undo mutations to undo stack if completed
// const result = commandService.syncExecuteCommand(SetDrawingApplyMutation.id, { unitId, subUnitId, op: redo, objects, type: DrawingApplyType.UPDATE });
const result = sequenceExecute(redoMutations, commandService);
if (result) {
undoRedoService.pushUndoRedo({
@@ -64,9 +64,11 @@ export const SetDrawingApplyMutation: IMutation<ISetDrawingApplyMutationParams>
break;
case DrawingApplyType.GROUP:
drawingManagerService.groupUpdateNotification(objects as IDrawingGroupUpdateParam[]);
sheetDrawingService.groupUpdateNotification(objects as IDrawingGroupUpdateParam[]);
break;
case DrawingApplyType.UNGROUP:
drawingManagerService.ungroupUpdateNotification(objects as IDrawingGroupUpdateParam[]);
sheetDrawingService.ungroupUpdateNotification(objects as IDrawingGroupUpdateParam[]);
break;
}
@@ -21,6 +21,10 @@ import type { ISheetDrawing } from '../services/sheet-drawing.service';
import { Disposable, DrawingTypeEnum, generateRandomId, ICommandService, Inject, IResourceManagerService, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
import { IDrawingManagerService } from '@univerjs/drawing';
import { CopySheetCommand, RemoveSheetCommand, SheetInterceptorService } from '@univerjs/sheets';
import { InsertSheetDrawingCommand } from '../commands/commands/insert-sheet-drawing.command';
import { RemoveSheetDrawingCommand } from '../commands/commands/remove-sheet-drawing.command';
import { SetDrawingArrangeCommand } from '../commands/commands/set-drawing-arrange.command';
import { SetSheetDrawingCommand } from '../commands/commands/set-sheet-drawing.command';
import { DrawingApplyType, SetDrawingApplyMutation } from '../commands/mutations/set-drawing-apply.mutation';
import { ISheetDrawingService } from '../services/sheet-drawing.service';
@@ -37,12 +41,22 @@ export class SheetsDrawingLoadController extends Disposable {
) {
super();
this._initCommands();
this._initSnapshot();
this._initSheetChange();
this.disposeWithMe(this._commandService.registerCommand(SetDrawingApplyMutation));
}
private _initCommands() {
[
SetSheetDrawingCommand,
InsertSheetDrawingCommand,
RemoveSheetDrawingCommand,
SetDrawingArrangeCommand,
].forEach((command) => this.disposeWithMe(this._commandService.registerCommand(command)));
}
private _initSnapshot() {
const toJson = (unitId: string, model?: IDrawingSubunitMap<ISheetDrawing>) => {
const map = model || this._sheetDrawingService.getDrawingDataForUnit(unitId);
@@ -21,7 +21,7 @@ import { SheetDrawingAnchorType } from '@univerjs/sheets-drawing';
/**
* @ignore
*/
export interface IFDrawingEnumMixin {
export interface IFSheetsDrawingEnumMixin {
/** Please refer to {@link DrawingTypeEnum}. */
DrawingType: typeof DrawingTypeEnum;
@@ -32,7 +32,7 @@ export interface IFDrawingEnumMixin {
SheetDrawingAnchorType: typeof SheetDrawingAnchorType;
}
export class FDrawingEnumMixin extends FEnum implements IFDrawingEnumMixin {
export class FSheetsDrawingEnumMixin extends FEnum implements IFSheetsDrawingEnumMixin {
override get DrawingType(): typeof DrawingTypeEnum { return DrawingTypeEnum; };
override get ImageSourceType(): Omit<typeof ImageSourceType, 'UUID'> { return ImageSourceType; };
@@ -40,8 +40,8 @@ export class FDrawingEnumMixin extends FEnum implements IFDrawingEnumMixin {
override get SheetDrawingAnchorType(): typeof SheetDrawingAnchorType { return SheetDrawingAnchorType; };
}
FEnum.extend(FDrawingEnumMixin);
FEnum.extend(FSheetsDrawingEnumMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FEnum extends IFDrawingEnumMixin { }
interface FEnum extends IFSheetsDrawingEnumMixin { }
}
@@ -0,0 +1,452 @@
/**
* 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.
*/
import type { IDrawingSearch } from '@univerjs/core';
import type { IEventBase } from '@univerjs/core/facade';
import type { ISheetImage } from '@univerjs/sheets-drawing';
import type { FWorkbook } from '@univerjs/sheets/facade';
import type { FOverGridImage } from './f-over-grid-image';
import { FEventName } from '@univerjs/core/facade';
/**
* @ignore
*/
interface IFSheetsDrawingEventNameMixin {
/**
* Triggered before float dom insertion.
* @see {@link IBeforeFloatDomAddParam}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeFloatDomAdd, (params) => {
* console.log(params);
* // do something
* const { workbook, drawings } = params;
* // Cancel the insertion operation
* params.cancel = true;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly BeforeFloatDomAdd: 'BeforeFloatDomAdd';
/**
* Triggered after float dom insertion.
* @see {@link IFloatDomAddedParam}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.FloatDomAdded, (params) => {
* console.log(params);
* // do something
* const { workbook, drawings } = params;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly FloatDomAdded: 'FloatDomAdded';
/**
* Triggered before float dom update.
* @see {@link IBeforeFloatDomUpdateParam}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeFloatDomUpdate, (params) => {
* console.log(params);
* // do something
* const { workbook, drawings } = params;
* // Cancel the update operation
* params.cancel = true;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly BeforeFloatDomUpdate: 'BeforeFloatDomUpdate';
/**
* Triggered after float dom update.
* @see {@link IFloatDomUpdatedParam}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.FloatDomUpdated, (params) => {
* console.log(params);
* // do something
* const { workbook, drawings } = params;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly FloatDomUpdated: 'FloatDomUpdated';
/**
* Triggered before float dom deletion.
* @see {@link IBeforeFloatDomDeleteParam}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeFloatDomDelete, (params) => {
* console.log(params);
* // do something
* const { workbook, drawings } = params;
* // Cancel the deletion operation
* params.cancel = true;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly BeforeFloatDomDelete: 'BeforeFloatDomDelete';
/**
* Triggered after float dom deletion.
* @see {@link IFloatDomDeletedParam}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.FloatDomDeleted, (params) => {
* console.log(params);
* // do something
* const { workbook, drawings } = params;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly FloatDomDeleted: 'FloatDomDeleted';
/**
* Triggered before floating image insertion.
* @see {@link IBeforeOverGridImageInsertEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeOverGridImageInsert, (params) => {
* console.log(params);
* // do something
* const { workbook, insertImageParams } = params;
* // Cancel the insertion operation
* params.cancel = true;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly BeforeOverGridImageInsert: 'BeforeOverGridImageInsert';
/**
* Triggered after floating image insertion.
* @see {@link IOverGridImageInsertedEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.OverGridImageInserted, (params) => {
* console.log(params);
* // do something
* const { workbook, images } = params;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly OverGridImageInserted: 'OverGridImageInserted';
/**
* Triggered before floating image removal.
* @see {@link IBeforeOverGridImageRemoveEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeOverGridImageRemove, (params) => {
* console.log(params);
* // do something
* const { workbook, images } = params;
* // Cancel the removal operation
* params.cancel = true;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly BeforeOverGridImageRemove: 'BeforeOverGridImageRemove';
/**
* Triggered after floating image removal.
* @see {@link IOverGridImageRemovedEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.OverGridImageRemoved, (params) => {
* console.log(params);
* // do something
* const { workbook, removeImageParams } = params;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly OverGridImageRemoved: 'OverGridImageRemoved';
/**
* Triggered before floating image change.
* @see {@link IBeforeOverGridImageChangeEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeOverGridImageChange, (params) => {
* console.log(params);
* // do something
* const { workbook, images } = params;
* // Cancel the image change
* params.cancel = true;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly BeforeOverGridImageChange: 'BeforeOverGridImageChange';
/**
* Triggered after floating image change.
* @see {@link IOverGridImageChangedEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.OverGridImageChanged, (params) => {
* console.log(params);
* // do something
* const { workbook, images } = params;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly OverGridImageChanged: 'OverGridImageChanged';
/**
* Triggered before floating image selection.
* @see {@link IBeforeOverGridImageSelectEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeOverGridImageSelect, (params) => {
* console.log(params);
* // do something
* const { workbook, selectedImages, oldSelectedImages } = params;
* // cancel the selection operation
* params.cancel = true;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly BeforeOverGridImageSelect: 'BeforeOverGridImageSelect';
/**
* Triggered after floating image selection.
* @see {@link IOverGridImageSelectedEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.OverGridImageSelected, (params) => {
* console.log(params);
* // do something
* const { workbook, selectedImages } = params;
* })
*
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
readonly OverGridImageSelected: 'OverGridImageSelected';
}
export class FSheetsDrawingEventNameMixin extends FEventName implements IFSheetsDrawingEventNameMixin {
override get BeforeFloatDomAdd(): 'BeforeFloatDomAdd' {
return 'BeforeFloatDomAdd' as const;
}
override get FloatDomAdded(): 'FloatDomAdded' {
return 'FloatDomAdded' as const;
}
override get BeforeFloatDomUpdate(): 'BeforeFloatDomUpdate' {
return 'BeforeFloatDomUpdate' as const;
}
override get FloatDomUpdated(): 'FloatDomUpdated' {
return 'FloatDomUpdated' as const;
}
override get BeforeFloatDomDelete(): 'BeforeFloatDomDelete' {
return 'BeforeFloatDomDelete' as const;
}
override get FloatDomDeleted(): 'FloatDomDeleted' {
return 'FloatDomDeleted' as const;
}
override get BeforeOverGridImageChange(): 'BeforeOverGridImageChange' {
return 'BeforeOverGridImageChange' as const;
}
override get OverGridImageChanged(): 'OverGridImageChanged' {
return 'OverGridImageChanged' as const;
}
override get BeforeOverGridImageInsert(): 'BeforeOverGridImageInsert' {
return 'BeforeOverGridImageInsert' as const;
}
override get OverGridImageInserted(): 'OverGridImageInserted' {
return 'OverGridImageInserted' as const;
}
override get BeforeOverGridImageRemove(): 'BeforeOverGridImageRemove' {
return 'BeforeOverGridImageRemove' as const;
}
override get OverGridImageRemoved(): 'OverGridImageRemoved' {
return 'OverGridImageRemoved' as const;
}
override get BeforeOverGridImageSelect(): 'BeforeOverGridImageSelect' {
return 'BeforeOverGridImageSelect' as const;
}
override get OverGridImageSelected(): 'OverGridImageSelected' {
return 'OverGridImageSelected' as const;
}
}
export interface IBeforeOverGridImageChangeParamObject {
/**
* Parameters of the image to be updated. {@link ISheetImage}
*/
changeParam: Partial<ISheetImage>;
/**
* Instance of the image to be updated. {@link FOverGridImage}
*/
image: FOverGridImage;
}
export interface IBeforeOverGridImageChangeEventParams extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* Collection of parameters of the images to be updated, there may be multiple images to be updated. {@link IBeforeOverGridImageChangeParamObject}
*/
images: IBeforeOverGridImageChangeParamObject[];
}
export interface IOverGridImageChangedEventParams extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* Instances of the images after the update. {@link FOverGridImage}
*/
images: FOverGridImage[];
}
export interface IBeforeOverGridImageInsertEventParams extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* Collection of parameters of the images to be inserted. {@link ISheetImage}
*/
insertImageParams: ISheetImage[];
}
export interface IOverGridImageInsertedEventParams extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* Collection of instances of the images after insertion. {@link FOverGridImage}
*/
images: FOverGridImage[];
}
export interface IBeforeOverGridImageRemoveEventParams extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* Collection of instances of the images to be removed. {@link FOverGridImage}
*/
images: FOverGridImage[];
}
export interface IOverGridImageRemovedEventParams extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* Collection of parameters of the images after removal. {@link ISheetImage}
*/
removeImageParams: IDrawingSearch[];
}
export interface IBeforeOverGridImageSelectEventParams extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* The images before selection. {@link FOverGridImage}
*/
oldSelectedImages: FOverGridImage[];
selectedImages: FOverGridImage[];
}
export interface IOverGridImageSelectedEventParams extends IEventBase {
/**
* The workbook instance currently being operated on. {@link FWorkbook}
*/
workbook: FWorkbook;
/**
* The selected images. {@link FOverGridImage}
*/
selectedImages: FOverGridImage[];
}
interface ISheetsDrawingEventParamConfig {
BeforeOverGridImageChange: IBeforeOverGridImageChangeEventParams;
OverGridImageChanged: IOverGridImageChangedEventParams;
BeforeOverGridImageInsert: IBeforeOverGridImageInsertEventParams;
OverGridImageInserted: IOverGridImageInsertedEventParams;
BeforeOverGridImageRemove: IBeforeOverGridImageRemoveEventParams;
OverGridImageRemoved: IOverGridImageRemovedEventParams;
BeforeOverGridImageSelect: IBeforeOverGridImageSelectEventParams;
OverGridImageSelected: IOverGridImageSelectedEventParams;
}
FEventName.extend(FSheetsDrawingEventNameMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FEventName extends IFSheetsDrawingEventNameMixin { }
interface IEventParamConfig extends ISheetsDrawingEventParamConfig { }
}
@@ -15,14 +15,14 @@
*/
import type { IRotationSkewFlipTransform, ISize } from '@univerjs/core';
import type { SpreadsheetSkeleton } from '@univerjs/engine-render';
import type { ICellOverGridPosition } from '@univerjs/sheets';
import type { ISheetImage, SheetDrawingAnchorType } from '@univerjs/sheets-drawing';
import { ArrangeTypeEnum, DrawingTypeEnum, generateRandomId, ICommandService, ImageSourceType, Inject, Injector } from '@univerjs/core';
import { FBase } from '@univerjs/core/facade';
import { getImageSize } from '@univerjs/drawing';
import { IRenderManagerService } from '@univerjs/engine-render';
import { RemoveSheetDrawingCommand, SetDrawingArrangeCommand, SetSheetDrawingCommand, transformToAxisAlignPosition } from '@univerjs/sheets-drawing-ui';
import { convertPositionCellToSheetOverGrid, convertPositionSheetOverGridToAbsolute, ISheetSelectionRenderService, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
import { convertPositionCellToSheetOverGrid, convertPositionSheetOverGridToAbsolute, SheetSkeletonService } from '@univerjs/sheets';
import { RemoveSheetDrawingCommand, SetDrawingArrangeCommand, SetSheetDrawingCommand, transformToAxisAlignPosition } from '@univerjs/sheets-drawing';
export interface IFOverGridImage extends Omit<ISheetImage, 'sheetTransform' | 'transform'>, ICellOverGridPosition, IRotationSkewFlipTransform, Required<ISize> {
@@ -31,10 +31,10 @@ export interface IFOverGridImage extends Omit<ISheetImage, 'sheetTransform' | 't
/**
* Convert the image parameter to a FOverGridImage
* @param {ISheetImage} sheetImage The image parameter
* @param {SheetSkeletonManagerService} sheetSkeletonManagerService The skeleton manager service
* @param {SpreadsheetSkeleton} skeleton The skeleton of the sheet where the image is located
* @returns {IFOverGridImage} The FOverGridImage {@link IFOverGridImage}
*/
function convertSheetImageToFOverGridImage(sheetImage: ISheetImage, sheetSkeletonManagerService: SheetSkeletonManagerService): IFOverGridImage {
function convertSheetImageToFOverGridImage(sheetImage: ISheetImage, skeleton: SpreadsheetSkeleton): IFOverGridImage {
const { from, to, flipY = false, flipX = false, angle = 0, skewX = 0, skewY = 0 } = sheetImage.sheetTransform;
const { column: fromColumn, columnOffset: fromColumnOffset, row: fromRow, rowOffset: fromRowOffset } = from;
@@ -43,7 +43,7 @@ function convertSheetImageToFOverGridImage(sheetImage: ISheetImage, sheetSkeleto
sheetImage.unitId,
sheetImage.subUnitId,
{ from, to },
sheetSkeletonManagerService
skeleton
);
const { width, height } = absolutePosition;
@@ -71,7 +71,12 @@ function convertSheetImageToFOverGridImage(sheetImage: ISheetImage, sheetSkeleto
* @param {SheetSkeletonManagerService} sheetSkeletonManagerService The skeleton manager service
* @returns {ISheetImage} The ISheetImage {@link ISheetImage}
*/
function convertFOverGridImageToSheetImage(fOverGridImage: IFOverGridImage, selectionRenderService: ISheetSelectionRenderService, sheetSkeletonManagerService: SheetSkeletonManagerService): ISheetImage {
function convertFOverGridImageToSheetImage(fOverGridImage: IFOverGridImage, sheetSkeletonService: SheetSkeletonService): ISheetImage {
const skeleton = sheetSkeletonService.ensureSkeleton(fOverGridImage.unitId, fOverGridImage.subUnitId);
if (!skeleton) {
throw new Error(`Skeleton for unitId ${fOverGridImage.unitId} and subUnitId ${fOverGridImage.subUnitId} not found`);
}
const { column: fromColumn, columnOffset: fromColumnOffset, row: fromRow, rowOffset: fromRowOffset, flipY = false, flipX = false, angle = 0, skewX = 0, skewY = 0, width, height } = fOverGridImage;
const absolutePosition = convertPositionCellToSheetOverGrid(
@@ -80,8 +85,7 @@ function convertFOverGridImageToSheetImage(fOverGridImage: IFOverGridImage, sele
{ column: fromColumn, columnOffset: fromColumnOffset, row: fromRow, rowOffset: fromRowOffset },
width,
height,
selectionRenderService,
sheetSkeletonManagerService
skeleton
);
const { sheetTransform, transform } = absolutePosition;
@@ -104,7 +108,7 @@ function convertFOverGridImageToSheetImage(fOverGridImage: IFOverGridImage, sele
skewX,
skewY,
},
axisAlignSheetTransform: transformToAxisAlignPosition(transform, selectionRenderService)!,
axisAlignSheetTransform: transformToAxisAlignPosition(transform, skeleton),
};
}
@@ -117,8 +121,6 @@ export class FOverGridImageBuilder {
unitId: string,
subUnitId: string,
@Inject(Injector) protected readonly _injector: Injector
// @Inject(SheetSkeletonManagerService) protected readonly _skeletonManagerService: SheetSkeletonManagerService,
// @ISheetSelectionRenderService protected readonly _selectionRenderService: ISheetSelectionRenderService
) {
this._image = {
drawingId: generateRandomId(6),
@@ -176,12 +178,12 @@ export class FOverGridImageBuilder {
* ```
*/
setImage(image: ISheetImage): FOverGridImageBuilder {
const renderManagerService = this._injector.get(IRenderManagerService);
const render = renderManagerService.getRenderById(image.unitId);
if (!render) {
throw new Error(`Render Unit with unitId ${image.unitId} not found`);
const { unitId, subUnitId } = image;
const sheetSkeletonService = this._injector.get(SheetSkeletonService);
const skeleton = sheetSkeletonService.getSkeleton(unitId, subUnitId);
if (!skeleton) {
throw new Error(`Skeleton for unitId ${unitId} and subUnitId ${subUnitId} not found`);
}
const skeletonManagerService = render.with(SheetSkeletonManagerService);
if (image.sheetTransform == null) {
image.sheetTransform = {
@@ -215,7 +217,7 @@ export class FOverGridImageBuilder {
},
};
}
this._image = convertSheetImageToFOverGridImage(image, skeletonManagerService);
this._image = convertSheetImageToFOverGridImage(image, skeleton);
return this;
}
@@ -622,13 +624,7 @@ export class FOverGridImageBuilder {
}
async buildAsync(): Promise<ISheetImage> {
const renderManagerService = this._injector.get(IRenderManagerService);
const render = renderManagerService.getRenderById(this._image.unitId);
if (!render) {
throw new Error(`Render Unit with unitId ${this._image.unitId} not found`);
}
const selectionRenderService = render.with(ISheetSelectionRenderService);
const skeletonManagerService = render.with(SheetSkeletonManagerService);
const sheetSkeletonService = this._injector.get(SheetSkeletonService);
if (this._image.width === 0 || this._image.height === 0) {
const size = await getImageSize(this._image.source);
@@ -644,7 +640,7 @@ export class FOverGridImageBuilder {
}
}
return convertFOverGridImageToSheetImage(this._image, selectionRenderService, skeletonManagerService);
return convertFOverGridImageToSheetImage(this._image, sheetSkeletonService);
}
}
@@ -899,14 +895,13 @@ export class FOverGridImage extends FBase {
this._image.sheetTransform.angle = angle;
this._image.transform && (this._image.transform.angle = angle);
if (this._image.transform) {
const renderManagerService = this._injector.get(IRenderManagerService);
const render = renderManagerService.getRenderById(this._image.unitId);
if (!render) {
throw new Error(`Render Unit with unitId ${this._image.unitId} not found`);
const sheetSkeletonService = this._injector.get(SheetSkeletonService);
const skeleton = sheetSkeletonService.getSkeleton(this._image.unitId, this._image.subUnitId);
if (!skeleton) {
throw new Error(`Skeleton for unitId ${this._image.unitId} and subUnitId ${this._image.subUnitId} not found`);
}
const selectionRenderService = render.with(ISheetSelectionRenderService);
this._image.axisAlignSheetTransform && (this._image.axisAlignSheetTransform = transformToAxisAlignPosition(this._image.transform, selectionRenderService)!);
this._image.axisAlignSheetTransform && (this._image.axisAlignSheetTransform = transformToAxisAlignPosition(this._image.transform, skeleton));
}
return this._commandService.syncExecuteCommand(SetSheetDrawingCommand.id, { unitId: this._image.unitId, drawings: [this._image] });
@@ -0,0 +1,289 @@
/**
* 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.
*/
import type { IDrawingSearch, Injector } from '@univerjs/core';
import type { IDeleteDrawingCommandParams, IInsertDrawingCommandParams, ISetDrawingCommandParams, ISheetImage } from '@univerjs/sheets-drawing';
import type {
IBeforeOverGridImageChangeEventParams,
IBeforeOverGridImageChangeParamObject,
IBeforeOverGridImageInsertEventParams,
IBeforeOverGridImageRemoveEventParams,
IBeforeOverGridImageSelectEventParams,
IOverGridImageChangedEventParams,
IOverGridImageInsertedEventParams,
IOverGridImageRemovedEventParams,
IOverGridImageSelectedEventParams,
} from './f-event';
import { CanceledError, ICommandService } from '@univerjs/core';
import { FUniver } from '@univerjs/core/facade';
import { IDrawingManagerService, SetDrawingSelectedOperation } from '@univerjs/drawing';
import { InsertSheetDrawingCommand, RemoveSheetDrawingCommand, SetSheetDrawingCommand } from '@univerjs/sheets-drawing';
import { FOverGridImage } from './f-over-grid-image';
/**
* @ignore
*/
export class FUniverSheetsDrawingMixin extends FUniver {
/**
* @ignore
*/
// eslint-disable-next-line max-lines-per-function
override _initialize(injector: Injector): void {
const commandService = injector.get(ICommandService);
this.disposeWithMe(
this.registerEventHandler(
this.Event.BeforeOverGridImageInsert,
() => commandService.beforeCommandExecuted((commandInfo) => {
if (commandInfo.id !== InsertSheetDrawingCommand.id) return;
const params = commandInfo.params as IInsertDrawingCommandParams;
const workbook = this.getActiveWorkbook();
if (workbook == null || params == null) {
return;
}
const { drawings } = params;
const eventParams: IBeforeOverGridImageInsertEventParams = {
workbook,
insertImageParams: drawings as ISheetImage[],
};
this.fireEvent(this.Event.BeforeOverGridImageInsert, eventParams);
if (eventParams.cancel) {
throw new CanceledError();
}
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.BeforeOverGridImageRemove,
() => commandService.beforeCommandExecuted((commandInfo) => {
if (commandInfo.id !== RemoveSheetDrawingCommand.id) return;
const params = commandInfo.params as IDeleteDrawingCommandParams;
const workbook = this.getActiveWorkbook();
if (workbook == null || params == null) {
return;
}
const drawingManagerService = injector.get(IDrawingManagerService);
const { drawings } = params;
const willRemoveDrawings = drawings.map((drawing) => {
return drawingManagerService.getDrawingByParam(drawing);
}) as ISheetImage[];
const eventParams: IBeforeOverGridImageRemoveEventParams = {
workbook,
images: this._createFOverGridImage(willRemoveDrawings),
};
this.fireEvent(this.Event.BeforeOverGridImageRemove, eventParams);
if (eventParams.cancel) {
throw new CanceledError();
}
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.BeforeOverGridImageChange,
() => commandService.beforeCommandExecuted((commandInfo) => {
if (commandInfo.id !== SetSheetDrawingCommand.id) return;
const params = commandInfo.params as ISetDrawingCommandParams;
const workbook = this.getActiveWorkbook();
if (workbook == null || params == null) {
return;
}
const { drawings } = params;
const drawingManagerService = injector.get(IDrawingManagerService);
const images: IBeforeOverGridImageChangeParamObject[] = [];
drawings.forEach((drawing) => {
const image = drawingManagerService.getDrawingByParam(drawing as IDrawingSearch) as ISheetImage;
if (image == null) {
return;
}
images.push({
changeParam: drawing,
image: this._injector.createInstance(FOverGridImage, image),
});
});
const eventParams: IBeforeOverGridImageChangeEventParams = {
workbook,
images,
};
this.fireEvent(this.Event.BeforeOverGridImageChange, eventParams);
if (eventParams.cancel) {
drawingManagerService.updateNotification(drawings as IDrawingSearch[]);
throw new CanceledError();
}
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.BeforeOverGridImageSelect,
() => commandService.beforeCommandExecuted((commandInfo) => {
if (commandInfo.id !== SetDrawingSelectedOperation.id) return;
const drawings = commandInfo.params as IDrawingSearch[];
const workbook = this.getActiveWorkbook();
if (workbook == null) {
return;
}
const drawingManagerService = injector.get(IDrawingManagerService);
const oldSelectedDrawings = drawingManagerService.getFocusDrawings() as ISheetImage[];
const selectedDrawings = drawings.map((drawing) => {
return drawingManagerService.getDrawingByParam(drawing);
}) as ISheetImage[];
const eventParams: IBeforeOverGridImageSelectEventParams = {
workbook,
selectedImages: this._createFOverGridImage(selectedDrawings),
oldSelectedImages: this._createFOverGridImage(oldSelectedDrawings),
};
this.fireEvent(this.Event.BeforeOverGridImageSelect, eventParams);
if (eventParams.cancel) {
throw new CanceledError();
}
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.OverGridImageInserted,
() => commandService.onCommandExecuted((commandInfo) => {
if (commandInfo.id !== InsertSheetDrawingCommand.id) return;
const params = commandInfo.params as IInsertDrawingCommandParams;
const workbook = this.getActiveWorkbook();
if (workbook == null || params == null) {
return;
}
const { drawings } = params;
const eventParams: IOverGridImageInsertedEventParams = {
workbook,
images: this._createFOverGridImage(drawings as ISheetImage[]),
};
this.fireEvent(this.Event.OverGridImageInserted, eventParams);
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.OverGridImageRemoved,
() => commandService.onCommandExecuted((commandInfo) => {
if (commandInfo.id !== RemoveSheetDrawingCommand.id) return;
const params = commandInfo.params as IDeleteDrawingCommandParams;
const workbook = this.getActiveWorkbook();
if (workbook == null || params == null) {
return;
}
const { drawings } = params;
const eventParams: IOverGridImageRemovedEventParams = {
workbook,
removeImageParams: drawings,
};
this.fireEvent(this.Event.OverGridImageRemoved, eventParams);
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.OverGridImageChanged,
() => commandService.onCommandExecuted((commandInfo) => {
if (commandInfo.id !== SetSheetDrawingCommand.id) return;
const params = commandInfo.params as ISetDrawingCommandParams;
const workbook = this.getActiveWorkbook();
if (workbook == null || params == null) {
return;
}
const { drawings } = params;
const drawingManagerService = injector.get(IDrawingManagerService);
const images = drawings.map((drawing) => {
return this._injector.createInstance(FOverGridImage, drawingManagerService.getDrawingByParam(drawing as IDrawingSearch) as ISheetImage);
});
const eventParams: IOverGridImageChangedEventParams = {
workbook,
images,
};
this.fireEvent(this.Event.OverGridImageChanged, eventParams);
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.OverGridImageSelected,
() => commandService.onCommandExecuted((commandInfo) => {
if (commandInfo.id !== SetDrawingSelectedOperation.id) return;
const drawings = commandInfo.params as IDrawingSearch[];
const workbook = this.getActiveWorkbook();
if (workbook == null) {
return;
}
const drawingManagerService = injector.get(IDrawingManagerService);
const selectedDrawings = drawings.map((drawing) => {
return drawingManagerService.getDrawingByParam(drawing);
}) as ISheetImage[];
const eventParams: IOverGridImageSelectedEventParams = {
workbook,
selectedImages: this._createFOverGridImage(selectedDrawings as ISheetImage[]),
};
this.fireEvent(this.Event.OverGridImageSelected, eventParams);
})
)
);
}
private _createFOverGridImage(drawings: ISheetImage[]): FOverGridImage[] {
return drawings.map((drawing) => {
return this._injector.createInstance(FOverGridImage, drawing);
});
}
}
FUniver.extend(FUniverSheetsDrawingMixin);
@@ -0,0 +1,328 @@
/**
* 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.
*/
import type { IFBlobSource } from '@univerjs/core/facade';
import type { ISheetImage } from '@univerjs/sheets-drawing';
import { DrawingTypeEnum, ImageSourceType } from '@univerjs/core';
import { InsertSheetDrawingCommand, ISheetDrawingService, RemoveSheetDrawingCommand, SetSheetDrawingCommand } from '@univerjs/sheets-drawing';
import { FWorksheet } from '@univerjs/sheets/facade';
import { FOverGridImage, FOverGridImageBuilder } from './f-over-grid-image';
/**
* @ignore
*/
export interface IFWorksheetDrawingMixin {
/**
* Insert an image to the sheet
* @param {string} url - The image url
* @returns true if the image is inserted successfully
* @example
* ```ts
* // Insert an image to the sheet, default position is A1
* const fWorksheet = univerAPI.getActiveWorkbook().getActiveSheet();
* const result = await fWorksheet.insertImage('https://avatars.githubusercontent.com/u/61444807?s=48&v=4');
* console.log(result);
* ```
*/
insertImage(url: string): Promise<boolean>;
/**
* @param {string} url - The image url
* @param {number} column - The column index to insert the image
* @param {number} row - The row index to insert the image
* @returns True if the image is inserted successfully
* @example
* ```ts
* // Insert an image to the sheet, position is F6
* const fWorksheet = univerAPI.getActiveWorkbook().getActiveSheet();
* const result = await fWorksheet.insertImage('https://avatars.githubusercontent.com/u/61444807?s=48&v=4', 5, 5);
* console.log(result);
* ```
*/
insertImage(url: string, column: number, row: number): Promise<boolean>;
/**
* @param {string} url - The image url
* @param {number} column - The column index to insert the image
* @param {number} row - The row index to insert the image
* @param {number} offsetX - The column offset, pixel unit
* @param {number} offsetY - The row offset, pixel unit
* @returns True if the image is inserted successfully
* @example
* ```ts
* // Insert an image to the sheet, position is F6, offset is 10px
* const fWorksheet = univerAPI.getActiveWorkbook().getActiveSheet();
* const result = await fWorksheet.insertImage('https://avatars.githubusercontent.com/u/61444807?s=48&v=4', 5, 5, 10, 10);
* console.log(result);
* ```
*/
insertImage(url: string, column: number, row: number, offsetX: number, offsetY: number): Promise<boolean>;
insertImage(url: IFBlobSource): Promise<boolean>;
insertImage(url: IFBlobSource, column: number, row: number): Promise<boolean>;
insertImage(url: IFBlobSource, column: number, row: number, offsetX: number, offsetY: number): Promise<boolean>;
insertImage(url: IFBlobSource | string, column: number, row: number, offsetX: number, offsetY: number): Promise<boolean>;
/**
* Insert images to the sheet
* @param {ISheetImage[]} sheetImages - The images to insert
* @returns {FWorksheet} The FWorksheet instance for chaining
* @example
* ```ts
* // create a new image builder and set image source.
* // then build `ISheetImage` and insert it into the sheet, position is start from F6 cell, width is 500px, height is 300px
* const fWorkbook = univerAPI.getActiveWorkbook();
* const fWorksheet = fWorkbook.getActiveSheet();
* const image = await fWorksheet.newOverGridImage()
* .setSource('https://avatars.githubusercontent.com/u/61444807?s=48&v=4', univerAPI.Enum.ImageSourceType.URL)
* .setColumn(5)
* .setRow(5)
* .setWidth(500)
* .setHeight(300)
* .buildAsync();
* fWorksheet.insertImages([image]);
*
* // update the image width to 100px and height to 50px
* setTimeout(async () => {
* const imageBuilder = fWorksheet.getImageById(image.drawingId).toBuilder();
* const newImage = await imageBuilder.setWidth(100).setHeight(50).buildAsync();
* fWorksheet.updateImages([newImage]);
* }, 4000);
* ```
*/
insertImages(sheetImages: ISheetImage[]): FWorksheet;
/**
* Get all images of the sheet.
* @returns {FOverGridImage[]} The FOverGridImage instances
* @example
* ```ts
* const fWorksheet = univerAPI.getActiveWorkbook().getActiveSheet();
* const images = fWorksheet.getImages();
* images.forEach((image) => {
* console.log(image, image.getId());
* });
* ```
*/
getImages(): FOverGridImage[];
/**
* Get image by drawing id
* @param {string} id - The drawing id of the image
* @returns {FOverGridImage | null} The FOverGridImage instance
* @example
* ```ts
* const fWorksheet = univerAPI.getActiveWorkbook().getActiveSheet();
* const image = fWorksheet.getImageById('xxxx');
* console.log(image);
* ```
*/
getImageById(id: string): FOverGridImage | null;
/**
* Delete images from the sheet
* @param {FOverGridImage[]} sheetImages - The images to delete
* @returns {FWorksheet} The FWorksheet instance for chaining
* @example
* ```ts
* const fWorksheet = univerAPI.getActiveWorkbook().getActiveSheet();
* const image = fWorksheet.getImages()[0];
*
* // Delete the first image of the sheet
* fWorksheet.deleteImages([image]);
* ```
*/
deleteImages(sheetImages: FOverGridImage[]): FWorksheet;
/**
* Update images to the sheet
* @param {ISheetImage[]} sheetImages - The images to update
* @returns {FWorksheet} The FWorksheet instance for chaining
* @example
* ```ts
* // create a new image builder and set image source.
* // then build `ISheetImage` and insert it into the sheet, position is start from F6 cell, width is 500px, height is 300px
* const fWorkbook = univerAPI.getActiveWorkbook();
* const fWorksheet = fWorkbook.getActiveSheet();
* const image = await fWorksheet.newOverGridImage()
* .setSource('https://avatars.githubusercontent.com/u/61444807?s=48&v=4', univerAPI.Enum.ImageSourceType.URL)
* .setColumn(5)
* .setRow(5)
* .setWidth(500)
* .setHeight(300)
* .buildAsync();
* fWorksheet.insertImages([image]);
*
* // update the image width to 100px and height to 50px after 4 seconds
* setTimeout(async () => {
* const imageBuilder = fWorksheet.getImageById(image.drawingId).toBuilder();
* const newImage = await imageBuilder.setWidth(100).setHeight(50).buildAsync();
* fWorksheet.updateImages([newImage]);
* }, 4000);
* ```
*/
updateImages(sheetImages: ISheetImage[]): FWorksheet;
/**
* Get the current selected images.
* @returns {FOverGridImage[]} The FOverGridImage instances
* @example
* ```ts
* const fWorksheet = univerAPI.getActiveWorkbook().getActiveSheet();
* const images = fWorksheet.getActiveImages();
* images.forEach((image) => {
* console.log(image, image.getId());
* });
* ```
*/
getActiveImages(): FOverGridImage[];
/**
* Create a new over grid image builder.
* @returns {FOverGridImageBuilder} The FOverGridImageBuilder instance
* @example
* ```ts
* // create a new image builder and set image source.
* // then build `ISheetImage` and insert it into the sheet, position is start from F6 cell, width is 500px, height is 300px
* const fWorkbook = univerAPI.getActiveWorkbook();
* const fWorksheet = fWorkbook.getActiveSheet();
* const image = await fWorksheet.newOverGridImage()
* .setSource('https://avatars.githubusercontent.com/u/61444807?s=48&v=4', univerAPI.Enum.ImageSourceType.URL)
* .setColumn(5)
* .setRow(5)
* .setWidth(500)
* .setHeight(300)
* .buildAsync();
* fWorksheet.insertImages([image]);
* ```
*/
newOverGridImage(): FOverGridImageBuilder;
}
export class FWorksheetDrawingMixin extends FWorksheet implements IFWorksheetDrawingMixin {
override async insertImage(url: IFBlobSource | string, column?: number, row?: number, offsetX?: number, offsetY?: number): Promise<boolean> {
const imageBuilder = this.newOverGridImage();
if (typeof url === 'string') {
imageBuilder.setSource(url);
} else {
const blobSource = url.getBlob();
const base64 = await blobSource.getDataAsString();
imageBuilder.setSource(base64, ImageSourceType.BASE64);
}
if (column !== undefined) {
imageBuilder.setColumn(column);
} else {
imageBuilder.setColumn(0);
}
if (row !== undefined) {
imageBuilder.setRow(row);
} else {
imageBuilder.setRow(0);
}
if (offsetX !== undefined) {
imageBuilder.setColumnOffset(offsetX);
} else {
imageBuilder.setColumnOffset(0);
}
if (offsetY !== undefined) {
imageBuilder.setRowOffset(offsetY);
} else {
imageBuilder.setRowOffset(0);
}
const param = await imageBuilder.buildAsync();
// param.drawingId
return this._commandService.syncExecuteCommand(InsertSheetDrawingCommand.id, { unitId: this._fWorkbook.getId(), drawings: [param] });
}
override insertImages(sheetImages: ISheetImage[]): FWorksheet {
const param = sheetImages.map((image) => {
image.unitId = this._fWorkbook.getId();
image.subUnitId = this.getSheetId();
return image;
});
this._commandService.syncExecuteCommand(InsertSheetDrawingCommand.id, { unitId: this._fWorkbook.getId(), drawings: param });
return this;
}
override deleteImages(sheetImages: FOverGridImage[]): FWorksheet {
const drawings = sheetImages.map((image) => {
return {
unitId: this._fWorkbook.getId(),
drawingId: image.getId(),
subUnitId: this.getSheetId(),
drawingType: image.getType(),
};
});
this._commandService.syncExecuteCommand(RemoveSheetDrawingCommand.id, { unitId: this._fWorkbook.getId(), drawings });
return this;
}
override getImages(): FOverGridImage[] {
const sheetDrawingService = this._injector.get(ISheetDrawingService);
const drawingData = sheetDrawingService.getDrawingData(this._fWorkbook.getId(), this.getSheetId());
const images: FOverGridImage[] = [];
for (const drawingId in drawingData) {
const drawing = drawingData[drawingId];
if (drawing.drawingType !== DrawingTypeEnum.DRAWING_IMAGE) {
continue;
}
images.push(this._injector.createInstance(FOverGridImage, drawing as ISheetImage));
}
return images;
}
override getImageById(id: string): FOverGridImage | null {
const sheetDrawingService = this._injector.get(ISheetDrawingService);
const drawing = sheetDrawingService.getDrawingByParam({ unitId: this._fWorkbook.getId(), subUnitId: this.getSheetId(), drawingId: id });
if (drawing && drawing.drawingType === DrawingTypeEnum.DRAWING_IMAGE) {
return this._injector.createInstance(FOverGridImage, drawing as ISheetImage);
}
return null;
}
override getActiveImages(): FOverGridImage[] {
const sheetDrawingService = this._injector.get(ISheetDrawingService);
const drawingData = sheetDrawingService.getFocusDrawings();
const images: FOverGridImage[] = [];
for (const drawingId in drawingData) {
const drawing = drawingData[drawingId];
images.push(this._injector.createInstance(FOverGridImage, drawing as ISheetImage));
}
return images;
}
override updateImages(sheetImages: ISheetImage[]): FWorksheet {
this._commandService.syncExecuteCommand(SetSheetDrawingCommand.id, { unitId: this._fWorkbook.getId(), drawings: sheetImages });
return this;
}
override newOverGridImage(): FOverGridImageBuilder {
const unitId = this._fWorkbook.getId();
const subUnitId = this.getSheetId();
return this._injector.createInstance(FOverGridImageBuilder, unitId, subUnitId);
}
}
FWorksheet.extend(FWorksheetDrawingMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FWorksheet extends IFWorksheetDrawingMixin { }
}
@@ -14,27 +14,14 @@
* limitations under the License.
*/
import type { DrawingTypeEnum } from '@univerjs/core';
import type { ISheetDrawing } from '@univerjs/sheets-drawing';
import './f-over-grid-image';
import './f-worksheet';
import './f-enum';
import './f-event';
import './f-univer';
export interface IInsertDrawingCommandParams {
unitId: string;
drawings: ISheetDrawing[];
}
export interface IDeleteDrawingCommandParam {
unitId: string;
subUnitId: string;
drawingId: string;
drawingType: DrawingTypeEnum;
}
export interface IDeleteDrawingCommandParams {
unitId: string;
drawings: IDeleteDrawingCommandParam[];
}
export interface ISetDrawingCommandParams {
unitId: string;
drawings: Partial<ISheetDrawing>[];
}
export type * from './f-enum';
export type * from './f-event';
export type * from './f-over-grid-image';
export type * from './f-univer';
export type * from './f-worksheet';
+5
View File
@@ -14,6 +14,11 @@
* limitations under the License.
*/
export { drawingPositionToTransform, transformToAxisAlignPosition, transformToDrawingPosition } from './basics/transform-position';
export { type IInsertDrawingCommandParams, InsertSheetDrawingCommand } from './commands/commands/insert-sheet-drawing.command';
export { type IDeleteDrawingCommandParam, type IDeleteDrawingCommandParams, RemoveSheetDrawingCommand } from './commands/commands/remove-sheet-drawing.command';
export { type ISetDrawingArrangeCommandParams, SetDrawingArrangeCommand } from './commands/commands/set-drawing-arrange.command';
export { type ISetDrawingCommandParams, SetSheetDrawingCommand } from './commands/commands/set-sheet-drawing.command';
export { DrawingApplyType, type ISetDrawingApplyMutationParams, SetDrawingApplyMutation } from './commands/mutations/set-drawing-apply.mutation';
export type { IUniverSheetsDrawingConfig } from './config/config';
export { SHEET_DRAWING_PLUGIN } from './controllers/sheet-drawing.controller';
@@ -20,10 +20,9 @@ import type { ISheetCommandSharedParams } from '@univerjs/sheets';
import type { FilterModel } from '@univerjs/sheets-filter';
import type { ISheetsFilterButtonShapeProps } from '../widgets/filter-button.shape';
import { CommandType, fromCallback, ICommandService, Inject, Injector, InterceptorEffectEnum, RxDisposable, ThemeService, VerticalAlign } from '@univerjs/core';
import { INTERCEPTOR_POINT, SetRangeValuesMutation, SheetInterceptorService } from '@univerjs/sheets';
import { attachSelectionWithCoord, INTERCEPTOR_POINT, SetRangeValuesMutation, SheetInterceptorService } from '@univerjs/sheets';
import { FILTER_MUTATIONS, SheetsFilterService } from '@univerjs/sheets-filter';
import { attachSelectionWithCoord, getCoordByCell, ISheetSelectionRenderService, SelectionControl, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
import { getCoordByCell, ISheetSelectionRenderService, SelectionControl, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
import { filter, map, of, startWith, switchMap, takeUntil, throttleTime } from 'rxjs';
import { FILTER_ICON_PADDING, FILTER_ICON_SIZE, SheetsFilterButtonShape } from '../widgets/filter-button.shape';
+2 -2
View File
@@ -25,8 +25,8 @@ export interface IFSheetsFilterEnumMixin {
CustomFilterOperator: typeof CustomFilterOperator;
}
export class FSheetsFilterEnumMixin implements IFSheetsFilterEnumMixin {
get CustomFilterOperator(): typeof CustomFilterOperator {
export class FSheetsFilterEnumMixin extends FEnum implements IFSheetsFilterEnumMixin {
override get CustomFilterOperator(): typeof CustomFilterOperator {
return CustomFilterOperator;
};
}
+38 -161
View File
@@ -14,19 +14,47 @@
* limitations under the License.
*/
import type { ICommandInfo, Injector } from '@univerjs/core';
import type { IEventBase } from '@univerjs/core/facade';
import type { ISetSheetsFilterCriteriaCommandParams } from '@univerjs/sheets-filter';
import type { FWorkbook, FWorksheet } from '@univerjs/sheets/facade';
import { ICommandService } from '@univerjs/core';
import { FEventName, FUniver } from '@univerjs/core/facade';
import { ClearSheetsFilterCriteriaCommand, SetSheetsFilterCriteriaCommand } from '@univerjs/sheets-filter';
import { FSheetEventName } from '@univerjs/sheets/facade';
import { FEventName } from '@univerjs/core/facade';
/**
* The params of SheetRangeFiltered and SheetBeforeRangeFilter events.
* @param workbook - The corresponding workbook wrapped in {@link FWorkbook}.
* @param worksheet - The corresponding worksheet wrapped in {@link FWorksheet}.
* @param col - The column on which the filter criteria is changed.
* @param criteria - Raw filter criteria.
*/
export interface ISheetsRangeFilteredEventParams extends IEventBase, Pick<ISetSheetsFilterCriteriaCommandParams, 'criteria' | 'col'> {
workbook: FWorkbook;
worksheet: FWorksheet;
}
/**
* The params of SheetRangeFilterCleared and SheetBeforeRangeFilterClear events.
* @param workbook - The corresponding workbook wrapped in {@link FWorkbook}.
* @param worksheet - The corresponding worksheet wrapped in {@link FWorksheet}.
*/
export interface ISheetsRangeFilterClearedEventParams extends IEventBase {
workbook: FWorkbook;
worksheet: FWorksheet;
}
/**
* @ignore
*/
export interface IFSheetFilterEventMixin {
interface ISheetsFilterEventParamConfig {
SheetBeforeRangeFilter: ISheetsRangeFilteredEventParams;
SheetRangeFiltered: ISheetsRangeFilteredEventParams;
SheetBeforeRangeFilterClear: ISheetsRangeFilterClearedEventParams;
SheetRangeFilterCleared: ISheetsRangeFilterClearedEventParams;
}
/**
* @ignore
*/
export interface IFSheetsFilterEventNameMixin {
/**
* This event will be emitted when the filter criteria on a column is changed.
* @see {@link ISheetRangeFilteredParams}
@@ -102,167 +130,16 @@ export interface IFSheetFilterEventMixin {
readonly SheetBeforeRangeFilterClear: 'SheetBeforeRangeFilterClear';
}
export class FSheetFilterEventName extends FEventName implements IFSheetFilterEventMixin {
export class FSheetsFilterEventNameMixin extends FEventName implements IFSheetsFilterEventNameMixin {
override get SheetBeforeRangeFilter(): 'SheetBeforeRangeFilter' { return 'SheetBeforeRangeFilter'; }
override get SheetRangeFiltered(): 'SheetRangeFiltered' { return 'SheetRangeFiltered'; }
override get SheetRangeFilterCleared(): 'SheetRangeFilterCleared' { return 'SheetRangeFilterCleared'; };
override get SheetBeforeRangeFilterClear(): 'SheetBeforeRangeFilterClear' { return 'SheetBeforeRangeFilterClear'; }
}
FEventName.extend(FSheetFilterEventName);
FEventName.extend(FSheetsFilterEventNameMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FEventName extends IFSheetFilterEventMixin { }
interface FEventName extends IFSheetsFilterEventNameMixin { }
interface IEventParamConfig extends ISheetsFilterEventParamConfig { }
}
/**
* The params of SheetRangeFiltered and SheetBeforeRangeFilter events.
* @param workbook - The corresponding workbook wrapped in {@link FWorkbook}.
* @param worksheet - The corresponding worksheet wrapped in {@link FWorksheet}.
* @param col - The column on which the filter criteria is changed.
* @param criteria - Raw filter criteria.
*/
export interface ISheetRangeFilteredParams extends IEventBase, Pick<ISetSheetsFilterCriteriaCommandParams, 'criteria' | 'col'> {
workbook: FWorkbook;
worksheet: FWorksheet;
}
/**
* The params of SheetRangeFilterCleared and SheetBeforeRangeFilterClear events.
* @param workbook - The corresponding workbook wrapped in {@link FWorkbook}.
* @param worksheet - The corresponding worksheet wrapped in {@link FWorksheet}.
*/
export interface ISheetRangeFilterClearedEventParams extends IEventBase {
workbook: FWorkbook;
worksheet: FWorksheet;
}
/**
* @ignore
*/
interface ISheetRangeFilterEventParamConfig {
SheetBeforeRangeFilter: ISheetRangeFilteredParams;
SheetRangeFiltered: ISheetRangeFilteredParams;
SheetBeforeRangeFilterClear: ISheetRangeFilterClearedEventParams;
SheetRangeFilterCleared: ISheetRangeFilterClearedEventParams;
}
FEventName.extend(FSheetEventName);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FEventName extends IFSheetFilterEventMixin { }
interface IEventParamConfig extends ISheetRangeFilterEventParamConfig { }
}
class FUniverSheetsFilterEventMixin extends FUniver {
/**
* @ignore
*/
override _initialize(injector: Injector): void {
const commandService = injector.get(ICommandService);
// Register filter criteria set event handlers
this.disposeWithMe(
this.registerEventHandler(
this.Event.SheetBeforeRangeFilter,
() => commandService.beforeCommandExecuted((commandInfo) => {
if (commandInfo.id === SetSheetsFilterCriteriaCommand.id) {
this._beforeRangeFilter(commandInfo as Readonly<ICommandInfo<ISetSheetsFilterCriteriaCommandParams>>);
}
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.SheetBeforeRangeFilterClear,
() => commandService.beforeCommandExecuted((commandInfo) => {
if (commandInfo.id === ClearSheetsFilterCriteriaCommand.id) {
this._beforeRangeFilterClear();
}
})
)
);
// Register filter criteria execution event handlers
this.disposeWithMe(
this.registerEventHandler(
this.Event.SheetRangeFiltered,
() => commandService.onCommandExecuted((commandInfo) => {
if (commandInfo.id === SetSheetsFilterCriteriaCommand.id) {
this._onRangeFiltered(commandInfo as Readonly<ICommandInfo<ISetSheetsFilterCriteriaCommandParams>>);
}
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.SheetRangeFilterCleared,
() => commandService.onCommandExecuted((commandInfo) => {
if (commandInfo.id === ClearSheetsFilterCriteriaCommand.id) {
this._onRangeFilterCleared();
}
})
)
);
}
private _beforeRangeFilter(commandInfo: Readonly<ICommandInfo<ISetSheetsFilterCriteriaCommandParams>>): void {
const params = commandInfo.params!;
const fWorkbook = this.getUniverSheet(params.unitId)!;
const eventParams: ISheetRangeFilteredParams = {
workbook: fWorkbook,
worksheet: fWorkbook.getSheetBySheetId(params.subUnitId)!,
col: params.col,
criteria: params.criteria,
};
this.fireEvent(this.Event.SheetBeforeRangeFilter, eventParams);
if (eventParams.cancel) {
throw new Error('SetSheetsFilterCriteriaCommand canceled.');
}
}
private _onRangeFiltered(commandInfo: Readonly<ICommandInfo<ISetSheetsFilterCriteriaCommandParams>>): void {
const params = commandInfo.params!;
const fWorkbook = this.getUniverSheet(params.unitId)!;
const eventParams: ISheetRangeFilteredParams = {
workbook: fWorkbook,
worksheet: fWorkbook.getSheetBySheetId(params.subUnitId)!,
col: params.col,
criteria: params.criteria,
};
this.fireEvent(this.Event.SheetRangeFiltered, eventParams);
}
private _beforeRangeFilterClear(): void {
const fWorkbook = this.getActiveWorkbook();
if (!fWorkbook) return;
const eventParams: ISheetRangeFilterClearedEventParams = {
workbook: fWorkbook,
worksheet: fWorkbook.getActiveSheet(),
};
this.fireEvent(this.Event.SheetBeforeRangeFilterClear, eventParams);
if (eventParams.cancel) {
throw new Error('SetSheetsFilterCriteriaCommand canceled.');
}
}
private _onRangeFilterCleared(): void {
const fWorkbook = this.getActiveWorkbook();
if (!fWorkbook) return;
const eventParams: ISheetRangeFilterClearedEventParams = {
workbook: fWorkbook,
worksheet: fWorkbook.getActiveSheet(),
};
this.fireEvent(this.Event.SheetRangeFilterCleared, eventParams);
}
}
FUniver.extend(FUniverSheetsFilterEventMixin);
+4 -4
View File
@@ -25,7 +25,7 @@ import { FFilter } from './f-filter';
/**
* @ignore
*/
export interface IFRangeFilter {
export interface IFRangeSheetsFilterMixin {
/**
* Create a filter for the current range. If the worksheet already has a filter, this method would return `null`.
* @returns {FFilter | null} The FFilter instance to handle the filter.
@@ -67,7 +67,7 @@ export interface IFRangeFilter {
getFilter(): FFilter | null;
}
export class FRangeFilter extends FRange implements IFRangeFilter {
export class FRangeSheetsFilterMixin extends FRange implements IFRangeSheetsFilterMixin {
override createFilter(): FFilter | null {
if (this._getFilterModel()) return null;
@@ -102,8 +102,8 @@ export class FRangeFilter extends FRange implements IFRangeFilter {
}
}
FRange.extend(FRangeFilter);
FRange.extend(FRangeSheetsFilterMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FRange extends IFRangeFilter { }
interface FRange extends IFRangeSheetsFilterMixin { }
}
@@ -0,0 +1,135 @@
/**
* 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.
*/
import type { ICommandInfo, Injector } from '@univerjs/core';
import type { ISetSheetsFilterCriteriaCommandParams } from '@univerjs/sheets-filter';
import type { ISheetsRangeFilterClearedEventParams, ISheetsRangeFilteredEventParams } from './f-event';
import { ICommandService } from '@univerjs/core';
import { FUniver } from '@univerjs/core/facade';
import { ClearSheetsFilterCriteriaCommand, SetSheetsFilterCriteriaCommand } from '@univerjs/sheets-filter';
export class FUniverSheetsFilterMixin extends FUniver {
/**
* @ignore
*/
override _initialize(injector: Injector): void {
const commandService = injector.get(ICommandService);
// Register filter criteria set event handlers
this.disposeWithMe(
this.registerEventHandler(
this.Event.SheetBeforeRangeFilter,
() => commandService.beforeCommandExecuted((commandInfo) => {
if (commandInfo.id === SetSheetsFilterCriteriaCommand.id) {
this._beforeRangeFilter(commandInfo as Readonly<ICommandInfo<ISetSheetsFilterCriteriaCommandParams>>);
}
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.SheetBeforeRangeFilterClear,
() => commandService.beforeCommandExecuted((commandInfo) => {
if (commandInfo.id === ClearSheetsFilterCriteriaCommand.id) {
this._beforeRangeFilterClear();
}
})
)
);
// Register filter criteria execution event handlers
this.disposeWithMe(
this.registerEventHandler(
this.Event.SheetRangeFiltered,
() => commandService.onCommandExecuted((commandInfo) => {
if (commandInfo.id === SetSheetsFilterCriteriaCommand.id) {
this._onRangeFiltered(commandInfo as Readonly<ICommandInfo<ISetSheetsFilterCriteriaCommandParams>>);
}
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.SheetRangeFilterCleared,
() => commandService.onCommandExecuted((commandInfo) => {
if (commandInfo.id === ClearSheetsFilterCriteriaCommand.id) {
this._onRangeFilterCleared();
}
})
)
);
}
private _beforeRangeFilter(commandInfo: Readonly<ICommandInfo<ISetSheetsFilterCriteriaCommandParams>>): void {
const params = commandInfo.params!;
const fWorkbook = this.getUniverSheet(params.unitId)!;
const eventParams: ISheetsRangeFilteredEventParams = {
workbook: fWorkbook,
worksheet: fWorkbook.getSheetBySheetId(params.subUnitId)!,
col: params.col,
criteria: params.criteria,
};
this.fireEvent(this.Event.SheetBeforeRangeFilter, eventParams);
if (eventParams.cancel) {
throw new Error('SetSheetsFilterCriteriaCommand canceled.');
}
}
private _onRangeFiltered(commandInfo: Readonly<ICommandInfo<ISetSheetsFilterCriteriaCommandParams>>): void {
const params = commandInfo.params!;
const fWorkbook = this.getUniverSheet(params.unitId)!;
const eventParams: ISheetsRangeFilteredEventParams = {
workbook: fWorkbook,
worksheet: fWorkbook.getSheetBySheetId(params.subUnitId)!,
col: params.col,
criteria: params.criteria,
};
this.fireEvent(this.Event.SheetRangeFiltered, eventParams);
}
private _beforeRangeFilterClear(): void {
const fWorkbook = this.getActiveWorkbook();
if (!fWorkbook) return;
const eventParams: ISheetsRangeFilterClearedEventParams = {
workbook: fWorkbook,
worksheet: fWorkbook.getActiveSheet(),
};
this.fireEvent(this.Event.SheetBeforeRangeFilterClear, eventParams);
if (eventParams.cancel) {
throw new Error('SetSheetsFilterCriteriaCommand canceled.');
}
}
private _onRangeFilterCleared(): void {
const fWorkbook = this.getActiveWorkbook();
if (!fWorkbook) return;
const eventParams: ISheetsRangeFilterClearedEventParams = {
workbook: fWorkbook,
worksheet: fWorkbook.getActiveSheet(),
};
this.fireEvent(this.Event.SheetRangeFilterCleared, eventParams);
}
}
FUniver.extend(FUniverSheetsFilterMixin);
@@ -23,7 +23,7 @@ import { FFilter } from './f-filter';
/**
* @ignore
*/
export interface IFWorksheetFilter {
export interface IFWorksheetFilterMixin {
/**
* Get the filter for the current worksheet.
* @returns {FFilter | null} The interface class to handle the filter. If the worksheet does not have a filter,
@@ -39,7 +39,7 @@ export interface IFWorksheetFilter {
getFilter(): FFilter | null;
}
export class FWorksheetFilter extends FWorksheet implements IFWorksheetFilter {
export class FWorksheetFilterMixin extends FWorksheet implements IFWorksheetFilterMixin {
override getFilter(): FFilter | null {
const filterModel = this._getFilterModel();
if (!filterModel) return null;
@@ -55,8 +55,8 @@ export class FWorksheetFilter extends FWorksheet implements IFWorksheetFilter {
}
}
FWorksheet.extend(FWorksheetFilter);
FWorksheet.extend(FWorksheetFilterMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FWorksheet extends IFWorksheetFilter { }
interface FWorksheet extends IFWorksheetFilterMixin { }
}
@@ -14,6 +14,7 @@
* limitations under the License.
*/
import './f-univer';
import './f-filter';
import './f-range';
import './f-worksheet';
@@ -25,4 +26,5 @@ export type * from './f-event';
export { FFilter } from './f-filter';
export type * from './f-filter';
export type * from './f-range';
export type * from './f-univer';
export type * from './f-worksheet';
@@ -506,7 +506,7 @@ export class SheetFindModel extends FindModel {
private _updateFindHighlight(): void {
this._disposeHighlights();
const skeleton = this._sheetSkeletonManagerService.getCurrent()?.skeleton;
const skeleton = this._sheetSkeletonManagerService.getCurrentSkeleton();
if (!skeleton) {
return;
}
@@ -21,7 +21,7 @@ import { FTextFinder } from './f-text-finder';
/**
* @ignore
*/
export interface IFUniverFindReplaceMixin {
export interface IFUniverSheetsFindReplaceMixin {
/**
* Create a text-finder for the current univer.
* @param {string} text - The text to find.
@@ -60,7 +60,7 @@ export interface IFUniverFindReplaceMixin {
createTextFinderAsync(text: string): Promise<FTextFinder | null>;
}
export class FUniverFindReplaceMixin extends FUniver implements IFUniverFindReplaceMixin {
export class FUniverSheetsFindReplaceMixin extends FUniver implements IFUniverSheetsFindReplaceMixin {
override async createTextFinderAsync(text: string): Promise<FTextFinder | null> {
const state: Partial<IFindReplaceState> = { findString: text };
const textFinder = this._injector.createInstance(FTextFinder, state);
@@ -69,8 +69,8 @@ export class FUniverFindReplaceMixin extends FUniver implements IFUniverFindRepl
}
}
FUniver.extend(FUniverFindReplaceMixin);
FUniver.extend(FUniverSheetsFindReplaceMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FUniver extends IFUniverFindReplaceMixin {}
interface FUniver extends IFUniverSheetsFindReplaceMixin {}
}
@@ -20,7 +20,7 @@ import { DocSelectionManagerService } from '@univerjs/docs';
import { EditorService, IEditorService } from '@univerjs/docs-ui';
import { LexerTreeBuilder } from '@univerjs/engine-formula';
import { IRenderManagerService, RenderManagerService } from '@univerjs/engine-render';
import { IRefSelectionsService, RangeProtectionRuleModel, RefSelectionsService, SheetInterceptorService, SheetsSelectionsService, WorkbookPermissionService, WorksheetPermissionService, WorksheetProtectionPointModel, WorksheetProtectionRuleModel } from '@univerjs/sheets';
import { IRefSelectionsService, RangeProtectionRuleModel, RefSelectionsService, SheetInterceptorService, SheetSkeletonService, SheetsSelectionsService, WorkbookPermissionService, WorksheetPermissionService, WorksheetProtectionPointModel, WorksheetProtectionRuleModel } from '@univerjs/sheets';
import { EditorBridgeService, IEditorBridgeService, ISheetSelectionRenderService, SheetSelectionRenderService, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
import { FormulaPromptService, IFormulaPromptService } from '../../../services/prompt.service';
@@ -79,6 +79,7 @@ export function createCommandTestBed(workbookData?: IWorkbookData, dependencies?
const injector = this._injector;
addDependency([ISheetSelectionRenderService, { useClass: SheetSelectionRenderService }]);
addDependency([SheetsSelectionsService]);
addDependency([SheetSkeletonService]);
addDependency([LexerTreeBuilder]);
addDependency([DocSelectionManagerService]);
addDependency([IFormulaPromptService, { useClass: FormulaPromptService }]);
@@ -20,7 +20,7 @@ import { DocSelectionManagerService } from '@univerjs/docs';
import { EditorService, IEditorService } from '@univerjs/docs-ui';
import { CalculateFormulaService, DefinedNamesService, FormulaCurrentConfigService, FormulaDataModel, FormulaRuntimeService, HyperlinkEngineFormulaService, ICalculateFormulaService, IDefinedNamesService, IFormulaCurrentConfigService, IFormulaRuntimeService, IHyperlinkEngineFormulaService, LexerTreeBuilder } from '@univerjs/engine-formula';
import { IRenderManagerService, RenderManagerService } from '@univerjs/engine-render';
import { DefinedNameDataController, IRefSelectionsService, RangeProtectionRuleModel, SheetInterceptorService, SheetsSelectionsService, WorkbookPermissionService, WorksheetPermissionService, WorksheetProtectionPointModel, WorksheetProtectionRuleModel } from '@univerjs/sheets';
import { DefinedNameDataController, IRefSelectionsService, RangeProtectionRuleModel, SheetInterceptorService, SheetSkeletonService, SheetsSelectionsService, WorkbookPermissionService, WorksheetPermissionService, WorksheetProtectionPointModel, WorksheetProtectionRuleModel } from '@univerjs/sheets';
import { EditorBridgeService, IEditorBridgeService, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
const TEST_WORKBOOK_DATA_DEMO: IWorkbookData = {
@@ -102,6 +102,7 @@ export function createCommandTestBed(workbookData?: IWorkbookData, dependencies?
injector.add([WorksheetProtectionRuleModel]);
injector.add([SheetsSelectionsService]);
injector.add([SheetInterceptorService]);
injector.add([SheetSkeletonService]);
injector.add([ICalculateFormulaService, { useClass: CalculateFormulaService }]);
injector.add([FormulaDataModel]);
injector.add([LexerTreeBuilder]);
@@ -160,7 +160,7 @@ export function clipboardTestBed(workbookData?: IWorkbookData, dependencies?: De
activated$: new BehaviorSubject(true),
activate: () => {},
deactivate: () => {},
}, injector, injector.get(SheetSkeletonService));
}, injector.get(SheetSkeletonService));
injector.add([SheetSkeletonManagerService, { useValue: fakeSheetSkeletonManagerService }]);
injector.get(IRenderManagerService).addRender('test', {
@@ -34,9 +34,8 @@ import {
SetFormulaCalculationResultMutation,
} from '@univerjs/engine-formula';
import { IRenderManagerService } from '@univerjs/engine-render';
import { BEFORE_CELL_EDIT, SetWorksheetRowAutoHeightMutation, SheetInterceptorService } from '@univerjs/sheets';
import { attachSelectionWithCoord, BEFORE_CELL_EDIT, SetWorksheetRowAutoHeightMutation, SheetInterceptorService, SheetSkeletonService } from '@univerjs/sheets';
import {
attachSelectionWithCoord,
SELECTION_SHAPE_DEPTH,
SelectionControl,
SheetSkeletonManagerService,
@@ -52,6 +51,7 @@ export class FormulaEditorShowController extends Disposable implements IRenderMo
constructor(
private readonly _context: IRenderContext<Workbook>,
@Inject(SheetInterceptorService) private readonly _sheetInterceptorService: SheetInterceptorService,
@Inject(SheetSkeletonService) private readonly _sheetSkeletonService: SheetSkeletonService,
@Inject(FormulaDataModel) private readonly _formulaDataModel: FormulaDataModel,
@Inject(ThemeService) private readonly _themeService: ThemeService,
@IRenderManagerService private readonly _renderManagerService: IRenderManagerService,
@@ -181,7 +181,7 @@ export class FormulaEditorShowController extends Disposable implements IRenderMo
}
const { startRow, startColumn, endRow, endColumn } = range;
if (rowIndex === row && columnIndex === col) {
this._createArrayFormulaRangeShape(range, unitId);
this._createArrayFormulaRangeShape(range, unitId, subUnitId);
return false;
}
if (row >= startRow && row <= endRow && col >= startColumn && col <= endColumn) {
@@ -198,7 +198,7 @@ export class FormulaEditorShowController extends Disposable implements IRenderMo
};
}
this._createArrayFormulaRangeShape(range, unitId);
this._createArrayFormulaRangeShape(range, unitId, subUnitId);
return false;
}
});
@@ -206,9 +206,9 @@ export class FormulaEditorShowController extends Disposable implements IRenderMo
return cellInfo;
}
private _createArrayFormulaRangeShape(arrayRange: IRange, unitId: string): void {
private _createArrayFormulaRangeShape(arrayRange: IRange, unitId: string, subUnitId: string): void {
const renderUnit = this._renderManagerService.getRenderById(unitId);
const skeleton = this._sheetSkeletonManagerService.getCurrentSkeleton();
const skeleton = this._sheetSkeletonService.getSkeleton(unitId, subUnitId);
if (!renderUnit || !skeleton) return;
const { scene } = renderUnit;
@@ -244,12 +244,12 @@ export class FormulaEditorShowController extends Disposable implements IRenderMo
this._previousShape = null;
}
private _refreshArrayFormulaRangeShape(unitId: string, _range?: IRange): void {
private _refreshArrayFormulaRangeShape(unitId: string, subUnitId: string): void {
if (this._previousShape) {
const { startRow, endRow, startColumn, endColumn } = this._previousShape.getRange();
const range = { startRow, endRow, startColumn, endColumn };
this._removeArrayFormulaRangeShape();
this._createArrayFormulaRangeShape(range, unitId);
this._createArrayFormulaRangeShape(range, unitId, subUnitId);
}
}
@@ -270,7 +270,7 @@ export class FormulaEditorShowController extends Disposable implements IRenderMo
private _updateArrayFormulaRangeShape(unitId: string, subUnitId: string): void {
if (!this._checkCurrentSheet(unitId, subUnitId)) return;
if (!this._previousShape) return;
this._refreshArrayFormulaRangeShape(unitId);
this._refreshArrayFormulaRangeShape(unitId, subUnitId);
}
private _refreshArrayFormulaRangeShapeByRow(unitId: string, subUnitId: string, rowAutoHeightInfo: IRowAutoHeightInfo[]): void {
@@ -278,18 +278,12 @@ export class FormulaEditorShowController extends Disposable implements IRenderMo
if (!this._previousShape) return;
const { startRow: shapeStartRow, endRow: shapeEndRow, startColumn: shapeStartColumn, endColumn: shapeEndColumn } = this._previousShape.getRange();
const { startRow: shapeStartRow } = this._previousShape.getRange();
for (let i = 0; i < rowAutoHeightInfo.length; i++) {
const { row } = rowAutoHeightInfo[i];
if (shapeStartRow >= row) {
const shapeRange = {
startRow: shapeStartRow,
endRow: shapeEndRow,
startColumn: shapeStartColumn,
endColumn: shapeEndColumn,
};
this._refreshArrayFormulaRangeShape(unitId, shapeRange);
this._refreshArrayFormulaRangeShape(unitId, subUnitId);
break;
}
}
@@ -19,7 +19,7 @@ import type { IShowRangeSelectorDialogOptions } from '@univerjs/sheets-formula-u
import { FUniver } from '@univerjs/core/facade';
import { GlobalRangeSelectorService } from '@univerjs/sheets-formula-ui';
export interface ISheetsFormulaUIMixin {
export interface IFUniverSheetsFormulaUIMixin {
/**
* Shows the range selector dialog.
*
@@ -51,16 +51,16 @@ export interface ISheetsFormulaUIMixin {
showRangeSelectorDialog(opts: IShowRangeSelectorDialogOptions): Promise<IUnitRangeName[]>;
}
export class FSheetsFormulaUIUniver extends FUniver implements ISheetsFormulaUIMixin {
export class FUniverSheetsFormulaUIMixin extends FUniver implements IFUniverSheetsFormulaUIMixin {
override showRangeSelectorDialog(opts: IShowRangeSelectorDialogOptions): Promise<IUnitRangeName[]> {
const globalRangeSelectorService = this._injector.get(GlobalRangeSelectorService);
return globalRangeSelectorService.showRangeSelectorDialog(opts);
}
}
FUniver.extend(FSheetsFormulaUIUniver);
FUniver.extend(FUniverSheetsFormulaUIMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FUniver extends ISheetsFormulaUIMixin { }
interface FUniver extends IFUniverSheetsFormulaUIMixin { }
}
@@ -19,8 +19,8 @@ import type { IMouseEvent, IPointerEvent, IRenderContext, IRenderModule, Scene,
import type { ISelectionStyle, ISelectionWithCoord, ISelectionWithStyle, SheetsSelectionsService, WorkbookSelectionModel } from '@univerjs/sheets';
import { DisposableCollection, IContextService, Inject, Injector, RANGE_TYPE, Rectangle, ThemeService, toDisposable } from '@univerjs/core';
import { ScrollTimerType, SHEET_VIEWPORT_KEY, Vector2 } from '@univerjs/engine-render';
import { convertSelectionDataToRange, IRefSelectionsService, SelectionMoveType } from '@univerjs/sheets';
import { attachSelectionWithCoord, BaseSelectionRenderService, checkInHeaderRanges, genNormalSelectionStyle, getAllSelection, getCoordByOffset, getSheetObject, SelectionControl, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
import { attachSelectionWithCoord, convertSelectionDataToRange, IRefSelectionsService, SelectionMoveType } from '@univerjs/sheets';
import { BaseSelectionRenderService, checkInHeaderRanges, genNormalSelectionStyle, getAllSelection, getCoordByOffset, getSheetObject, SelectionControl, SheetSkeletonManagerService } from '@univerjs/sheets-ui';
import { IShortcutService } from '@univerjs/ui';
/**
@@ -127,7 +127,8 @@ export class RefSelectionsRenderService extends BaseSelectionRenderService imple
listenerDisposables.add(
spreadsheetRowHeader?.onPointerDown$.subscribeEvent((evt: IPointerEvent | IMouseEvent, state) => {
if (!this.inRefSelectionMode()) return;
const skeleton = this._sheetSkeletonManagerService.getCurrent()!.skeleton;
const skeleton = this._sheetSkeletonManagerService.getCurrentSkeleton();
if (!skeleton) return;
const { row } = getCoordByOffset(evt.offsetX, evt.offsetY, scene, skeleton);
const matchSelectionData = checkInHeaderRanges(this._workbookSelections.getCurrentSelections(), row, RANGE_TYPE.ROW);
if (matchSelectionData) return;
@@ -141,7 +142,8 @@ export class RefSelectionsRenderService extends BaseSelectionRenderService imple
listenerDisposables.add(spreadsheetColumnHeader?.onPointerDown$.subscribeEvent((evt: IPointerEvent | IMouseEvent, state) => {
if (!this.inRefSelectionMode()) return;
const skeleton = this._sheetSkeletonManagerService.getCurrent()!.skeleton;
const skeleton = this._sheetSkeletonManagerService.getCurrentSkeleton();
if (!skeleton) return;
const { column } = getCoordByOffset(evt.offsetX, evt.offsetY, scene, skeleton);
const matchSelectionData = checkInHeaderRanges(this._workbookSelections.getCurrentSelections(), column, RANGE_TYPE.COLUMN);
if (matchSelectionData) return;
@@ -157,7 +159,8 @@ export class RefSelectionsRenderService extends BaseSelectionRenderService imple
// remove all other selections
this._reset();
if (!this.inRefSelectionMode()) return;
const skeleton = this._sheetSkeletonManagerService.getCurrent()!.skeleton;
const skeleton = this._sheetSkeletonManagerService.getCurrentSkeleton();
if (!skeleton) return;
const selectionWithStyle = getAllSelection(skeleton);
this._addSelectionControlByModelData(selectionWithStyle);
this._selectionMoveStart$.next(this.getSelectionDataWithStyle());
@@ -76,7 +76,7 @@ export function calcHighlightRanges(opts: {
const currentSheetId = worksheet.getSheetId();
const getSheetIdByName = (name: string) => workbook?.getSheetBySheetName(name)?.getSheetId();
const skeleton = sheetSkeletonManagerService?.getWorksheetSkeleton(currentSheetId)?.skeleton;
const skeleton = sheetSkeletonManagerService?.getSkeleton(currentSheetId);
if (!skeleton) return;
const endIndexes: number[] = [];
for (let i = 0, len = refSelections.length; i < len; i++) {
+5 -5
View File
@@ -20,22 +20,22 @@ import { CalculationMode } from '@univerjs/sheets-formula';
/**
* @ignore
*/
export interface IFSheetsFormulaEnum {
export interface IFSheetsFormulaEnumMixin {
/**
* Define the calculation mode during initialization
*/
CalculationMode: typeof CalculationMode;
}
export class FSheetsFormulaEnum implements IFSheetsFormulaEnum {
get CalculationMode(): typeof CalculationMode {
export class FSheetsFormulaEnumMixin extends FEnum implements IFSheetsFormulaEnumMixin {
override get CalculationMode(): typeof CalculationMode {
return CalculationMode;
}
}
FEnum.extend(FSheetsFormulaEnum);
FEnum.extend(FSheetsFormulaEnumMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
export interface FEnum extends IFSheetsFormulaEnum {
export interface FEnum extends IFSheetsFormulaEnumMixin {
}
}
@@ -16,7 +16,6 @@
import { SheetsHyperLinkParserService } from '@univerjs/sheets-hyper-link';
import { SheetsHyperLinkResolverService } from '@univerjs/sheets-hyper-link-ui';
import { FWorkbookHyperLinkMixin } from '@univerjs/sheets-hyper-link/facade';
import { FWorkbook } from '@univerjs/sheets/facade';
interface IFWorkbookHyperlinkUIMixin {
@@ -47,7 +46,7 @@ interface IFWorkbookHyperlinkUIMixin {
navigateToSheetHyperlink(this: FWorkbook, hyperlink: string): void;
}
class FWorkbookHyperLinkUIMixin extends FWorkbookHyperLinkMixin implements IFWorkbookHyperlinkUIMixin {
class FWorkbookHyperlinkUIMixin extends FWorkbook implements IFWorkbookHyperlinkUIMixin {
// TODO: this should be migrated back to hyperlink ui plugin
override navigateToSheetHyperlink(hyperlink: string): void {
const parserService = this._injector.get(SheetsHyperLinkParserService);
@@ -57,7 +56,7 @@ class FWorkbookHyperLinkUIMixin extends FWorkbookHyperLinkMixin implements IFWor
}
}
FWorkbook.extend(FWorkbookHyperLinkUIMixin);
FWorkbook.extend(FWorkbookHyperlinkUIMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FWorkbook extends IFWorkbookHyperlinkUIMixin {}
@@ -22,10 +22,10 @@ import { FEventName } from '@univerjs/core/facade';
/**
* @ignore
*/
interface IFSheetLinkEvent {
interface IFSheetsHyperlinkEventNameMixin {
/**
* Event triggered before adding a link
* @see {@link IBeforeSheetLinkAddEvent}
* @see {@link IBeforeSheetLinkAddEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetLinkAdd, (params) => {
@@ -43,7 +43,7 @@ interface IFSheetLinkEvent {
/**
* Event triggered before canceling a link
* @see {@link IBeforeSheetLinkCancelEvent}
* @see {@link IBeforeSheetLinkCancelEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetLinkCancel, (params) => {
@@ -61,7 +61,7 @@ interface IFSheetLinkEvent {
/**
* Event triggered before updating a link
* @see {@link IBeforeSheetLinkUpdateEvent}
* @see {@link IBeforeSheetLinkUpdateEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetLinkUpdate, (params) => {
@@ -78,21 +78,21 @@ interface IFSheetLinkEvent {
readonly BeforeSheetLinkUpdate: 'BeforeSheetLinkUpdate';
}
export class FSheetLinkEvent implements IFSheetLinkEvent {
get BeforeSheetLinkAdd(): 'BeforeSheetLinkAdd' {
export class FSheetsHyperlinkEventNameMixin extends FEventName implements IFSheetsHyperlinkEventNameMixin {
override get BeforeSheetLinkAdd(): 'BeforeSheetLinkAdd' {
return 'BeforeSheetLinkAdd' as const;
}
get BeforeSheetLinkCancel(): 'BeforeSheetLinkCancel' {
override get BeforeSheetLinkCancel(): 'BeforeSheetLinkCancel' {
return 'BeforeSheetLinkCancel' as const;
}
get BeforeSheetLinkUpdate(): 'BeforeSheetLinkUpdate' {
override get BeforeSheetLinkUpdate(): 'BeforeSheetLinkUpdate' {
return 'BeforeSheetLinkUpdate' as const;
}
}
export interface IBeforeSheetLinkAddEvent extends IEventBase {
export interface IBeforeSheetLinkAddEventParams extends IEventBase {
/** The workbook instance */
workbook: FWorkbook;
/** The worksheet where the link will be added */
@@ -105,7 +105,7 @@ export interface IBeforeSheetLinkAddEvent extends IEventBase {
link: ISheetHyperLink;
}
export interface IBeforeSheetLinkCancelEvent extends IEventBase {
export interface IBeforeSheetLinkCancelEventParams extends IEventBase {
/** The workbook instance */
workbook: FWorkbook;
/** The worksheet containing the link */
@@ -118,7 +118,7 @@ export interface IBeforeSheetLinkCancelEvent extends IEventBase {
id: string;
}
export interface IBeforeSheetLinkUpdateEvent extends IEventBase {
export interface IBeforeSheetLinkUpdateEventParams extends IEventBase {
/** The workbook instance */
workbook: FWorkbook;
/** The worksheet containing the link */
@@ -136,19 +136,17 @@ export interface IBeforeSheetLinkUpdateEvent extends IEventBase {
/**
* @ignore
*/
export interface ISheetLinkEventConfig {
BeforeSheetLinkAdd: IBeforeSheetLinkAddEvent;
BeforeSheetLinkCancel: IBeforeSheetLinkCancelEvent;
BeforeSheetLinkUpdate: IBeforeSheetLinkUpdateEvent;
export interface ISheetsHyperlinkEventParamConfig {
BeforeSheetLinkAdd: IBeforeSheetLinkAddEventParams;
BeforeSheetLinkCancel: IBeforeSheetLinkCancelEventParams;
BeforeSheetLinkUpdate: IBeforeSheetLinkUpdateEventParams;
}
FEventName.extend(FSheetLinkEvent);
FEventName.extend(FSheetsHyperlinkEventNameMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FEventName extends IFSheetLinkEvent {
}
interface FEventName extends IFSheetsHyperlinkEventNameMixin {}
interface IEventParamConfig extends ISheetLinkEventConfig {
}
interface IEventParamConfig extends ISheetsHyperlinkEventParamConfig { }
}
@@ -30,7 +30,7 @@ export interface ICellHyperLink {
/**
* @ignore
*/
export interface IFRangeHyperlinkMixin {
export interface IFRangeSheetsHyperlinkMixin {
/**
* @deprecated use `range.setRichTextValueForCell(univerAPI.newRichText().insertLink(label, url))` instead
* @example
@@ -124,7 +124,7 @@ export interface IFRangeHyperlinkMixin {
getUrl(): string;
}
export class FRangeHyperlinkMixin extends FRange implements IFRangeHyperlinkMixin {
export class FRangeSheetsHyperlinkMixin extends FRange implements IFRangeSheetsHyperlinkMixin {
// #region hyperlink
override setHyperLink(url: string, label?: string): Promise<boolean> {
@@ -196,8 +196,8 @@ export class FRangeHyperlinkMixin extends FRange implements IFRangeHyperlinkMixi
// #endregion
}
FRange.extend(FRangeHyperlinkMixin);
FRange.extend(FRangeSheetsHyperlinkMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FRange extends IFRangeHyperlinkMixin {}
interface FRange extends IFRangeSheetsHyperlinkMixin {}
}
@@ -16,12 +16,12 @@
import type { Injector } from '@univerjs/core';
import type { IAddHyperLinkCommandParams, ICancelHyperLinkCommandParams, IUpdateHyperLinkCommandParams } from '@univerjs/sheets-hyper-link';
import type { IBeforeSheetLinkAddEvent, IBeforeSheetLinkCancelEvent, IBeforeSheetLinkUpdateEvent } from './f-event';
import type { IBeforeSheetLinkAddEventParams, IBeforeSheetLinkCancelEventParams, IBeforeSheetLinkUpdateEventParams } from './f-event';
import { CanceledError, ICommandService } from '@univerjs/core';
import { FUniver } from '@univerjs/core/facade';
import { AddHyperLinkCommand, CancelHyperLinkCommand, UpdateHyperLinkCommand } from '@univerjs/sheets-hyper-link';
export class FSheetLinkUniver extends FUniver {
export class FUniverSheetsHyperlinkMixin extends FUniver {
/**
* @ignore
*/
@@ -38,7 +38,7 @@ export class FSheetLinkUniver extends FUniver {
if (!eventTarget) return;
const params = commandInfo.params as IAddHyperLinkCommandParams;
const eventParams: IBeforeSheetLinkAddEvent = {
const eventParams: IBeforeSheetLinkAddEventParams = {
workbook: eventTarget.workbook,
worksheet: eventTarget.worksheet,
row: params.link.row,
@@ -63,7 +63,7 @@ export class FSheetLinkUniver extends FUniver {
if (!eventTarget) return;
const params = commandInfo.params as IUpdateHyperLinkCommandParams;
const eventParams: IBeforeSheetLinkUpdateEvent = {
const eventParams: IBeforeSheetLinkUpdateEventParams = {
workbook: eventTarget.workbook,
worksheet: eventTarget.worksheet,
row: params.row,
@@ -89,7 +89,7 @@ export class FSheetLinkUniver extends FUniver {
if (!eventTarget) return;
const params = commandInfo.params as ICancelHyperLinkCommandParams;
const eventParams: IBeforeSheetLinkCancelEvent = {
const eventParams: IBeforeSheetLinkCancelEventParams = {
workbook: eventTarget.workbook,
worksheet: eventTarget.worksheet,
row: params.row,
@@ -106,4 +106,4 @@ export class FSheetLinkUniver extends FUniver {
}
}
FUniver.extend(FSheetLinkUniver);
FUniver.extend(FUniverSheetsHyperlinkMixin);
@@ -14,7 +14,6 @@
* limitations under the License.
*/
import type { IRange } from '@univerjs/core';
import type { ISheetHyperLinkInfo } from '@univerjs/sheets-hyper-link';
import type { FRange } from '@univerjs/sheets/facade';
import { Inject } from '@univerjs/core';
@@ -40,11 +39,6 @@ export class SheetHyperLinkBuilder {
* @ignore
*/
export interface IFWorkbookHyperlinkMixin {
/**
* @deprecated use `getUrl` method in `FRange` or `FWorksheet` instead.
*/
createSheetHyperlink(this: FWorkbook, sheetId: string, range?: string | IRange): string;
/**
* Parse the hyperlink string to get the hyperlink info.
* @param {string} hyperlink - The hyperlink string.
@@ -65,12 +59,7 @@ export interface IFWorkbookHyperlinkMixin {
parseSheetHyperlink(this: FWorkbook, hyperlink: string): ISheetHyperLinkInfo;
}
export class FWorkbookHyperLinkMixin extends FWorkbook implements IFWorkbookHyperlinkMixin {
override createSheetHyperlink(sheetId: string, range?: string | IRange): string {
const parserService = this._injector.get(SheetsHyperLinkParserService);
return parserService.buildHyperLink(this.getId(), sheetId, range);
}
export class FWorkbookHyperlinkMixin extends FWorkbook implements IFWorkbookHyperlinkMixin {
/**
* Parse the hyperlink string to get the hyperlink info.
* @param {string} hyperlink the hyperlink string
@@ -82,8 +71,8 @@ export class FWorkbookHyperLinkMixin extends FWorkbook implements IFWorkbookHype
}
}
FWorkbook.extend(FWorkbookHyperLinkMixin);
FWorkbook.extend(FWorkbookHyperlinkMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FWorkbook extends IFWorkbookHyperlinkMixin {}
interface FWorkbook extends IFWorkbookHyperlinkMixin { }
}
@@ -23,6 +23,6 @@ import './f-univer';
export type * from './f-event';
export type * from './f-range';
export type * from './f-univer';
export { FWorkbookHyperLinkMixin } from './f-workbook';
export { FWorkbookHyperlinkMixin } from './f-workbook';
export type * from './f-workbook';
export type * from './f-worksheet';
+36 -36
View File
@@ -82,7 +82,7 @@ export interface ISheetsNoteEventParamConfig {
/**
* @ignore
*/
interface ISheetNoteEvent {
interface IFSheetsNoteEventNameMixin {
/**
* Event fired when a note is added
* @see {@link ISheetNoteAddEventParams}
@@ -96,7 +96,7 @@ interface ISheetNoteEvent {
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
SheetNoteAdd: 'SheetNoteAdd';
readonly SheetNoteAdd: 'SheetNoteAdd';
/**
* Event fired when a note is deleted
* @see {@link ISheetNoteDeleteEventParams}
@@ -110,7 +110,7 @@ interface ISheetNoteEvent {
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
SheetNoteDelete: 'SheetNoteDelete';
readonly SheetNoteDelete: 'SheetNoteDelete';
/**
* Event fired when a note is updated
* @see {@link ISheetNoteUpdateEventParams}
@@ -124,7 +124,7 @@ interface ISheetNoteEvent {
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
SheetNoteUpdate: 'SheetNoteUpdate';
readonly SheetNoteUpdate: 'SheetNoteUpdate';
/**
* Event fired when a note is shown
* @see {@link ISheetNoteShowEventParams}
@@ -138,7 +138,7 @@ interface ISheetNoteEvent {
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
SheetNoteShow: 'SheetNoteShow';
readonly SheetNoteShow: 'SheetNoteShow';
/**
* Event fired when a note is hidden
* @see {@link ISheetNoteHideEventParams}
@@ -152,7 +152,7 @@ interface ISheetNoteEvent {
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
SheetNoteHide: 'SheetNoteHide';
readonly SheetNoteHide: 'SheetNoteHide';
/**
* Event fired before a note is added
@@ -170,7 +170,7 @@ interface ISheetNoteEvent {
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
BeforeSheetNoteAdd: 'BeforeSheetNoteAdd';
readonly BeforeSheetNoteAdd: 'BeforeSheetNoteAdd';
/**
* Event fired before a note is deleted
* @see {@link ISheetNoteDeleteEventParams}
@@ -187,7 +187,7 @@ interface ISheetNoteEvent {
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
BeforeSheetNoteDelete: 'BeforeSheetNoteDelete';
readonly BeforeSheetNoteDelete: 'BeforeSheetNoteDelete';
/**
* Event fired before a note is updated
* @see {@link ISheetNoteUpdateEventParams}
@@ -204,7 +204,7 @@ interface ISheetNoteEvent {
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
BeforeSheetNoteUpdate: 'BeforeSheetNoteUpdate';
readonly BeforeSheetNoteUpdate: 'BeforeSheetNoteUpdate';
/**
* Event fired before a note is shown
* @see {@link ISheetNoteShowEventParams}
@@ -221,7 +221,7 @@ interface ISheetNoteEvent {
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
BeforeSheetNoteShow: 'BeforeSheetNoteShow';
readonly BeforeSheetNoteShow: 'BeforeSheetNoteShow';
/**
* Event fired before a note is hidden
* @see {@link ISheetNoteHideEventParams}
@@ -238,58 +238,58 @@ interface ISheetNoteEvent {
* // Remove the event listener, use `disposable.dispose()`
* ```
*/
BeforeSheetNoteHide: 'BeforeSheetNoteHide';
readonly BeforeSheetNoteHide: 'BeforeSheetNoteHide';
}
/**
* @ignore
*/
export class FSheetNoteEvent implements ISheetNoteEvent {
get SheetNoteAdd(): 'SheetNoteAdd' {
return 'SheetNoteAdd';
export class FSheetsNoteEventNameMixin extends FEventName implements IFSheetsNoteEventNameMixin {
override get SheetNoteAdd(): 'SheetNoteAdd' {
return 'SheetNoteAdd' as const;
}
get SheetNoteDelete(): 'SheetNoteDelete' {
return 'SheetNoteDelete';
override get SheetNoteDelete(): 'SheetNoteDelete' {
return 'SheetNoteDelete' as const;
}
get SheetNoteUpdate(): 'SheetNoteUpdate' {
return 'SheetNoteUpdate';
override get SheetNoteUpdate(): 'SheetNoteUpdate' {
return 'SheetNoteUpdate' as const;
}
get SheetNoteShow(): 'SheetNoteShow' {
return 'SheetNoteShow';
override get SheetNoteShow(): 'SheetNoteShow' {
return 'SheetNoteShow' as const;
}
get SheetNoteHide(): 'SheetNoteHide' {
return 'SheetNoteHide';
override get SheetNoteHide(): 'SheetNoteHide' {
return 'SheetNoteHide' as const;
}
get BeforeSheetNoteAdd(): 'BeforeSheetNoteAdd' {
return 'BeforeSheetNoteAdd';
override get BeforeSheetNoteAdd(): 'BeforeSheetNoteAdd' {
return 'BeforeSheetNoteAdd' as const;
}
get BeforeSheetNoteDelete(): 'BeforeSheetNoteDelete' {
return 'BeforeSheetNoteDelete';
override get BeforeSheetNoteDelete(): 'BeforeSheetNoteDelete' {
return 'BeforeSheetNoteDelete' as const;
}
get BeforeSheetNoteUpdate(): 'BeforeSheetNoteUpdate' {
return 'BeforeSheetNoteUpdate';
override get BeforeSheetNoteUpdate(): 'BeforeSheetNoteUpdate' {
return 'BeforeSheetNoteUpdate' as const;
}
get BeforeSheetNoteShow(): 'BeforeSheetNoteShow' {
return 'BeforeSheetNoteShow';
override get BeforeSheetNoteShow(): 'BeforeSheetNoteShow' {
return 'BeforeSheetNoteShow' as const;
}
get BeforeSheetNoteHide(): 'BeforeSheetNoteHide' {
return 'BeforeSheetNoteHide';
override get BeforeSheetNoteHide(): 'BeforeSheetNoteHide' {
return 'BeforeSheetNoteHide' as const;
}
}
/**
* @ignore
*/
export interface ISheetNoteEventConfig {
export interface ISheetsNoteEventParamConfig {
SheetNoteAdd: ISheetNoteAddEventParams;
SheetNoteDelete: ISheetNoteDeleteEventParams;
SheetNoteUpdate: ISheetNoteUpdateEventParams;
@@ -303,9 +303,9 @@ export interface ISheetNoteEventConfig {
BeforeSheetNoteHide: ISheetNoteHideEventParams;
}
FEventName.extend(FSheetNoteEvent);
FEventName.extend(FSheetsNoteEventNameMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FEventName extends ISheetNoteEvent {}
interface IEventParamConfig extends ISheetNoteEventConfig {}
interface FEventName extends IFSheetsNoteEventNameMixin {}
interface IEventParamConfig extends ISheetsNoteEventParamConfig {}
}
+4 -4
View File
@@ -22,7 +22,7 @@ import { FRange } from '@univerjs/sheets/facade';
/**
* @ignore
*/
export interface IFSheetsNoteRange {
export interface IFRangeSheetsNoteMixin {
/**
* Get the annotation of the top-left cell in the range
* @returns {Nullable<ISheetNote>} The annotation of the top-left cell in the range
@@ -74,7 +74,7 @@ export interface IFSheetsNoteRange {
deleteNote(): FRange;
}
export class FSheetsNoteRangeMixin extends FRange implements IFSheetsNoteRange {
export class FRangeSheetsNoteMixin extends FRange implements IFRangeSheetsNoteMixin {
override createOrUpdateNote(note: ISheetNote): FRange {
this._commandService.syncExecuteCommand(
UpdateNoteMutation.id,
@@ -110,8 +110,8 @@ export class FSheetsNoteRangeMixin extends FRange implements IFSheetsNoteRange {
}
}
FRange.extend(FSheetsNoteRangeMixin);
FRange.extend(FRangeSheetsNoteMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FRange extends IFSheetsNoteRange { }
interface FRange extends IFRangeSheetsNoteMixin { }
}
+33 -40
View File
@@ -16,19 +16,13 @@
import type { Injector } from '@univerjs/core';
import type { IRemoveNoteMutationParams, IUpdateNoteMutationParams } from '@univerjs/sheets-note';
import type { ISheetNoteAddEventParams, ISheetNoteDeleteEventParams, ISheetNoteHideEventParams, ISheetNoteShowEventParams, ISheetNoteUpdateEventParams } from './f-event';
import { CanceledError, ICommandService, IUniverInstanceService } from '@univerjs/core';
import { FUniver } from '@univerjs/core/facade';
import { getSheetCommandTarget, SheetsSelectionsService } from '@univerjs/sheets';
import { SheetDeleteNoteCommand, SheetsNoteModel, SheetToggleNotePopupCommand, SheetUpdateNoteCommand } from '@univerjs/sheets-note';
/**
* @ignore
*/
export interface IFUniverSheetNoteMixin {
// Add any note-specific methods here if needed
}
export class FUniverSheetNoteMixin extends FUniver implements IFUniverSheetNoteMixin {
export class FUniverSheetsNoteMixin extends FUniver {
// eslint-disable-next-line max-lines-per-function
override _initialize(injector: Injector): void {
const commandService = injector.get(ICommandService);
@@ -46,14 +40,14 @@ export class FUniverSheetNoteMixin extends FUniver implements IFUniverSheetNoteM
return;
}
const { workbook, worksheet } = target;
this.fireEvent(this.Event.SheetNoteAdd, {
const eventParams: ISheetNoteAddEventParams = {
workbook,
worksheet,
row: newNote.row,
col: newNote.col,
note: newNote,
});
};
this.fireEvent(this.Event.SheetNoteAdd, eventParams);
}
});
}
@@ -73,14 +67,14 @@ export class FUniverSheetNoteMixin extends FUniver implements IFUniverSheetNoteM
return;
}
const { workbook, worksheet } = target;
this.fireEvent(this.Event.SheetNoteDelete, {
const eventParams: ISheetNoteDeleteEventParams = {
workbook,
worksheet,
row: oldNote.row,
col: oldNote.col,
oldNote,
});
};
this.fireEvent(this.Event.SheetNoteDelete, eventParams);
}
});
}
@@ -100,15 +94,15 @@ export class FUniverSheetNoteMixin extends FUniver implements IFUniverSheetNoteM
return;
}
const { workbook, worksheet } = target;
this.fireEvent(this.Event.SheetNoteUpdate, {
const eventParams: ISheetNoteUpdateEventParams = {
workbook,
worksheet,
row: newNote.row,
col: newNote.col,
note: newNote,
oldNote,
});
};
this.fireEvent(this.Event.SheetNoteUpdate, eventParams);
}
});
}
@@ -128,13 +122,13 @@ export class FUniverSheetNoteMixin extends FUniver implements IFUniverSheetNoteM
return;
}
const { workbook, worksheet } = target;
this.fireEvent(this.Event.SheetNoteShow, {
const eventParams: ISheetNoteShowEventParams = {
workbook,
worksheet,
row: newNote.row,
col: newNote.col,
});
};
this.fireEvent(this.Event.SheetNoteShow, eventParams);
}
});
}
@@ -154,13 +148,13 @@ export class FUniverSheetNoteMixin extends FUniver implements IFUniverSheetNoteM
return;
}
const { workbook, worksheet } = target;
this.fireEvent(this.Event.SheetNoteHide, {
const eventParams: ISheetNoteHideEventParams = {
workbook,
worksheet,
row: newNote.row,
col: newNote.col,
});
};
this.fireEvent(this.Event.SheetNoteHide, eventParams);
}
});
}
@@ -182,13 +176,14 @@ export class FUniverSheetNoteMixin extends FUniver implements IFUniverSheetNoteM
if (oldNote) return;
const { workbook, worksheet } = target;
const cancel = this.fireEvent(this.Event.BeforeSheetNoteAdd, {
const eventParams: ISheetNoteAddEventParams = {
workbook,
worksheet,
row,
col,
note,
});
};
const cancel = this.fireEvent(this.Event.BeforeSheetNoteAdd, eventParams);
if (cancel) {
throw new CanceledError();
}
@@ -211,13 +206,14 @@ export class FUniverSheetNoteMixin extends FUniver implements IFUniverSheetNoteM
if (!oldNote) return;
const { workbook, worksheet } = target;
const cancel = this.fireEvent(this.Event.BeforeSheetNoteDelete, {
const eventParams: ISheetNoteDeleteEventParams = {
workbook,
worksheet,
row,
col,
oldNote,
});
};
const cancel = this.fireEvent(this.Event.BeforeSheetNoteDelete, eventParams);
if (cancel) {
throw new CanceledError();
@@ -242,14 +238,15 @@ export class FUniverSheetNoteMixin extends FUniver implements IFUniverSheetNoteM
if (!oldNote) return;
const { workbook, worksheet } = target;
const cancel = this.fireEvent(this.Event.BeforeSheetNoteUpdate, {
const eventParams: ISheetNoteUpdateEventParams = {
workbook,
worksheet,
row,
col,
note,
oldNote,
});
};
const cancel = this.fireEvent(this.Event.BeforeSheetNoteUpdate, eventParams);
if (cancel) {
throw new CanceledError();
}
@@ -280,13 +277,13 @@ export class FUniverSheetNoteMixin extends FUniver implements IFUniverSheetNoteM
const { actualColumn, actualRow } = selection.primary;
const note = sheetsNoteModel.getNote(unitId, subUnitId, { row: actualRow, col: actualColumn });
if (!note || note.show) return;
const cancel = this.fireEvent(this.Event.BeforeSheetNoteShow, {
const eventParams: ISheetNoteShowEventParams = {
workbook,
worksheet,
row: actualRow,
col: actualColumn,
});
};
const cancel = this.fireEvent(this.Event.BeforeSheetNoteShow, eventParams);
if (cancel) {
throw new CanceledError();
}
@@ -317,13 +314,13 @@ export class FUniverSheetNoteMixin extends FUniver implements IFUniverSheetNoteM
const { actualColumn, actualRow } = selection.primary;
const note = sheetsNoteModel.getNote(unitId, subUnitId, { row: actualRow, col: actualColumn });
if (!note || !note.show) return;
const cancel = this.fireEvent(this.Event.BeforeSheetNoteHide, {
const eventParams: ISheetNoteHideEventParams = {
workbook,
worksheet,
row: actualRow,
col: actualColumn,
});
};
const cancel = this.fireEvent(this.Event.BeforeSheetNoteHide, eventParams);
if (cancel) {
throw new CanceledError();
}
@@ -334,8 +331,4 @@ export class FUniverSheetNoteMixin extends FUniver implements IFUniverSheetNoteM
}
}
FUniver.extend(FUniverSheetNoteMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FUniver extends IFUniverSheetNoteMixin {}
}
FUniver.extend(FUniverSheetsNoteMixin);
@@ -21,7 +21,7 @@ import { FWorksheet } from '@univerjs/sheets/facade';
/**
* @ignore
*/
export interface IFSheetsNoteWorksheet {
export interface IFWorksheetNoteMixin {
/**
* Get all annotations in the worksheet
* @returns {ISheetNote[]} An array of all annotations in the worksheet
@@ -41,7 +41,7 @@ export interface IFSheetsNoteWorksheet {
getNotes(): ISheetNote[];
}
export class FSheetsNoteWorksheet extends FWorksheet implements IFSheetsNoteWorksheet {
export class FWorksheetNoteMixin extends FWorksheet implements IFWorksheetNoteMixin {
override getNotes(): ISheetNote[] {
const model = this._injector.get(SheetsNoteModel);
const notes = model.getSheetNotes(this.getWorkbook().getUnitId(), this.getSheetId());
@@ -52,8 +52,8 @@ export class FSheetsNoteWorksheet extends FWorksheet implements IFSheetsNoteWork
}
}
FWorksheet.extend(FSheetsNoteWorksheet);
FWorksheet.extend(FWorksheetNoteMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FWorksheet extends IFSheetsNoteWorksheet { }
interface FWorksheet extends IFWorksheetNoteMixin { }
}
+2 -2
View File
@@ -95,7 +95,7 @@ export interface IFRangeSheetsNumfmtMixin {
getNumberFormats(): string[][];
}
export class FRangeLegacy extends FRange implements IFRangeSheetsNumfmtMixin {
export class FRangeSheetsNumfmtMixin extends FRange implements IFRangeSheetsNumfmtMixin {
override setNumberFormat(pattern: string): FRange {
// TODO@Gggpound: the API should support other types of parameters
const values: ISetNumfmtCommandParams['values'] = [];
@@ -149,7 +149,7 @@ export class FRangeLegacy extends FRange implements IFRangeSheetsNumfmtMixin {
}
}
FRange.extend(FRangeLegacy);
FRange.extend(FRangeSheetsNumfmtMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FRange extends IFRangeSheetsNumfmtMixin { }
@@ -18,7 +18,7 @@ import type { INumfmtLocaleTag } from '@univerjs/core';
import { SheetsNumfmtCellContentController } from '@univerjs/sheets-numfmt';
import { FWorkbook } from '@univerjs/sheets/facade';
export interface IFWorkbookNumfmtMixin {
export interface IFWorkbookSheetsNumfmtMixin {
/**
* Set the locale for number formatting.
* @param {INumfmtLocaleTag} locale zh_CN,zh_TW,zh_HK,ja,ko,th,cs,da,nl,en,en_AU,en_CA,en_GB,en_IE,fi,fr,fr_CA,fr_CH,de,de_CH,el,hu,is,id,it,it_CH,nb,no,pl,pt,pt_BR,ru,sk,es,es_AR,es_BO,es_CL,es_CO,es_EC,es_MX,es_PY,es_UY,es_VE,sv,tr,cy,az,be,bg,ca,fil,gu,he,hr,hy,ka,kk,kn,lt,lv,ml,mn,mr,my,pa,ro,sl,sr,ta,te,uk,vi,ar,bn,hi
@@ -42,15 +42,15 @@ export interface IFWorkbookNumfmtMixin {
*/
setNumfmtLocal(locale: INumfmtLocaleTag): FWorkbook;
}
export class FWorkbookLegacy extends FWorkbook implements IFWorkbookNumfmtMixin {
export class FWorkbookSheetsNumfmtMixin extends FWorkbook implements IFWorkbookSheetsNumfmtMixin {
override setNumfmtLocal(locale: INumfmtLocaleTag): FWorkbook {
const sheetsNumfmtCellContentController = this._injector.get(SheetsNumfmtCellContentController);
sheetsNumfmtCellContentController.setNumfmtLocal(locale);
return this;
}
}
FWorkbook.extend(FWorkbookLegacy);
FWorkbook.extend(FWorkbookSheetsNumfmtMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FWorkbook extends IFWorkbookNumfmtMixin { }
interface FWorkbook extends IFWorkbookSheetsNumfmtMixin { }
}
+10 -92
View File
@@ -14,19 +14,14 @@
* limitations under the License.
*/
import type { ICommandInfo, Injector } from '@univerjs/core';
import type { IEventBase } from '@univerjs/core/facade';
import type { ISortRangeCommandParams } from '@univerjs/sheets-sort';
import type { FRange, FWorkbook, FWorksheet } from '@univerjs/sheets/facade';
import { ICommandService } from '@univerjs/core';
import { FEventName, FUniver } from '@univerjs/core/facade';
import { SortRangeCommand, SortType } from '@univerjs/sheets-sort';
import { FSheetEventName } from '@univerjs/sheets/facade';
import { FEventName } from '@univerjs/core/facade';
/**
* @ignore
*/
export interface IFSheetSortEventMixin {
export interface IFSheetsSortEventNameMixin {
/**
* This event will be emitted when a range on a worksheet is sorted.
* @see {@link ISheetRangeSortParams}
@@ -61,7 +56,7 @@ export interface IFSheetSortEventMixin {
SheetBeforeRangeSort: 'SheetBeforeRangeSort';
}
export class FSheetSortEventName implements IFSheetSortEventMixin {
export class FSheetsSortEventNameMixin implements IFSheetsSortEventNameMixin {
get SheetRangeSorted(): 'SheetRangeSorted' { return 'SheetRangeSorted' as const; }
get SheetBeforeRangeSort(): 'SheetBeforeRangeSort' { return 'SheetBeforeRangeSort' as const; }
}
@@ -71,7 +66,7 @@ interface ISortColumn {
ascending: boolean;
}
export interface ISheetRangeSortParams extends IEventBase {
export interface ISheetsRangeSortEventParams extends IEventBase {
workbook: FWorkbook;
worksheet: FWorksheet;
range: FRange;
@@ -81,91 +76,14 @@ export interface ISheetRangeSortParams extends IEventBase {
/**
* @ignore
*/
export interface ISheetRangeSortEventParamConfig {
SheetBeforeRangeSort: ISheetRangeSortParams;
SheetRangeSorted: ISheetRangeSortParams;
export interface ISheetsSortEventParamConfig {
SheetBeforeRangeSort: ISheetsRangeSortEventParams;
SheetRangeSorted: ISheetsRangeSortEventParams;
}
FEventName.extend(FSheetEventName);
class FUniverSheetsSortEventMixin extends FUniver {
/**
* @ignore
*/
override _initialize(injector: Injector): void {
const commandService = injector.get(ICommandService);
this.disposeWithMe(
this.registerEventHandler(
this.Event.SheetBeforeRangeSort,
() => commandService.beforeCommandExecuted((commandInfo) => {
if (commandInfo.id !== SortRangeCommand.id) return;
this._beforeRangeSort(commandInfo as Readonly<ICommandInfo<ISortRangeCommandParams>>);
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.SheetRangeSorted,
() => commandService.onCommandExecuted((commandInfo) => {
if (commandInfo.id !== SortRangeCommand.id) return;
this._onRangeSorted(commandInfo as Readonly<ICommandInfo<ISortRangeCommandParams>>);
})
)
);
}
private _beforeRangeSort(commandInfo: Readonly<ICommandInfo<ISortRangeCommandParams>>): void {
const params = commandInfo.params!;
const fWorkbook = this.getUniverSheet(params.unitId)!;
const fWorksheet = fWorkbook.getSheetBySheetId(params.subUnitId)!;
const { startColumn, endColumn, startRow, endRow } = params.range;
const fRange = fWorksheet.getRange(startRow, startColumn, endRow - startRow + 1, endColumn - startColumn + 1);
const eventParams: ISheetRangeSortParams = {
workbook: fWorkbook,
worksheet: fWorksheet,
range: fRange,
sortColumn: params.orderRules.map((rule) => ({
column: rule.colIndex - startColumn,
ascending: rule.type === SortType.ASC,
})),
};
this.fireEvent(this.Event.SheetBeforeRangeSort, eventParams);
if (eventParams.cancel) {
throw new Error('SortRangeCommand canceled.');
}
}
private _onRangeSorted(commandInfo: Readonly<ICommandInfo<ISortRangeCommandParams>>): void {
const params = commandInfo.params!;
const fWorkbook = this.getUniverSheet(params.unitId)!;
const fWorksheet = fWorkbook.getSheetBySheetId(params.subUnitId)!;
const { startColumn, endColumn, startRow, endRow } = params.range;
const fRange = fWorksheet.getRange(startRow, startColumn, endRow - startRow + 1, endColumn - startColumn + 1);
const eventParams: ISheetRangeSortParams = {
workbook: fWorkbook,
worksheet: fWorksheet,
range: fRange,
sortColumn: params.orderRules.map((rule) => ({
column: rule.colIndex - startColumn,
ascending: rule.type === SortType.ASC,
})),
};
this.fireEvent(this.Event.SheetRangeSorted, eventParams);
if (eventParams.cancel) {
throw new Error('SortRangeCommand canceled.');
}
}
}
FUniver.extend(FUniverSheetsSortEventMixin);
FEventName.extend(FSheetSortEventName);
FEventName.extend(FSheetsSortEventNameMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FEventName extends IFSheetSortEventMixin { }
interface IEventParamConfig extends ISheetRangeSortEventParamConfig { }
interface FEventName extends IFSheetsSortEventNameMixin { }
interface IEventParamConfig extends ISheetsSortEventParamConfig { }
}
+4 -4
View File
@@ -23,7 +23,7 @@ export type SortColumnSpec = { column: number; ascending: boolean } | number;
/**
* @ignore
*/
export interface IFRangeSort {
export interface IFRangeSheetsSortMixin {
/**
* Sorts the cells in the given range, by column(s) and order specified.
* @param {SortColumnSpec | SortColumnSpec[]} column The column index with order or an array of column indexes with order. The range first column index is 0.
@@ -47,7 +47,7 @@ export interface IFRangeSort {
sort(column: SortColumnSpec | SortColumnSpec[]): FRange;
}
export class FRangeSort extends FRange implements IFRangeSort {
export class FRangeSheetsSortMixin extends FRange implements IFRangeSheetsSortMixin {
override sort(column: SortColumnSpec | SortColumnSpec[]): FRange {
const columnBase = this._range.startColumn;
const columns = Array.isArray(column) ? column : [column];
@@ -72,8 +72,8 @@ export class FRangeSort extends FRange implements IFRangeSort {
}
}
FRange.extend(FRangeSort);
FRange.extend(FRangeSheetsSortMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FRange extends IFRangeSort {}
interface FRange extends IFRangeSheetsSortMixin {}
}
@@ -0,0 +1,97 @@
/**
* 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.
*/
import type { ICommandInfo, Injector } from '@univerjs/core';
import type { ISortRangeCommandParams } from '@univerjs/sheets-sort';
import type { ISheetsRangeSortEventParams } from './f-event';
import { ICommandService } from '@univerjs/core';
import { FUniver } from '@univerjs/core/facade';
import { SortRangeCommand, SortType } from '@univerjs/sheets-sort';
export class FUniverSheetsSortMixin extends FUniver {
/**
* @ignore
*/
override _initialize(injector: Injector): void {
const commandService = injector.get(ICommandService);
this.disposeWithMe(
this.registerEventHandler(
this.Event.SheetBeforeRangeSort,
() => commandService.beforeCommandExecuted((commandInfo) => {
if (commandInfo.id !== SortRangeCommand.id) return;
this._beforeRangeSort(commandInfo as Readonly<ICommandInfo<ISortRangeCommandParams>>);
})
)
);
this.disposeWithMe(
this.registerEventHandler(
this.Event.SheetRangeSorted,
() => commandService.onCommandExecuted((commandInfo) => {
if (commandInfo.id !== SortRangeCommand.id) return;
this._onRangeSorted(commandInfo as Readonly<ICommandInfo<ISortRangeCommandParams>>);
})
)
);
}
private _beforeRangeSort(commandInfo: Readonly<ICommandInfo<ISortRangeCommandParams>>): void {
const params = commandInfo.params!;
const fWorkbook = this.getUniverSheet(params.unitId)!;
const fWorksheet = fWorkbook.getSheetBySheetId(params.subUnitId)!;
const { startColumn, endColumn, startRow, endRow } = params.range;
const fRange = fWorksheet.getRange(startRow, startColumn, endRow - startRow + 1, endColumn - startColumn + 1);
const eventParams: ISheetsRangeSortEventParams = {
workbook: fWorkbook,
worksheet: fWorksheet,
range: fRange,
sortColumn: params.orderRules.map((rule) => ({
column: rule.colIndex - startColumn,
ascending: rule.type === SortType.ASC,
})),
};
this.fireEvent(this.Event.SheetBeforeRangeSort, eventParams);
if (eventParams.cancel) {
throw new Error('SortRangeCommand canceled.');
}
}
private _onRangeSorted(commandInfo: Readonly<ICommandInfo<ISortRangeCommandParams>>): void {
const params = commandInfo.params!;
const fWorkbook = this.getUniverSheet(params.unitId)!;
const fWorksheet = fWorkbook.getSheetBySheetId(params.subUnitId)!;
const { startColumn, endColumn, startRow, endRow } = params.range;
const fRange = fWorksheet.getRange(startRow, startColumn, endRow - startRow + 1, endColumn - startColumn + 1);
const eventParams: ISheetsRangeSortEventParams = {
workbook: fWorkbook,
worksheet: fWorksheet,
range: fRange,
sortColumn: params.orderRules.map((rule) => ({
column: rule.colIndex - startColumn,
ascending: rule.type === SortType.ASC,
})),
};
this.fireEvent(this.Event.SheetRangeSorted, eventParams);
if (eventParams.cancel) {
throw new Error('SortRangeCommand canceled.');
}
}
}
FUniver.extend(FUniverSheetsSortMixin);
@@ -23,7 +23,7 @@ import { FWorksheet } from '@univerjs/sheets/facade';
/**
* @ignore
*/
export interface IFWorksheetSort {
export interface IFWorksheetSortMixin {
/**
* Sort the worksheet by the specified column.
* @param {number} colIndex The column index to sort by.
@@ -44,7 +44,7 @@ export interface IFWorksheetSort {
sort(colIndex: number, asc?: boolean): FWorksheet;
}
export class FWorksheetSort extends FWorksheet implements IFWorksheetSort {
export class FWorksheetSortMixin extends FWorksheet implements IFWorksheetSortMixin {
override sort(colIndex: number, asc = true): FWorksheet {
const orderRules: IOrderRule[] = [{
colIndex,
@@ -69,8 +69,8 @@ export class FWorksheetSort extends FWorksheet implements IFWorksheetSort {
}
}
FWorksheet.extend(FWorksheetSort);
FWorksheet.extend(FWorksheetSortMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FWorksheet extends IFWorksheetSort {}
interface FWorksheet extends IFWorksheetSortMixin {}
}
+2
View File
@@ -14,10 +14,12 @@
* limitations under the License.
*/
import './f-univer';
import './f-range';
import './f-worksheet';
import './f-event';
export type * from './f-event';
export type * from './f-range';
export type * from './f-univer';
export type * from './f-worksheet';
+4 -4
View File
@@ -20,7 +20,7 @@ import { TableColumnFilterTypeEnum, TableConditionTypeEnum, TableDateCompareType
/**
* @ignore
*/
export interface ITableEnumMixin {
export interface IFSheetsTableEnumMixin {
TableColumnFilterTypeEnum: typeof TableColumnFilterTypeEnum;
TableConditionTypeEnum: typeof TableConditionTypeEnum;
TableNumberCompareTypeEnum: typeof TableNumberCompareTypeEnum;
@@ -28,7 +28,7 @@ export interface ITableEnumMixin {
TableDateCompareTypeEnum: typeof TableDateCompareTypeEnum;
}
export class TableEnum extends FEnum implements ITableEnumMixin {
export class FSheetsTableEnumMixin extends FEnum implements IFSheetsTableEnumMixin {
override get TableColumnFilterTypeEnum(): typeof TableColumnFilterTypeEnum {
return TableColumnFilterTypeEnum;
};
@@ -50,8 +50,8 @@ export class TableEnum extends FEnum implements ITableEnumMixin {
}
}
FEnum.extend(TableEnum);
FEnum.extend(FSheetsTableEnumMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FEnum extends ITableEnumMixin { }
interface FEnum extends IFSheetsTableEnumMixin { }
}
@@ -40,7 +40,7 @@ import { FWorksheet } from '@univerjs/sheets/facade';
/**
* @ignore
*/
export interface IFWorkSheetTableMixin {
export interface IFWorksheetTableMixin {
/**
* Add a table to the worksheet
* @param {string} tableName The table name
@@ -344,7 +344,7 @@ export interface IFWorkSheetTableMixin {
addTableTheme(tableId: string, themeStyleJSON: IRangeThemeStyleJSON): Promise<boolean>;
}
export class FWorkSheetTableMixin extends FWorksheet implements IFWorkSheetTableMixin {
export class FWorksheetTableMixin extends FWorksheet implements IFWorksheetTableMixin {
override addTable(tableName: string, rangeInfo: ITableRange, tableId?: string, options?: ITableOptions): Promise<boolean> | boolean {
const subUnitId = this.getSheetId();
const workbook = this.getWorkbook();
@@ -469,8 +469,8 @@ export class FWorkSheetTableMixin extends FWorksheet implements IFWorkSheetTable
}
}
FWorksheet.extend(FWorkSheetTableMixin);
FWorksheet.extend(FWorksheetTableMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FWorksheet extends IFWorkSheetTableMixin { }
interface FWorksheet extends IFWorksheetTableMixin { }
}
@@ -15,9 +15,9 @@
*/
import { describe, expect, it, vi } from 'vitest';
import { FWorkbookThreadCommentMixin } from '../f-workbook';
import { FWorkbookSheetsThreadCommentMixin } from '../f-workbook';
describe('FWorkbookThreadCommentMixin', () => {
describe('FWorkbookSheetsThreadCommentMixin', () => {
it('should lazily resolve the thread comment model and create workbook comment facades', async () => {
const rootComment = { id: 'comment-1' };
const deleteAsync = vi.fn(async () => true);
@@ -25,7 +25,7 @@ describe('FWorkbookThreadCommentMixin', () => {
const createInstance = vi.fn(() => ({ deleteAsync }));
const get = vi.fn(() => ({ getUnit }));
const instance = Object.create(FWorkbookThreadCommentMixin.prototype) as any;
const instance = Object.create(FWorkbookSheetsThreadCommentMixin.prototype) as any;
instance._injector = { get, createInstance };
instance._workbook = { getUnitId: () => 'unit-1' };
@@ -23,10 +23,10 @@ import { FEventName } from '@univerjs/core/facade';
/**
* @ignore
*/
interface ICommentEventMixin {
interface IFSheetsThreadCommentEventNameMixin {
/**
* Event fired after comment added
* @see {@link ISheetCommentAddEvent}
* @see {@link ISheetCommentAddEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.CommentAdded, (params) => {
@@ -41,7 +41,7 @@ interface ICommentEventMixin {
/**
* Event fired before comment added
* @see {@link IBeforeSheetCommentAddEvent}
* @see {@link IBeforeSheetCommentAddEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentAdd, (params) => {
@@ -59,7 +59,7 @@ interface ICommentEventMixin {
/**
* Event fired after comment updated
* @see {@link ISheetCommentUpdateEvent}
* @see {@link ISheetCommentUpdateEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.CommentUpdated, (params) => {
@@ -74,7 +74,7 @@ interface ICommentEventMixin {
/**
* Event fired before comment update
* @see {@link IBeforeSheetCommentUpdateEvent}
* @see {@link IBeforeSheetCommentUpdateEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentUpdate, (params) => {
@@ -92,7 +92,7 @@ interface ICommentEventMixin {
/**
* Event fired after comment deleted
* @see {@link ISheetCommentDeleteEvent}
* @see {@link ISheetCommentDeleteEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.CommentDeleted, (params) => {
@@ -107,7 +107,7 @@ interface ICommentEventMixin {
/**
* Event fired before comment delete
* @see {@link IBeforeSheetCommentDeleteEvent}
* @see {@link IBeforeSheetCommentDeleteEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentDelete, (params) => {
@@ -125,7 +125,7 @@ interface ICommentEventMixin {
/**
* Event fired after comment resolve
* @see {@link ISheetCommentResolveEvent}
* @see {@link ISheetCommentResolveEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.CommentResolved, (params) => {
@@ -140,7 +140,7 @@ interface ICommentEventMixin {
/**
* Event fired before comment resolve
* @see {@link ISheetCommentResolveEvent}
* @see {@link ISheetCommentResolveEventParams}
* @example
* ```ts
* const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentResolve, (params) => {
@@ -157,63 +157,49 @@ interface ICommentEventMixin {
readonly BeforeCommentResolve: 'BeforeCommentResolve';
}
const CommentEvent: ICommentEventMixin = {
CommentAdded: 'CommentAdded',
BeforeCommentAdd: 'BeforeCommentAdd',
CommentUpdated: 'CommentUpdated',
BeforeCommentUpdate: 'BeforeCommentUpdate',
CommentDeleted: 'CommentDeleted',
BeforeCommentDelete: 'BeforeCommentDelete',
CommentResolved: 'CommentResolved',
BeforeCommentResolve: 'BeforeCommentResolve',
} as const;
/**
* @ignore
*/
export class FCommentEvent extends FEventName {
export class FSheetsThreadCommentEventNameMixin extends FEventName implements IFSheetsThreadCommentEventNameMixin {
override get CommentAdded(): 'CommentAdded' {
return CommentEvent.CommentAdded;
return 'CommentAdded' as const;
}
override get BeforeCommentAdd(): 'BeforeCommentAdd' {
return CommentEvent.BeforeCommentAdd;
return 'BeforeCommentAdd' as const;
}
override get CommentUpdated(): 'CommentUpdated' {
return CommentEvent.CommentUpdated;
return 'CommentUpdated' as const;
}
override get BeforeCommentUpdate(): 'BeforeCommentUpdate' {
return CommentEvent.BeforeCommentUpdate;
return 'BeforeCommentUpdate' as const;
}
override get CommentDeleted(): 'CommentDeleted' {
return CommentEvent.CommentDeleted;
return 'CommentDeleted' as const;
}
override get BeforeCommentDelete(): 'BeforeCommentDelete' {
return CommentEvent.BeforeCommentDelete;
return 'BeforeCommentDelete' as const;
}
override get CommentResolved(): 'CommentResolved' {
return CommentEvent.CommentResolved;
return 'CommentResolved' as const;
}
override get BeforeCommentResolve(): 'BeforeCommentResolve' {
return CommentEvent.BeforeCommentResolve;
return 'BeforeCommentResolve' as const;
}
}
/**
* Event interface triggered after a comment is added to a sheet
* @interface ISheetCommentAddEvent
* @interface ISheetCommentAddEventParams
* @augments {IEventBase}
*/
export interface ISheetCommentAddEvent extends IEventBase {
export interface ISheetCommentAddEventParams extends IEventBase {
/** The workbook instance */
workbook: FWorkbook;
/** The worksheet where the comment is added */
@@ -228,10 +214,10 @@ export interface ISheetCommentAddEvent extends IEventBase {
/**
* Event interface triggered before a comment is added to a sheet
* @interface IBeforeSheetCommentAddEvent
* @interface IBeforeSheetCommentAddEventParams
* @augments {IEventBase}
*/
export interface IBeforeSheetCommentAddEvent extends IEventBase {
export interface IBeforeSheetCommentAddEventParams extends IEventBase {
/** The workbook instance */
workbook: FWorkbook;
/** The worksheet where the comment will be added */
@@ -246,10 +232,10 @@ export interface IBeforeSheetCommentAddEvent extends IEventBase {
/**
* Event interface triggered after a comment is updated in a sheet
* @interface ISheetCommentUpdateEvent
* @interface ISheetCommentUpdateEventParams
* @augments {IEventBase}
*/
export interface ISheetCommentUpdateEvent extends IEventBase {
export interface ISheetCommentUpdateEventParams extends IEventBase {
/** The workbook instance */
workbook: FWorkbook;
/** The worksheet containing the updated comment */
@@ -264,10 +250,10 @@ export interface ISheetCommentUpdateEvent extends IEventBase {
/**
* Event interface triggered before a comment is updated in a sheet
* @interface IBeforeSheetCommentUpdateEvent
* @interface IBeforeSheetCommentUpdateEventParams
* @augments {IEventBase}
*/
export interface IBeforeSheetCommentUpdateEvent extends IEventBase {
export interface IBeforeSheetCommentUpdateEventParams extends IEventBase {
/** The workbook instance */
workbook: FWorkbook;
/** The worksheet containing the comment */
@@ -284,10 +270,10 @@ export interface IBeforeSheetCommentUpdateEvent extends IEventBase {
/**
* Event interface triggered before a comment is deleted from a sheet
* @interface IBeforeSheetCommentDeleteEvent
* @interface IBeforeSheetCommentDeleteEventParams
* @augments {IEventBase}
*/
export interface IBeforeSheetCommentDeleteEvent extends IEventBase {
export interface IBeforeSheetCommentDeleteEventParams extends IEventBase {
/** The workbook instance */
workbook: FWorkbook;
/** The worksheet containing the comment */
@@ -302,10 +288,10 @@ export interface IBeforeSheetCommentDeleteEvent extends IEventBase {
/**
* Event interface triggered after a comment is deleted from a sheet
* @interface ISheetCommentDeleteEvent
* @interface ISheetCommentDeleteEventParams
* @augments {IEventBase}
*/
export interface ISheetCommentDeleteEvent extends IEventBase {
export interface ISheetCommentDeleteEventParams extends IEventBase {
/** The workbook instance */
workbook: FWorkbook;
/** The worksheet that contained the comment */
@@ -316,10 +302,10 @@ export interface ISheetCommentDeleteEvent extends IEventBase {
/**
* Event interface triggered when a comment's resolve status changes
* @interface ISheetCommentResolveEvent
* @interface ISheetCommentResolveEventParams
* @augments {IEventBase}
*/
export interface ISheetCommentResolveEvent extends IEventBase {
export interface ISheetCommentResolveEventParams extends IEventBase {
/** The workbook instance */
workbook: FWorkbook;
/** The worksheet containing the comment */
@@ -334,30 +320,27 @@ export interface ISheetCommentResolveEvent extends IEventBase {
resolved: boolean;
}
FEventName.extend(FCommentEvent);
/**
* @ignore
*/
export interface ISheetCommentEventConfig {
BeforeCommentAdd: IBeforeSheetCommentAddEvent;
CommentAdded: ISheetCommentAddEvent;
export interface ISheetsThreadCommentEventParamConfig {
BeforeCommentAdd: IBeforeSheetCommentAddEventParams;
CommentAdded: ISheetCommentAddEventParams;
BeforeCommentUpdate: IBeforeSheetCommentUpdateEvent;
CommentUpdated: ISheetCommentUpdateEvent;
BeforeCommentUpdate: IBeforeSheetCommentUpdateEventParams;
CommentUpdated: ISheetCommentUpdateEventParams;
BeforeCommentDelete: IBeforeSheetCommentDeleteEvent;
CommentDeleted: ISheetCommentDeleteEvent;
BeforeCommentDelete: IBeforeSheetCommentDeleteEventParams;
CommentDeleted: ISheetCommentDeleteEventParams;
BeforeCommentResolve: ISheetCommentResolveEvent;
CommentResolved: ISheetCommentResolveEvent;
BeforeCommentResolve: ISheetCommentResolveEventParams;
CommentResolved: ISheetCommentResolveEventParams;
}
FEventName.extend(FSheetsThreadCommentEventNameMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FEventName extends ICommentEventMixin {
}
interface FEventName extends IFSheetsThreadCommentEventNameMixin {}
interface IEventParamConfig extends ISheetCommentEventConfig {
}
interface IEventParamConfig extends ISheetsThreadCommentEventParamConfig { }
}
@@ -25,7 +25,7 @@ import { FTheadCommentBuilder, FThreadComment } from './f-thread-comment';
/**
* @ignore
*/
export interface IFRangeCommentMixin {
export interface IFRangeSheetsThreadCommentMixin {
/**
* Get the comment of the start cell in the current range.
* @returns {FThreadComment | null} The comment of the start cell in the current range. If the cell does not have a comment, return `null`.
@@ -115,7 +115,7 @@ export interface IFRangeCommentMixin {
/**
* @ignore
*/
export class FRangeCommentMixin extends FRange implements IFRangeCommentMixin {
export class FRangeSheetsThreadCommentMixin extends FRange implements IFRangeSheetsThreadCommentMixin {
override getComment(): Nullable<FThreadComment> {
const injector = this._injector;
const sheetsTheadCommentModel = injector.get(SheetsThreadCommentModel);
@@ -221,8 +221,8 @@ export class FRangeCommentMixin extends FRange implements IFRangeCommentMixin {
}
}
FRange.extend(FRangeCommentMixin);
FRange.extend(FRangeSheetsThreadCommentMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FRange extends IFRangeCommentMixin {}
interface FRange extends IFRangeSheetsThreadCommentMixin { }
}
@@ -14,10 +14,18 @@
* limitations under the License.
*/
import type { IDisposable, Injector } from '@univerjs/core';
import type { Injector } from '@univerjs/core';
import type { FWorkbook, FWorksheet } from '@univerjs/sheets/facade';
import type { IAddCommentCommandParams, IDeleteCommentCommandParams, IResolveCommentCommandParams, IThreadComment, IUpdateCommentCommandParams } from '@univerjs/thread-comment';
import type { IBeforeSheetCommentAddEvent, IBeforeSheetCommentDeleteEvent, IBeforeSheetCommentUpdateEvent, ISheetCommentAddEvent, ISheetCommentDeleteEvent, ISheetCommentResolveEvent, ISheetCommentUpdateEvent } from './f-event';
import type {
IBeforeSheetCommentAddEventParams,
IBeforeSheetCommentDeleteEventParams,
IBeforeSheetCommentUpdateEventParams,
ISheetCommentAddEventParams,
ISheetCommentDeleteEventParams,
ISheetCommentResolveEventParams,
ISheetCommentUpdateEventParams,
} from './f-event';
import { CanceledError, ICommandService, RichTextValue } from '@univerjs/core';
import { FUniver } from '@univerjs/core/facade';
import { deserializeRangeWithSheet } from '@univerjs/engine-formula';
@@ -27,27 +35,7 @@ import { FTheadCommentBuilder, FTheadCommentItem } from './f-thread-comment';
/**
* @ignore
*/
export interface IFUniverCommentMixin {
/**
* @deprecated use `univerAPI.addEvent(univerAPI.Event.CommentAdded, (params) => {})` as instead
*/
onCommentAdded(callback: (event: ISheetCommentAddEvent) => void): IDisposable;
/**
* @deprecated use `univerAPI.addEvent(univerAPI.Event.CommentUpdated, (params) => {})` as instead
*/
onCommentUpdated(callback: (event: ISheetCommentUpdateEvent) => void): IDisposable;
/**
* @deprecated use `univerAPI.addEvent(univerAPI.Event.CommentDeleted, (params) => {})` as instead
*/
onCommentDeleted(callback: (event: ISheetCommentDeleteEvent) => void): IDisposable;
/**
* @deprecated use `univerAPI.addEvent(univerAPI.Event.CommentResolved, (params) => {})` as instead
*/
onCommentResolved(callback: (event: ISheetCommentResolveEvent) => void): IDisposable;
export interface IFUniverSheetsThreadCommentMixin {
/**
* Create a new thread comment
* @returns {FTheadCommentBuilder} The thead comment builder
@@ -76,7 +64,7 @@ export interface IFUniverCommentMixin {
/**
* @ignore
*/
export class FUniverCommentMixin extends FUniver implements IFUniverCommentMixin {
export class FUniverSheetsThreadCommentMixin extends FUniver implements IFUniverSheetsThreadCommentMixin {
private _getTargetSheet(params: { unitId?: string; subUnitId?: string } = {}): {
workbook: FWorkbook;
worksheet: FWorksheet;
@@ -109,16 +97,16 @@ export class FUniverCommentMixin extends FUniver implements IFUniverCommentMixin
const { workbook, worksheet } = target;
const { comment } = commandInfo.params as IAddCommentCommandParams;
const threadComment = worksheet.getCommentById(comment.id);
if (!threadComment) return;
if (threadComment) {
this.fireEvent(this.Event.CommentAdded, {
workbook,
worksheet,
row: threadComment.getRange()?.getRow() ?? 0,
col: threadComment.getRange()?.getColumn() ?? 0,
comment: threadComment,
});
}
const eventParams: ISheetCommentAddEventParams = {
workbook,
worksheet,
row: threadComment.getRange()?.getRow() ?? 0,
col: threadComment.getRange()?.getColumn() ?? 0,
comment: threadComment,
};
this.fireEvent(this.Event.CommentAdded, eventParams);
})
)
);
@@ -135,16 +123,16 @@ export class FUniverCommentMixin extends FUniver implements IFUniverCommentMixin
const { workbook, worksheet } = target;
const { payload } = commandInfo.params as IUpdateCommentCommandParams;
const threadComment = worksheet.getCommentById(payload.commentId);
if (!threadComment) return;
if (threadComment) {
this.fireEvent(this.Event.CommentUpdated, {
workbook,
worksheet,
row: threadComment.getRange()?.getRow() ?? 0,
col: threadComment.getRange()?.getColumn() ?? 0,
comment: threadComment,
});
}
const eventParams: ISheetCommentUpdateEventParams = {
workbook,
worksheet,
row: threadComment.getRange()?.getRow() ?? 0,
col: threadComment.getRange()?.getColumn() ?? 0,
comment: threadComment,
};
this.fireEvent(this.Event.CommentUpdated, eventParams);
})
)
);
@@ -161,11 +149,12 @@ export class FUniverCommentMixin extends FUniver implements IFUniverCommentMixin
const { workbook, worksheet } = target;
const { commentId } = commandInfo.params as IDeleteCommentCommandParams;
this.fireEvent(this.Event.CommentDeleted, {
const eventParams: ISheetCommentDeleteEventParams = {
workbook,
worksheet,
commentId,
});
};
this.fireEvent(this.Event.CommentDeleted, eventParams);
})
)
);
@@ -182,17 +171,17 @@ export class FUniverCommentMixin extends FUniver implements IFUniverCommentMixin
const { workbook, worksheet } = target;
const { commentId, resolved } = commandInfo.params as IResolveCommentCommandParams;
const threadComment = worksheet.getCommentById(commentId);
if (!threadComment) return;
if (threadComment) {
this.fireEvent(this.Event.CommentResolved, {
workbook,
worksheet,
row: threadComment.getRange()?.getRow() ?? 0,
col: threadComment.getRange()?.getColumn() ?? 0,
comment: threadComment,
resolved,
});
}
const eventParams: ISheetCommentResolveEventParams = {
workbook,
worksheet,
row: threadComment.getRange()?.getRow() ?? 0,
col: threadComment.getRange()?.getColumn() ?? 0,
comment: threadComment,
resolved,
};
this.fireEvent(this.Event.CommentResolved, eventParams);
})
)
);
@@ -211,14 +200,13 @@ export class FUniverCommentMixin extends FUniver implements IFUniverCommentMixin
const { comment } = commandInfo.params as IAddCommentCommandParams;
const { range } = deserializeRangeWithSheet(comment.ref);
const eventParams: IBeforeSheetCommentAddEvent = {
const eventParams: IBeforeSheetCommentAddEventParams = {
workbook,
worksheet,
row: range.startRow,
col: range.startColumn,
comment: FTheadCommentItem.create(comment),
};
this.fireEvent(this.Event.BeforeCommentAdd, eventParams);
if (eventParams.cancel) {
throw new CanceledError();
@@ -239,20 +227,19 @@ export class FUniverCommentMixin extends FUniver implements IFUniverCommentMixin
const { workbook, worksheet } = target;
const { payload } = commandInfo.params as IUpdateCommentCommandParams;
const threadComment = worksheet.getCommentById(payload.commentId);
if (!threadComment) return;
if (threadComment) {
const eventParams: IBeforeSheetCommentUpdateEvent = {
workbook,
worksheet,
row: threadComment.getRange()?.getRow() ?? 0,
col: threadComment.getRange()?.getColumn() ?? 0,
comment: threadComment,
newContent: RichTextValue.createByBody(payload.text),
};
this.fireEvent(this.Event.BeforeCommentUpdate, eventParams);
if (eventParams.cancel) {
throw new CanceledError();
}
const eventParams: IBeforeSheetCommentUpdateEventParams = {
workbook,
worksheet,
row: threadComment.getRange()?.getRow() ?? 0,
col: threadComment.getRange()?.getColumn() ?? 0,
comment: threadComment,
newContent: RichTextValue.createByBody(payload.text),
};
this.fireEvent(this.Event.BeforeCommentUpdate, eventParams);
if (eventParams.cancel) {
throw new CanceledError();
}
})
)
@@ -270,19 +257,18 @@ export class FUniverCommentMixin extends FUniver implements IFUniverCommentMixin
const { workbook, worksheet } = target;
const { commentId } = commandInfo.params as IDeleteCommentCommandParams;
const threadComment = worksheet.getCommentById(commentId);
if (!threadComment) return;
if (threadComment) {
const eventParams: IBeforeSheetCommentDeleteEvent = {
workbook,
worksheet,
row: threadComment.getRange()?.getRow() ?? 0,
col: threadComment.getRange()?.getColumn() ?? 0,
comment: threadComment,
};
this.fireEvent(this.Event.BeforeCommentDelete, eventParams);
if (eventParams.cancel) {
throw new CanceledError();
}
const eventParams: IBeforeSheetCommentDeleteEventParams = {
workbook,
worksheet,
row: threadComment.getRange()?.getRow() ?? 0,
col: threadComment.getRange()?.getColumn() ?? 0,
comment: threadComment,
};
this.fireEvent(this.Event.BeforeCommentDelete, eventParams);
if (eventParams.cancel) {
throw new CanceledError();
}
})
)
@@ -300,20 +286,19 @@ export class FUniverCommentMixin extends FUniver implements IFUniverCommentMixin
const { workbook, worksheet } = target;
const { commentId, resolved } = commandInfo.params as IResolveCommentCommandParams;
const threadComment = worksheet.getCommentById(commentId);
if (!threadComment) return;
if (threadComment) {
const eventParams: ISheetCommentResolveEvent = {
workbook,
worksheet,
row: threadComment.getRange()!.getRow() ?? 0,
col: threadComment.getRange()!.getColumn() ?? 0,
comment: threadComment,
resolved,
};
this.fireEvent(this.Event.BeforeCommentResolve, eventParams);
if (eventParams.cancel) {
throw new CanceledError();
}
const eventParams: ISheetCommentResolveEventParams = {
workbook,
worksheet,
row: threadComment.getRange()!.getRow() ?? 0,
col: threadComment.getRange()!.getColumn() ?? 0,
comment: threadComment,
resolved,
};
this.fireEvent(this.Event.BeforeCommentResolve, eventParams);
if (eventParams.cancel) {
throw new CanceledError();
}
})
)
@@ -328,9 +313,9 @@ export class FUniverCommentMixin extends FUniver implements IFUniverCommentMixin
}
}
FUniver.extend(FUniverCommentMixin);
FUniver.extend(FUniverSheetsThreadCommentMixin);
declare module '@univerjs/core/facade' {
// eslint-disable-next-line ts/naming-convention
interface FUniver extends IFUniverCommentMixin {}
interface FUniver extends IFUniverSheetsThreadCommentMixin {}
}
@@ -28,7 +28,7 @@ type IUpdateCommandParams = any;
/**
* @ignore
*/
export interface IFWorkbookThreadCommentMixin {
export interface IFWorkbookSheetsThreadCommentMixin {
/**
* Get all comments in the current workbook
* @returns {FThreadComment[]} All comments in the current workbook
@@ -97,7 +97,7 @@ export interface IFWorkbookThreadCommentMixin {
/**
* @ignore
*/
export class FWorkbookThreadCommentMixin extends FWorkbook implements IFWorkbookThreadCommentMixin {
export class FWorkbookSheetsThreadCommentMixin extends FWorkbook implements IFWorkbookSheetsThreadCommentMixin {
declare _threadCommentModel: ThreadCommentModel;
/**
@@ -187,8 +187,8 @@ export class FWorkbookThreadCommentMixin extends FWorkbook implements IFWorkbook
}
}
FWorkbook.extend(FWorkbookThreadCommentMixin);
FWorkbook.extend(FWorkbookSheetsThreadCommentMixin);
declare module '@univerjs/sheets/facade' {
// eslint-disable-next-line ts/naming-convention
interface FWorkbook extends IFWorkbookThreadCommentMixin {}
interface FWorkbook extends IFWorkbookSheetsThreadCommentMixin {}
}
@@ -41,6 +41,7 @@ import {
RemoveWorksheetMergeMutation,
SetRangeValuesMutation,
SetSelectionsOperation,
SheetSkeletonService,
SheetsSelectionsService,
} from '@univerjs/sheets';
import { IPlatformService, IShortcutService, PlatformService, ShortcutService } from '@univerjs/ui';
@@ -287,6 +288,7 @@ describe('Test auto fill rules in controller', () => {
const testBed = createCommandTestBed(TEST_WORKBOOK_DATA, [
[DocSelectionManagerService],
[ISheetSelectionRenderService, { useClass: SheetSelectionRenderService }],
[SheetSkeletonService],
[IAutoFillService, { useClass: AutoFillService }],
[IShortcutService, { useClass: ShortcutService }],
[IPlatformService, { useClass: PlatformService }],
@@ -15,10 +15,9 @@
*/
import type { IWorkbookData } from '@univerjs/core';
import { Disposable, DisposableCollection, ICommandService, LocaleType, UniverInstanceType } from '@univerjs/core';
import { Disposable, DisposableCollection, ICommandService, IUniverInstanceService, LocaleType, UniverInstanceType } from '@univerjs/core';
import { IRenderManagerService, RenderManagerService } from '@univerjs/engine-render';
import { CancelFrozenCommand, SetFrozenMutation, SetSelectionsOperation, SheetSkeletonService } from '@univerjs/sheets';
import { BehaviorSubject } from 'rxjs';
import { SheetScrollManagerService } from '../../../services/scroll-manager.service';
import { SelectAllService } from '../../../services/select-all/select-all.service';
@@ -198,7 +197,7 @@ export function createFrozenCommandTestBed(workbookData?: IWorkbookData) {
const injector = univer.__getInjector();
injector.add([SheetSkeletonService]);
// NOTE: this is a hack. Please refer to ./services/clipboard/__tests__/clipboard-test-bed.ts
const mockSheetSkService = new SheetSkeletonService(injector);
const mockSheetSkService = new SheetSkeletonService(injector, get(IUniverInstanceService));
const fakeSheetSkeletonManagerService = new SheetSkeletonManagerService({
unit: sheet,
unitId,
@@ -212,7 +211,7 @@ export function createFrozenCommandTestBed(workbookData?: IWorkbookData) {
activated$: new BehaviorSubject(true),
activate: () => {},
deactivate: () => {},
}, injector, injector.get(SheetSkeletonService));
}, injector.get(SheetSkeletonService));
injector.add([SheetSkeletonManagerService, { useValue: fakeSheetSkeletonManagerService }]);
injector.get(IRenderManagerService).addRender(unitId, {
+1 -2
View File
@@ -17,8 +17,7 @@
import type { IPosition, IRange, Workbook, Worksheet } from '@univerjs/core';
import type { IBoundRectNoAngle, IRender, Scene, SpreadsheetSkeleton } from '@univerjs/engine-render';
import type { ICollaborator } from '@univerjs/protocol';
import type { ISheetLocation } from '@univerjs/sheets';
import type { ISheetSkeletonManagerParam } from '../services/sheet-skeleton-manager.service';
import type { ISheetLocation, ISheetSkeletonManagerParam } from '@univerjs/sheets';
import { SHEET_VIEWPORT_KEY, Vector2 } from '@univerjs/engine-render';
export function getUserListEqual(userList1: ICollaborator[], userList2: ICollaborator[]) {
@@ -14,9 +14,9 @@
* limitations under the License.
*/
import type { IConfigService, IUniverInstanceService, Workbook } from '@univerjs/core';
import type { IUniverInstanceService, Workbook } from '@univerjs/core';
import type { RenderManagerService } from '@univerjs/engine-render';
import type { SheetInterceptorService, SheetsSelectionsService } from '@univerjs/sheets';
import type { SheetInterceptorService } from '@univerjs/sheets';
import {
CancelMarkDirtyRowAutoHeightMutation,
MarkDirtyRowAutoHeightMutation,
@@ -62,9 +62,7 @@ describe('AutoHeightController', () => {
const controller = new AutoHeightController(
renderManagerService,
sheetInterceptorService,
{ } as unknown as SheetsSelectionsService,
univerInstanceService,
{} as IConfigService
univerInstanceService
);
expect(controller).toBeTruthy();
@@ -14,10 +14,9 @@
* limitations under the License.
*/
import type { IRange, ObjectMatrix, Workbook } from '@univerjs/core';
import type { RenderManagerService } from '@univerjs/engine-render';
import type { IMutationInfo, IRange, ObjectMatrix, Workbook } from '@univerjs/core';
import type { ISetWorksheetRowAutoHeightMutationParams } from '@univerjs/sheets';
import { Disposable, generateRandomId, IConfigService, Inject, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
import { Disposable, generateRandomId, Inject, IUniverInstanceService, UniverInstanceType } from '@univerjs/core';
import { IRenderManagerService } from '@univerjs/engine-render';
import {
CancelMarkDirtyRowAutoHeightMutation,
@@ -26,30 +25,20 @@ import {
SetWorksheetRowAutoHeightMutation,
SetWorksheetRowAutoHeightMutationFactory,
SheetInterceptorService,
SheetsSelectionsService,
} from '@univerjs/sheets';
import { SheetSkeletonManagerService } from '../services/sheet-skeleton-manager.service';
interface IAutoHeightParams {
cellHeights?: ObjectMatrix<number>;
autoHeightRanges?: IRange[];
lazyAutoHeightRanges?: IRange[];
ranges: IRange[];
}
export class AutoHeightController extends Disposable {
constructor(
@IRenderManagerService private readonly _renderManagerService: RenderManagerService,
@IRenderManagerService private readonly _renderManagerService: IRenderManagerService,
@Inject(SheetInterceptorService) private readonly _sheetInterceptorService: SheetInterceptorService,
@Inject(SheetsSelectionsService) private readonly _selectionManagerService: SheetsSelectionsService,
@Inject(IUniverInstanceService) private readonly _univerInstanceService: IUniverInstanceService,
@IConfigService private readonly _configService: IConfigService
@Inject(IUniverInstanceService) private readonly _univerInstanceService: IUniverInstanceService
) {
super();
this._initialize();
}
private _processLazyAutoHeight(redoUndoItem: { redos: any[]; undos: any[] }, unitId: string, subUnitId: string, lazyAutoHeightRanges?: IRange[]) {
private _processLazyAutoHeight(redoUndoItem: { redos: IMutationInfo[]; undos: IMutationInfo[] }, unitId: string, subUnitId: string, lazyAutoHeightRanges?: IRange[]) {
if (lazyAutoHeightRanges?.length) {
const redo = {
id: MarkDirtyRowAutoHeightMutation.id,
@@ -84,7 +73,7 @@ export class AutoHeightController extends Disposable {
return redoUndoItem;
}
getUndoRedoParamsOfAutoHeight(ranges: IRange[], subUnitIdParam?: string, currentCellHeights?: ObjectMatrix<number>): { redos: any[]; undos: any[] } {
getUndoRedoParamsOfAutoHeight(ranges: IRange[], subUnitIdParam?: string, currentCellHeights?: ObjectMatrix<number>): { redos: IMutationInfo[]; undos: IMutationInfo[] } {
const { _univerInstanceService: univerInstanceService } = this;
const workbook = univerInstanceService.getCurrentUnitForType<Workbook>(UniverInstanceType.UNIVER_SHEET)!;
@@ -16,8 +16,7 @@
import type { ICellCustomRender, ICellDataForSheetInterceptor, ICellRenderContext, Nullable, Workbook } from '@univerjs/core';
import type { IMouseEvent, IPointerEvent, IRenderContext, IRenderModule, RenderManagerService, Spreadsheet } from '@univerjs/engine-render';
import type { ICellPermission } from '@univerjs/sheets';
import type { ISheetSkeletonManagerParam } from '../services/sheet-skeleton-manager.service';
import type { ICellPermission, ISheetSkeletonManagerParam } from '@univerjs/sheets';
import { Disposable, DisposableCollection, fromEventSubject, Inject, IPermissionService, sortRules } from '@univerjs/core';
import { IRenderManagerService, Vector2 } from '@univerjs/engine-render';
import { UnitAction, WorkbookEditablePermission, WorksheetEditPermission } from '@univerjs/sheets';
@@ -16,7 +16,7 @@
import type { Nullable, Workbook } from '@univerjs/core';
import type { IRenderContext, IRenderModule } from '@univerjs/engine-render';
import type { ISheetSkeletonManagerParam } from '../services/sheet-skeleton-manager.service';
import type { ISheetSkeletonManagerParam } from '@univerjs/sheets';
import { Disposable, DisposableCollection, Inject } from '@univerjs/core';
import { IRenderManagerService } from '@univerjs/engine-render';
import { DragManagerService } from '../services/drag-manager.service';
@@ -16,7 +16,7 @@
import type { Nullable, Workbook } from '@univerjs/core';
import type { IRenderContext, IRenderModule } from '@univerjs/engine-render';
import type { ISheetSkeletonManagerParam } from '../services/sheet-skeleton-manager.service';
import type { ISheetSkeletonManagerParam } from '@univerjs/sheets';
import { Disposable, DisposableCollection, fromEventSubject, Inject } from '@univerjs/core';
import { SHEET_VIEW_KEY } from '../common/keys';
import { HoverManagerService } from '../services/hover-manager.service';
@@ -21,12 +21,10 @@ import {
Inject,
RANGE_TYPE,
} from '@univerjs/core';
import { SheetsSelectionsService } from '@univerjs/sheets';
import { attachSelectionWithCoord, SheetsSelectionsService } from '@univerjs/sheets';
import { ContextMenuPosition, IContextMenuService } from '@univerjs/ui';
import { SHEET_VIEW_KEY } from '../../common/keys';
import { ISheetSelectionRenderService } from '../../services/selection/base-selection-render.service';
import { attachSelectionWithCoord } from '../../services/selection/util';
/**
* This controller subscribe to context menu events in sheet rendering views and invoke context menu at a correct

Some files were not shown because too many files have changed in this diff Show More