diff --git a/data/core.yaml b/data/core.yaml index 7aa4c95bd..9c7cf4ee5 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -306,14 +306,19 @@ en: multiple: These features can't be rotated because parts of them have not yet been downloaded. reverse: title: Reverse - description: Make this line go in the opposite direction. + description: + point: Flip the direction of this point. + points: Flip the direction of these points. + line: Make this line go in the opposite direction. + lines: Make these lines go in the opposite direction. + features: Flip the directions of these features. key: V - annotation: Reversed a line. - node: - description: - single: Flip the direction of this point. - annotation: - single: Reversed a point. + annotation: + point: Reversed a point. + points: Reversed multiple points. + line: Reversed a line. + lines: Reversed multiple lines. + features: Reversed multiple features. split: title: Split description: diff --git a/dist/locales/en.json b/dist/locales/en.json index 13151d965..c4f29f5b6 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -396,16 +396,20 @@ }, "reverse": { "title": "Reverse", - "description": "Make this line go in the opposite direction.", + "description": { + "point": "Flip the direction of this point.", + "points": "Flip the direction of these points.", + "line": "Make this line go in the opposite direction.", + "lines": "Make these lines go in the opposite direction.", + "features": "Flip the directions of these features." + }, "key": "V", - "annotation": "Reversed a line.", - "node": { - "description": { - "single": "Flip the direction of this point." - }, - "annotation": { - "single": "Reversed a point." - } + "annotation": { + "point": "Reversed a point.", + "points": "Reversed multiple points.", + "line": "Reversed a line.", + "lines": "Reversed multiple lines.", + "features": "Reversed multiple features." } }, "split": { diff --git a/modules/actions/reverse.js b/modules/actions/reverse.js index ea29f67bd..85b8b82fe 100644 --- a/modules/actions/reverse.js +++ b/modules/actions/reverse.js @@ -143,5 +143,9 @@ export function actionReverse(entityID, options) { return 'nondirectional_node'; }; + action.entityID = function() { + return entityID; + }; + return action; } diff --git a/modules/operations/reverse.js b/modules/operations/reverse.js index 89958bafb..2116a6b6c 100644 --- a/modules/operations/reverse.js +++ b/modules/operations/reverse.js @@ -4,39 +4,51 @@ import { behaviorOperation } from '../behavior/operation'; export function operationReverse(selectedIDs, context) { - var entityID = selectedIDs[0]; var operation = function() { - context.perform(action(), operation.annotation()); + context.perform(function combinedReverseAction(graph) { + actions().forEach(function(action) { + graph = action(graph); + }); + return graph; + }, operation.annotation()); context.validator().validate(); }; - function action() { - return actionReverse(entityID); + function actions(situation) { + return selectedIDs.map(function(entityID) { + var entity = context.hasEntity(entityID); + if (!entity) return; + + if (situation === 'toolbar') { + if (entity.type === 'way' && + (!entity.isOneWay() && !entity.isSided())) return; + } + + var geometry = entity.geometry(context.graph()); + if (entity.type !== 'node' && geometry !== 'line') return; + + var action = actionReverse(entityID); + if (action.disabled(context.graph())) return; + + return action; + }).filter(Boolean); } - function isNode() { - var entity = context.hasEntity(entityID); - return entity && entity.type === 'node'; + function reverseTypeID() { + var acts = actions(); + var nodeActionCount = acts.filter(function(act) { + var entity = context.hasEntity(act.entityID()); + return entity && entity.type === 'node'; + }).length; + var typeID = nodeActionCount === 0 ? 'line' : (nodeActionCount === acts.length ? 'point' : 'features'); + if (typeID !== 'features' && acts.length > 1) typeID += 's'; + return typeID; } operation.available = function(situation) { - if (situation === 'toolbar') { - if (!selectedIDs.some(function(id) { - var entity = context.hasEntity(id); - return entity && entity.type === 'way' && (entity.isOneWay() || entity.isSided()); - })) { - return false; - } - } - if (selectedIDs.length !== 1) return false; - - var geometry = context.geometry(entityID); - if (geometry !== 'line' && geometry !== 'vertex' && geometry !== 'point') { - return false; - } - return action().disabled(context.graph()) === false; + return actions(situation).length > 0; }; @@ -46,14 +58,12 @@ export function operationReverse(selectedIDs, context) { operation.tooltip = function() { - var id = isNode() ? 'node.description.single' : 'description'; - return t('operations.reverse.' + id); + return t('operations.reverse.description.' + reverseTypeID()); }; operation.annotation = function() { - var id = isNode() ? 'node.annotation.single' : 'annotation'; - return t('operations.reverse.' + id); + return t('operations.reverse.annotation.' + reverseTypeID()); };