UNPKG

devexpress-diagram

Version:

DevExpress Diagram Control

118 lines (112 loc) 5.77 kB
import { ClipboardCommand } from "./ClipboardCommand"; import { SimpleCommandState } from "../CommandStates"; import { Importer } from "../../ImportAndExport/Importer"; import { Shape } from "../../Model/Shapes/Shape"; import { ImportShapeHistoryItem } from "../../History/Common/ImportShapeHistoryItem"; import { Connector } from "../../Model/Connectors/Connector"; import { ImportConnectorHistoryItem } from "../../History/Common/ImportConnectorHistoryItem"; import { ModelUtils } from "../../Model/ModelUtils"; import { SetSelectionHistoryItem } from "../../History/Common/SetSelectionHistoryItem"; import { DiagramItem } from "../../Model/DiagramItem"; import { Point } from "@devexpress/utils/lib/geometry/point"; import { UnitConverter } from "@devexpress/utils/lib/class/unit-converter"; export abstract class PasteSelectionCommandBase extends ClipboardCommand { static readonly positionOffset = UnitConverter.pixelsToTwips(10); isEnabled(): boolean { return super.isEnabled() && (this.isPasteSupportedByBrowser() || ClipboardCommand.clipboardData !== undefined); } isVisible(): boolean { return this.isPasteSupportedByBrowser() || ClipboardCommand.clipboardData !== undefined; } parseClipboardData(data: string): DiagramItem[] { let items: DiagramItem[] = []; const importer = new Importer(this.control.shapeDescriptionManager, data); items = importer.importItems(this.control.model); const offset = this.getEventPositionOffset(items, this.control.contextMenuPosition); for(let i = 0; i < items.length; i++) { const item = items[i]; if(item instanceof Shape) item.position.offsetByPoint(offset); else if(item instanceof Connector) { item.points.forEach(p => p.offsetByPoint(offset)); item.clearRenderPoints(); } } return items; } protected abstract getEventPositionOffset(items: DiagramItem[], evtPosition?: Point): Point; executeCore(state: SimpleCommandState, parameter?: string): boolean { let ret = true; if(parameter === undefined) this.getClipboardData(data => { ret = this.execute(data); }); else this.performPaste(parameter); return ret; } addItemForSortingRecursive(itemsHashtable: {[key: string]: number}, item: DiagramItem): number { if(itemsHashtable[item.key]) return itemsHashtable[item.key]; if(item instanceof Connector) { if(item.endItem) itemsHashtable[item.key] = this.addItemForSortingRecursive(itemsHashtable, item.endItem) - 0.5; else if(item.beginItem) itemsHashtable[item.key] = this.addItemForSortingRecursive(itemsHashtable, item.beginItem) + 0.5; else itemsHashtable[item.key] = -1; return itemsHashtable[item.key]; } if(item.attachedConnectors.length === 0) return itemsHashtable[item.key] = 0; else for(let i = 0; i < item.attachedConnectors.length; i++) { const beginItem = item.attachedConnectors[i].beginItem; if(item.attachedConnectors[i].endItem === item && beginItem && beginItem !== item.attachedConnectors[i].endItem) return itemsHashtable[item.key] = this.addItemForSortingRecursive(itemsHashtable, beginItem) + 1; else return itemsHashtable[item.key] = 0; } } getSortedPasteItems(items: DiagramItem[]): DiagramItem[] { const sortedItems: DiagramItem[] = []; const connectors = []; const itemsHashtable = {}; for(let i = 0; i < items.length; i++) { const item = items[i]; if(item instanceof Shape) sortedItems.push(item); else if(item instanceof Connector) { connectors.push(item); this.addItemForSortingRecursive(itemsHashtable, item); } } connectors.sort((a, b) => itemsHashtable[b.key] - itemsHashtable[a.key]); return sortedItems.concat(connectors); } performPaste(data: string): void { this.control.beginUpdateCanvas(); this.control.history.beginTransaction(); const idsForSelection: {[id: string]: boolean} = {}; let items = this.parseClipboardData(data); items = this.getSortedPasteItems(items); for(let i = 0; i < items.length; i++) { const item = items[i]; if(item instanceof Shape) this.control.history.addAndRedo(new ImportShapeHistoryItem(item)); else if(item instanceof Connector) this.control.history.addAndRedo(new ImportConnectorHistoryItem(item)); const containerKey = item.container && item.container.key; if(!containerKey || idsForSelection[containerKey] === undefined) idsForSelection[item.key] = true; else if(containerKey && idsForSelection[containerKey] !== undefined) idsForSelection[item.key] = false; } ModelUtils.tryUpdateModelRectangle(this.control.history); this.control.history.addAndRedo(new SetSelectionHistoryItem(this.control.selection, Object.keys(idsForSelection).filter(id => idsForSelection[id]))); this.control.history.endTransaction(); this.control.endUpdateCanvas(); this.control.barManager.updateItemsState(); } protected get isPermissionsRequired(): boolean { return true; } }