Skip to content

Commit

Permalink
feat(render-engine): support repeat table header (#4139)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jocs authored Nov 29, 2024
1 parent 284a454 commit c26f9b0
Show file tree
Hide file tree
Showing 11 changed files with 316 additions and 204 deletions.
18 changes: 10 additions & 8 deletions mockdata/src/docs/default-document.data-simple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,11 @@ function createTableDataStream(tables: string[][]) {
}

const exampleTables = [
['Description', 'Date', 'Location'],
['Description', 'Date', 'Location'],
['Description', 'Date', 'Location'],
['Description', 'Date', 'Location'],
['Description', 'Date', 'Location'],
['Description', 'Date', 'Location'],
['Description', 'Date', 'Location'],
['Description', 'Date', 'Location'],
['Academic Senate Meeting 1 Academic Senate Meeting 2 Academic Senate Meeting 3 Academic Senate Meeting 4 Academic Senate Meeting 5', 'May 25, 2205', 'Building 99 Room 1'],
['Faculty Council', 'June 1, 2205', 'Building 35 Room 5'],
['Faculty Council', 'June 15, 2205', 'Building 35 Room 5'],
['Faculty Council', 'June 30, 2205', 'Building 35 Room 5'],
['Commencement Meeting ', 'December 15, 2205', 'Building 42 Room 10'],
['Dean\'s Council', 'February 1, 2206', 'Building 35 Room 5'],
['Faculty Council', 'March 1, 2206', 'Building 35 Room 5'],
Expand Down Expand Up @@ -201,7 +197,13 @@ const tableColumn: ITableColumn = {
},
};

const tableRows = [...new Array(exampleTables.length).fill(null).map(() => Tools.deepClone(tableRow))];
const tableRows: ITableRow[] = [...new Array(exampleTables.length).fill(null).map((_, i) => {
return {
...Tools.deepClone(tableRow),
isFirstRow: i === 0 ? BooleanNumber.TRUE : BooleanNumber.FALSE,
repeatHeaderRow: i === 0 ? BooleanNumber.TRUE : BooleanNumber.FALSE,
};
})];
const tableColumns = [...new Array(exampleTables[0].length).fill(null).map(() => Tools.deepClone(tableColumn))];

tableColumns[0].size.width.v = 250;
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/docs/data-model/empty-snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@
* limitations under the License.
*/

import type { IDocumentData } from '../../types/interfaces';
import { Tools } from '../../shared/tools';
import { BooleanNumber } from '../../types/enum';
import { LocaleType } from '../../types/enum/locale-type';
import { DocumentFlavor, type IDocumentData } from '../../types/interfaces';
import { DocumentFlavor } from '../../types/interfaces';

export function getEmptySnapshot(
unitID = Tools.generateRandomId(6),
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/services/instance/instance.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@
* limitations under the License.
*/

import { BehaviorSubject, distinctUntilChanged, filter, map, Subject } from 'rxjs';
import type { Observable } from 'rxjs';
import type { IDisposable } from '../../common/di';

import type { UnitModel, UnitType } from '../../common/unit';
import type { Nullable } from '../../shared';
import { BehaviorSubject, distinctUntilChanged, filter, map, Subject } from 'rxjs';
import { createIdentifier, Inject, Injector } from '../../common/di';
import { UniverInstanceType } from '../../common/unit';
import { DocumentDataModel } from '../../docs/data-model/document-data-model';
Expand All @@ -25,9 +28,6 @@ import { Workbook } from '../../sheets/workbook';
import { SlideDataModel } from '../../slides/slide-model';
import { FOCUSING_DOC, FOCUSING_SHEET, FOCUSING_SLIDE, FOCUSING_UNIT } from '../context/context';
import { IContextService } from '../context/context.service';
import type { IDisposable } from '../../common/di';
import type { UnitModel, UnitType } from '../../common/unit';
import type { Nullable } from '../../shared';

export type UnitCtor = new (...args: any[]) => UnitModel;

Expand Down
4 changes: 2 additions & 2 deletions packages/docs-ui/src/basics/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export function findBellowCell(cell: IDocumentSkeletonPage): Nullable<IDocumentS
if (skeTables.has(nextTableId)) {
const nextTable = skeTables.get(nextTableId);
if (nextTable?.rows.length) {
bellowRow = nextTable.rows[0];
bellowRow = nextTable.rows.find((r) => !r.isRepeatRow)!;
break;
}
}
Expand Down Expand Up @@ -138,7 +138,7 @@ export function findAboveCell(cell: IDocumentSkeletonPage): Nullable<IDocumentSk

const col = row.cells.indexOf(cell);

if (aboveRow == null) {
if (aboveRow == null || aboveRow.isRepeatRow) {
if (table.tableId.indexOf('#-#')) {
const [id, index] = table.tableId.split('#-#');
const pages = (table.parent?.parent as IDocumentSkeletonCached)?.pages;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,28 @@
* limitations under the License.
*/

import type { ICommand, Nullable } from '@univerjs/core';
import type { IOffsets } from './table';
import { CommandType, ICommandService, IUniverInstanceService } from '@univerjs/core';
import { DocSelectionManagerService } from '@univerjs/docs';
import type { ICommand, Nullable } from '@univerjs/core';
import { getCommandSkeleton } from '../../util';
import { DocTableInsertRowCommand } from './doc-table-insert.command';
import { CellPosition, getCellOffsets, INSERT_ROW_POSITION } from './table';
import type { IOffsets } from './table';

export interface IDocTableTabCommandParams {
shift: boolean;
}

export const DocTableTabCommand: ICommand<IDocTableTabCommandParams> = {

id: 'doc.table.tab-in-table',

type: CommandType.COMMAND,

handler: async (accessor, params: IDocTableTabCommandParams) => {
const { shift } = params;
const textSelectionManager = accessor.get(DocSelectionManagerService);
const activeTextRange = textSelectionManager.getActiveTextRange();
const docRanges = textSelectionManager.getDocRanges();
const commandService = accessor.get(ICommandService);
const univerInstanceService = accessor.get(IUniverInstanceService);

Expand All @@ -41,25 +44,26 @@ export const DocTableTabCommand: ICommand<IDocTableTabCommandParams> = {
return false;
}

const activeRange = docRanges.find((range) => range.isActive) ?? docRanges[0];
const unitId = docDataModel.getUnitId();
const docSkeletonManagerService = getCommandSkeleton(accessor, unitId);
const skeleton = docSkeletonManagerService?.getSkeleton();
const viewModel = skeleton?.getViewModel().getSelfOrHeaderFooterViewModel(activeTextRange?.segmentId);
const viewModel = skeleton?.getViewModel().getSelfOrHeaderFooterViewModel(activeRange?.segmentId);

if (viewModel == null) {
return false;
}

if (activeTextRange == null) {
if (activeRange == null) {
return false;
}

let offsets: Nullable<IOffsets> = null;

if (shift) {
offsets = getCellOffsets(viewModel, activeTextRange, CellPosition.PREV);
offsets = getCellOffsets(viewModel, activeRange, CellPosition.PREV);
} else {
offsets = getCellOffsets(viewModel, activeTextRange, CellPosition.NEXT);
offsets = getCellOffsets(viewModel, activeRange, CellPosition.NEXT);
}

if (offsets) {
Expand Down
18 changes: 14 additions & 4 deletions packages/docs-ui/src/controllers/doc-auto-format.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@
import type { Nullable } from 'vitest';
import type { ITabCommandParams } from '../commands/commands/auto-format.command';
import { Disposable, Inject, QuickListTypeMap } from '@univerjs/core';
import { DocSkeletonManagerService } from '@univerjs/docs';
import { IRenderManagerService } from '@univerjs/engine-render';
import { AfterSpaceCommand, EnterCommand, TabCommand } from '../commands/commands/auto-format.command';
import { BreakLineCommand } from '../commands/commands/break-line.command';
import { ChangeListNestingLevelCommand, ChangeListNestingLevelType, ListOperationCommand, QuickListCommand } from '../commands/commands/list.command';
import { DocTableTabCommand } from '../commands/commands/table/doc-table-tab.command';
import { DocAutoFormatService } from '../services/doc-auto-format.service';
import { isInSameTableCell } from '../services/selection/convert-rect-range';
import { isInSameTableCellData } from '../services/selection/convert-rect-range';

export class DocAutoFormatController extends Disposable {
constructor(
@Inject(DocAutoFormatService) private readonly _docAutoFormatService: DocAutoFormatService
@Inject(DocAutoFormatService) private readonly _docAutoFormatService: DocAutoFormatService,
@IRenderManagerService private readonly _renderManagerService: IRenderManagerService
) {
super();

Expand Down Expand Up @@ -76,11 +79,18 @@ export class DocAutoFormatController extends Disposable {
this._docAutoFormatService.registerAutoFormat({
id: TabCommand.id,
match: (context) => {
const { selection } = context;
const { selection, unit } = context;

const { startNodePosition, endNodePosition } = selection;

if (startNodePosition && endNodePosition && isInSameTableCell(startNodePosition, endNodePosition)) {
const renderObject = this._renderManagerService.getRenderById(unit.getUnitId());
const skeleton = renderObject?.with(DocSkeletonManagerService).getSkeleton();

if (skeleton == null) {
return false;
}

if (startNodePosition && endNodePosition && isInSameTableCellData(skeleton, startNodePosition, endNodePosition)) {
return true;
}

Expand Down
3 changes: 2 additions & 1 deletion packages/docs-ui/src/services/doc-auto-format.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ export class DocAutoFormatService extends Disposable {
onAutoFormat(id: string, params: Nullable<object>): ICommandInfo[] {
const autoFormats = this._matches.get(id) ?? [];
const unit = this._univerInstanceService.getCurrentUnitForType<DocumentDataModel>(UniverInstanceType.UNIVER_DOC);
const selection = this._textSelectionManagerService.getActiveTextRange();
const docRanges = this._textSelectionManagerService.getDocRanges();
const selection = docRanges.find((range) => range.isActive) ?? docRanges[0];

if (unit && selection) {
const doc = unit.getSelfOrHeaderFooterModel(selection.segmentId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ export interface IDocumentSkeletonRow {
ed: number; // endIndex 文本结束索引
rowSource: ITableRow;
parent?: IDocumentSkeletonTable;
isRepeatRow: boolean; // 是否是标题重复行
}

export interface IDocumentSkeletonColumn {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,18 @@ export function lineBreaking(
ctx.paragraphConfigCache.set(segmentId, segmentParagraphCache);
}

segmentParagraphCache.set(endIndex, paragraphConfig);
if (segmentParagraphCache.has(endIndex)) {
const bulletSkeleton = segmentParagraphCache.get(endIndex)?.bulletSkeleton;

const listLevelAncestors = _getListLevelAncestors(bullet, skeListLevel); // 取得列表所有 level 的缓存
const bulletSkeleton = dealWithBullet(bullet, lists, listLevelAncestors, localeService); // 生成 bullet
paragraphConfig.bulletSkeleton = bulletSkeleton;
} else {
const listLevelAncestors = _getListLevelAncestors(bullet, skeListLevel); // 取得列表所有 level 的缓存
const bulletSkeleton = dealWithBullet(bullet, lists, listLevelAncestors, localeService); // 生成 bullet

_updateListLevelAncestors(paragraph, bullet, bulletSkeleton, skeListLevel); // 更新最新的 level 缓存列表
_updateListLevelAncestors(paragraph, bullet, bulletSkeleton, skeListLevel); // 更新最新的 level 缓存列表

paragraphConfig.bulletSkeleton = bulletSkeleton;
paragraphConfig.bulletSkeleton = bulletSkeleton;
}

for (let i = 0, len = blocks.length; i < len; i++) {
const charIndex = blocks[i];
Expand All @@ -218,6 +222,8 @@ export function lineBreaking(
}
}

segmentParagraphCache.set(endIndex, paragraphConfig);

let allPages = [curPage];
let isParagraphFirstShapedText = true; // 第一个分词
for (const [_index, { text, glyphs, breakPointType }] of shapedTextList.entries()) {
Expand Down
Loading

0 comments on commit c26f9b0

Please sign in to comment.