modules/operations/paste.js (68 lines of code) (raw):

import { actionCopyEntities } from '../actions/copy_entities'; import { actionMove } from '../actions/move'; import { modeSelect } from '../modes/select'; import { vecSubtract } from '@id-sdk/math'; import { Extent } from '@id-sdk/extent'; import { t } from '../core/localizer'; import { uiCmd } from '../ui/cmd'; import { utilDisplayLabel } from '../util/util'; // see also `behaviorPaste` export function operationPaste(context) { var _pastePoint; var operation = function() { if (!_pastePoint) return; var oldIDs = context.copyIDs(); if (!oldIDs.length) return; var projection = context.projection; var extent = new Extent(); var oldGraph = context.copyGraph(); var newIDs = []; var action = actionCopyEntities(oldIDs, oldGraph); context.perform(action); var copies = action.copies(); var originals = new Set(); Object.values(copies).forEach(function(entity) { originals.add(entity.id); }); for (var id in copies) { var oldEntity = oldGraph.entity(id); var newEntity = copies[id]; extent = extent.extend(oldEntity.extent(oldGraph)); // Exclude child nodes from newIDs if their parent way was also copied. var parents = context.graph().parentWays(newEntity); var parentCopied = parents.some(function(parent) { return originals.has(parent.id); }); if (!parentCopied) { newIDs.push(newEntity.id); } } // Use the location of the copy operation to offset the paste location, // or else use the center of the pasted extent var copyPoint = (context.copyLonLat() && projection(context.copyLonLat())) || projection(extent.center()); var delta = vecSubtract(_pastePoint, copyPoint); // Move the pasted objects to be anchored at the paste location context.replace(actionMove(newIDs, delta, projection), operation.annotation()); context.enter(modeSelect(context, newIDs)); }; operation.point = function(val) { _pastePoint = val; return operation; }; operation.available = function() { return context.mode().id === 'browse'; }; operation.disabled = function() { return !context.copyIDs().length; }; operation.tooltip = function() { var oldGraph = context.copyGraph(); var ids = context.copyIDs(); if (!ids.length) { return t('operations.paste.nothing_copied'); } return t('operations.paste.description', { feature: utilDisplayLabel(oldGraph.entity(ids[0]), oldGraph), n: ids.length }); }; operation.annotation = function() { var ids = context.copyIDs(); return t('operations.paste.annotation', { n: ids.length }); }; operation.id = 'paste'; operation.keys = [uiCmd('⌘V')]; operation.title = t('operations.paste.title'); return operation; }