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

Commit e910403e authored by Steve McKay's avatar Steve McKay
Browse files

Fix event relay to correctly dispatch events.

This fixes:
- UI to show selection which was broken in ag/838866
- Delete undo, which throws IOB exception
  when undoing a a full delete of all entries.

Change-Id: Idbb43510974e130d283313602a71ac15ad10aadf
parent b9444c23
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -58,7 +58,7 @@ abstract class DocumentsAdapter
     * Triggers item-change notifications by stable ID (as opposed to position).
     * Triggers item-change notifications by stable ID (as opposed to position).
     * Passing an unrecognized ID will result in a warning in logcat, but no other error.
     * Passing an unrecognized ID will result in a warning in logcat, but no other error.
     */
     */
    abstract void notifyItemSelectionChanged(String id);
    abstract void onItemSelectionChanged(String id);


    /**
    /**
     * @return The model ID of the item at the given adapter position.
     * @return The model ID of the item at the given adapter position.
+13 −2
Original line number Original line Diff line number Diff line
@@ -86,8 +86,19 @@ public class Model implements SiblingProvider {
    private static String createModelId(Cursor c) {
    private static String createModelId(Cursor c) {
        // TODO: Maybe more efficient to use just the document ID, in cases where there is only one
        // TODO: Maybe more efficient to use just the document ID, in cases where there is only one
        // authority (which should be the majority of cases).
        // authority (which should be the majority of cases).
        return getCursorString(c, RootCursorWrapper.COLUMN_AUTHORITY) +
        return createModelId(
                "|" + getCursorString(c, Document.COLUMN_DOCUMENT_ID);
                getCursorString(c, RootCursorWrapper.COLUMN_AUTHORITY),
                getCursorString(c, Document.COLUMN_DOCUMENT_ID));
    }

    /**
     * Generates a Model ID for a cursor entry that refers to a document. The Model ID is a unique
     * string that can be used to identify the document referred to by the cursor.
     *
     * @param c A cursor that refers to a document.
     */
    static String createModelId(String authority, String docId) {
        return authority + "|" + docId;
    }
    }


    private void notifyUpdateListeners() {
    private void notifyUpdateListeners() {
+12 −5
Original line number Original line Diff line number Diff line
@@ -25,7 +25,6 @@ import static com.android.documentsui.model.DocumentInfo.getCursorString;


import android.database.Cursor;
import android.database.Cursor;
import android.provider.DocumentsContract.Document;
import android.provider.DocumentsContract.Document;
import android.support.v7.widget.GridLayoutManager;
import android.util.Log;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseArray;
import android.view.ViewGroup;
import android.view.ViewGroup;
@@ -187,9 +186,17 @@ final class ModelBackedDocumentsAdapter extends DocumentsAdapter {
    @Override
    @Override
    public void unhide(SparseArray<String> ids) {
    public void unhide(SparseArray<String> ids) {
        if (DEBUG) Log.d(TAG, "Un-iding ids: " + ids);
        if (DEBUG) Log.d(TAG, "Un-iding ids: " + ids);
        // Proceed backwards through the list of items, because each addition causes the

        // positions of all subsequent items to change.
        // An ArrayList can shrink at runtime...and in fact
        for (int i = ids.size() - 1; i >= 0; --i) {
        // it does when we clear it completely.
        // This means we can't call add(pos, id) without
        // first checking the list size.
        List<String> oldIds = mModelIds;
        mModelIds = new ArrayList<>(oldIds.size() + ids.size());
        mModelIds.addAll(oldIds);

        // Finally insert the unhidden items.
        for (int i = 0; i < ids.size(); i++) {
            int pos = ids.keyAt(i);
            int pos = ids.keyAt(i);
            String id = ids.get(pos);
            String id = ids.get(pos);
            mHiddenIds.remove(id);
            mHiddenIds.remove(id);
@@ -211,7 +218,7 @@ final class ModelBackedDocumentsAdapter extends DocumentsAdapter {
    }
    }


    @Override
    @Override
    public void notifyItemSelectionChanged(String id) {
    public void onItemSelectionChanged(String id) {
        int position = mModelIds.indexOf(id);
        int position = mModelIds.indexOf(id);


        if (position >= 0) {
        if (position >= 0) {
+1 −1
Original line number Original line Diff line number Diff line
@@ -976,7 +976,7 @@ public final class MultiSelectManager implements View.OnKeyListener {


        @Override
        @Override
        public void notifyItemChanged(String id) {
        public void notifyItemChanged(String id) {
            mAdapter.notifyItemSelectionChanged(id);
            mAdapter.onItemSelectionChanged(id);
        }
        }


        @Override
        @Override
+42 −36
Original line number Original line Diff line number Diff line
@@ -43,40 +43,9 @@ final class SectionBreakDocumentsAdapterWrapper extends DocumentsAdapter {
        mEnv = environment;
        mEnv = environment;
        mDelegate = delegate;
        mDelegate = delegate;


        // Events and information flows two ways between recycler view and adapter.
        // Relay events published by our delegate to our listeners (presumably RecyclerView)
        // So we need to listen to events on our delegate and forward them
        // with adjusted positions.
        // to our listeners with a corrected position.
        mDelegate.registerAdapterDataObserver(new EventRelay());
        AdapterDataObserver adapterDataObserver = new AdapterDataObserver() {
            public void onChanged() {
                throw new UnsupportedOperationException();
            }

            public void onItemRangeChanged(int positionStart, int itemCount) {
                checkArgument(itemCount == 1);
            }

            public void onItemRangeInserted(int positionStart, int itemCount) {
                checkArgument(itemCount == 1);
                if (positionStart < mBreakPosition) {
                    mBreakPosition++;
                }
                notifyItemRangeInserted(toViewPosition(positionStart), itemCount);
            }

            public void onItemRangeRemoved(int positionStart, int itemCount) {
                checkArgument(itemCount == 1);
                if (positionStart < mBreakPosition) {
                    mBreakPosition--;
                }
                notifyItemRangeRemoved(toViewPosition(positionStart), itemCount);
            }

            public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
                throw new UnsupportedOperationException();
            }
        };

        mDelegate.registerAdapterDataObserver(adapterDataObserver);
    }
    }


    public GridLayoutManager.SpanSizeLookup createSpanSizeLookup() {
    public GridLayoutManager.SpanSizeLookup createSpanSizeLookup() {
@@ -205,7 +174,44 @@ final class SectionBreakDocumentsAdapterWrapper extends DocumentsAdapter {
    }
    }


    @Override
    @Override
    public void notifyItemSelectionChanged(String id) {
    public void onItemSelectionChanged(String id) {
        mDelegate.notifyItemSelectionChanged(id);
        mDelegate.onItemSelectionChanged(id);
    }

    // Listener we add to our delegate. This allows us to relay events published
    // by the delegate to our listeners (presumably RecyclerView) with adjusted positions.
    private final class EventRelay extends AdapterDataObserver {
        public void onChanged() {
            throw new UnsupportedOperationException();
        }

        public void onItemRangeChanged(int positionStart, int itemCount) {
            throw new UnsupportedOperationException();
        }

        public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
            checkArgument(itemCount == 1);
            notifyItemRangeChanged(toViewPosition(positionStart), itemCount, payload);
        }

        public void onItemRangeInserted(int positionStart, int itemCount) {
            checkArgument(itemCount == 1);
            if (positionStart < mBreakPosition) {
                mBreakPosition++;
            }
            notifyItemRangeInserted(toViewPosition(positionStart), itemCount);
        }

        public void onItemRangeRemoved(int positionStart, int itemCount) {
            checkArgument(itemCount == 1);
            if (positionStart < mBreakPosition) {
                mBreakPosition--;
            }
            notifyItemRangeRemoved(toViewPosition(positionStart), itemCount);
        }

        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
            throw new UnsupportedOperationException();
        }
    }
    }
}
}
Loading