UNPKG

devexpress-richedit

Version:

DevExpress Rich Text Editor is an advanced word-processing tool designed for working with rich text documents.

186 lines (185 loc) 11.7 kB
import { TableCellBoundFlags } from '../../../layout/table/layout-table-cell-info'; import { FixedInterval } from '@devexpress/utils/lib/intervals/fixed'; import { ListUtils } from '@devexpress/utils/lib/utils/list'; import { NumberMapUtils } from '@devexpress/utils/lib/utils/map/number'; import { DocumentLayoutDetailsLevel } from '../../../layout/document-layout-details-level'; import { LayoutPosition } from '../../../layout/layout-position'; import { LayoutBoxType } from '../../../layout/main-structures/layout-boxes/layout-box'; import { ColumnChange } from '../../changes/changes/column-change'; import { AnchoredPictureChange, LayoutChangeType } from '../../changes/changes/layout-change-base'; import { PageAreaChange } from '../../changes/changes/page-area-change'; import { PageChange } from '../../changes/changes/page-change'; import { LayoutFormatterState } from '../enums'; import { LastRowInfo } from './last-row-info'; export class RestartPreparer { constructor(manager) { this.manager = manager; } restartCommonPart(modelPosition) { if (this.manager.mainFormatter.rowFormatter.getPosition() < modelPosition) { this.manager.mainFormatter.rowFormatter.iterator.setPosition(this.manager.mainFormatter.rowFormatter.getPosition(), true, true); return false; } this.manager.mainFormatter.rowFormatter.numberingListCountersManager.reset(); this.manager.mainFormatter.rowFormatter.setPosition(modelPosition, true, true); return true; } restartFromPage(pageIndex, isRestartNow, resetTableFormatter) { const restartPosition = this.calcRestartPosition(pageIndex); if (!this.restartCommonPart(restartPosition)) return; const newLp = new LayoutPosition(DocumentLayoutDetailsLevel.None); newLp.pageIndex = pageIndex; const newLastRowInfo = new LastRowInfo(this.manager.mainFormatter.rowFormatter.subDocument.paragraphs); const prevPage = this.manager.layout.pages[pageIndex - 1]; if (!prevPage) newLastRowInfo.reset(this.manager.mainFormatter.rowFormatter); else { const pageArea = ListUtils.last(prevPage.mainSubDocumentPageAreas); const column = pageArea.getLastColumn(); newLastRowInfo.setRowInfo(column.getLastRow(), prevPage.getPosition() + pageArea.pageOffset + column.pageAreaOffset, false); } const boundsCalculator = this.manager.boundsCalculator; boundsCalculator.init(this.manager.model.getSectionByPosition(restartPosition)); this.manager.mainFormatter.setParamsForRestart(LayoutFormatterState.PageStart, newLp, newLastRowInfo, resetTableFormatter); if (isRestartNow) this.manager.runFormatting(pageIndex); } calcRestartPosition(pageIndex) { if (pageIndex == 0) return 0; const prevPage = this.manager.layout.pages[pageIndex - 1]; const pageArea = ListUtils.last(prevPage.mainSubDocumentPageAreas); const column = pageArea.getLastColumn(); const row = column.getLastRow(); const box = ListUtils.last(row.boxes); const lastPosition = prevPage.getPosition() + pageArea.pageOffset + column.pageAreaOffset + row.columnOffset + box.rowOffset + box.getLength(); const tableCellInfo = row.tableCellInfo; if (!tableCellInfo || tableCellInfo.boundFlags.get(TableCellBoundFlags.StartOnThisColumn)) return lastPosition; return Math.max(lastPosition, this.calcRestartPosition(pageIndex - 1)); } restartHeaderFooterInternal(subDocument, pageIndex) { const page = this.manager.layout.pages[pageIndex]; this.manager.changesManager.addPageChange(new PageChange(pageIndex, LayoutChangeType.Updated, [], [])); if (subDocument.isHeader()) this.manager.otherPageAreaFormatter.formatHeaderPageArea(page, subDocument.info); else this.manager.otherPageAreaFormatter.formatFooterPageArea(page, subDocument.info); this.manager.onPagesReady(); this.restartFromPage(pageIndex, true, true); } restartFormatingAllLayout() { while (this.manager.layout.pages.shift()) this.manager.changesManager.addPageChange(new PageChange(0, LayoutChangeType.Deleted, [], [])); this.manager.layout.setEmptyLayout(this.manager.model.pageBackColor); this.manager.mainFormatter.rowFormatter.setPosition(0, true, true); this.manager.mainFormatter.rowFormatter.numberingListCountersManager.reset(); const newLastRow = new LastRowInfo(this.manager.mainFormatter.rowFormatter.subDocument.paragraphs); newLastRow.reset(this.manager.mainFormatter.rowFormatter); this.manager.mainFormatter.setParamsForRestart(LayoutFormatterState.DocumentStart, null, newLastRow, true); this.manager.runFormatting(0); } restartByAnchoredObject(page) { const pageIndex = page.index; const subDocument = this.manager.mainFormatter.subDocument; if (!subDocument.tables.length) return this.restartFromPage(pageIndex, false, true); const lp = new LayoutPosition(DocumentLayoutDetailsLevel.Page); lp.pageIndex = pageIndex; lp.page = page; let table = this.manager.invalidator.isPageStartWithMultipageTable(page); if (!table) { if (!this.manager.mainFormatter.tableFormatter || this.manager.activeFormatter.subDocument.isMain()) return this.restartFromPage(pageIndex, false, true); return this.restartFromPage(pageIndex, false, false); } labelEnd: for (lp.pageAreaIndex = 0; lp.pageArea = lp.page.mainSubDocumentPageAreas[lp.pageAreaIndex]; lp.pageAreaIndex++) { for (lp.columnIndex = 0; lp.column = lp.pageArea.columns[lp.columnIndex]; lp.columnIndex++) { for (lp.rowIndex = 0; lp.row = lp.column.rows[lp.rowIndex]; lp.rowIndex++) { if (!lp.row.tableCellInfo || lp.row.tableCellInfo.parentRow.parentTable.getTopLevelColumn().logicInfo.grid.table.index != table.index) break labelEnd; } } } if (!lp.pageArea || !lp.column || !lp.row) return this.restartFromPage(pageIndex, false, true); this.restartFromRow(lp, this.manager.invalidator.getStartModelPositionOfRow(lp), false, false); this.manager.floatingRestartInfoHolder.init(); } restartFromRow(lp, modelPosition, isRestartNow, removePrevAncObjects = true) { if (lp.isFirstRowOnPage()) return this.restartFromPage(lp.page.index, isRestartNow, true); const mainFormatter = this.manager.mainFormatter; const newLastRowInfo = new LastRowInfo(mainFormatter.rowFormatter.subDocument.paragraphs); const prevRowLP = lp.clone(); if (prevRowLP.advanceToPrevRow(this.manager.layout)) { newLastRowInfo.setRowInfo(prevRowLP.row, lp.getLogPosition(DocumentLayoutDetailsLevel.Column) + prevRowLP.row.columnOffset, true); } else { newLastRowInfo.setRowInfo(null, 0, true); } if (!this.restartCommonPart(modelPosition)) return; const pageChange = this.createNewLayoutPage(lp, modelPosition); if (removePrevAncObjects) { const ancPosInfo = this.manager.layout.anchorObjectsPositionInfo; const rowPos = this.manager.invalidator.getStartModelPositionOfRow(lp); lp.page.anchoredObjectHolder.objects = NumberMapUtils.reducedMap(lp.page.anchoredObjectHolder.objects, (obj) => { if (ancPosInfo.getPosition(obj.objectId) >= rowPos && lp.pageArea.subDocument.id === obj.belongsToSubDocId) { if (obj.getType() === LayoutBoxType.AnchorTextBox) { const id = obj.internalSubDocId; delete lp.page.otherPageAreas[id]; pageChange.otherPageAreaChanges.push(new PageAreaChange(id, LayoutChangeType.Deleted)); } else pageChange.anchoredPictureChanges.push(new AnchoredPictureChange(obj.objectId, LayoutChangeType.Deleted)); return null; } else return obj; }); } this.setBoundsCalculatorState(modelPosition, lp.page, lp.pageIndex); const boundsCalculator = this.manager.boundsCalculator; const pageAreaBounds = ListUtils.last(boundsCalculator.mainPageAreasBounds); const columnsBounds = ListUtils.last(boundsCalculator.mainColumnsBounds); mainFormatter.setBoundsForRestart(pageAreaBounds, columnsBounds); const bounds = new FixedInterval(lp.pageArea.x + columnsBounds[lp.columnIndex].x, columnsBounds[lp.columnIndex].width); mainFormatter.layoutRowBoundsCalculator.resetByColumn(lp.page.anchoredObjectHolder.objects, bounds, false); mainFormatter.setParamsForRestart(LayoutFormatterState.RowFormatting, lp, newLastRowInfo, true); if (isRestartNow) this.manager.runFormatting(lp.page.index); } setBoundsCalculatorState(modelPosition, page, pageIndex) { const boundsCalculator = this.manager.boundsCalculator; boundsCalculator.init(this.manager.model.getSectionByPosition(modelPosition)); const prevPage = this.manager.layout.pages[pageIndex - 1]; boundsCalculator.calculatePageBounds(prevPage ? prevPage.bottom : 0); const layoutOtherPageAreasInfo = page.getLayoutOtherPageAreasInfo(); if (layoutOtherPageAreasInfo.headerPageArea) boundsCalculator.setHeaderBounds(layoutOtherPageAreasInfo.headerPageArea.columns[0].height); if (layoutOtherPageAreasInfo.footerPageArea) boundsCalculator.setFooterBounds(layoutOtherPageAreasInfo.footerPageArea.columns[0].height); boundsCalculator.calculateMainPageAreaBounds(-1); boundsCalculator.calculateColumnBounds(boundsCalculator.mainPageAreasBounds[boundsCalculator.mainPageAreasBounds.length - 1]); } createNewLayoutPage(lp, modelPosition) { const pageChange = new PageChange(lp.pageIndex, LayoutChangeType.Updated, [], []); lp.page = lp.page.deepCopy(); lp.pageArea = lp.page.mainSubDocumentPageAreas[lp.pageAreaIndex]; lp.column = lp.pageArea.columns[lp.columnIndex]; lp.row = lp.column.rows[lp.rowIndex]; this.manager.removeRedundantHelper.removeRedundantPageAreas(lp.page, lp.pageAreaIndex + 1, pageChange); const pageAreaChange = new PageAreaChange(lp.pageAreaIndex, LayoutChangeType.Updated); pageChange.mainPageAreaChanges.push(pageAreaChange); this.manager.removeRedundantHelper.removeRedundantColumnsFromArea(lp.pageArea, lp.columnIndex + 1, pageAreaChange); const columnChange = new ColumnChange(lp.columnIndex, LayoutChangeType.Updated); pageAreaChange.columnChanges.push(columnChange); this.manager.removeRedundantHelper.removeRedundantRowsFromColumn(lp.column, lp.rowIndex, columnChange); const tblIndex = ListUtils.indexBy(lp.column.tablesInfo, (tbl) => tbl.logicInfo.grid.table.getStartPosition() >= modelPosition); this.manager.removeRedundantHelper.removeRedundantTableInfosFromColumn(lp.column, tblIndex == -1 ? lp.column.tablesInfo.length : tblIndex, columnChange); return pageChange; } }