AST-255 - when you create a widget, you get to select a filter. Awesome.

pull/14/head
Tim Su 14 years ago
parent 960d0eb7ad
commit fe3dfb2fab

Binary file not shown.

Binary file not shown.

@ -116,7 +116,14 @@
android:theme="@style/Theme" />
<!-- Activity for preferences -->
<activity android:name="com.todoroo.astrid.activity.EditPreferences" />
<!-- Activity that configures widget -->
<activity android:name="com.todoroo.astrid.widget.WidgetConfigActivity"
android:theme="@style/Theme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<!-- ======================================================= Receivers = -->
<receiver android:name="com.todoroo.astrid.reminders.Notifications" />

@ -151,7 +151,7 @@ public final class LocaleEditAlerts extends ExpandableListActivity {
// if we match a selection, make it selected
final String finalSelection = selectionToMatch;
adapter = new FilterAdapter(this, getExpandableListView(), R.layout.filter_adapter_row) {
adapter = new FilterAdapter(this, getExpandableListView(), R.layout.filter_adapter_row, true) {
@Override
public void onReceiveFilter(FilterListItem item) {
if(adapter.getSelection() != null || finalSelection == null)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 10 KiB

@ -7,16 +7,34 @@
android:orientation="vertical"
android:background="@drawable/widget_frame">
<ImageButton
android:id="@+id/widget_button"
android:src="@drawable/button_plus"
android:layout_gravity="right"
android:layout_width="100dip"
android:layout_height="50dip"
android:background="#00000000"
android:paddingLeft="38dip"
android:paddingTop="4dip"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="2dp"
android:paddingLeft="40dp">
<TextView
android:id="@+id/widget_title"
android:layout_gravity="left"
android:layout_width="128dp"
android:layout_height="47dp"
android:textColor="#ffffff"
android:textSize="14sp"
android:textStyle="bold"
android:gravity="center"
android:ellipsize="start" />
<ImageButton
android:id="@+id/widget_button"
android:src="@drawable/button_plus"
android:layout_gravity="right"
android:layout_width="35dp"
android:layout_height="47dp"
android:background="#00000000" />
</LinearLayout>
<LinearLayout android:id="@+id/taskbody"
android:layout_width="fill_parent"
android:layout_height="fill_parent"

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- See the file "LICENSE" for the full license governing this code. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="@drawable/background_gradient">
<!-- List -->
<ExpandableListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="100"
android:scrollbars="vertical"
android:cacheColorHint="#00000000"/>
<!-- List -->
<Button android:id="@+id/ok"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@android:string/ok"/>
</LinearLayout>

@ -7,15 +7,32 @@
android:orientation="vertical"
android:background="@drawable/widget_frame">
<ImageButton
android:id="@+id/widget_button"
android:src="@drawable/button_plus"
android:layout_gravity="right"
android:layout_width="100dp"
android:layout_height="50dp"
android:background="#00000000"
android:paddingLeft="36dp"
android:paddingTop="6dp"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="40dp">
<TextView
android:id="@+id/widget_title"
android:layout_gravity="left"
android:layout_width="82dp"
android:layout_height="47dp"
android:textColor="#ffffff"
android:textSize="14sp"
android:textStyle="bold"
android:gravity="center"
android:ellipsize="start" />
<ImageButton
android:id="@+id/widget_button"
android:src="@drawable/button_plus"
android:layout_gravity="right"
android:layout_width="35dp"
android:layout_height="47dp"
android:background="#00000000" />
</LinearLayout>
<LinearLayout android:id="@+id/taskbody"
android:layout_width="fill_parent"

@ -521,8 +521,11 @@ to the plugin creator for fastest service.
<!-- ====================================================== TasksWidget == -->
<!-- Widget text when loading tasks -->
<!-- Widget text when loading tasks -->
<string name="TWi_loading">Loading...</string>
<!-- Widget configuration activity title: select a filter -->
<string name="WCA_title">Select tasks to view...</string>
<!-- ============================================================= Misc == -->

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:configure="com.todoroo.astrid.widget.WidgetConfigActivity"
android:minWidth="142dip"
android:minHeight="142dip"
android:updatePeriodMillis="86400000"

@ -190,7 +190,7 @@ public class FilterListActivity extends ExpandableListActivity {
/** Sets up the coach list adapter */
protected void setUpList() {
adapter = new FilterAdapter(this, getExpandableListView(),
R.layout.filter_adapter_row);
R.layout.filter_adapter_row, false);
setListAdapter(adapter);
registerForContextMenu(getExpandableListView());

@ -24,6 +24,7 @@ import android.widget.TextView;
import com.timsu.astrid.R;
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;
@ -46,14 +47,16 @@ public class FilterAdapter extends BaseExpandableListAdapter {
private final FilterReceiver filterReceiver = new FilterReceiver();
private final int layout;
private final LayoutInflater inflater;
private final boolean skipIntentFilters;
public FilterAdapter(Activity activity, ExpandableListView listView,
int rowLayout) {
int rowLayout, boolean skipIntentFilters) {
super();
this.activity = activity;
this.items = new ArrayList<FilterListItem>();
this.listView = listView;
this.layout = rowLayout;
this.skipIntentFilters = skipIntentFilters;
inflater = (LayoutInflater) activity.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
@ -216,6 +219,12 @@ public class FilterAdapter extends BaseExpandableListAdapter {
final Parcelable[] filters = intent.getExtras().
getParcelableArray(AstridApiConstants.EXTRAS_RESPONSE);
for (Parcelable item : filters) {
FilterListItem filter = (FilterListItem) item;
if(skipIntentFilters && !(filter instanceof Filter ||
filter instanceof FilterListHeader ||
filter instanceof FilterCategory))
continue;
add((FilterListItem)item);
onReceiveFilter((FilterListItem)item);
}

@ -227,8 +227,7 @@ public class TaskDao extends GenericDao<Task> {
ReminderService.getInstance().scheduleAlarm(task);
Astrid2TaskProvider.notifyDatabaseModification();
ContextManager.getContext().startService(new Intent(ContextManager.getContext(),
TasksWidget.UpdateService.class));
TasksWidget.updateWidgets(ContextManager.getContext());
}
/**

@ -18,6 +18,7 @@ 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.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.activity.SortSelectionActivity;
import com.todoroo.astrid.activity.TaskEditActivity;
@ -36,6 +37,10 @@ public class TasksWidget extends AppWidgetProvider {
AstridDependencyInjector.initialize();
}
static final String PREF_TITLE = "taskswidget-title-"; //$NON-NLS-1$
static final String PREF_SQL = "taskswidget-sql-"; //$NON-NLS-1$
static final String PREF_VALUES = "taskswidget-values-"; //$NON-NLS-1$
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,
@ -49,14 +54,36 @@ public class TasksWidget extends AppWidgetProvider {
super.onUpdate(context, appWidgetManager, appWidgetIds);
// Start in service to prevent Application Not Responding timeout
context.startService(new Intent(context, UpdateService.class));
updateWidgets(context);
} catch (SecurityException e) {
// :(
}
}
/**
* Update all widgets
* @param id
*/
public static void updateWidgets(Context context) {
context.startService(new Intent(ContextManager.getContext(),
TasksWidget.UpdateService.class));
}
/**
* Update widget with the given id
* @param id
*/
public static void updateWidget(Context context, int id) {
Intent intent = new Intent(ContextManager.getContext(),
TasksWidget.UpdateService.class);
intent.putExtra(UpdateService.EXTRA_WIDGET_ID, id);
context.startService(intent);
}
public static class UpdateService extends Service {
public static String EXTRA_WIDGET_ID = "widget_id"; //$NON-NLS-1$
@Autowired
Database database;
@ -66,12 +93,22 @@ public class TasksWidget extends AppWidgetProvider {
@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);
int extrasId = intent.getIntExtra(EXTRA_WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
if(extrasId == AppWidgetManager.INVALID_APPWIDGET_ID) {
for(int id : manager.getAppWidgetIds(thisWidget)) {
RemoteViews updateViews = buildUpdate(this, id);
manager.updateAppWidget(id, updateViews);
}
} else {
int id = extrasId;
RemoteViews updateViews = buildUpdate(this, id);
manager.updateAppWidget(id, updateViews);
}
}
@Override
@ -80,7 +117,7 @@ public class TasksWidget extends AppWidgetProvider {
}
@SuppressWarnings("nls")
public RemoteViews buildUpdate(Context context) {
public RemoteViews buildUpdate(Context context, int widgetId) {
DependencyInjectionService.getInstance().inject(this);
RemoteViews views = null;
@ -99,11 +136,13 @@ public class TasksWidget extends AppWidgetProvider {
TodorooCursor<Task> cursor = null;
try {
Filter inboxFilter = CoreFilterExposer.buildInboxFilter(getResources());
Filter filter = getFilter(widgetId);
views.setTextViewText(R.id.widget_title, filter.title);
int flags = Preferences.getInt(SortSelectionActivity.PREF_SORT_FLAGS, 0);
int sort = Preferences.getInt(SortSelectionActivity.PREF_SORT_SORT, 0);
String query = SortSelectionActivity.adjustQueryForFlagsAndSort(
inboxFilter.sqlQuery, flags, sort) + " LIMIT " + numberOfTasks;
filter.sqlQuery, flags, sort) + " LIMIT " + numberOfTasks;
database.openForReading();
cursor = taskService.fetchFiltered(query, null, Task.TITLE, Task.DUE_DATE);
@ -147,5 +186,21 @@ public class TasksWidget extends AppWidgetProvider {
return views;
}
private Filter getFilter(int widgetId) {
// base our filter off the inbox filter, replace stuff if we have it
Filter filter = CoreFilterExposer.buildInboxFilter(getResources());
String sql = Preferences.getStringValue(PREF_SQL + widgetId);
if(sql != null)
filter.sqlQuery = sql;
String title = Preferences.getStringValue(PREF_TITLE + widgetId);
if(title != null)
filter.title = title;
String contentValues = Preferences.getStringValue(PREF_VALUES + widgetId);
if(contentValues != null)
filter.valuesForNewTasks = AndroidUtilities.contentValuesFromSerializedString(contentValues);
return filter;
}
}
}

@ -0,0 +1,133 @@
package com.todoroo.astrid.widget;
import android.app.ExpandableListActivity;
import android.appwidget.AppWidgetManager;
import android.content.ContentValues;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ExpandableListView;
import com.timsu.astrid.R;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.astrid.adapter.FilterAdapter;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterCategory;
import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.utility.Preferences;
public class WidgetConfigActivity extends ExpandableListActivity {
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
FilterAdapter adapter = null;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Set the result to CANCELED. This will cause the widget host to cancel
// out of the widget placement if they press the back button.
setResult(RESULT_CANCELED);
// Set the view layout resource to use.
setContentView(R.layout.widget_config_activity);
setTitle(R.string.WCA_title);
// Find the widget id from the intent.
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
// If they gave us an intent without the widget id, just bail.
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
}
// set up ui
adapter = new FilterAdapter(this, getExpandableListView(),
R.layout.filter_adapter_row, false);
setListAdapter(adapter);
Button button = (Button)findViewById(R.id.ok);
button.setOnClickListener(mOnClickListener);
}
View.OnClickListener mOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
// Save configuration options
saveConfiguration(adapter.getSelection());
// Push widget update to surface with newly set prefix
TasksWidget.updateWidget(WidgetConfigActivity.this, mAppWidgetId);
// Make sure we pass back the original appWidgetId
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
};
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
FilterListItem item = (FilterListItem) adapter.getChild(groupPosition,
childPosition);
if(item instanceof Filter) {
adapter.setSelection(item);
}
return true;
}
@Override
public void onGroupExpand(int groupPosition) {
FilterListItem item = (FilterListItem) adapter.getGroup(groupPosition);
if(item instanceof Filter)
adapter.setSelection(item);
else if(item instanceof FilterCategory)
adapter.saveExpansionSetting((FilterCategory) item, true);
}
@Override
public void onGroupCollapse(int groupPosition) {
FilterListItem item = (FilterListItem) adapter.getGroup(groupPosition);
if(item instanceof Filter)
adapter.setSelection(item);
else if(item instanceof FilterCategory)
adapter.saveExpansionSetting((FilterCategory) item, false);
}
@Override
protected void onResume() {
super.onResume();
adapter.registerRecevier();
}
@Override
protected void onPause() {
super.onPause();
adapter.unregisterRecevier();
}
private void saveConfiguration(FilterListItem filterListItem) {
String sql = null, contentValuesString = null, title = null;
if(filterListItem != null && filterListItem instanceof Filter) {
sql = ((Filter)filterListItem).sqlQuery;
ContentValues values = ((Filter)filterListItem).valuesForNewTasks;
if(values != null)
contentValuesString = AndroidUtilities.contentValuesToSerializedString(values);
title = ((Filter)filterListItem).title;
}
Preferences.setString(TasksWidget.PREF_TITLE + mAppWidgetId, title);
Preferences.setString(TasksWidget.PREF_SQL + mAppWidgetId, sql);
Preferences.setString(TasksWidget.PREF_VALUES + mAppWidgetId, contentValuesString);
}
}
Loading…
Cancel
Save