diff --git a/data/core.yaml b/data/core.yaml index d7b123749..dcbab6945 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -191,8 +191,14 @@ en: disconnect: title: Disconnect description: Disconnect these lines/areas from each other. + line: + description: Disconnect this line from other features. + area: + description: Disconnect this area from other features. key: D annotation: Disconnected lines/areas. + too_large: + single: This can't be disconnected because not enough of it is currently visible. not_connected: There aren't enough lines/areas here to disconnect. connected_to_hidden: This can't be disconnected because it is connected to a hidden feature. relation: This can't be disconnected because it connects members of a relation. diff --git a/dist/locales/en.json b/dist/locales/en.json index 29234efef..0eebd7146 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -246,8 +246,17 @@ "disconnect": { "title": "Disconnect", "description": "Disconnect these lines/areas from each other.", + "line": { + "description": "Disconnect this line from other features." + }, + "area": { + "description": "Disconnect this area from other features." + }, "key": "D", "annotation": "Disconnected lines/areas.", + "too_large": { + "single": "This can't be disconnected because not enough of it is currently visible." + }, "not_connected": "There aren't enough lines/areas here to disconnect.", "connected_to_hidden": "This can't be disconnected because it is connected to a hidden feature.", "relation": "This can't be disconnected because it connects members of a relation." diff --git a/modules/actions/disconnect.js b/modules/actions/disconnect.js index 169dbf92e..aa8c6a393 100644 --- a/modules/actions/disconnect.js +++ b/modules/actions/disconnect.js @@ -82,9 +82,6 @@ export function actionDisconnect(nodeId, newNodeId) { var sharedRelation; parentWays.forEach(function(way) { - if (wayIds && wayIds.indexOf(way.id) === -1) - return; - var relations = graph.parentRelations(way); relations.forEach(function(relation) { if (relation.id in seenRelationIds) { diff --git a/modules/operations/disconnect.js b/modules/operations/disconnect.js index 0b35597f7..59b5a4407 100644 --- a/modules/operations/disconnect.js +++ b/modules/operations/disconnect.js @@ -7,6 +7,7 @@ export function operationDisconnect(selectedIDs, context) { var vertices = [], ways = [], others = []; + var extent; selectedIDs.forEach(function(id) { if (context.geometry(id) === 'vertex') { @@ -20,17 +21,30 @@ export function operationDisconnect(selectedIDs, context) { var actions = []; - vertices.forEach(function(vertexID) { - var action = actionDisconnect(vertexID); + var disconnectingWay = vertices.length === 0 && ways.length === 1 && ways[0]; - if (ways.length > 0) { - var waysIDsForVertex = ways.filter(function(wayID) { - return context.graph().entity(wayID).nodes.includes(vertexID); - }); - action.limitWays(waysIDsForVertex); - } - actions.push(action); - }); + if (disconnectingWay) { + extent = context.entity(disconnectingWay).extent(context.graph()); + + context.entity(disconnectingWay).nodes.forEach(function(vertexID) { + var action = actionDisconnect(vertexID).limitWays(ways); + if (action.disabled(context.graph()) !== 'not_connected') { + actions.push(action); + } + }); + } else { + vertices.forEach(function(vertexID) { + var action = actionDisconnect(vertexID); + + if (ways.length > 0) { + var waysIDsForVertex = ways.filter(function(wayID) { + return context.graph().entity(wayID).nodes.includes(vertexID); + }); + action.limitWays(waysIDsForVertex); + } + actions.push(action); + }); + } var operation = function() { @@ -44,18 +58,26 @@ export function operationDisconnect(selectedIDs, context) { operation.available = function() { - return vertices.length > 0 && - others.length === 0 && - (ways.length === 0 || ways.every(function(way) { - return vertices.some(function(vertex) { - return context.graph().entity(way).nodes.includes(vertex); - }); - })); + + if (actions.length === 0) return false; + + if (others.length !== 0) return false; + + if (vertices.length !== 0 && ways.length !== 0 && !ways.every(function(way) { + return vertices.some(function(vertex) { + return context.graph().entity(way).nodes.includes(vertex); + }); + })) return false; + + return true; }; operation.disabled = function() { var reason; + if (extent && extent.area() && extent.percentContainedIn(context.extent()) < 0.8) { + return 'too_large.single'; + } if (selectedIDs.some(context.hasHiddenConnections)) { reason = 'connected_to_hidden'; } @@ -70,9 +92,13 @@ export function operationDisconnect(selectedIDs, context) { operation.tooltip = function() { var disable = operation.disabled(); - return disable ? - t('operations.disconnect.' + disable) : - t('operations.disconnect.description'); + if (disable) { + return t('operations.disconnect.' + disable); + } + if (disconnectingWay) { + return t('operations.disconnect.' + context.geometry(disconnectingWay) + '.description'); + } + return t('operations.disconnect.description'); };