diff --git a/src/main/java/com/todoroo/astrid/data/Task.java b/src/main/java/com/todoroo/astrid/data/Task.java index 0543915b0..bd6facc63 100644 --- a/src/main/java/com/todoroo/astrid/data/Task.java +++ b/src/main/java/com/todoroo/astrid/data/Task.java @@ -383,7 +383,7 @@ public class Task extends RemoteModel { long dueDate = getDueDate(); long compareTo = hasDueTime() ? DateUtilities.now() : DateUtilities.getStartOfDay(DateUtilities.now()); - return dueDate < compareTo; + return dueDate < compareTo && !isCompleted(); } public boolean repeatAfterCompletion() { diff --git a/src/main/java/com/todoroo/astrid/widget/WidgetConfigActivity.java b/src/main/java/com/todoroo/astrid/widget/WidgetConfigActivity.java index 02d5b1cc4..f04895ef3 100644 --- a/src/main/java/com/todoroo/astrid/widget/WidgetConfigActivity.java +++ b/src/main/java/com/todoroo/astrid/widget/WidgetConfigActivity.java @@ -12,6 +12,7 @@ import android.os.Bundle; import android.util.DisplayMetrics; import android.view.View; import android.widget.Button; +import android.widget.CheckBox; import android.widget.ListView; import com.todoroo.andlib.utility.AndroidUtilities; @@ -39,6 +40,7 @@ public class WidgetConfigActivity extends InjectingListActivity { public static final String PREF_CUSTOM_INTENT = "widget-intent-"; public static final String PREF_CUSTOM_EXTRAS = "widget-extras-"; public static final String PREF_TAG_ID = "widget-tag-id-"; + public static final String PREF_DUE_DATE = "widget-due-date-"; int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; @@ -64,7 +66,6 @@ public class WidgetConfigActivity extends InjectingListActivity { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); - preferences.applyTheme(); // Set the result to CANCELED. This will cause the widget host to cancel // out of the widget placement if they press the back button. @@ -95,26 +96,24 @@ public class WidgetConfigActivity extends InjectingListActivity { setListAdapter(adapter); Button button = (Button)findViewById(R.id.ok); - button.setOnClickListener(mOnClickListener); + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // Save configuration options + CheckBox checkBox = (CheckBox) findViewById(R.id.showDueDate); + saveConfiguration(adapter.getSelection(), checkBox.isChecked()); + + updateWidget(); + + // Make sure we pass back the original appWidgetId + Intent resultValue = new Intent(); + resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); + setResult(RESULT_OK, resultValue); + finish(); + } + }); } - View.OnClickListener mOnClickListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - // Save configuration options - saveConfiguration(adapter.getSelection()); - - updateWidget(); - - // 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 protected void onListItemClick(ListView l, View v, int position, long id) { @@ -135,11 +134,13 @@ public class WidgetConfigActivity extends InjectingListActivity { adapter.unregisterRecevier(); } - private void saveConfiguration(FilterListItem filterListItem){ + private void saveConfiguration(FilterListItem filterListItem, boolean showDueDate){ DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); - String sql = null, contentValuesString = null, title = null; + String sql = null; + String contentValuesString = null; + String title = null; if(filterListItem != null && filterListItem instanceof Filter) { sql = ((Filter)filterListItem).getSqlQuery(); @@ -153,6 +154,7 @@ public class WidgetConfigActivity extends InjectingListActivity { preferences.setString(WidgetConfigActivity.PREF_TITLE + mAppWidgetId, title); preferences.setString(WidgetConfigActivity.PREF_SQL + mAppWidgetId, sql); preferences.setString(WidgetConfigActivity.PREF_VALUES + mAppWidgetId, contentValuesString); + preferences.setBoolean(WidgetConfigActivity.PREF_DUE_DATE + mAppWidgetId, showDueDate); if(filterListItem instanceof FilterWithCustomIntent) { String flattenedName = ((FilterWithCustomIntent)filterListItem).customTaskList.flattenToString(); diff --git a/src/main/java/com/todoroo/astrid/widget/WidgetUpdateService.java b/src/main/java/com/todoroo/astrid/widget/WidgetUpdateService.java index 4172912f2..a15e84faa 100644 --- a/src/main/java/com/todoroo/astrid/widget/WidgetUpdateService.java +++ b/src/main/java/com/todoroo/astrid/widget/WidgetUpdateService.java @@ -26,6 +26,7 @@ import org.slf4j.LoggerFactory; import org.tasks.R; import org.tasks.injection.InjectingService; import org.tasks.preferences.Preferences; +import org.tasks.widget.DueDateFormatter; import org.tasks.widget.WidgetHelper; import javax.inject.Inject; @@ -43,6 +44,7 @@ public class WidgetUpdateService extends InjectingService { @Inject WidgetHelper widgetHelper; @Inject Preferences preferences; @Inject SubtasksHelper subtasksHelper; + @Inject DueDateFormatter dueDateFormatter; @Override public void onStart(final Intent intent, int startId) { @@ -109,30 +111,32 @@ public class WidgetUpdateService extends InjectingService { filter.getSqlQuery(), flags, sort).replaceAll("LIMIT \\d+", "") + " LIMIT " + numberOfTasks; String tagName = preferences.getStringValue(WidgetConfigActivity.PREF_TITLE + widgetId); + boolean showDueDates = preferences.getBoolean(WidgetConfigActivity.PREF_DUE_DATE + widgetId, false); query = subtasksHelper.applySubtasksToWidgetFilter(filter, query, tagName, numberOfTasks); database.openForReading(); cursor = taskService.fetchFiltered(query, null, Task.ID, Task.TITLE, Task.DUE_DATE, Task.COMPLETION_DATE); int i; + Resources r = context.getResources(); for (i = 0; i < cursor.getCount() && i < numberOfTasks; i++) { cursor.moveToPosition(i); Task task = new Task(cursor); - - String textContent; - Resources r = context.getResources(); - int textColor = r - .getColor(preferences.isDarkWidgetTheme() ? R.color.widget_text_color_dark : R.color.widget_text_color_light); - - textContent = task.getTitle(); - + String textContent = task.getTitle(); + int textColor = r.getColor(preferences.isDarkWidgetTheme() + ? R.color.widget_text_color_dark + : R.color.widget_text_color_light); if(task.isCompleted()) { textColor = r.getColor(R.color.task_list_done); - } else if(task.hasDueDate() && task.isOverdue()) { - textColor = r.getColor(R.color.task_list_overdue); } RemoteViews row = new RemoteViews(Constants.PACKAGE, R.layout.widget_row); + if (showDueDates) { + dueDateFormatter.formatDueDate(row, task, textColor); + } else if(task.hasDueDate() && task.isOverdue()) { + textColor = r.getColor(R.color.task_list_overdue); + } + row.setTextViewText(R.id.text, textContent); row.setTextColor(R.id.text, textColor); diff --git a/src/main/java/org/tasks/widget/DueDateFormatter.java b/src/main/java/org/tasks/widget/DueDateFormatter.java new file mode 100644 index 000000000..ac86ae01e --- /dev/null +++ b/src/main/java/org/tasks/widget/DueDateFormatter.java @@ -0,0 +1,61 @@ +package org.tasks.widget; + +import android.content.Context; +import android.content.res.Resources; +import android.opengl.Visibility; +import android.view.View; +import android.widget.RemoteViews; + +import com.todoroo.andlib.utility.DateUtilities; +import com.todoroo.astrid.data.Task; + +import org.tasks.R; +import org.tasks.injection.ForApplication; + +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; + +import static org.tasks.date.DateTimeUtils.newDate; + +public class DueDateFormatter { + + private final Map dateCache = new HashMap<>(); + private final Context context; + private final Resources resources; + + @Inject + public DueDateFormatter(@ForApplication Context context) { + this.context = context; + resources = context.getResources(); + } + + public void formatDueDate(RemoteViews row, Task task, int textColor) { + if (task.hasDueDate() || task.hasDueTime()) { + row.setViewVisibility(R.id.dueDate, View.VISIBLE); + row.setTextViewText(R.id.dueDate, task.isCompleted() + ? resources.getString(R.string.TAd_completed, formatDate(task.getCompletionDate())) + : formatDate(task.getDueDate())); + row.setTextColor(R.id.dueDate, task.isOverdue() ? resources.getColor(R.color.task_list_overdue) : textColor); + } else { + row.setViewVisibility(R.id.dueDate, View.GONE); + } + } + + private String formatDate(long date) { + if (dateCache.containsKey(date)) { + return dateCache.get(date); + } + + String formatString = "%s %s"; + String string = DateUtilities.getRelativeDay(context, date); + if (Task.hasDueTime(date)) { + string = String.format(formatString, string, //$NON-NLS-1$ + DateUtilities.getTimeString(context, newDate(date))); + } + + dateCache.put(date, string); + return string; + } +} diff --git a/src/main/java/org/tasks/widget/ScrollableViewsFactory.java b/src/main/java/org/tasks/widget/ScrollableViewsFactory.java index 39c0a963c..cde5be34b 100644 --- a/src/main/java/org/tasks/widget/ScrollableViewsFactory.java +++ b/src/main/java/org/tasks/widget/ScrollableViewsFactory.java @@ -45,6 +45,8 @@ public class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFac private final Filter filter; private final int widgetId; private boolean dark; + private boolean showDueDates; + private final DueDateFormatter dueDateFormatter; private TodorooCursor cursor; @@ -65,10 +67,13 @@ public class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFac this.dark = dark; this.database = database; this.taskService = taskService; + + dueDateFormatter = new DueDateFormatter(context); } @Override public void onCreate() { + showDueDates = preferences.getBoolean(WidgetConfigActivity.PREF_DUE_DATE + widgetId, false); database.openForReading(); cursor = getCursor(); } @@ -146,9 +151,12 @@ public class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFac row.setInt(R.id.text, "setPaintFlags", Paint.STRIKE_THRU_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG); } else { row.setInt(R.id.text, "setPaintFlags", Paint.ANTI_ALIAS_FLAG); - if (task.hasDueDate() && task.isOverdue()) { - textColor = r.getColor(R.color.task_list_overdue); - } + } + + if (showDueDates) { + dueDateFormatter.formatDueDate(row, task, textColor); + } else if (task.hasDueDate() && task.isOverdue()) { + textColor = r.getColor(R.color.task_list_overdue); } row.setTextViewText(R.id.text, textContent); diff --git a/src/main/java/org/tasks/widget/WidgetHelper.java b/src/main/java/org/tasks/widget/WidgetHelper.java index 58e4c4abc..ca287ec44 100644 --- a/src/main/java/org/tasks/widget/WidgetHelper.java +++ b/src/main/java/org/tasks/widget/WidgetHelper.java @@ -14,13 +14,10 @@ import android.os.Bundle; import android.widget.RemoteViews; import com.todoroo.andlib.utility.AndroidUtilities; -import com.todoroo.astrid.activity.TaskEditActivity; -import com.todoroo.astrid.activity.TaskEditFragment; import com.todoroo.astrid.activity.TaskListActivity; import com.todoroo.astrid.activity.TaskListFragment; import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.FilterWithCustomIntent; -import com.todoroo.astrid.api.PermaSql; import com.todoroo.astrid.core.BuiltInFilterExposer; import com.todoroo.astrid.dao.TagDataDao; import com.todoroo.astrid.data.TagData; diff --git a/src/main/res/layout/widget_config_activity.xml b/src/main/res/layout/widget_config_activity.xml index d34682bc6..9bdae5e37 100644 --- a/src/main/res/layout/widget_config_activity.xml +++ b/src/main/res/layout/widget_config_activity.xml @@ -2,27 +2,38 @@ - + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="?attr/asContentBackground" + android:orientation="vertical"> + + + - + android:textSize="18sp" /> + + android:cacheColorHint="#00000000" + android:scrollbars="vertical"/>