diff --git a/.classpath b/.classpath
index f4b028622..69c7a3e5a 100644
--- a/.classpath
+++ b/.classpath
@@ -2,6 +2,6 @@
-
+
diff --git a/res/layout/importance_spinner_dropdown.xml b/res/layout/importance_spinner_dropdown.xml
new file mode 100644
index 000000000..cfe049ab0
--- /dev/null
+++ b/res/layout/importance_spinner_dropdown.xml
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/res/layout/task_view.xml b/res/layout/task_view.xml
index 2cedf32b4..356b23b84 100644
--- a/res/layout/task_view.xml
+++ b/res/layout/task_view.xml
@@ -36,16 +36,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index ca2c1d6c4..1de6a63bb 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -25,8 +25,8 @@
#ffbbbbbb
#ffff0000
- #ffe36150
- #ffe3ad50
+ #ffec4a8e
+ #ffffbe33
#ffffffff
#ffb5b0a8
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5de126290..d31919efc 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -48,6 +48,8 @@
Edit Task
Delete Task
+ Start Timer
+ Stop Timer
Filters
Hidden/Blocked Tasks
Completed Tasks
diff --git a/src/com/timsu/astrid/activities/TaskEdit.java b/src/com/timsu/astrid/activities/TaskEdit.java
index e3649097d..ab1e9f1ef 100644
--- a/src/com/timsu/astrid/activities/TaskEdit.java
+++ b/src/com/timsu/astrid/activities/TaskEdit.java
@@ -59,9 +59,11 @@ import com.timsu.astrid.widget.NumberPickerDialog;
import com.timsu.astrid.widget.NumberPickerDialog.OnNumberPickedListener;
public class TaskEdit extends TaskModificationActivity {
- private static final int SAVE_ID = Menu.FIRST;
- private static final int DISCARD_ID = Menu.FIRST + 1;
- private static final int DELETE_ID = Menu.FIRST + 2;
+ private static final int SAVE_ID = Menu.FIRST;
+ private static final int DISCARD_ID = Menu.FIRST + 1;
+ private static final int DELETE_ID = Menu.FIRST + 2;
+
+ public static final int RESULT_DELETE = RESULT_FIRST_USER;
private EditText name;
private Spinner importance;
@@ -72,6 +74,8 @@ public class TaskEdit extends TaskModificationActivity {
private DateControlSet hiddenUntil;
private EditText notes;
+ private boolean shouldSaveState = true;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -116,6 +120,10 @@ public class TaskEdit extends TaskModificationActivity {
}
private void save() {
+ // usually, user accidentally created a new task
+ if(name.getText().length() == 0)
+ return;
+
model.setName(name.getText().toString());
model.setEstimatedSeconds(estimatedDuration.getTimeDurationInSeconds());
model.setElapsedSeconds(elapsedDuration.getTimeDurationInSeconds());
@@ -162,7 +170,7 @@ public class TaskEdit extends TaskModificationActivity {
ImportanceAdapter importanceAdapter = new ImportanceAdapter(this,
android.R.layout.simple_spinner_item,
- android.R.layout.simple_spinner_dropdown_item,
+ R.layout.importance_spinner_dropdown,
Importance.values());
importance.setAdapter(importanceAdapter);
}
@@ -247,12 +255,12 @@ public class TaskEdit extends TaskModificationActivity {
}
private void saveButtonClick() {
- save();
setResult(RESULT_OK);
finish();
}
private void discardButtonClick() {
+ shouldSaveState = false;
setResult(RESULT_CANCELED);
finish();
}
@@ -267,7 +275,8 @@ public class TaskEdit extends TaskModificationActivity {
@Override
public void onClick(DialogInterface dialog, int which) {
controller.deleteTask(model.getTaskIdentifier());
- setResult(RESULT_OK);
+ shouldSaveState = false;
+ setResult(RESULT_DELETE);
finish();
}
})
@@ -301,21 +310,30 @@ public class TaskEdit extends TaskModificationActivity {
item.setIcon(android.R.drawable.ic_menu_save);
item.setAlphabeticShortcut('s');
- item = menu.add(Menu.NONE, DISCARD_ID, 0, R.string.discard_label);
- item.setIcon(android.R.drawable.ic_menu_close_clear_cancel);
- item.setAlphabeticShortcut('c');
+ if(model.getTaskIdentifier() != null) {
+ item = menu.add(Menu.NONE, DISCARD_ID, 0, R.string.discard_label);
+ item.setIcon(android.R.drawable.ic_menu_close_clear_cancel);
+ item.setAlphabeticShortcut('c');
+ }
- item = menu.add(Menu.NONE, DISCARD_ID, 0, R.string.delete_label);
+ item = menu.add(Menu.NONE, DELETE_ID, 0, R.string.delete_label);
item.setIcon(android.R.drawable.ic_menu_delete);
item.setAlphabeticShortcut('d');
return true;
}
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ save();
+ super.onSaveInstanceState(outState);
+ }
+
@Override
protected void onPause() {
+ if(shouldSaveState)
+ save();
super.onPause();
- save();
}
@Override
diff --git a/src/com/timsu/astrid/activities/TaskList.java b/src/com/timsu/astrid/activities/TaskList.java
index 74e13442a..3b9c496d8 100644
--- a/src/com/timsu/astrid/activities/TaskList.java
+++ b/src/com/timsu/astrid/activities/TaskList.java
@@ -18,6 +18,7 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.timsu.astrid.activities;
+import java.util.Date;
import java.util.List;
import android.app.Activity;
@@ -70,6 +71,7 @@ public class TaskList extends Activity {
private static final int CONTEXT_EDIT_ID = Menu.FIRST + 10;
private static final int CONTEXT_DELETE_ID = Menu.FIRST + 11;
+ private static final int CONTEXT_TIMER_ID = Menu.FIRST + 12;
private static final int CONTEXT_FILTER_HIDDEN = Menu.FIRST + 20;
private static final int CONTEXT_FILTER_DONE = Menu.FIRST + 21;
@@ -78,6 +80,7 @@ public class TaskList extends Activity {
private ListView listView;
private Button addButton;
+ private List taskArray;
private boolean filterShowHidden = false;
private boolean filterShowDone = false;
@@ -135,8 +138,7 @@ public class TaskList extends Activity {
startManagingCursor(tasksCursor);
int totalTasks = tasksCursor.getCount();
- List taskArray =
- controller.createTaskListFromCursor(tasksCursor, !filterShowHidden);
+ taskArray = controller.createTaskListFromCursor(tasksCursor, !filterShowHidden);
int hiddenTasks = totalTasks - taskArray.size();
// hide "add" button if we have a few tasks
@@ -266,13 +268,19 @@ public class TaskList extends Activity {
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
TaskModelForList task = (TaskModelForList)v.getTag();
- int id = (int)task.getTaskIdentifier().getId();
- menu.add(id, CONTEXT_EDIT_ID, Menu.NONE,
+ menu.add(position, CONTEXT_EDIT_ID, Menu.NONE,
R.string.taskList_context_edit);
- menu.add(id, CONTEXT_DELETE_ID, Menu.NONE,
+ menu.add(position, CONTEXT_DELETE_ID, Menu.NONE,
R.string.taskList_context_delete);
+ int timerTitle;
+ if(task.getTimerStart() == null)
+ timerTitle = R.string.taskList_context_startTimer;
+ else
+ timerTitle = R.string.taskList_context_stopTimer;
+ menu.add(position, CONTEXT_TIMER_ID, Menu.NONE, timerTitle);
+
menu.setHeaderTitle(task.getName());
}
});
@@ -329,16 +337,24 @@ public class TaskList extends Activity {
return true;
case CONTEXT_EDIT_ID:
- long id = item.getGroupId(); // hackhack =(
-
+ TaskModelForList task = taskArray.get(item.getGroupId());
Intent intent = new Intent(TaskList.this, TaskEdit.class);
- intent.putExtra(TaskEdit.LOAD_INSTANCE_TOKEN, id);
+ intent.putExtra(TaskEdit.LOAD_INSTANCE_TOKEN, task.getTaskIdentifier().getId());
startActivityForResult(intent, ACTIVITY_EDIT);
return true;
case CONTEXT_DELETE_ID:
- id = item.getGroupId();
-
- deleteTask(new TaskIdentifier(id));
+ task = taskArray.get(item.getGroupId());
+ deleteTask(task.getTaskIdentifier());
+ return true;
+ case CONTEXT_TIMER_ID:
+ task = taskArray.get(item.getGroupId());
+ if(task.getTimerStart() == null)
+ task.setTimerStart(new Date());
+ else {
+ task.stopTimerAndUpdateElapsedTime();
+ }
+ controller.saveTask(task);
+ fillData();
return true;
case CONTEXT_FILTER_HIDDEN:
diff --git a/src/com/timsu/astrid/activities/TaskModificationActivity.java b/src/com/timsu/astrid/activities/TaskModificationActivity.java
index 2039fe163..7d1eef577 100644
--- a/src/com/timsu/astrid/activities/TaskModificationActivity.java
+++ b/src/com/timsu/astrid/activities/TaskModificationActivity.java
@@ -22,7 +22,7 @@ public abstract class TaskModificationActivity {
private static final int ACTIVITY_EDIT = 0;
+ private static final int EDIT_ID = Menu.FIRST;
+ private static final int DELETE_ID = Menu.FIRST + 1;
+
private TextView name;
private TextView elapsed;
private TextView estimated;
@@ -78,6 +85,8 @@ public class TaskView extends TaskModificationActivity {
return controller.fetchTaskForView(identifier);
}
+ // --- initialization
+
private void setUpUIComponents() {
Resources r = getResources();
setTitle(r.getString(R.string.taskView_title));
@@ -115,7 +124,7 @@ public class TaskView extends TaskModificationActivity {
}
};
- // update the UI
+ // update the timer UI
updateTimer = new Timer();
updateTimer.scheduleAtFixedRate(elapsedTimeUpdater, 0, 1000);
}
@@ -125,10 +134,7 @@ public class TaskView extends TaskModificationActivity {
edit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- Intent intent = new Intent(TaskView.this, TaskEdit.class);
- intent.putExtra(TaskEdit.LOAD_INSTANCE_TOKEN,
- model.getTaskIdentifier().getId());
- startActivityForResult(intent, ACTIVITY_EDIT);
+ editButtonClick();
}
});
@@ -139,11 +145,7 @@ public class TaskView extends TaskModificationActivity {
model.setTimerStart(new Date());
controller.saveTask(model);
} else {
- long start = model.getTimerStart().getTime();
- model.setTimerStart(null);
- long secondsElapsed = (System.currentTimeMillis() - start)/1000;
- model.setElapsedSeconds((int) (model.getElapsedSeconds() +
- secondsElapsed));
+ model.stopTimerAndUpdateElapsedTime();
controller.saveTask(model);
}
@@ -196,15 +198,33 @@ public class TaskView extends TaskModificationActivity {
view.setText(text);
}
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ MenuItem item;
+
+ item = menu.add(Menu.NONE, EDIT_ID, 0, R.string.edit_label);
+ item.setIcon(android.R.drawable.ic_menu_edit);
+ item.setAlphabeticShortcut('s');
+
+ item = menu.add(Menu.NONE, DELETE_ID, 0, R.string.delete_label);
+ item.setIcon(android.R.drawable.ic_menu_delete);
+ item.setAlphabeticShortcut('d');
+
+ return true;
+ }
+
+ // --- event handlers
+
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
- if(resultCode == RESULT_CANCELED)
- return;
- // if user edits a task, take them straight to the listing page
- setResult(resultCode);
- finish();
+ // if user doesn't click 'back', finish this activity too
+ if(resultCode != RESULT_CANCELED) {
+ setResult(resultCode);
+ finish();
+ }
}
@Override
@@ -218,6 +238,54 @@ public class TaskView extends TaskModificationActivity {
populateFields();
}
+ @Override
+ /** Cancel the timer thread */
+ protected void onDestroy() {
+ super.onDestroy();
+ updateTimer.cancel();
+ }
+
+ // --- event response methods
+
+ private void editButtonClick() {
+ Intent intent = new Intent(TaskView.this, TaskEdit.class);
+ intent.putExtra(TaskEdit.LOAD_INSTANCE_TOKEN,
+ model.getTaskIdentifier().getId());
+ startActivityForResult(intent, ACTIVITY_EDIT);
+ }
+
+ private void deleteButtonClick() {
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.delete_title)
+ .setMessage(R.string.delete_this_task_title)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setPositiveButton(android.R.string.ok,
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ controller.deleteTask(model.getTaskIdentifier());
+ setResult(RESULT_OK);
+ finish();
+ }
+ })
+ .setNegativeButton(android.R.string.cancel, null)
+ .show();
+ }
+
+ @Override
+ public boolean onMenuItemSelected(int featureId, MenuItem item) {
+ switch(item.getItemId()) {
+ case EDIT_ID:
+ editButtonClick();
+ return true;
+ case DELETE_ID:
+ deleteButtonClick();
+ return true;
+ }
+
+ return super.onMenuItemSelected(featureId, item);
+ }
+
/** Update components that depend on elapsed time */
private void updateElapsedTimeText() {
Resources r = getResources();
@@ -253,12 +321,5 @@ public class TaskView extends TaskModificationActivity {
progressDialog.setInitialValue(model.getProgressPercentage());
}
-
- @Override
- /** Cancel the timer thread */
- protected void onDestroy() {
- super.onDestroy();
- updateTimer.cancel();
- }
}
diff --git a/src/com/timsu/astrid/data/enums/Importance.java b/src/com/timsu/astrid/data/enums/Importance.java
index 4ca7d4dcf..e83cb3dda 100644
--- a/src/com/timsu/astrid/data/enums/Importance.java
+++ b/src/com/timsu/astrid/data/enums/Importance.java
@@ -15,7 +15,7 @@ public enum Importance {
int label;
int color;
- public static final Importance DEFAULT = LEVEL_2;
+ public static final Importance DEFAULT = LEVEL_3;
private Importance(int label, int color) {
this.label = label;
diff --git a/src/com/timsu/astrid/data/task/AbstractTaskModel.java b/src/com/timsu/astrid/data/task/AbstractTaskModel.java
index 8d205c7c9..3ae274d16 100644
--- a/src/com/timsu/astrid/data/task/AbstractTaskModel.java
+++ b/src/com/timsu/astrid/data/task/AbstractTaskModel.java
@@ -136,6 +136,15 @@ public abstract class AbstractTaskModel extends AbstractModel {
return getProgressPercentage() >= COMPLETE_PERCENTAGE;
}
+ /** Stops the timer & increments elapsed time. Requires timerStart and
+ * elapsedSeconds */
+ protected void stopTimerAndUpdateElapsedTime() {
+ long start = getTimerStart().getTime();
+ setTimerStart(null);
+ long secondsElapsed = (System.currentTimeMillis() - start)/1000;
+ setElapsedSeconds((int) (getElapsedSeconds() + secondsElapsed));
+ }
+
// --- task identifier
private TaskIdentifier identifier = null;
diff --git a/src/com/timsu/astrid/data/task/TaskController.java b/src/com/timsu/astrid/data/task/TaskController.java
index 6154a07f6..d8ce91ae7 100644
--- a/src/com/timsu/astrid/data/task/TaskController.java
+++ b/src/com/timsu/astrid/data/task/TaskController.java
@@ -1,9 +1,7 @@
package com.timsu.astrid.data.task;
-import java.util.Date;
import java.util.List;
-import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
@@ -46,27 +44,16 @@ public class TaskController extends AbstractController {
return database.delete(TASK_TABLE_NAME, KEY_ROWID + "=" + id, null) > 0;
}
- /** Sets the timer start time to the given value. Passing in "null"
- * signifies that the timer is not running. */
- public boolean startTimer(TaskModelForView task, Date startDate) throws
- SQLException {
- task.setTimerStart(startDate);
-
- long id = task.getTaskIdentifier().getId();
- ContentValues values = new ContentValues();
- AbstractTaskModel.putDate(values, AbstractTaskModel.TIMER_START,
- startDate);
- return database.update(TASK_TABLE_NAME, values, KEY_ROWID + "=" + id,
- null) > 0;
- }
-
/** Saves the given task to the database. Returns true on success. */
public boolean saveTask(AbstractTaskModel task) {
boolean saveSucessful;
if(task.getTaskIdentifier() == null) {
- saveSucessful = database.insert(TASK_TABLE_NAME, AbstractTaskModel.NAME,
- task.getMergedValues()) >= 0;
+ long newRow = database.insert(TASK_TABLE_NAME, AbstractTaskModel.NAME,
+ task.getMergedValues());
+ task.setTaskIdentifier(new TaskIdentifier(newRow));
+
+ saveSucessful = newRow >= 0;
} else {
long id = task.getTaskIdentifier().getId();
saveSucessful = database.update(TASK_TABLE_NAME, task.getSetValues(),
diff --git a/src/com/timsu/astrid/data/task/TaskModelForList.java b/src/com/timsu/astrid/data/task/TaskModelForList.java
index 732b0ffa6..ece2886c6 100644
--- a/src/com/timsu/astrid/data/task/TaskModelForList.java
+++ b/src/com/timsu/astrid/data/task/TaskModelForList.java
@@ -180,4 +180,14 @@ public class TaskModelForList extends AbstractTaskModel {
public void setProgressPercentage(int progressPercentage) {
super.setProgressPercentage(progressPercentage);
}
+
+ @Override
+ public void setTimerStart(Date timerStart) {
+ super.setTimerStart(timerStart);
+ }
+
+ @Override
+ public void stopTimerAndUpdateElapsedTime() {
+ super.stopTimerAndUpdateElapsedTime();
+ }
}
diff --git a/src/com/timsu/astrid/data/task/TaskModelForView.java b/src/com/timsu/astrid/data/task/TaskModelForView.java
index 8b88a7633..16a9a3f0b 100644
--- a/src/com/timsu/astrid/data/task/TaskModelForView.java
+++ b/src/com/timsu/astrid/data/task/TaskModelForView.java
@@ -99,7 +99,7 @@ public class TaskModelForView extends AbstractTaskModel {
}
@Override
- public void setElapsedSeconds(int elapsedSeconds) {
- super.setElapsedSeconds(elapsedSeconds);
+ public void stopTimerAndUpdateElapsedTime() {
+ super.stopTimerAndUpdateElapsedTime();
}
}