mobile/android/base/db/TopSitesCursorWrapper.java

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:efedb1d3cf93
1 package org.mozilla.gecko.db;
2
3 import android.database.Cursor;
4 import android.database.CursorWrapper;
5 import android.util.SparseArray;
6
7 import org.mozilla.gecko.db.BrowserContract.Bookmarks;
8 import org.mozilla.gecko.db.BrowserDB.URLColumns;
9
10 /**
11 * {@TopSitesCursorWrapper} is a cursor wrapper that merges
12 * the top and pinned sites cursors into one. It ensures the
13 * cursor will contain at least a given minimum number of
14 * entries.
15 */
16 public class TopSitesCursorWrapper extends CursorWrapper {
17
18 private static class PinnedSite {
19 public final String title;
20 public final String url;
21
22 public PinnedSite(String title, String url) {
23 this.title = (title == null ? "" : title);
24 this.url = (url == null ? "" : url);
25 }
26 }
27
28 // The cursor for the top sites query
29 private final Cursor topCursor;
30
31 // Associates pinned sites and their respective positions
32 private SparseArray<PinnedSite> pinnedSites;
33
34 // Current position of the cursor
35 private int currentPosition = -1;
36
37 // The size of the cursor wrapper
38 private final int count;
39
40 public TopSitesCursorWrapper(Cursor pinnedCursor, Cursor topCursor, int minSize) {
41 super(topCursor);
42
43 setPinnedSites(pinnedCursor);
44 this.topCursor = topCursor;
45
46 count = Math.max(minSize, pinnedSites.size() + topCursor.getCount());
47 }
48
49 public void setPinnedSites(Cursor c) {
50 pinnedSites = new SparseArray<PinnedSite>();
51
52 if (c == null) {
53 return;
54 }
55
56 try {
57 if (c.getCount() <= 0) {
58 return;
59 }
60
61 c.moveToPosition(0);
62 do {
63 final int pos = c.getInt(c.getColumnIndex(Bookmarks.POSITION));
64 final String url = c.getString(c.getColumnIndex(URLColumns.URL));
65 final String title = c.getString(c.getColumnIndex(URLColumns.TITLE));
66 pinnedSites.put(pos, new PinnedSite(title, url));
67 } while (c.moveToNext());
68 } finally {
69 c.close();
70 }
71 }
72
73 public boolean hasPinnedSites() {
74 return (pinnedSites != null && pinnedSites.size() > 0);
75 }
76
77 public PinnedSite getPinnedSite(int position) {
78 if (!hasPinnedSites()) {
79 return null;
80 }
81
82 return pinnedSites.get(position);
83 }
84
85 public boolean isPinned() {
86 return (pinnedSites.get(currentPosition) != null);
87 }
88
89 private int getPinnedBefore(int position) {
90 int numFound = 0;
91 if (!hasPinnedSites()) {
92 return numFound;
93 }
94
95 for (int i = 0; i < position; i++) {
96 if (pinnedSites.get(i) != null) {
97 numFound++;
98 }
99 }
100
101 return numFound;
102 }
103
104 @Override
105 public int getPosition() {
106 return currentPosition;
107 }
108
109 @Override
110 public int getCount() {
111 return count;
112 }
113
114 @Override
115 public boolean isAfterLast() {
116 return (currentPosition >= count);
117 }
118
119 @Override
120 public boolean isBeforeFirst() {
121 return (currentPosition < 0);
122 }
123
124 @Override
125 public boolean isLast() {
126 return (currentPosition == count - 1);
127 }
128
129 @Override
130 public boolean moveToNext() {
131 return moveToPosition(currentPosition + 1);
132 }
133
134 @Override
135 public boolean moveToPrevious() {
136 return moveToPosition(currentPosition - 1);
137 }
138
139 @Override
140 public boolean move(int offset) {
141 return moveToPosition(currentPosition + offset);
142 }
143
144 @Override
145 public boolean moveToFirst() {
146 return moveToPosition(0);
147 }
148
149 @Override
150 public boolean moveToLast() {
151 return moveToPosition(count - 1);
152 }
153
154 @Override
155 public boolean moveToPosition(int position) {
156 currentPosition = position;
157
158 // Move the real cursor as if we were stepping through it to this position.
159 // Account for pinned sites, and be careful to update its position to the
160 // minimum or maximum position, even if we're moving beyond its bounds.
161 final int before = getPinnedBefore(position);
162 final int p2 = position - before;
163
164 if (p2 <= -1) {
165 super.moveToPosition(-1);
166 } else if (p2 >= topCursor.getCount()) {
167 super.moveToPosition(topCursor.getCount());
168 } else {
169 super.moveToPosition(p2);
170 }
171
172 return (!isBeforeFirst() && !isAfterLast());
173 }
174
175 @Override
176 public long getLong(int columnIndex) {
177 if (hasPinnedSites()) {
178 final PinnedSite site = getPinnedSite(currentPosition);
179
180 if (site != null) {
181 return 0;
182 }
183 }
184
185 if (!super.isBeforeFirst() && !super.isAfterLast()) {
186 return super.getLong(columnIndex);
187 }
188
189 return 0;
190 }
191
192 @Override
193 public int getInt(int columnIndex) {
194 if (hasPinnedSites()) {
195 final PinnedSite site = getPinnedSite(currentPosition);
196
197 if (site != null) {
198 return 0;
199 }
200 }
201
202 if (!super.isBeforeFirst() && !super.isAfterLast()) {
203 return super.getInt(columnIndex);
204 }
205
206 return 0;
207 }
208
209 @Override
210 public String getString(int columnIndex) {
211 if (hasPinnedSites()) {
212 final PinnedSite site = getPinnedSite(currentPosition);
213
214 if (site != null) {
215 if (columnIndex == topCursor.getColumnIndex(URLColumns.URL)) {
216 return site.url;
217 } else if (columnIndex == topCursor.getColumnIndex(URLColumns.TITLE)) {
218 return site.title;
219 }
220
221 return "";
222 }
223 }
224
225 if (!super.isBeforeFirst() && !super.isAfterLast()) {
226 return super.getString(columnIndex);
227 }
228
229 return "";
230 }
231 }

mercurial