Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.quicksearchbox.ui;
     18 
     19 import com.android.quicksearchbox.SuggestionCursor;
     20 import com.android.quicksearchbox.SuggestionPosition;
     21 import com.android.quicksearchbox.Suggestions;
     22 
     23 import android.database.DataSetObserver;
     24 import android.util.Log;
     25 import android.view.View.OnFocusChangeListener;
     26 
     27 /**
     28  * A {@link SuggestionsListAdapter} that doesn't expose the new suggestions
     29  * until there are some results to show.
     30  */
     31 public class DelayingSuggestionsAdapter<A> implements SuggestionsAdapter<A> {
     32 
     33     private static final boolean DBG = false;
     34     private static final String TAG = "QSB.DelayingSuggestionsAdapter";
     35 
     36     private DataSetObserver mPendingDataSetObserver;
     37 
     38     private Suggestions mPendingSuggestions;
     39 
     40     private final SuggestionsAdapterBase<A> mDelayedAdapter;
     41 
     42     public DelayingSuggestionsAdapter(SuggestionsAdapterBase<A> delayed) {
     43         mDelayedAdapter = delayed;
     44     }
     45 
     46     public void close() {
     47         setPendingSuggestions(null);
     48         mDelayedAdapter.close();
     49     }
     50 
     51     @Override
     52     public void setSuggestions(Suggestions suggestions) {
     53         if (suggestions == null) {
     54             mDelayedAdapter.setSuggestions(null);
     55             setPendingSuggestions(null);
     56             return;
     57         }
     58         if (shouldPublish(suggestions)) {
     59             if (DBG) Log.d(TAG, "Publishing suggestions immediately: " + suggestions);
     60             mDelayedAdapter.setSuggestions(suggestions);
     61             // Clear any old pending suggestions.
     62             setPendingSuggestions(null);
     63         } else {
     64             if (DBG) Log.d(TAG, "Delaying suggestions publishing: " + suggestions);
     65             setPendingSuggestions(suggestions);
     66         }
     67     }
     68 
     69     /**
     70      * Gets whether the given suggestions are non-empty for the selected source.
     71      */
     72     private boolean shouldPublish(Suggestions suggestions) {
     73         if (suggestions.isDone()) return true;
     74         SuggestionCursor cursor = suggestions.getResult();
     75         if (cursor != null && cursor.getCount() > 0) {
     76             return true;
     77         }
     78         return false;
     79     }
     80 
     81     private void setPendingSuggestions(Suggestions suggestions) {
     82         if (mPendingSuggestions == suggestions) {
     83             return;
     84         }
     85         if (mDelayedAdapter.isClosed()) {
     86             if (suggestions != null) {
     87                 suggestions.release();
     88             }
     89             return;
     90         }
     91         if (mPendingDataSetObserver == null) {
     92             mPendingDataSetObserver = new PendingSuggestionsObserver();
     93         }
     94         if (mPendingSuggestions != null) {
     95             mPendingSuggestions.unregisterDataSetObserver(mPendingDataSetObserver);
     96             // Close old suggestions, but only if they are not also the current
     97             // suggestions.
     98             if (mPendingSuggestions != getSuggestions()) {
     99                 mPendingSuggestions.release();
    100             }
    101         }
    102         mPendingSuggestions = suggestions;
    103         if (mPendingSuggestions != null) {
    104             mPendingSuggestions.registerDataSetObserver(mPendingDataSetObserver);
    105         }
    106     }
    107 
    108     protected void onPendingSuggestionsChanged() {
    109         if (DBG) {
    110             Log.d(TAG, "onPendingSuggestionsChanged(), mPendingSuggestions="
    111                     + mPendingSuggestions);
    112         }
    113         if (shouldPublish(mPendingSuggestions)) {
    114             if (DBG) Log.d(TAG, "Suggestions now available, publishing: " + mPendingSuggestions);
    115             mDelayedAdapter.setSuggestions(mPendingSuggestions);
    116             // The suggestions are no longer pending.
    117             setPendingSuggestions(null);
    118         }
    119     }
    120 
    121     private class PendingSuggestionsObserver extends DataSetObserver {
    122         @Override
    123         public void onChanged() {
    124             onPendingSuggestionsChanged();
    125         }
    126     }
    127 
    128     @Override
    129     public A getListAdapter() {
    130         return mDelayedAdapter.getListAdapter();
    131     }
    132 
    133     public SuggestionCursor getCurrentPromotedSuggestions() {
    134         return mDelayedAdapter.getCurrentSuggestions();
    135     }
    136 
    137     @Override
    138     public Suggestions getSuggestions() {
    139         return mDelayedAdapter.getSuggestions();
    140     }
    141 
    142     @Override
    143     public SuggestionPosition getSuggestion(long suggestionId) {
    144         return mDelayedAdapter.getSuggestion(suggestionId);
    145     }
    146 
    147     @Override
    148     public void onSuggestionClicked(long suggestionId) {
    149         mDelayedAdapter.onSuggestionClicked(suggestionId);
    150     }
    151 
    152     @Override
    153     public void onSuggestionQueryRefineClicked(long suggestionId) {
    154         mDelayedAdapter.onSuggestionQueryRefineClicked(suggestionId);
    155     }
    156 
    157     @Override
    158     public void setOnFocusChangeListener(OnFocusChangeListener l) {
    159         mDelayedAdapter.setOnFocusChangeListener(l);
    160     }
    161 
    162     @Override
    163     public void setSuggestionClickListener(SuggestionClickListener listener) {
    164         mDelayedAdapter.setSuggestionClickListener(listener);
    165     }
    166 
    167     @Override
    168     public boolean isEmpty() {
    169         return mDelayedAdapter.isEmpty();
    170     }
    171 
    172 }
    173