New sort selection activity now works, updates the task list as you'd expect.

pull/14/head
Tim Su 14 years ago
parent 796d26955b
commit 0ced4fc3d9

@ -1,30 +1,37 @@
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.SPACE;
public class Order {
private final Object expression;
private final OrderType orderType;
private Order(Object expression) {
this(expression, OrderType.ASC);
}
private Order(Object expression, OrderType orderType) {
this.expression = expression;
this.orderType = orderType;
}
public static Order asc(Object expression) {
return new Order(expression);
}
public static Order desc(Object expression) {
return new Order(expression, OrderType.DESC);
}
@Override
public String toString() {
return expression + SPACE + orderType;
}
}
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.SPACE;
public class Order {
private final Object expression;
private final OrderType orderType;
private Order(Object expression) {
this(expression, OrderType.ASC);
}
private Order(Object expression, OrderType orderType) {
this.expression = expression;
this.orderType = orderType;
}
public static Order asc(Object expression) {
return new Order(expression);
}
public static Order desc(Object expression) {
return new Order(expression, OrderType.DESC);
}
@Override
public String toString() {
return expression + SPACE + orderType;
}
public Order reverse() {
if(orderType == OrderType.ASC)
return new Order(expression, OrderType.DESC);
else
return new Order(expression, OrderType.ASC);
}
}

@ -70,7 +70,8 @@ public class LocaleReceiver extends BroadcastReceiver {
DependencyInjectionService.getInstance().inject(this);
Filter filter = new Filter(title, title, null, null);
filter.sqlQuery = sql;
TodorooCursor<Task> cursor = PluginServices.getTaskService().fetchFiltered(filter, null, Task.ID);
TodorooCursor<Task> cursor = PluginServices.getTaskService().fetchFiltered(
sql, null, Task.ID);
try {
if(cursor.getCount() == 0)
return;

@ -2,7 +2,9 @@
<!-- See the file "LICENSE" for the full license governing this code. -->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:paddingLeft="10dip"
android:paddingRight="10dip">
<LinearLayout
android:layout_width="fill_parent"
@ -30,10 +32,13 @@
<TextView
android:layout_width="fill_parent"
android:layout_height="1dip"
android:layout_height="wrap_content"
android:padding="5dip"
android:gravity="center"
android:textSize="20sp"
android:textColor="#ffffff"
android:text="@string/SSD_sort_header"
style="@style/TextAppearance.FLA_Header" />
android:background="@drawable/edit_titlebar"/>
<RadioGroup
android:layout_width="fill_parent"

@ -2,14 +2,42 @@ package com.todoroo.astrid.activity;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.view.View;
import android.widget.CheckBox;
import android.widget.RadioButton;
import com.timsu.astrid.R;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Functions;
import com.todoroo.andlib.sql.Order;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
import com.todoroo.astrid.model.Task;
import com.todoroo.astrid.service.TaskService;
/**
* Shows the sort / hidden dialog
*
* @author Tim Su <tim@todoroo.com>
*
*/
public class SortSelectionActivity {
private SortSelectionActivity() {
// use the static method
public static final int FLAG_REVERSE_SORT = 1 << 0;
public static final int FLAG_SHOW_COMPLETED = 1 << 1;
public static final int FLAG_SHOW_HIDDEN = 1 << 2;
public static final int FLAG_SHOW_DELETED = 1 << 3;
public static final int SORT_AUTO = 0;
public static final int SORT_ALPHA = 1;
public static final int SORT_DUE = 2;
public static final int SORT_IMPORTANCE = 3;
public static final int SORT_MODIFIED = 4;
public interface OnSortSelectedListener {
public void onSortSelected(boolean always, int flags, int sort);
}
/**
@ -17,18 +45,145 @@ public class SortSelectionActivity {
* @param activity
* @return
*/
public static AlertDialog createDialog(Activity activity) {
public static AlertDialog createDialog(Activity activity,
OnSortSelectedListener listener, int flags, int sort) {
View body = activity.getLayoutInflater().inflate(R.layout.sort_selection_dialog, null);
if((flags & FLAG_REVERSE_SORT) > 0)
((CheckBox)body.findViewById(R.id.reverse)).setChecked(true);
if((flags & FLAG_SHOW_COMPLETED) > 0)
((CheckBox)body.findViewById(R.id.completed)).setChecked(true);
if((flags & FLAG_SHOW_HIDDEN) > 0)
((CheckBox)body.findViewById(R.id.hidden)).setChecked(true);
if((flags & FLAG_SHOW_DELETED) > 0)
((CheckBox)body.findViewById(R.id.deleted)).setChecked(true);
switch(sort) {
case SORT_ALPHA:
((RadioButton)body.findViewById(R.id.sort_alpha)).setChecked(true);
break;
case SORT_DUE:
((RadioButton)body.findViewById(R.id.sort_due)).setChecked(true);
break;
case SORT_IMPORTANCE:
((RadioButton)body.findViewById(R.id.sort_importance)).setChecked(true);
break;
case SORT_MODIFIED:
((RadioButton)body.findViewById(R.id.sort_modified)).setChecked(true);
break;
default:
((RadioButton)body.findViewById(R.id.sort_smart)).setChecked(true);
}
AlertDialog dialog = new AlertDialog.Builder(activity).
setTitle(R.string.SSD_title).
setIcon(android.R.drawable.ic_menu_sort_by_size).
setView(body).
setPositiveButton(R.string.SSD_save_always, null).
setNegativeButton(R.string.SSD_save_temp, null).
setPositiveButton(R.string.SSD_save_always,
new DialogOkListener(body, listener, true)).
setNegativeButton(R.string.SSD_save_temp,
new DialogOkListener(body, listener, false)).
create();
dialog.setOwnerActivity(activity);
return dialog;
}
@SuppressWarnings("nls")
public static String adjustSortAndFlags(String originalSql, int flags, int sort) {
// sort
if(!originalSql.toUpperCase().contains("ORDER BY")) {
Order order;
switch(sort) {
case SortSelectionActivity.SORT_ALPHA:
order = Order.asc(Functions.upper(Task.TITLE));
break;
case SortSelectionActivity.SORT_DUE:
order = Order.asc(Functions.caseStatement(Task.DUE_DATE.eq(0),
DateUtilities.now()*2, Task.DUE_DATE) + "+" + Task.IMPORTANCE);
break;
case SortSelectionActivity.SORT_IMPORTANCE:
order = Order.asc(Task.IMPORTANCE + "*" + (2*DateUtilities.now()) + //$NON-NLS-1$
"+" + Functions.caseStatement(Task.DUE_DATE.eq(0), //$NON-NLS-1$
Functions.now() + "+" + DateUtilities.ONE_WEEK, //$NON-NLS-1$
Task.DUE_DATE));
break;
case SortSelectionActivity.SORT_MODIFIED:
order = Order.desc(Task.MODIFICATION_DATE);
break;
default:
order = TaskService.defaultTaskOrder();
}
if((flags & SortSelectionActivity.FLAG_REVERSE_SORT) > 0)
order = order.reverse();
originalSql += " ORDER BY " + order;
}
// flags
if((flags & FLAG_SHOW_COMPLETED) > 0)
originalSql = originalSql.replace(Task.COMPLETION_DATE.eq(0).toString(),
Criterion.all.toString());
if((flags & FLAG_SHOW_HIDDEN) > 0)
originalSql = originalSql.replace(TaskCriteria.isVisible().toString(),
Criterion.all.toString());
if((flags & FLAG_SHOW_DELETED) > 0)
originalSql = originalSql.replace(Task.DELETION_DATE.eq(0).toString(),
Criterion.all.toString());
return originalSql;
}
// --- internal implementation
/** preference key for sort flags */
public static final String PREF_SORT_FLAGS = "tla_flags"; //$NON-NLS-1$
/** preference key for sort sort */
public static final String PREF_SORT_SORT = "tla_sort"; //$NON-NLS-1$
private SortSelectionActivity() {
// use the static method
}
private static class DialogOkListener implements OnClickListener {
private final OnSortSelectedListener listener;
private final boolean always;
private final View body;
public DialogOkListener(View body, OnSortSelectedListener listener, boolean always) {
this.body = body;
this.listener = listener;
this.always = always;
}
@Override
public void onClick(DialogInterface view, int button) {
int flags = 0;
int sort = 0;
if(((CheckBox)body.findViewById(R.id.reverse)).isChecked())
flags |= FLAG_REVERSE_SORT;
if(((CheckBox)body.findViewById(R.id.completed)).isChecked())
flags |= FLAG_SHOW_COMPLETED;
if(((CheckBox)body.findViewById(R.id.hidden)).isChecked())
flags |= FLAG_SHOW_HIDDEN;
if(((CheckBox)body.findViewById(R.id.deleted)).isChecked())
flags |= FLAG_SHOW_DELETED;
if(((RadioButton)body.findViewById(R.id.sort_alpha)).isChecked())
sort = SORT_ALPHA;
else if(((RadioButton)body.findViewById(R.id.sort_due)).isChecked())
sort = SORT_DUE;
else if(((RadioButton)body.findViewById(R.id.sort_importance)).isChecked())
sort = SORT_IMPORTANCE;
else if(((RadioButton)body.findViewById(R.id.sort_modified)).isChecked())
sort = SORT_MODIFIED;
else
sort = SORT_AUTO;
listener.onSortSelected(always, flags, sort);
}
}
}

@ -3,6 +3,7 @@ package com.todoroo.astrid.activity;
import java.util.Date;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicReference;
import android.app.AlertDialog;
import android.app.ListActivity;
@ -48,6 +49,7 @@ import com.flurry.android.FlurryAgent;
import com.timsu.astrid.R;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.ExceptionService;
import com.todoroo.andlib.utility.AndroidUtilities;
@ -56,6 +58,7 @@ import com.todoroo.andlib.utility.DialogUtilities;
import com.todoroo.andlib.utility.Pair;
import com.todoroo.andlib.widget.GestureService;
import com.todoroo.andlib.widget.GestureService.GestureInterface;
import com.todoroo.astrid.activity.SortSelectionActivity.OnSortSelectedListener;
import com.todoroo.astrid.adapter.TaskAdapter;
import com.todoroo.astrid.adapter.TaskAdapter.ViewHolder;
import com.todoroo.astrid.api.AstridApiConstants;
@ -80,6 +83,8 @@ import com.todoroo.astrid.service.StartupService;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.utility.Constants;
import com.todoroo.astrid.utility.Flags;
import com.todoroo.astrid.utility.Preferences;
import com.todoroo.astrid.widget.TasksWidget;
/**
* Primary activity for the Bente application. Shows a list of upcoming
@ -88,7 +93,8 @@ import com.todoroo.astrid.utility.Flags;
* @author Tim Su <tim@todoroo.com>
*
*/
public class TaskListActivity extends ListActivity implements OnScrollListener, GestureInterface {
public class TaskListActivity extends ListActivity implements OnScrollListener,
GestureInterface, OnSortSelectedListener {
// --- activities
@ -145,6 +151,9 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
ImageButton quickAddButton;
EditText quickAddBox;
Filter filter;
int sortFlags;
int sortSort;
AtomicReference<String> sqlQueryTemplate = new AtomicReference<String>();
/* ======================================================================
* ======================================================= initialization
@ -515,21 +524,18 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
* Fill in the Task List with current items
* @param withCustomId force task with given custom id to be part of list
*/
@SuppressWarnings("nls")
protected void setUpTaskList() {
// use default ordering if none specified
if(!filter.sqlQuery.toUpperCase().contains("ORDER BY")) {
filter.sqlQuery += " ORDER BY " + TaskService.defaultTaskOrder();
}
sqlQueryTemplate.set(SortSelectionActivity.adjustSortAndFlags(filter.sqlQuery,
sortFlags, sortSort));
// perform query
TodorooCursor<Task> currentCursor = taskService.fetchFiltered(
filter, null, TaskAdapter.PROPERTIES);
sqlQueryTemplate.get(), null, TaskAdapter.PROPERTIES);
startManagingCursor(currentCursor);
// set up list adapters
taskAdapter = new TaskAdapter(this, R.layout.task_adapter_row,
currentCursor, filter, false, null);
currentCursor, sqlQueryTemplate, false, null);
setListAdapter(taskAdapter);
getListView().setOnScrollListener(this);
registerForContextMenu(getListView());
@ -555,14 +561,13 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
}
// create a custom cursor
if(filter.sqlQuery == null)
filter.sqlQuery = "";
if(!filter.sqlQuery.contains("WHERE"))
filter.sqlQuery += " WHERE " + TaskCriteria.byId(withCustomId);
if(!sqlQueryTemplate.get().contains("WHERE"))
sqlQueryTemplate.set(sqlQueryTemplate.get() + " WHERE " + TaskCriteria.byId(withCustomId));
else
filter.sqlQuery = filter.sqlQuery.replace("WHERE ", "WHERE " +
TaskCriteria.byId(withCustomId) + " OR ");
currentCursor = taskService.fetchFiltered(filter, null, TaskAdapter.PROPERTIES);
sqlQueryTemplate.set(sqlQueryTemplate.get().replace("WHERE ", "WHERE " +
TaskCriteria.byId(withCustomId) + " OR "));
currentCursor = taskService.fetchFiltered(sqlQueryTemplate.get(), null, TaskAdapter.PROPERTIES);
getListView().setFilterText("");
startManagingCursor(currentCursor);
@ -724,7 +729,8 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
startActivityForResult(intent, ACTIVITY_SETTINGS);
return true;
case MENU_SORT_ID:
AlertDialog dialog = SortSelectionActivity.createDialog(this);
AlertDialog dialog = SortSelectionActivity.createDialog(this,
this, sortFlags, sortSort);
dialog.show();
return true;
case MENU_HELP_ID:
@ -815,4 +821,19 @@ public class TaskListActivity extends ListActivity implements OnScrollListener,
}
}
@Override
public void onSortSelected(boolean always, int flags, int sort) {
sortFlags = flags;
sortSort = sort;
if(always) {
Preferences.setInt(SortSelectionActivity.PREF_SORT_FLAGS, flags);
Preferences.setInt(SortSelectionActivity.PREF_SORT_SORT, sort);
ContextManager.getContext().startService(new Intent(ContextManager.getContext(),
TasksWidget.UpdateService.class));
}
setUpTaskList();
}
}

@ -5,6 +5,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import android.app.ListActivity;
import android.content.Context;
@ -15,12 +16,12 @@ import android.graphics.Paint;
import android.text.Html;
import android.text.util.Linkify;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.CheckBox;
@ -42,7 +43,6 @@ import com.todoroo.astrid.activity.TaskEditActivity;
import com.todoroo.astrid.alarms.AlarmDetailExposer;
import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.DetailExposer;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.TaskAction;
import com.todoroo.astrid.api.TaskDecoration;
import com.todoroo.astrid.model.Task;
@ -109,7 +109,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
private final LayoutInflater inflater;
private int fontSize;
private final Filter filter;
private final AtomicReference<String> query;
// the task that's expanded
private long expanded = -1;
@ -136,7 +136,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
* task listener. can be null
*/
public TaskAdapter(ListActivity activity, int resource,
Cursor c, Filter filter, boolean autoRequery,
Cursor c, AtomicReference<String> query, boolean autoRequery,
OnCompletedTaskListener onCompletedTaskListener) {
super(activity, c, autoRequery);
DependencyInjectionService.getInstance().inject(this);
@ -144,7 +144,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
inflater = (LayoutInflater) activity.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
this.filter = filter;
this.query = query;
this.resource = resource;
this.activity = activity;
this.onCompletedTaskListener = onCompletedTaskListener;
@ -169,7 +169,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
// perform query
TodorooCursor<Task> newCursor = taskService.fetchFiltered(
filter, constraint, TaskAdapter.PROPERTIES);
query.get(), constraint, TaskAdapter.PROPERTIES);
activity.startManagingCursor(newCursor);
return newCursor;
}

@ -9,10 +9,9 @@ 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.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;
@ -157,14 +156,14 @@ public class TaskService {
* @return
*/
@SuppressWarnings("nls")
public TodorooCursor<Task> fetchFiltered(Filter filter, CharSequence constraint,
public TodorooCursor<Task> fetchFiltered(String queryTemplate, CharSequence constraint,
Property<?>... properties) {
Criterion whereConstraint = null;
if(constraint != null)
whereConstraint = Functions.upper(Task.TITLE).like("%" +
constraint.toString().toUpperCase() + "%");
if(filter == null || filter.sqlQuery == null) {
if(queryTemplate == null) {
if(whereConstraint == null)
return taskDao.query(Query.select(properties));
else
@ -173,12 +172,13 @@ public class TaskService {
String sql;
if(whereConstraint != null) {
if(!filter.sqlQuery.toUpperCase().contains("WHERE"))
sql = filter.sqlQuery + " WHERE " + whereConstraint;
if(!queryTemplate.toUpperCase().contains("WHERE"))
sql = queryTemplate + " WHERE " + whereConstraint;
else
sql = filter.sqlQuery.replace("WHERE ", "WHERE " + whereConstraint + " AND ");
sql = queryTemplate.replace("WHERE ", "WHERE " + whereConstraint + " AND ");
} else
sql = filter.sqlQuery;
sql = queryTemplate;
return taskDao.query(Query.select(properties).withQueryTemplate(sql));
}

@ -224,6 +224,31 @@ public class Preferences {
editor.commit();
}
// --- preference fetching (int)
/** Gets a int preference
*
* @param key
* @param defValue
* @return default if value is unset otherwise the value
*/
public static int getInt(String key, int defValue) {
Context context = ContextManager.getContext();
return getPrefs(context).getInt(key, defValue);
}
/**
* Sets int preference
* @param key
* @param value
*/
public static void setInt(String key, int value) {
Context context = ContextManager.getContext();
Editor editor = getPrefs(context).edit();
editor.putInt(key, value);
editor.commit();
}
// --- preference fetching (long)
/** Gets a long preference

@ -1,146 +1,151 @@
package com.todoroo.astrid.widget;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;
import com.timsu.astrid.R;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.activity.TaskEditActivity;
import com.todoroo.astrid.activity.TaskListActivity;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.core.CoreFilterExposer;
import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.model.Task;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.service.TaskService;
public class TasksWidget extends AppWidgetProvider {
static {
AstridDependencyInjector.initialize();
}
public final static int[] TEXT_IDS = { R.id.task_1, R.id.task_2,
R.id.task_3, R.id.task_4, R.id.task_5 };
public final static int[] SEPARATOR_IDS = { R.id.separator_1,
R.id.separator_2, R.id.separator_3, R.id.separator_4 };
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
try {
super.onUpdate(context, appWidgetManager, appWidgetIds);
// Start in service to prevent Application Not Responding timeout
context.startService(new Intent(context, UpdateService.class));
} catch (SecurityException e) {
// :(
}
}
public static class UpdateService extends Service {
@Autowired
Database database;
@Autowired
TaskService taskService;
@Override
public void onStart(Intent intent, int startId) {
ContextManager.setContext(this);
RemoteViews updateViews = buildUpdate(this);
ComponentName thisWidget = new ComponentName(this,
TasksWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(thisWidget, updateViews);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@SuppressWarnings("nls")
public RemoteViews buildUpdate(Context context) {
DependencyInjectionService.getInstance().inject(this);
RemoteViews views = null;
views = new RemoteViews(context.getPackageName(),
R.layout.widget_initialized);
int[] textIDs = TEXT_IDS;
int[] separatorIDs = SEPARATOR_IDS;
int numberOfTasks = 5;
Intent listIntent = new Intent(context, TaskListActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
listIntent, 0);
views.setOnClickPendingIntent(R.id.taskbody, pendingIntent);
TodorooCursor<Task> cursor = null;
try {
Filter inboxFilter = CoreFilterExposer.buildInboxFilter(getResources());
inboxFilter.sqlQuery += "ORDER BY " + TaskService.defaultTaskOrder() + " LIMIT " + numberOfTasks;
database.openForReading();
cursor = taskService.fetchFiltered(inboxFilter, null, Task.TITLE, Task.DUE_DATE);
Task task = new Task();
for (int i = 0; i < cursor.getCount() && i < numberOfTasks; i++) {
cursor.moveToPosition(i);
task.readFromCursor(cursor);
String textContent = "";
int textColor = Color.WHITE;
textContent = task.getValue(Task.TITLE);
if(task.hasDueDate() && task.getValue(Task.DUE_DATE) < DateUtilities.now())
textColor = context.getResources().getColor(R.color.task_list_overdue);
if(i > 0)
views.setViewVisibility(separatorIDs[i-1], View.VISIBLE);
views.setTextViewText(textIDs[i], textContent);
views.setTextColor(textIDs[i], textColor);
}
for(int i = cursor.getCount() - 1; i < separatorIDs.length; i++) {
if(i >= 0)
views.setViewVisibility(separatorIDs[i], View.INVISIBLE);
if(i > cursor.getCount() - 1)
views.setViewVisibility(textIDs[i], View.INVISIBLE);
}
} catch (Exception e) {
// can happen if database is not ready
Log.e("WIDGET-UPDATE", "Error updating widget", e);
} finally {
if(cursor != null)
cursor.close();
}
Intent editIntent = new Intent(context, TaskEditActivity.class);
pendingIntent = PendingIntent.getActivity(context, 0,
editIntent, 0);
views.setOnClickPendingIntent(R.id.widget_button, pendingIntent);
return views;
}
}
}
package com.todoroo.astrid.widget;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.RemoteViews;
import com.timsu.astrid.R;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.activity.SortSelectionActivity;
import com.todoroo.astrid.activity.TaskEditActivity;
import com.todoroo.astrid.activity.TaskListActivity;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.core.CoreFilterExposer;
import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.model.Task;
import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.utility.Preferences;
public class TasksWidget extends AppWidgetProvider {
static {
AstridDependencyInjector.initialize();
}
public final static int[] TEXT_IDS = { R.id.task_1, R.id.task_2,
R.id.task_3, R.id.task_4, R.id.task_5 };
public final static int[] SEPARATOR_IDS = { R.id.separator_1,
R.id.separator_2, R.id.separator_3, R.id.separator_4 };
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
try {
super.onUpdate(context, appWidgetManager, appWidgetIds);
// Start in service to prevent Application Not Responding timeout
context.startService(new Intent(context, UpdateService.class));
} catch (SecurityException e) {
// :(
}
}
public static class UpdateService extends Service {
@Autowired
Database database;
@Autowired
TaskService taskService;
@Override
public void onStart(Intent intent, int startId) {
ContextManager.setContext(this);
RemoteViews updateViews = buildUpdate(this);
ComponentName thisWidget = new ComponentName(this,
TasksWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(thisWidget, updateViews);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@SuppressWarnings("nls")
public RemoteViews buildUpdate(Context context) {
DependencyInjectionService.getInstance().inject(this);
RemoteViews views = null;
views = new RemoteViews(context.getPackageName(),
R.layout.widget_initialized);
int[] textIDs = TEXT_IDS;
int[] separatorIDs = SEPARATOR_IDS;
int numberOfTasks = 5;
Intent listIntent = new Intent(context, TaskListActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
listIntent, 0);
views.setOnClickPendingIntent(R.id.taskbody, pendingIntent);
TodorooCursor<Task> cursor = null;
try {
Filter inboxFilter = CoreFilterExposer.buildInboxFilter(getResources());
int sort = Preferences.getInt(SortSelectionActivity.PREF_SORT_SORT, 0);
int flags = Preferences.getInt(SortSelectionActivity.PREF_SORT_FLAGS, 0);
String query = SortSelectionActivity.adjustSortAndFlags(
inboxFilter.sqlQuery, sort, flags) + " LIMIT " + numberOfTasks;
database.openForReading();
cursor = taskService.fetchFiltered(query, null, Task.TITLE, Task.DUE_DATE);
Task task = new Task();
for (int i = 0; i < cursor.getCount() && i < numberOfTasks; i++) {
cursor.moveToPosition(i);
task.readFromCursor(cursor);
String textContent = "";
int textColor = Color.WHITE;
textContent = task.getValue(Task.TITLE);
if(task.hasDueDate() && task.getValue(Task.DUE_DATE) < DateUtilities.now())
textColor = context.getResources().getColor(R.color.task_list_overdue);
if(i > 0)
views.setViewVisibility(separatorIDs[i-1], View.VISIBLE);
views.setTextViewText(textIDs[i], textContent);
views.setTextColor(textIDs[i], textColor);
}
for(int i = cursor.getCount() - 1; i < separatorIDs.length; i++) {
if(i >= 0)
views.setViewVisibility(separatorIDs[i], View.INVISIBLE);
if(i > cursor.getCount() - 1)
views.setViewVisibility(textIDs[i], View.INVISIBLE);
}
} catch (Exception e) {
// can happen if database is not ready
Log.e("WIDGET-UPDATE", "Error updating widget", e);
} finally {
if(cursor != null)
cursor.close();
}
Intent editIntent = new Intent(context, TaskEditActivity.class);
pendingIntent = PendingIntent.getActivity(context, 0,
editIntent, 0);
views.setOnClickPendingIntent(R.id.widget_button, pendingIntent);
return views;
}
}
}

Loading…
Cancel
Save