diff --git a/astrid/src/com/todoroo/astrid/adapter/FilterAdapter.java b/astrid/src/com/todoroo/astrid/adapter/FilterAdapter.java index d92dc375a..7f8d60833 100644 --- a/astrid/src/com/todoroo/astrid/adapter/FilterAdapter.java +++ b/astrid/src/com/todoroo/astrid/adapter/FilterAdapter.java @@ -4,6 +4,7 @@ package com.todoroo.astrid.adapter; import java.util.ArrayList; +import java.util.concurrent.LinkedBlockingQueue; import android.app.Activity; import android.content.BroadcastReceiver; @@ -23,11 +24,15 @@ import android.widget.ImageView; import android.widget.TextView; import com.timsu.astrid.R; +import com.todoroo.andlib.data.Property.CountProperty; +import com.todoroo.andlib.service.Autowired; +import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.FilterCategory; import com.todoroo.astrid.api.FilterListHeader; import com.todoroo.astrid.api.FilterListItem; +import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.utility.Preferences; public class FilterAdapter extends BaseExpandableListAdapter { @@ -40,18 +45,45 @@ public class FilterAdapter extends BaseExpandableListAdapter { // --- instance variables + @Autowired + private TaskService taskService; + + /** parent activity */ protected final Activity activity; + + /** owner listview */ protected final ExpandableListView listView; + + /** list of filters */ private final ArrayList items; + + /** display metrics for scaling icons */ private final DisplayMetrics metrics = new DisplayMetrics(); + + /** receiver for new filters */ private final FilterReceiver filterReceiver = new FilterReceiver(); + + /** row layout to inflate */ private final int layout; + + /** layout inflater */ private final LayoutInflater inflater; + + /** whether to skip Filters that launch intents instead of being real filters */ private final boolean skipIntentFilters; + /** queue for loading list sizes */ + private final LinkedBlockingQueue filterQueue = new LinkedBlockingQueue(); + + /** thread for loading list sizes */ + private Thread filterSizeLoadingThread = null; + public FilterAdapter(Activity activity, ExpandableListView listView, int rowLayout, boolean skipIntentFilters) { super(); + + DependencyInjectionService.getInstance().inject(this); + this.activity = activity; this.items = new ArrayList(); this.listView = listView; @@ -64,6 +96,35 @@ public class FilterAdapter extends BaseExpandableListAdapter { activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); listView.setGroupIndicator( activity.getResources().getDrawable(R.drawable.expander_group)); + + startFilterSizeLoadingThread(); + } + + private void startFilterSizeLoadingThread() { + filterSizeLoadingThread = new Thread() { + @Override + public void run() { + CountProperty cp = new CountProperty(); + while(true) { + try { + Filter filter = filterQueue.take(); + int size = taskService.countTasks(filter, cp); + filter.listingTitle = filter.listingTitle + (" (" + //$NON-NLS-1$ + size + ")"); //$NON-NLS-1$ + activity.runOnUiThread(new Runnable() { + public void run() { + notifyDataSetInvalidated(); + } + }); + } catch (InterruptedException e) { + break; + } catch (Exception e) { + Log.e("astrid-filter-adapter", "Error loading filter size", e); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + }; + filterSizeLoadingThread.start(); } public boolean hasStableIds() { @@ -72,6 +133,14 @@ public class FilterAdapter extends BaseExpandableListAdapter { public void add(FilterListItem item) { items.add(item); + + // load sizes + if(item instanceof Filter) { + filterQueue.offer((Filter) item); + } else if(item instanceof FilterCategory) { + for(Filter filter : ((FilterCategory)item).children) + filterQueue.offer(filter); + } } public void clear() { @@ -300,6 +369,8 @@ public class FilterAdapter extends BaseExpandableListAdapter { */ public void unregisterRecevier() { activity.unregisterReceiver(filterReceiver); + if(filterSizeLoadingThread != null) + filterSizeLoadingThread.interrupt(); } /** diff --git a/astrid/src/com/todoroo/astrid/service/TaskService.java b/astrid/src/com/todoroo/astrid/service/TaskService.java index bd73e95a7..926514236 100644 --- a/astrid/src/com/todoroo/astrid/service/TaskService.java +++ b/astrid/src/com/todoroo/astrid/service/TaskService.java @@ -1,6 +1,7 @@ package com.todoroo.astrid.service; import com.todoroo.andlib.data.Property; +import com.todoroo.andlib.data.Property.CountProperty; import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.DependencyInjectionService; @@ -9,10 +10,11 @@ import com.todoroo.andlib.sql.Functions; import com.todoroo.andlib.sql.Order; import com.todoroo.andlib.sql.Query; import com.todoroo.andlib.utility.DateUtilities; +import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.PermaSql; import com.todoroo.astrid.dao.MetadataDao; -import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria; +import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.TaskDao.TaskCriteria; import com.todoroo.astrid.model.Metadata; import com.todoroo.astrid.model.Task; @@ -231,6 +233,16 @@ public class TaskService { } } + public int countTasks(Filter filter, CountProperty countProperty) { + TodorooCursor cursor = query(Query.select(countProperty).withQueryTemplate(filter.sqlQuery)); + try { + cursor.moveToFirst(); + return cursor.getInt(0); + } finally { + cursor.close(); + } + } + }