Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable follow way mode if undo invalidates the prerequisites #2536

Merged
merged 1 commit into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -27,10 +27,13 @@
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject;
import androidx.test.uiautomator.UiObjectNotFoundException;
import androidx.test.uiautomator.UiSelector;
import androidx.test.uiautomator.Until;
import de.blau.android.App;
import de.blau.android.LayerUtils;
import de.blau.android.Logic;
Expand Down Expand Up @@ -342,6 +345,42 @@ public void followWay() {
TestUtils.clickUp(device);
}

/**
* Create a new way from menu check that the follow way button goes away when we undo
*/
// @SdkSuppress(minSdkVersion = 26)
@Test
public void followWayUndo() {
map.getDataLayer().setVisible(true);
TestUtils.zoomToLevel(device, main, 21);
TestUtils.unlock(device);
TestUtils.clickSimpleButton(device);
assertTrue(TestUtils.clickText(device, false, context.getString(R.string.menu_add_way), true, false));
assertTrue(TestUtils.findText(device, false, context.getString(R.string.add_way_start_instruction)));
StorageDelegator delegator = App.getDelegator();
Node n1 = (Node) delegator.getOsmElement(Node.NAME, 2206393022L);
assertNotNull(n1);
TestUtils.clickAtCoordinates(device, map, n1.getLon() / 1E7D, n1.getLat() / 1E7D, true);
assertTrue(TestUtils.findText(device, false, context.getString(R.string.add_way_node_instruction), 1000));
Node n2 = (Node) delegator.getOsmElement(Node.NAME, 2206393031L);
assertNotNull(n2);
BySelector bySelector = By.clickable(true).descStartsWith(context.getString(R.string.menu_follow_way));
UiSelector uiSelector = new UiSelector().clickable(true).descriptionStartsWith(context.getString(R.string.menu_follow_way));
device.wait(Until.findObject(bySelector), 1000);
UiObject button = device.findObject(uiSelector);
assertFalse(button.exists());
TestUtils.clickAtCoordinates(device, map, n2.getLon() / 1E7D, n2.getLat() / 1E7D, true);
device.wait(Until.findObject(bySelector), 1000);
button = device.findObject(uiSelector);
assertTrue(button.exists());
assertTrue(TestUtils.clickMenuButton(device, context.getString(R.string.undo), false, false, 1000));
device.wait(Until.findObject(bySelector), 1000);
button = device.findObject(uiSelector);
assertFalse(button.exists());

TestUtils.clickUp(device);
}

/**
* Create a new Note
*/
Expand Down
Expand Up @@ -395,7 +395,7 @@ protected Set<OsmElement> findToElements(@NonNull OsmElement viaElement) {
* From:
* https://stackoverflow.com/questions/27438644/how-do-we-show-a-back-button-instead-of-donecheckmark-button-in-the-contextual
*
* @param mode2
* @param mode the current ActionMode
*
* @return the View or null if not found
*/
Expand Down
Expand Up @@ -44,7 +44,8 @@
* This callback handles path creation.
*/
public class PathCreationActionModeCallback extends BuilderActionModeCallback {
private static final String DEBUG_TAG = PathCreationActionModeCallback.class.getSimpleName().substring(0, Math.min(23, PathCreationActionModeCallback.class.getSimpleName().length()));
private static final String DEBUG_TAG = PathCreationActionModeCallback.class.getSimpleName().substring(0,
Math.min(23, PathCreationActionModeCallback.class.getSimpleName().length()));

protected static final int MENUITEM_UNDO = 1;
private static final int MENUITEM_SNAP = 2;
Expand Down Expand Up @@ -401,22 +402,9 @@ private synchronized void pathCreateNode(float x, float y) {
// node already existed id clicked != null
if (clicked != null) {
existingNodes.add(clicked);
// check if we are potentially following a way
// check if we are potentially can follow a way
if (lastSelectedNode != null) {
boolean alreadyAvailable = candidatesForFollowing != null && !candidatesForFollowing.isEmpty();
candidatesForFollowing = logic.getWaysForNode(lastSelectedNode);
candidatesForFollowing.retainAll(logic.getWaysForNode(clicked));
candidatesForFollowing.remove(createdWay);
// remove any ways that we have "used up"
for (Way candidate : new ArrayList<>(candidatesForFollowing)) {
if (candidate.isEndNode(clicked) && !candidate.isClosed()) {
candidatesForFollowing.remove(candidate);
}
}
initialFollowNode = lastSelectedNode;
if (!alreadyAvailable || (alreadyAvailable && candidatesForFollowing.isEmpty())) {
mode.invalidate();
}
enableFollowWay(lastSelectedNode, clicked);
}
} else {
candidatesForFollowing = null;
Expand All @@ -427,6 +415,29 @@ private synchronized void pathCreateNode(float x, float y) {
main.invalidateMap();
}

/**
* Enable following if pre-conditions are met
*
* @param current current selected node
* @param next next node
*/
private void enableFollowWay(@NonNull Node current, @NonNull Node next) {
boolean alreadyAvailable = candidatesForFollowing != null && !candidatesForFollowing.isEmpty();
candidatesForFollowing = logic.getWaysForNode(current);
candidatesForFollowing.retainAll(logic.getWaysForNode(next));
candidatesForFollowing.remove(createdWay);
// remove any ways that we have "used up"
for (Way candidate : new ArrayList<>(candidatesForFollowing)) {
if (candidate.isEndNode(next) && !candidate.isClosed()) {
candidatesForFollowing.remove(candidate);
}
}
initialFollowNode = current;
if (!alreadyAvailable || (alreadyAvailable && candidatesForFollowing.isEmpty())) {
mode.invalidate();
}
}

/**
* Remove spurious empty checkpoint created by touching again
*/
Expand Down Expand Up @@ -499,12 +510,17 @@ private void handleFollow() {
* @param mode the current ActionMode
*/
private void followWay(@NonNull ActionMode mode, @NonNull Way follow) {
final int size = addedNodes.size();
if (size < 2) {
Log.e(DEBUG_TAG, "followWay inconsistent state addedNodes size " + size);
return;
}
wayToFollow = follow;
List<Node> endNodesCandidates = new ArrayList<>(follow.getNodes()); // copy required!!
// remove nodes that are not "in front of the current node"
final Node current = addedNodes.get(addedNodes.size() - 1);
final Node current = addedNodes.get(size - 1);
int posCurrent = endNodesCandidates.indexOf(current);
final Node previous = addedNodes.get(addedNodes.size() - 2);
final Node previous = addedNodes.get(size - 2);
int posPrevious = endNodesCandidates.indexOf(previous);
if (follow.isClosed()) {
endNodesCandidates.removeAll(addedNodes);
Expand Down Expand Up @@ -583,11 +599,18 @@ private synchronized void handleUndo() {
manager.finish();
} else {
// select last node
logic.setSelectedNode(addedNodes.get(addedNodes.size() - 1));
int size = addedNodes.size();
Node lastSelected = addedNodes.get(size - 1);
logic.setSelectedNode(lastSelected);
candidatesForFollowing = null;
if (size > 1) {
enableFollowWay(addedNodes.get(size - 2), lastSelected);
} else {
mode.invalidate();
}
}

createdWay = logic.getSelectedWay(); // will be null if way was deleted by undo

main.invalidateMap();
}

Expand Down