Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 53cfc8a3 authored by Ben Kwa's avatar Ben Kwa
Browse files

Fix shift-selection.

The shift-selection code was failing to correctly anchor the selection
prior to shifting focus.  This meant that the first shift-navigation
event (i.e. starting from non-selection mode) would not select the right
set of stuff.

BUG=26459949

Change-Id: I62ed959fb549198c503cfd2131d2499f9a61f7e5
parent c625816a
Loading
Loading
Loading
Loading
+16 −12
Original line number Diff line number Diff line
@@ -1913,37 +1913,41 @@ public final class MultiSelectManager implements View.OnKeyListener {
        // Here we unpack information from the event and pass it to an more
        // easily tested method....basically eliminating the need to synthesize
        // events and views and so on in our tests.
        int position = findTargetPosition(view, keyCode);
        if (position == RecyclerView.NO_POSITION) {
        int endPos = findTargetPosition(view, keyCode);
        if (endPos == RecyclerView.NO_POSITION) {
            // If there is no valid navigation target, don't handle the keypress.
            return false;
        }

        return attemptChangeFocus(position, event.isShiftPressed());
        int startPos = mEnvironment.getAdapterPositionForChildView(view);

        return changeFocus(startPos, endPos, event.isShiftPressed());
    }

    /**
     * @param startPosition The current focus position.
     * @param targetPosition The adapter position to focus.
     * @param extendSelection
     */
    @VisibleForTesting
    boolean attemptChangeFocus(int targetPosition, boolean extendSelection) {
    boolean changeFocus(int startPosition, int targetPosition, boolean extendSelection) {
        // Focus the new file.
        mEnvironment.focusItem(targetPosition);

        if (extendSelection) {
            if (!hasSelection()) {
                // If there is no selection, start a selection when the user presses shift-arrow.
                toggleSelection(targetPosition);
                setSelectionRangeBegin(targetPosition);
            } else if (!mSingleSelect) {
                mRanger.snapSelection(targetPosition);
                notifySelectionChanged();
            } else {
            if (mSingleSelect) {
                // We're in single select and have an existing selection.
                // Our best guess as to what the user would expect is to advance the selection.
                clearSelection();
                toggleSelection(targetPosition);
            } else {
                if (!hasSelection()) {
                    // No selection - start a selection when the user presses shift-arrow.
                    toggleSelection(startPosition);
                    setSelectionRangeBegin(startPosition);
                }
                mRanger.snapSelection(targetPosition);
                notifySelectionChanged();
            }
        }

+9 −3
Original line number Diff line number Diff line
@@ -166,6 +166,12 @@ public class MultiSelectManagerTest extends AndroidTestCase {
        assertRangeSelection(0, 7);
    }

    public void testKeyboardSelection() {
        // This simulates shift-navigation.
        keyToPosition(5, 10, true);
        assertRangeSelection(5, 10);
    }

    public void testSingleSelectMode() {
        mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_SINGLE);
        mManager.addCallback(mCallback);
@@ -186,7 +192,7 @@ public class MultiSelectManagerTest extends AndroidTestCase {
        mManager = new MultiSelectManager(mEnv, mAdapter, MultiSelectManager.MODE_SINGLE);
        mManager.addCallback(mCallback);
        longPress(20);
        keyToPosition(22, true);
        keyToPosition(20, 22, true);
        assertSelection(items.get(22));
    }

@@ -250,8 +256,8 @@ public class MultiSelectManagerTest extends AndroidTestCase {
        mManager.onSingleTapUp(TestInputEvent.shiftClick(position));
    }

    private void keyToPosition(int position, boolean shift) {
        mManager.attemptChangeFocus(position, shift);
    private void keyToPosition(int startPos, int endPos, boolean shift) {
        mManager.changeFocus(startPos, endPos, shift);
    }

    private void assertSelected(String... expected) {