devexpress-richedit
Version:
DevExpress Rich Text Editor is an advanced word-processing tool designed for working with rich text documents.
90 lines (89 loc) • 5.95 kB
JavaScript
import { ControlOptions } from '../../model/options/control';
import { TablePosition } from '../../model/tables/main-structures/table';
import { TableCellMergingState } from '../../model/tables/secondary-structures/table-base-structures';
import { TableCellUtils, TableConditionalFormattingCalculator } from '../../model/tables/table-utils';
import { ListUtils } from '@devexpress/utils/lib/utils/list';
import { SearchUtils } from '@devexpress/utils/lib/utils/search';
import { SelectionHistoryItem } from '../../model/history/selection/selection-history-item';
import { RichEditClientCommand } from '../client-command';
import { SimpleCommandState } from '../command-states';
import { TableCommandBase } from './table-command-base';
export class SplitTableCellsCommand extends TableCommandBase {
getState() {
return new SimpleCommandState(this.isEnabled());
}
isEnabled() {
return super.isEnabled() && ControlOptions.isEnabled(this.control.modelManager.richOptions.control.tables) && this.selection.tableInfo.extendedData.areCellsSelectedInSeries;
}
executeCore(_state, options) {
const parameters = options.param;
this.history.beginTransaction();
const tableInfo = this.selection.tableInfo;
let selectedCells = ListUtils.map(tableInfo.rawData.rows, (rowInfo) => ListUtils.map(rowInfo.cells, (cellInfo) => cellInfo.cell));
let firstCell = tableInfo.extendedData.firstCell;
if (parameters.isMergeBeforeSplit) {
this.control.commandManager.getCommand(RichEditClientCommand.MergeTableCells).execute(this.control.commandManager.isPublicApiCall);
selectedCells = this.filterRemovedCells(selectedCells);
}
this.splitTableCellsHorizontally(this.selection.activeSubDocument, selectedCells, parameters);
this.splitTableCellsVertically(this.selection.activeSubDocument, selectedCells, parameters);
this.history.addAndRedo(new SelectionHistoryItem(this.modelManipulator, this.selection, this.selection.getState(), this.selection.getState().setPosition(selectedCells[0][0].startParagraphPosition.value).setEndOfLine(false)));
TableConditionalFormattingCalculator.updateTable(this.control.modelManager, firstCell.parentRow.parentTable, this.selection.activeSubDocument);
this.history.endTransaction();
return true;
}
splitTableCellsHorizontally(subDocument, selectedCells, parameters) {
let startCell = selectedCells[0][0];
let table = startCell.parentRow.parentTable;
if (parameters.isMergeBeforeSplit) {
let rowIndex = SearchUtils.normedInterpolationIndexOf(table.rows, r => r.getStartPosition(), startCell.startParagraphPosition.value);
let cellIndex = SearchUtils.normedInterpolationIndexOf(table.rows[rowIndex].cells, c => c.startParagraphPosition.value, startCell.startParagraphPosition.value);
this.splitTableCellsHorizontallyCore(subDocument, TablePosition.createAndInit(table, rowIndex, cellIndex), parameters.columnCount);
return;
}
let topRowIndex = SearchUtils.normedInterpolationIndexOf(table.rows, r => r.getStartPosition(), startCell.startParagraphPosition.value);
for (var i = selectedCells.length - 1; i >= 0; i--) {
let rowIndex = i + topRowIndex;
let row = table.rows[rowIndex];
let startCellIndex = SearchUtils.normedInterpolationIndexOf(row.cells, c => c.startParagraphPosition.value, selectedCells[i][0].startParagraphPosition.value);
for (let j = selectedCells[i].length - 1; j >= 0; j--) {
let cellIndex = startCellIndex + j;
let cell = row.cells[cellIndex];
if (cell.verticalMerging === TableCellMergingState.Continue)
continue;
this.splitTableCellsHorizontallyCore(subDocument, TablePosition.createAndInit(table, rowIndex, cellIndex), parameters.columnCount);
}
}
}
splitTableCellsVertically(subDocument, selectedCells, parameters) {
if (parameters.rowCount === 1)
return;
let columnCount = this.getColumnsCountForSplitVertically(selectedCells[0], parameters);
let startCell = selectedCells[0][0];
let topRowIndex = SearchUtils.normedInterpolationIndexOf(startCell.parentRow.parentTable.rows, r => r.getStartPosition(), startCell.startParagraphPosition.value);
let startCellIndex = SearchUtils.normedInterpolationIndexOf(startCell.parentRow.cells, c => c.startParagraphPosition.value, startCell.startParagraphPosition.value);
this.splitTableCellsVerticallyCore(subDocument, TablePosition.createAndInit(startCell.parentRow.parentTable, topRowIndex, startCellIndex), parameters.rowCount, columnCount);
}
splitTableCellsVerticallyCore(subDocument, position, rowsCount, columnsCount) {
TableCellUtils.splitTableCellsVerticallyCore(this.control, subDocument, position, rowsCount, columnsCount, this.inputPosition);
}
splitTableCellsHorizontallyCore(subDocument, position, columnsCount) {
TableCellUtils.splitTableCellsHorizontallyCore(this.control, subDocument, position, columnsCount, this.inputPosition);
}
getColumnsCountForSplitVertically(selectedCells, parameters) {
if (parameters.isMergeBeforeSplit)
return parameters.columnCount;
return selectedCells.length * parameters.columnCount;
}
filterRemovedCells(selectedCells) {
let result = [];
let table = selectedCells[0][0].parentRow.parentTable;
for (let i = 0, horCells; horCells = selectedCells[i]; i++) {
let row = horCells[0].parentRow;
if (table.rows.indexOf(row) < 0)
continue;
result.push([horCells[0]]);
}
return result;
}
}