1816804b67619af133860a1e28e92f58bc642260dBjorn Bringert/* 2816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * Copyright (C) 2009 The Android Open Source Project 3816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * 4816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); 5816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * you may not use this file except in compliance with the License. 6816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * You may obtain a copy of the License at 7816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * 8816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 9816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * 10816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * Unless required by applicable law or agreed to in writing, software 11816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS, 12816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * See the License for the specific language governing permissions and 14816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * limitations under the License. 15816804b67619af133860a1e28e92f58bc642260dBjorn Bringert */ 16816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 17816804b67619af133860a1e28e92f58bc642260dBjorn Bringertpackage com.android.quicksearchbox.ui; 18816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 19116affd19a834a2df4226a1ae37afcc1113a230eMathew Inwoodimport com.android.quicksearchbox.CorpusResult; 20fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwoodimport com.android.quicksearchbox.Promoter; 21816804b67619af133860a1e28e92f58bc642260dBjorn Bringertimport com.android.quicksearchbox.SuggestionCursor; 227a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwoodimport com.android.quicksearchbox.SuggestionPosition; 23816804b67619af133860a1e28e92f58bc642260dBjorn Bringertimport com.android.quicksearchbox.Suggestions; 24816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 25816804b67619af133860a1e28e92f58bc642260dBjorn Bringertimport android.database.DataSetObserver; 26816804b67619af133860a1e28e92f58bc642260dBjorn Bringertimport android.util.Log; 27fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwoodimport android.view.View.OnFocusChangeListener; 28816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 29816804b67619af133860a1e28e92f58bc642260dBjorn Bringert/** 30fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood * A {@link SuggestionsListAdapter} that doesn't expose the new suggestions 31816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * until there are some results to show. 32816804b67619af133860a1e28e92f58bc642260dBjorn Bringert */ 33fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwoodpublic class DelayingSuggestionsAdapter<A> implements SuggestionsAdapter<A> { 34816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 35b5fc08b7f16a32d3865f44b7f26d8aaa5304a2adBjorn Bringert private static final boolean DBG = false; 36816804b67619af133860a1e28e92f58bc642260dBjorn Bringert private static final String TAG = "QSB.DelayingSuggestionsAdapter"; 37816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 38816804b67619af133860a1e28e92f58bc642260dBjorn Bringert private DataSetObserver mPendingDataSetObserver; 39816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 40816804b67619af133860a1e28e92f58bc642260dBjorn Bringert private Suggestions mPendingSuggestions; 41816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 42fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood private final SuggestionsAdapterBase<A> mDelayedAdapter; 43fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood 44fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood public DelayingSuggestionsAdapter(SuggestionsAdapterBase<A> delayed) { 45fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood mDelayedAdapter = delayed; 46816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 47816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 48816804b67619af133860a1e28e92f58bc642260dBjorn Bringert public void close() { 49816804b67619af133860a1e28e92f58bc642260dBjorn Bringert setPendingSuggestions(null); 50fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood mDelayedAdapter.close(); 51816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 52816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 53fde948e69f59589cf0d217ea414af7947de600bbBjorn Bringert @Override 54816804b67619af133860a1e28e92f58bc642260dBjorn Bringert public void setSuggestions(Suggestions suggestions) { 55816804b67619af133860a1e28e92f58bc642260dBjorn Bringert if (suggestions == null) { 56fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood mDelayedAdapter.setSuggestions(null); 57816804b67619af133860a1e28e92f58bc642260dBjorn Bringert setPendingSuggestions(null); 58816804b67619af133860a1e28e92f58bc642260dBjorn Bringert return; 59816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 60816804b67619af133860a1e28e92f58bc642260dBjorn Bringert if (shouldPublish(suggestions)) { 61816804b67619af133860a1e28e92f58bc642260dBjorn Bringert if (DBG) Log.d(TAG, "Publishing suggestions immediately: " + suggestions); 62fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood mDelayedAdapter.setSuggestions(suggestions); 63816804b67619af133860a1e28e92f58bc642260dBjorn Bringert // Clear any old pending suggestions. 64816804b67619af133860a1e28e92f58bc642260dBjorn Bringert setPendingSuggestions(null); 65816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } else { 66816804b67619af133860a1e28e92f58bc642260dBjorn Bringert if (DBG) Log.d(TAG, "Delaying suggestions publishing: " + suggestions); 67816804b67619af133860a1e28e92f58bc642260dBjorn Bringert setPendingSuggestions(suggestions); 68816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 69816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 70816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 71816804b67619af133860a1e28e92f58bc642260dBjorn Bringert /** 72816804b67619af133860a1e28e92f58bc642260dBjorn Bringert * Gets whether the given suggestions are non-empty for the selected source. 73816804b67619af133860a1e28e92f58bc642260dBjorn Bringert */ 74816804b67619af133860a1e28e92f58bc642260dBjorn Bringert private boolean shouldPublish(Suggestions suggestions) { 75816804b67619af133860a1e28e92f58bc642260dBjorn Bringert if (suggestions.isDone()) return true; 76fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood SuggestionCursor cursor = mDelayedAdapter.getPromoted(suggestions); 77116affd19a834a2df4226a1ae37afcc1113a230eMathew Inwood if (cursor != null && cursor.getCount() > 0) { 78116affd19a834a2df4226a1ae37afcc1113a230eMathew Inwood return true; 79116affd19a834a2df4226a1ae37afcc1113a230eMathew Inwood } else if (mDelayedAdapter.willPublishNonPromotedSuggestions()) { 80116affd19a834a2df4226a1ae37afcc1113a230eMathew Inwood Iterable<CorpusResult> results = suggestions.getCorpusResults(); 81116affd19a834a2df4226a1ae37afcc1113a230eMathew Inwood for (CorpusResult result : results) { 82116affd19a834a2df4226a1ae37afcc1113a230eMathew Inwood if (result.getCount() > 0) { 83116affd19a834a2df4226a1ae37afcc1113a230eMathew Inwood return true; 84116affd19a834a2df4226a1ae37afcc1113a230eMathew Inwood } 85116affd19a834a2df4226a1ae37afcc1113a230eMathew Inwood } 86116affd19a834a2df4226a1ae37afcc1113a230eMathew Inwood } 87116affd19a834a2df4226a1ae37afcc1113a230eMathew Inwood return false; 88816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 89816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 90816804b67619af133860a1e28e92f58bc642260dBjorn Bringert private void setPendingSuggestions(Suggestions suggestions) { 91816804b67619af133860a1e28e92f58bc642260dBjorn Bringert if (mPendingSuggestions == suggestions) { 92816804b67619af133860a1e28e92f58bc642260dBjorn Bringert return; 93816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 94fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood if (mDelayedAdapter.isClosed()) { 95816804b67619af133860a1e28e92f58bc642260dBjorn Bringert if (suggestions != null) { 96b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert suggestions.release(); 97816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 98816804b67619af133860a1e28e92f58bc642260dBjorn Bringert return; 99816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 100816804b67619af133860a1e28e92f58bc642260dBjorn Bringert if (mPendingDataSetObserver == null) { 101816804b67619af133860a1e28e92f58bc642260dBjorn Bringert mPendingDataSetObserver = new PendingSuggestionsObserver(); 102816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 103816804b67619af133860a1e28e92f58bc642260dBjorn Bringert if (mPendingSuggestions != null) { 104816804b67619af133860a1e28e92f58bc642260dBjorn Bringert mPendingSuggestions.unregisterDataSetObserver(mPendingDataSetObserver); 105816804b67619af133860a1e28e92f58bc642260dBjorn Bringert // Close old suggestions, but only if they are not also the current 106816804b67619af133860a1e28e92f58bc642260dBjorn Bringert // suggestions. 107816804b67619af133860a1e28e92f58bc642260dBjorn Bringert if (mPendingSuggestions != getSuggestions()) { 108b83882b9efa37ec0f20a0f1c85cf5ccc93194aeeBjorn Bringert mPendingSuggestions.release(); 109816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 110816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 111816804b67619af133860a1e28e92f58bc642260dBjorn Bringert mPendingSuggestions = suggestions; 112816804b67619af133860a1e28e92f58bc642260dBjorn Bringert if (mPendingSuggestions != null) { 113816804b67619af133860a1e28e92f58bc642260dBjorn Bringert mPendingSuggestions.registerDataSetObserver(mPendingDataSetObserver); 114816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 115816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 116816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 117816804b67619af133860a1e28e92f58bc642260dBjorn Bringert protected void onPendingSuggestionsChanged() { 118816804b67619af133860a1e28e92f58bc642260dBjorn Bringert if (DBG) { 119816804b67619af133860a1e28e92f58bc642260dBjorn Bringert Log.d(TAG, "onPendingSuggestionsChanged(), mPendingSuggestions=" 120816804b67619af133860a1e28e92f58bc642260dBjorn Bringert + mPendingSuggestions); 121816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 122816804b67619af133860a1e28e92f58bc642260dBjorn Bringert if (shouldPublish(mPendingSuggestions)) { 123816804b67619af133860a1e28e92f58bc642260dBjorn Bringert if (DBG) Log.d(TAG, "Suggestions now available, publishing: " + mPendingSuggestions); 124fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood mDelayedAdapter.setSuggestions(mPendingSuggestions); 125816804b67619af133860a1e28e92f58bc642260dBjorn Bringert // The suggestions are no longer pending. 126816804b67619af133860a1e28e92f58bc642260dBjorn Bringert setPendingSuggestions(null); 127816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 128816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 129816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 130816804b67619af133860a1e28e92f58bc642260dBjorn Bringert private class PendingSuggestionsObserver extends DataSetObserver { 131816804b67619af133860a1e28e92f58bc642260dBjorn Bringert @Override 132816804b67619af133860a1e28e92f58bc642260dBjorn Bringert public void onChanged() { 133816804b67619af133860a1e28e92f58bc642260dBjorn Bringert onPendingSuggestionsChanged(); 134816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 135816804b67619af133860a1e28e92f58bc642260dBjorn Bringert } 136816804b67619af133860a1e28e92f58bc642260dBjorn Bringert 137fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood public A getListAdapter() { 138fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood return mDelayedAdapter.getListAdapter(); 139fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood } 140fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood 141fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood public SuggestionCursor getCurrentPromotedSuggestions() { 142fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood return mDelayedAdapter.getCurrentPromotedSuggestions(); 143fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood } 144fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood 145fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood public Suggestions getSuggestions() { 146fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood return mDelayedAdapter.getSuggestions(); 147fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood } 148fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood 1497a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood public SuggestionPosition getSuggestion(long suggestionId) { 1507a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood return mDelayedAdapter.getSuggestion(suggestionId); 151fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood } 152fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood 1537a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood public void onSuggestionClicked(long suggestionId) { 1547a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood mDelayedAdapter.onSuggestionClicked(suggestionId); 155fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood } 156fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood 1577a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood public void onSuggestionQueryRefineClicked(long suggestionId) { 1587a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood mDelayedAdapter.onSuggestionQueryRefineClicked(suggestionId); 159fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood } 160fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood 1617a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood public void onSuggestionQuickContactClicked(long suggestionId) { 1627a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood mDelayedAdapter.onSuggestionQuickContactClicked(suggestionId); 1637a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood } 1647a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood 1657a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood public void onSuggestionRemoveFromHistoryClicked(long suggestionId) { 1667a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood mDelayedAdapter.onSuggestionRemoveFromHistoryClicked(suggestionId); 167fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood } 168fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood 169fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood public void setMaxPromoted(int maxPromoted) { 170fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood mDelayedAdapter.setMaxPromoted(maxPromoted); 171fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood } 172fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood 173fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood public void setOnFocusChangeListener(OnFocusChangeListener l) { 174fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood mDelayedAdapter.setOnFocusChangeListener(l); 175fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood } 176fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood 177fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood @Override 178fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood public void setPromoter(Promoter promoter) { 179fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood mDelayedAdapter.setPromoter(promoter); 180fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood } 181fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood 182fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood public void setSuggestionClickListener(SuggestionClickListener listener) { 183fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood mDelayedAdapter.setSuggestionClickListener(listener); 184fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood } 185fd4a4cbc1143a734d357897531daa7105db6459bMathew Inwood 1867a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood @Override 1877a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood public boolean isEmpty() { 1887a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood return mDelayedAdapter.isEmpty(); 1897a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood } 1907a0c3a7c6fdabce949b59e0a2c6ec1d44a140c24Mathew Inwood 191816804b67619af133860a1e28e92f58bc642260dBjorn Bringert} 192