Fix to postponed tasks to keep a per/task counter, bug fixes for refreshing the list.

pull/14/head
Tim Su 17 years ago
parent 3d5b8d45b3
commit 14766f250f

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.timsu.astrid" package="com.timsu.astrid"
android:versionCode="97" android:versionCode="98"
android:versionName="2.5.5"> android:versionName="2.6.0">
<meta-data android:name="com.a0soft.gphone.aTrackDog.webURL" <meta-data android:name="com.a0soft.gphone.aTrackDog.webURL"
android:value="http://www.weloveastrid.com" /> android:value="http://www.weloveastrid.com" />

@ -63,7 +63,7 @@
<item>Why postpone when you can um... not postpone!</item> <item>Why postpone when you can um... not postpone!</item>
<item>You\'ll finish this eventually, I presume?</item> <item>You\'ll finish this eventually, I presume?</item>
<item>I think you\'re really great! How about not putting this off?</item> <item>I think you\'re really great! How about not putting this off?</item>
<item>Every time you do that, God kills a kitten, meow!</item> <item>Every time you do that, you put yourself at risk!</item>
<item>Postpone, postpone, postpone. When will you change!</item> <item>Postpone, postpone, postpone. When will you change!</item>
<item>I\'ve had enough with your excuses! Just do it already!</item> <item>I\'ve had enough with your excuses! Just do it already!</item>
<item>Didn\'t you make that excuse last time?</item> <item>Didn\'t you make that excuse last time?</item>

@ -149,8 +149,8 @@
<string name="taskList_sort_duedate">Sort By Due Date</string> <string name="taskList_sort_duedate">Sort By Due Date</string>
<string name="taskList_sort_reverse">Sort Reverse</string> <string name="taskList_sort_reverse">Sort Reverse</string>
<string name="taskList_nonag_reminder">Select an Action:</string>
<string name="taskList_postpone_count">Times You\'ve Postponed: %d</string> <string name="taskList_postpone_count">Times You\'ve Postponed: %d</string>
<string name="taskList_postpone_firsttime">(You can turn off Astrid\'s Hints on the Settings screen)</string>
<string name="taskList_postpone_dialog">Postpone for how long?</string> <string name="taskList_postpone_dialog">Postpone for how long?</string>
<string name="taskList_cleanup_dialog">"Delete completed tasks older than # days:"</string> <string name="taskList_cleanup_dialog">"Delete completed tasks older than # days:"</string>
@ -364,10 +364,9 @@ Thanks for using Astrid!\n
<string name="prefs_category_other">Other</string> <string name="prefs_category_other">Other</string>
<string name="p_postponecount">ppcount</string>
<string name="p_nagging">nagging</string> <string name="p_nagging">nagging</string>
<string name="prefs_nagging_title">Nag Messages</string> <string name="prefs_nagging_title">Nag Messages</string>
<string name="prefs_nagging_desc">Astrid\'s little messages help you stay on track</string> <string name="prefs_nagging_desc">Show Astrid\'s comments when viewing reminders and postponing tasks?</string>
<string name="p_deadlineTime">deadline_time</string> <string name="p_deadlineTime">deadline_time</string>
<string name="prefs_deadlineTime_title">Default Deadlines</string> <string name="prefs_deadlineTime_title">Default Deadlines</string>

@ -68,10 +68,10 @@ public class TaskList extends Activity {
public static final String VARIABLES_TAG = "v"; public static final String VARIABLES_TAG = "v";
/** Minimum distance a fling must cover to trigger motion */ /** Minimum distance a fling must cover to trigger motion */
private static final int FLING_DIST_THRESHOLD = 160; private static final int FLING_DIST_THRESHOLD = 120;
/** Maximum distance in the other axis for a fling */ /** Maximum distance in the other axis for a fling */
private static final int MAX_FLING_OTHER_AXIS = 130; private static final int MAX_FLING_OTHER_AXIS = 150;
/** Minimum velocity a fling must have to trigger motion */ /** Minimum velocity a fling must have to trigger motion */
private static final int FLING_VEL_THRESHOLD = 300; private static final int FLING_VEL_THRESHOLD = 300;

@ -152,6 +152,7 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
public void setExpanded(View view, TaskModelForList task, boolean state) { public void setExpanded(View view, TaskModelForList task, boolean state) {
try { try {
if(state) { if(state) {
task.clearCache();
task.putCachedLabel(KEY_EXPANDED, CACHE_TRUE); task.putCachedLabel(KEY_EXPANDED, CACHE_TRUE);
hooks.setSelectedItem(task.getTaskIdentifier()); hooks.setSelectedItem(task.getTaskIdentifier());
} else { } else {
@ -561,11 +562,9 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
* @param position the index of the item * @param position the index of the item
*/ */
public void refreshItem(ListView listView, int position) { public void refreshItem(ListView listView, int position) {
View view = listView.getChildAt(position);
TaskModelForList task = hooks.getTaskArray().get(position); TaskModelForList task = hooks.getTaskArray().get(position);
task.clearCache(); task.clearCache();
listView.invalidateViews();
setupView(view, task);
} }
/** Set listeners for this view. This is called once total */ /** Set listeners for this view. This is called once total */

@ -119,7 +119,8 @@ public class TaskListSubActivity extends SubActivity {
private static final int SORTFLAG_FILTERHIDDEN = (1 << 6); private static final int SORTFLAG_FILTERHIDDEN = (1 << 6);
private static final int HIDE_ADD_BTN_PORTRAIT = 4; private static final int HIDE_ADD_BTN_PORTRAIT = 4;
private static final int HIDE_ADD_BTN_LANDSCPE = 2; private static final int HIDE_ADD_BTN_LANDSCPE = 2;
private static final float POSTPONE_STAT_PCT = 0.2f; private static final float POSTPONE_STAT_PCT = 0.4f;
private static final int AUTO_REFRESH_MAX_LIST_SIZE = 50;
// UI components // UI components
private ListView listView; private ListView listView;
@ -400,7 +401,7 @@ public class TaskListSubActivity extends SubActivity {
String[] responses = r.getStringArray(R.array.reminder_responses); String[] responses = r.getStringArray(R.array.reminder_responses);
response = responses[new Random().nextInt(responses.length)]; response = responses[new Random().nextInt(responses.length)];
} else } else
response = ""; response = r.getString(R.string.taskList_nonag_reminder);
new AlertDialog.Builder(getParent()) new AlertDialog.Builder(getParent())
.setTitle(R.string.taskView_notifyTitle) .setTitle(R.string.taskView_notifyTitle)
.setMessage(task.getName() + "\n\n" + response) .setMessage(task.getName() + "\n\n" + response)
@ -815,8 +816,20 @@ public class TaskListSubActivity extends SubActivity {
void onWindowFocusChanged(boolean hasFocus) { void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus); super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
if (shouldRefreshTaskList) if (shouldRefreshTaskList)
reloadList(); reloadList();
else if (context.taskArray != null &&
context.taskArray.size() > 0 &&
context.taskArray.size() < AUTO_REFRESH_MAX_LIST_SIZE) {
// invalidate caches
for (TaskModelForList task : context.taskArray)
task.clearCache();
listView.invalidateViews();
}
}
shouldRefreshTaskList = false; shouldRefreshTaskList = false;
} }
@ -966,6 +979,9 @@ public class TaskListSubActivity extends SubActivity {
new OnNNumberPickedListener() { new OnNNumberPickedListener() {
public void onNumbersPicked(int[] values) { public void onNumbersPicked(int[] values) {
long postponeMillis = (values[0] * 24 + values[1]) * 3600L * 1000; long postponeMillis = (values[0] * 24 + values[1]) * 3600L * 1000;
if(postponeMillis <= 0)
return;
task.setPreferredDueDate(computePostponeDate(task task.setPreferredDueDate(computePostponeDate(task
.getPreferredDueDate(), postponeMillis, .getPreferredDueDate(), postponeMillis,
true)); true));
@ -974,23 +990,16 @@ public class TaskListSubActivity extends SubActivity {
task.setHiddenUntil(computePostponeDate(task. task.setHiddenUntil(computePostponeDate(task.
getHiddenUntil(), postponeMillis, false)); getHiddenUntil(), postponeMillis, false));
getTaskController().saveTask(task);
getTaskController().updateAlarmForTask(
task.getTaskIdentifier());
context.listAdapter.refreshItem(listView,
context.taskArray.indexOf(task));
// show nag // show nag
int postponeCount = Preferences.getPostponeCount(getParent()); int postponeCount = getTaskController().fetchTaskPostponeCount(
task.getTaskIdentifier()) + 1;
if(Preferences.shouldShowNags(getParent())) { if(Preferences.shouldShowNags(getParent())) {
Random random = new Random(); Random random = new Random();
final String nagText; final String nagText;
if(postponeCount == 1 || postponeCount == 5) if(postponeCount > 1 && random.nextFloat() < POSTPONE_STAT_PCT) {
nagText = r.getString(R.string.taskList_postpone_firsttime);
else if(random.nextFloat() < POSTPONE_STAT_PCT)
nagText = r.getString(R.string.taskList_postpone_count, nagText = r.getString(R.string.taskList_postpone_count,
postponeCount); postponeCount);
else { } else {
String[] nags = r.getStringArray(R.array.postpone_nags); String[] nags = r.getStringArray(R.array.postpone_nags);
nagText = nags[random.nextInt(nags.length)]; nagText = nags[random.nextInt(nags.length)];
} }
@ -1002,7 +1011,13 @@ public class TaskListSubActivity extends SubActivity {
} }
}); });
} }
Preferences.setPostponeCount(getParent(), postponeCount + 1); task.setPostponeCount(postponeCount);
getTaskController().saveTask(task);
getTaskController().updateAlarmForTask(
task.getTaskIdentifier());
context.listAdapter.refreshItem(listView,
context.taskArray.indexOf(task));
} }
}); });
} }

@ -45,7 +45,7 @@ import com.timsu.astrid.utilities.Preferences;
public abstract class AbstractTaskModel extends AbstractModel { public abstract class AbstractTaskModel extends AbstractModel {
/** Version number of this model */ /** Version number of this model */
static final int VERSION = 4; static final int VERSION = 5;
public static final int COMPLETE_PERCENTAGE = 100; public static final int COMPLETE_PERCENTAGE = 100;
@ -61,6 +61,7 @@ public abstract class AbstractTaskModel extends AbstractModel {
static final String DEFINITE_DUE_DATE = "definiteDueDate"; static final String DEFINITE_DUE_DATE = "definiteDueDate";
static final String PREFERRED_DUE_DATE = "preferredDueDate"; static final String PREFERRED_DUE_DATE = "preferredDueDate";
static final String HIDDEN_UNTIL = "hiddenUntil"; static final String HIDDEN_UNTIL = "hiddenUntil";
static final String POSTPONE_COUNT = "postponeCount";
static final String NOTIFICATIONS = "notifications"; static final String NOTIFICATIONS = "notifications";
static final String NOTIFICATION_FLAGS = "notificationFlags"; static final String NOTIFICATION_FLAGS = "notificationFlags";
static final String LAST_NOTIFIED = "lastNotified"; static final String LAST_NOTIFIED = "lastNotified";
@ -95,6 +96,7 @@ public abstract class AbstractTaskModel extends AbstractModel {
defaultValues.put(PREFERRED_DUE_DATE, (Long)null); defaultValues.put(PREFERRED_DUE_DATE, (Long)null);
defaultValues.put(HIDDEN_UNTIL, (Long)null); defaultValues.put(HIDDEN_UNTIL, (Long)null);
defaultValues.put(BLOCKING_ON, (Long)null); defaultValues.put(BLOCKING_ON, (Long)null);
defaultValues.put(POSTPONE_COUNT, 0);
defaultValues.put(NOTIFICATIONS, 0); defaultValues.put(NOTIFICATIONS, 0);
defaultValues.put(NOTIFICATION_FLAGS, NOTIFY_AT_DEADLINE); defaultValues.put(NOTIFICATION_FLAGS, NOTIFY_AT_DEADLINE);
defaultValues.put(LAST_NOTIFIED, (Long)null); defaultValues.put(LAST_NOTIFIED, (Long)null);
@ -130,6 +132,7 @@ public abstract class AbstractTaskModel extends AbstractModel {
append(PREFERRED_DUE_DATE).append(" integer,"). append(PREFERRED_DUE_DATE).append(" integer,").
append(HIDDEN_UNTIL).append(" integer,"). append(HIDDEN_UNTIL).append(" integer,").
append(BLOCKING_ON).append(" integer,"). append(BLOCKING_ON).append(" integer,").
append(POSTPONE_COUNT).append(" integer,").
append(NOTIFICATIONS).append(" integer,"). append(NOTIFICATIONS).append(" integer,").
append(NOTIFICATION_FLAGS).append(" integer,"). append(NOTIFICATION_FLAGS).append(" integer,").
append(LAST_NOTIFIED).append(" integer,"). append(LAST_NOTIFIED).append(" integer,").
@ -189,7 +192,18 @@ public abstract class AbstractTaskModel extends AbstractModel {
Log.e("astrid", "Error updating table!", e); Log.e("astrid", "Error updating table!", e);
} }
case 4:
sql = new StringBuilder().append("ALTER TABLE ").
append(tableName).append(" ADD COLUMN ").
append(POSTPONE_COUNT).append(" integer").toString();
try {
db.execSQL(sql);
} catch (Exception e) {
Log.e("astrid", "Error updating table!", e);
}
break; break;
default: default:
// we don't know how to handle it... do the unfortunate thing // we don't know how to handle it... do the unfortunate thing
Log.e(getClass().getSimpleName(), "Unsupported migration, table dropped!"); Log.e(getClass().getSimpleName(), "Unsupported migration, table dropped!");
@ -254,6 +268,8 @@ public abstract class AbstractTaskModel extends AbstractModel {
getHiddenUntil(); getHiddenUntil();
else if(field.equals(BLOCKING_ON)) else if(field.equals(BLOCKING_ON))
getBlockingOn(); getBlockingOn();
else if(field.equals(POSTPONE_COUNT))
getPostponeCount();
else if(field.equals(NOTIFICATIONS)) else if(field.equals(NOTIFICATIONS))
getNotificationIntervalSeconds(); getNotificationIntervalSeconds();
else if(field.equals(CREATION_DATE)) else if(field.equals(CREATION_DATE))
@ -400,6 +416,10 @@ public abstract class AbstractTaskModel extends AbstractModel {
return new TaskIdentifier(value); return new TaskIdentifier(value);
} }
protected Integer getPostponeCount() {
return retrieveInteger(POSTPONE_COUNT);
}
protected Integer getNotificationIntervalSeconds() { protected Integer getNotificationIntervalSeconds() {
return retrieveInteger(NOTIFICATIONS); return retrieveInteger(NOTIFICATIONS);
} }
@ -484,6 +504,10 @@ public abstract class AbstractTaskModel extends AbstractModel {
putIfChangedFromDatabase(BLOCKING_ON, blockingOn.getId()); putIfChangedFromDatabase(BLOCKING_ON, blockingOn.getId());
} }
protected void setPostponeCount(int postponeCount) {
putIfChangedFromDatabase(POSTPONE_COUNT, postponeCount);
}
protected void setCreationDate(Date creationDate) { protected void setCreationDate(Date creationDate) {
putDate(CREATION_DATE, creationDate); putDate(CREATION_DATE, creationDate);
} }

@ -450,15 +450,6 @@ public class TaskController extends AbstractController {
return model; return model;
} }
/** Updates the alarm for the task identified by the given id */
public void updateAlarmForTask(TaskIdentifier taskId) throws SQLException {
TaskModelForNotify task = fetchTaskForNotify(taskId);
AlertController alertController = new AlertController(context);
alertController.open();
Notifications.updateAlarm(context, this, alertController, task);
alertController.close();
}
/** Returns null if unsuccessful, otherwise moves cursor to the task. /** Returns null if unsuccessful, otherwise moves cursor to the task.
* Don't forget to close the cursor when you're done. */ * Don't forget to close the cursor when you're done. */
private Cursor fetchTaskCursor(TaskIdentifier taskId, String[] fieldList) { private Cursor fetchTaskCursor(TaskIdentifier taskId, String[] fieldList) {
@ -472,6 +463,33 @@ public class TaskController extends AbstractController {
return cursor; return cursor;
} }
// --- methods supporting individual features
/** Returns a TaskModelForView corresponding to the given TaskIdentifier */
public int fetchTaskPostponeCount(TaskIdentifier taskId) throws SQLException {
Cursor cursor = fetchTaskCursor(taskId, new String[] {AbstractTaskModel.POSTPONE_COUNT});
try {
if (cursor == null || cursor.getCount() == 0)
return 0;
cursor.moveToFirst();
return cursor.getInt(0);
} catch (Exception e) {
return 0;
} finally {
if(cursor != null)
cursor.close();
}
}
/** Updates the alarm for the task identified by the given id */
public void updateAlarmForTask(TaskIdentifier taskId) throws SQLException {
TaskModelForNotify task = fetchTaskForNotify(taskId);
AlertController alertController = new AlertController(context);
alertController.open();
Notifications.updateAlarm(context, this, alertController, task);
alertController.close();
}
// --- boilerplate // --- boilerplate
/** /**

@ -253,4 +253,9 @@ public class TaskModelForList extends AbstractTaskModel {
public void setHiddenUntil(Date hiddenUntil) { public void setHiddenUntil(Date hiddenUntil) {
super.setHiddenUntil(hiddenUntil); super.setHiddenUntil(hiddenUntil);
} }
@Override
public void setPostponeCount(int postponeCount) {
super.setPostponeCount(postponeCount);
}
} }

@ -46,9 +46,6 @@ public class Preferences {
if(!prefs.contains(r.getString(R.string.p_deadlineTime))) { if(!prefs.contains(r.getString(R.string.p_deadlineTime))) {
editor.putString(r.getString(R.string.p_deadlineTime), "1"); editor.putString(r.getString(R.string.p_deadlineTime), "1");
} }
if(!prefs.contains(r.getString(R.string.p_postponecount))) {
editor.putInt(r.getString(R.string.p_postponecount), 0);
}
if(!prefs.contains(r.getString(R.string.p_notif_defaultRemind))) { if(!prefs.contains(r.getString(R.string.p_notif_defaultRemind))) {
editor.putString(r.getString(R.string.p_notif_defaultRemind), "0"); editor.putString(r.getString(R.string.p_notif_defaultRemind), "0");
} }
@ -174,23 +171,6 @@ public class Preferences {
getString(R.string.p_nagging), true); getString(R.string.p_nagging), true);
} }
/** gets # of times user has postponed a task */
public static int getPostponeCount(Context context) {
try {
return getPrefs(context).getInt(context.getResources().
getString(R.string.p_postponecount), 0);
} catch (ClassCastException e) {
return 0;
}
}
/** sets # of times user has postponed a task */
public static void setPostponeCount(Context context, int value) {
Editor editor = getPrefs(context).edit();
editor.putInt(context.getResources().getString(R.string.p_postponecount), value);
editor.commit();
}
// --- appearance settings // --- appearance settings
/** returns the font size user wants on the front page */ /** returns the font size user wants on the front page */

Loading…
Cancel
Save