Loading src/com/fsck/k9/fragment/MessageListFragment.java +6 −11 Original line number Diff line number Diff line Loading @@ -338,7 +338,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick private String[] mAccountUuids; private int mUnreadMessageCount = 0; private Map<Integer, Cursor> mCursors = new HashMap<Integer, Cursor>(); private Cursor[] mCursors; /** * Stores the name of the folder that we want to open as soon as possible Loading Loading @@ -700,7 +700,9 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick initializeMessageList(); LoaderManager loaderManager = getLoaderManager(); for (int i = 0, len = mAccountUuids.length; i < len; i++) { int len = mAccountUuids.length; mCursors = new Cursor[len]; for (int i = 0; i < len; i++) { loaderManager.initLoader(i, null, this); } } Loading Loading @@ -2757,16 +2759,9 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { mCursors.put(loader.getId(), data); List<Integer> list = new LinkedList<Integer>(mCursors.keySet()); Collections.sort(list); List<Cursor> cursors = new ArrayList<Cursor>(list.size()); for (Integer id : list) { cursors.add(mCursors.get(id)); } mCursors[loader.getId()] = data; MergeCursorWithUniqueId cursor = new MergeCursorWithUniqueId(cursors); MergeCursorWithUniqueId cursor = new MergeCursorWithUniqueId(mCursors); mSelected = new SparseBooleanArray(cursor.getCount()); //TODO: use the (stable) IDs as index and reuse the old mSelected Loading src/com/fsck/k9/helper/MergeCursor.java +103 −78 Original line number Diff line number Diff line package com.fsck.k9.helper; /* * Copyright (C) 2012 The K-9 Dog Walkers * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.util.List; package com.fsck.k9.helper; import android.annotation.TargetApi; import android.content.ContentResolver; import android.database.CharArrayBuffer; import android.database.ContentObserver; Loading @@ -18,7 +34,7 @@ public class MergeCursor implements Cursor { /** * List of the cursors combined in this object. */ protected final List<Cursor> mCursors; protected final Cursor[] mCursors; /** * The currently active cursor. Loading @@ -32,6 +48,8 @@ public class MergeCursor implements Cursor { */ protected int mActiveCursorIndex; protected int mPosition; /** * Used to cache the value of {@link #getCount()} */ Loading @@ -44,18 +62,26 @@ public class MergeCursor implements Cursor { * @param cursors * The list of cursors this {@code MultiCursor} should combine. */ public MergeCursor(List<Cursor> cursors) { mCursors = cursors; mActiveCursorIndex = 0; mActiveCursor = cursors.get(0); public MergeCursor(Cursor[] cursors) { mCursors = cursors.clone(); for (int i = 0, len = mCursors.length; i < len; i++) { if (mCursors[i] != null) { mActiveCursorIndex = i; mActiveCursor = mCursors[mActiveCursorIndex]; } } mPosition = -1; } @Override public void close() { for (Cursor cursor : mCursors) { if (cursor != null) { cursor.close(); } } } @Override public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) { Loading @@ -65,9 +91,11 @@ public class MergeCursor implements Cursor { @Override public void deactivate() { for (Cursor cursor : mCursors) { if (cursor != null) { cursor.deactivate(); } } } @Override public byte[] getBlob(int columnIndex) { Loading Loading @@ -105,8 +133,10 @@ public class MergeCursor implements Cursor { if (mCount == -1) { int count = 0; for (Cursor cursor : mCursors) { if (cursor != null) { count += cursor.getCount(); } } mCount = count; } Loading Loading @@ -136,12 +166,7 @@ public class MergeCursor implements Cursor { @Override public int getPosition() { int pos = 0; for (int i = 0; i < mActiveCursorIndex; i++) { pos += mCursors.get(i).getCount(); } return pos + mActiveCursor.getPosition(); return mPosition; } @Override Loading @@ -154,6 +179,7 @@ public class MergeCursor implements Cursor { return mActiveCursor.getString(columnIndex); } @TargetApi(11) @Override public int getType(int columnIndex) { return mActiveCursor.getType(columnIndex); Loading @@ -166,20 +192,21 @@ public class MergeCursor implements Cursor { @Override public boolean isAfterLast() { if (mActiveCursorIndex == mCursors.size() - 1) { return mActiveCursor.isAfterLast(); int count = getCount(); if (count == 0) { return true; } return false; return (mPosition == count); } @Override public boolean isBeforeFirst() { if (mActiveCursorIndex == 0) { return mActiveCursor.isBeforeFirst(); if (getCount() == 0) { return true; } return false; return (mPosition == -1); } @Override Loading @@ -189,20 +216,21 @@ public class MergeCursor implements Cursor { @Override public boolean isFirst() { if (mActiveCursorIndex == 0) { return mActiveCursor.isFirst(); if (getCount() == 0) { return false; } return false; return (mPosition == 0); } @Override public boolean isLast() { if (mActiveCursorIndex == mCursors.size() - 1) { return mActiveCursor.isLast(); int count = getCount(); if (count == 0) { return false; } return false; return (mPosition == (count - 1)); } @Override Loading @@ -212,81 +240,78 @@ public class MergeCursor implements Cursor { @Override public boolean move(int offset) { int ofs = offset; int pos = mActiveCursor.getPosition(); if (offset >= 0) { while (pos + ofs > mActiveCursor.getCount() & mActiveCursorIndex < mCursors.size() - 1) { // Adjust the "move offset" ofs -= mActiveCursor.getCount() - pos; // Move to the next cursor mActiveCursor = mCursors.get(++mActiveCursorIndex); // Move the new cursor to the first position mActiveCursor.moveToFirst(); pos = 0; } } else { while (pos + ofs < 0 && mActiveCursorIndex > 0) { // Adjust the "move offset" ofs += pos; // Move to the next cursor mActiveCursor = mCursors.get(--mActiveCursorIndex); // Move the new cursor to the first position mActiveCursor.moveToLast(); pos = mActiveCursor.getPosition(); } } return mActiveCursor.move(ofs); return moveToPosition(mPosition + offset); } @Override public boolean moveToFirst() { mActiveCursorIndex = 0; mActiveCursor = mCursors.get(mActiveCursorIndex); return mActiveCursor.moveToFirst(); return moveToPosition(0); } @Override public boolean moveToLast() { mActiveCursorIndex = mCursors.size() - 1; mActiveCursor = mCursors.get(mActiveCursorIndex); return mActiveCursor.moveToLast(); return moveToPosition(getCount() - 1); } @Override public boolean moveToNext() { return move(1); return moveToPosition(mPosition + 1); } @Override public boolean moveToPosition(int position) { // Start at the beginning mActiveCursorIndex = 0; mActiveCursor = mCursors.get(mActiveCursorIndex); // Make sure position isn't past the end of the cursor final int count = getCount(); if (position >= count) { mPosition = count; return false; } // Make sure position isn't before the beginning of the cursor if (position < 0) { mPosition = -1; return false; } // Check for no-op moves, and skip the rest of the work for them if (position == mPosition) { return true; } int pos = position; while (pos > mActiveCursor.getCount() - 1 && mActiveCursorIndex < mCursors.size() - 1) { /* Find the right cursor */ mActiveCursor = null; mActiveCursorIndex = -1; mPosition = -1; int cursorStartPos = 0; // Adjust the position pos -= mActiveCursor.getCount(); for (int i = 0, len = mCursors.length; i < len; i++) { if (mCursors[i] == null) { continue; } if (position < (cursorStartPos + mCursors[i].getCount())) { mActiveCursorIndex = i; mActiveCursor = mCursors[mActiveCursorIndex]; break; } // Move to the next cursor mActiveCursor = mCursors.get(++mActiveCursorIndex); cursorStartPos += mCursors[i].getCount(); } return mActiveCursor.moveToPosition(pos); /* Move it to the right position */ if (mActiveCursor != null) { boolean success = mActiveCursor.moveToPosition(position - cursorStartPos); mPosition = (success) ? position : -1; return success; } return false; } @Override public boolean moveToPrevious() { return move(-1); return moveToPosition(mPosition - 1); } @Override Loading src/com/fsck/k9/helper/MergeCursorWithUniqueId.java +2 −4 Original line number Diff line number Diff line package com.fsck.k9.helper; import java.util.List; import android.database.Cursor; Loading @@ -14,10 +12,10 @@ public class MergeCursorWithUniqueId extends MergeCursor { private int mIdColumnIndex = -1; public MergeCursorWithUniqueId(List<Cursor> cursors) { public MergeCursorWithUniqueId(Cursor[] cursors) { super(cursors); if (cursors.size() > MAX_CURSORS) { if (cursors.length > MAX_CURSORS) { throw new IllegalArgumentException("This class only supports up to " + MAX_CURSORS + " cursors"); } Loading Loading
src/com/fsck/k9/fragment/MessageListFragment.java +6 −11 Original line number Diff line number Diff line Loading @@ -338,7 +338,7 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick private String[] mAccountUuids; private int mUnreadMessageCount = 0; private Map<Integer, Cursor> mCursors = new HashMap<Integer, Cursor>(); private Cursor[] mCursors; /** * Stores the name of the folder that we want to open as soon as possible Loading Loading @@ -700,7 +700,9 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick initializeMessageList(); LoaderManager loaderManager = getLoaderManager(); for (int i = 0, len = mAccountUuids.length; i < len; i++) { int len = mAccountUuids.length; mCursors = new Cursor[len]; for (int i = 0; i < len; i++) { loaderManager.initLoader(i, null, this); } } Loading Loading @@ -2757,16 +2759,9 @@ public class MessageListFragment extends SherlockFragment implements OnItemClick @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { mCursors.put(loader.getId(), data); List<Integer> list = new LinkedList<Integer>(mCursors.keySet()); Collections.sort(list); List<Cursor> cursors = new ArrayList<Cursor>(list.size()); for (Integer id : list) { cursors.add(mCursors.get(id)); } mCursors[loader.getId()] = data; MergeCursorWithUniqueId cursor = new MergeCursorWithUniqueId(cursors); MergeCursorWithUniqueId cursor = new MergeCursorWithUniqueId(mCursors); mSelected = new SparseBooleanArray(cursor.getCount()); //TODO: use the (stable) IDs as index and reuse the old mSelected Loading
src/com/fsck/k9/helper/MergeCursor.java +103 −78 Original line number Diff line number Diff line package com.fsck.k9.helper; /* * Copyright (C) 2012 The K-9 Dog Walkers * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.util.List; package com.fsck.k9.helper; import android.annotation.TargetApi; import android.content.ContentResolver; import android.database.CharArrayBuffer; import android.database.ContentObserver; Loading @@ -18,7 +34,7 @@ public class MergeCursor implements Cursor { /** * List of the cursors combined in this object. */ protected final List<Cursor> mCursors; protected final Cursor[] mCursors; /** * The currently active cursor. Loading @@ -32,6 +48,8 @@ public class MergeCursor implements Cursor { */ protected int mActiveCursorIndex; protected int mPosition; /** * Used to cache the value of {@link #getCount()} */ Loading @@ -44,18 +62,26 @@ public class MergeCursor implements Cursor { * @param cursors * The list of cursors this {@code MultiCursor} should combine. */ public MergeCursor(List<Cursor> cursors) { mCursors = cursors; mActiveCursorIndex = 0; mActiveCursor = cursors.get(0); public MergeCursor(Cursor[] cursors) { mCursors = cursors.clone(); for (int i = 0, len = mCursors.length; i < len; i++) { if (mCursors[i] != null) { mActiveCursorIndex = i; mActiveCursor = mCursors[mActiveCursorIndex]; } } mPosition = -1; } @Override public void close() { for (Cursor cursor : mCursors) { if (cursor != null) { cursor.close(); } } } @Override public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) { Loading @@ -65,9 +91,11 @@ public class MergeCursor implements Cursor { @Override public void deactivate() { for (Cursor cursor : mCursors) { if (cursor != null) { cursor.deactivate(); } } } @Override public byte[] getBlob(int columnIndex) { Loading Loading @@ -105,8 +133,10 @@ public class MergeCursor implements Cursor { if (mCount == -1) { int count = 0; for (Cursor cursor : mCursors) { if (cursor != null) { count += cursor.getCount(); } } mCount = count; } Loading Loading @@ -136,12 +166,7 @@ public class MergeCursor implements Cursor { @Override public int getPosition() { int pos = 0; for (int i = 0; i < mActiveCursorIndex; i++) { pos += mCursors.get(i).getCount(); } return pos + mActiveCursor.getPosition(); return mPosition; } @Override Loading @@ -154,6 +179,7 @@ public class MergeCursor implements Cursor { return mActiveCursor.getString(columnIndex); } @TargetApi(11) @Override public int getType(int columnIndex) { return mActiveCursor.getType(columnIndex); Loading @@ -166,20 +192,21 @@ public class MergeCursor implements Cursor { @Override public boolean isAfterLast() { if (mActiveCursorIndex == mCursors.size() - 1) { return mActiveCursor.isAfterLast(); int count = getCount(); if (count == 0) { return true; } return false; return (mPosition == count); } @Override public boolean isBeforeFirst() { if (mActiveCursorIndex == 0) { return mActiveCursor.isBeforeFirst(); if (getCount() == 0) { return true; } return false; return (mPosition == -1); } @Override Loading @@ -189,20 +216,21 @@ public class MergeCursor implements Cursor { @Override public boolean isFirst() { if (mActiveCursorIndex == 0) { return mActiveCursor.isFirst(); if (getCount() == 0) { return false; } return false; return (mPosition == 0); } @Override public boolean isLast() { if (mActiveCursorIndex == mCursors.size() - 1) { return mActiveCursor.isLast(); int count = getCount(); if (count == 0) { return false; } return false; return (mPosition == (count - 1)); } @Override Loading @@ -212,81 +240,78 @@ public class MergeCursor implements Cursor { @Override public boolean move(int offset) { int ofs = offset; int pos = mActiveCursor.getPosition(); if (offset >= 0) { while (pos + ofs > mActiveCursor.getCount() & mActiveCursorIndex < mCursors.size() - 1) { // Adjust the "move offset" ofs -= mActiveCursor.getCount() - pos; // Move to the next cursor mActiveCursor = mCursors.get(++mActiveCursorIndex); // Move the new cursor to the first position mActiveCursor.moveToFirst(); pos = 0; } } else { while (pos + ofs < 0 && mActiveCursorIndex > 0) { // Adjust the "move offset" ofs += pos; // Move to the next cursor mActiveCursor = mCursors.get(--mActiveCursorIndex); // Move the new cursor to the first position mActiveCursor.moveToLast(); pos = mActiveCursor.getPosition(); } } return mActiveCursor.move(ofs); return moveToPosition(mPosition + offset); } @Override public boolean moveToFirst() { mActiveCursorIndex = 0; mActiveCursor = mCursors.get(mActiveCursorIndex); return mActiveCursor.moveToFirst(); return moveToPosition(0); } @Override public boolean moveToLast() { mActiveCursorIndex = mCursors.size() - 1; mActiveCursor = mCursors.get(mActiveCursorIndex); return mActiveCursor.moveToLast(); return moveToPosition(getCount() - 1); } @Override public boolean moveToNext() { return move(1); return moveToPosition(mPosition + 1); } @Override public boolean moveToPosition(int position) { // Start at the beginning mActiveCursorIndex = 0; mActiveCursor = mCursors.get(mActiveCursorIndex); // Make sure position isn't past the end of the cursor final int count = getCount(); if (position >= count) { mPosition = count; return false; } // Make sure position isn't before the beginning of the cursor if (position < 0) { mPosition = -1; return false; } // Check for no-op moves, and skip the rest of the work for them if (position == mPosition) { return true; } int pos = position; while (pos > mActiveCursor.getCount() - 1 && mActiveCursorIndex < mCursors.size() - 1) { /* Find the right cursor */ mActiveCursor = null; mActiveCursorIndex = -1; mPosition = -1; int cursorStartPos = 0; // Adjust the position pos -= mActiveCursor.getCount(); for (int i = 0, len = mCursors.length; i < len; i++) { if (mCursors[i] == null) { continue; } if (position < (cursorStartPos + mCursors[i].getCount())) { mActiveCursorIndex = i; mActiveCursor = mCursors[mActiveCursorIndex]; break; } // Move to the next cursor mActiveCursor = mCursors.get(++mActiveCursorIndex); cursorStartPos += mCursors[i].getCount(); } return mActiveCursor.moveToPosition(pos); /* Move it to the right position */ if (mActiveCursor != null) { boolean success = mActiveCursor.moveToPosition(position - cursorStartPos); mPosition = (success) ? position : -1; return success; } return false; } @Override public boolean moveToPrevious() { return move(-1); return moveToPosition(mPosition - 1); } @Override Loading
src/com/fsck/k9/helper/MergeCursorWithUniqueId.java +2 −4 Original line number Diff line number Diff line package com.fsck.k9.helper; import java.util.List; import android.database.Cursor; Loading @@ -14,10 +12,10 @@ public class MergeCursorWithUniqueId extends MergeCursor { private int mIdColumnIndex = -1; public MergeCursorWithUniqueId(List<Cursor> cursors) { public MergeCursorWithUniqueId(Cursor[] cursors) { super(cursors); if (cursors.size() > MAX_CURSORS) { if (cursors.length > MAX_CURSORS) { throw new IllegalArgumentException("This class only supports up to " + MAX_CURSORS + " cursors"); } Loading