Got rid of taskview, now handling that function by expanding the list row. Appropriate hacks to notification. Also, new pink chat icon.

pull/14/head
Tim Su 16 years ago
parent 4e256262bc
commit c0cbd60444

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.timsu.astrid"
android:versionCode="74"
android:versionName="2.2.0">
android:versionCode="75"
android:versionName="2.2.5">
<meta-data android:name="com.a0soft.gphone.aTrackDog.webURL"
android:value="http://www.weloveastrid.com" />
@ -14,22 +14,15 @@
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".activities.TaskList"
android:label="@string/app_name">
<activity android:name=".activities.TaskList">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".activities.TaskView"
android:theme="@android:style/Theme.Dialog">
</activity>
<activity android:name=".activities.TaskViewNotifier"
android:excludeFromRecents="true"
android:theme="@android:style/Theme.Dialog"
android:launchMode="singleTask" />
<activity android:name=".activities.TaskListNotify"
android:launchMode="singleTop" />
<activity android:name=".activities.TaskEdit"
android:label="@string/taskEdit_label"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -79,39 +79,48 @@
color="@color/taskList_dueDate"
android:singleLine="true"/>
<!-- elapsed / estimated time -->
<TextView android:id="@+id/text_times"
<!-- other details (gray) -->
<TextView android:id="@+id/details"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
style="@style/TextAppearance.TaskList_Detail"
android:singleLine="true"/>
<!-- repeats -->
<TextView android:id="@+id/text_repeats"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
style="@style/TextAppearance.TaskList_Detail"
android:singleLine="true"/>
<!-- reminders -->
<TextView android:id="@+id/text_reminders"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
style="@style/TextAppearance.TaskList_Detail"
android:singleLine="true"/>
style="@style/TextAppearance.TaskList_Detail"/>
<!-- tags -->
<TextView android:id="@+id/text_tags"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
style="@style/TextAppearance.TaskList_Detail"
android:singleLine="true"/>
<LinearLayout android:id="@+id/expanded_layout"
android:orientation="vertical"
android:paddingTop="5dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<!-- notes -->
<TextView android:id="@+id/text_notes"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
style="@style/TextAppearance.TaskList_Detail"/>
<View android:background="@android:drawable/divider_horizontal_dark"
android:layout_width="fill_parent"
android:layout_height="1dip"/>
<TextView android:id="@+id/expanded_details"
android:paddingTop="5dip"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
style="@style/TextAppearance.TaskList_Detail"/>
<LinearLayout android:id="@+id/expanded_buttons"
android:orientation="horizontal"
android:paddingTop="5dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button android:id="@+id/timer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"/>
<Button android:id="@+id/edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="@string/edit_label"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>

@ -1,220 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
ASTRID: Android's Simple Task Recording Dashboard
Copyright (c) 2009 Tim Su
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scroll_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout android:id="@+id/view_layout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/name"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:textAppearance="?android:attr/textAppearanceLargeInverse"
android:gravity="center_horizontal"
android:padding="5dip"/>
<!-- Button Row -->
<LinearLayout android:id="@+id/button_layout"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="15dip">
<Button android:id="@+id/timerButton"
android:gravity="center"
android:layout_weight="0.5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/startTimer_label"/>
<Button android:id="@+id/progress"
android:gravity="center"
android:layout_weight="0.5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<!-- Elapsed Time -->
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5px"
android:paddingTop="5px"
android:text="@string/taskView_elapsed"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView android:id="@+id/cell_elapsed"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5px"
android:textAppearance="?android:attr/textAppearanceSmall"
android:colorForeground="@color/view_table_values" />
</LinearLayout>
<!-- Estimated Time -->
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5px"
android:src="@android:drawable/divider_horizontal_bright" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5px"
android:text="@string/taskView_estimated"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView android:id="@+id/cell_estimated"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5px"
android:textAppearance="?android:attr/textAppearanceSmall"
android:colorForeground="@color/view_table_values" />
</LinearLayout>
<!-- Notes -->
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5px"
android:src="@android:drawable/divider_horizontal_bright" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5px"
android:text="@string/taskView_notes"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView android:id="@+id/cell_notes"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5px"
android:autoLink="all"
android:textAppearance="?android:attr/textAppearanceSmall"
android:colorForeground="@color/view_table_values" />
</LinearLayout>
<!-- Absolute Deadline -->
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5px"
android:src="@android:drawable/divider_horizontal_bright" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5px"
android:text="@string/taskView_definiteDueDate"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView android:id="@+id/cell_definiteDueDate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5px"
android:textAppearance="?android:attr/textAppearanceSmall"
android:colorForeground="@color/view_table_values" />
</LinearLayout>
<!-- Goal Deadline -->
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5px"
android:src="@android:drawable/divider_horizontal_bright" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5px"
android:text="@string/taskView_preferredDueDate"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView android:id="@+id/cell_preferredDueDate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5px"
android:textAppearance="?android:attr/textAppearanceSmall"
android:colorForeground="@color/view_table_values" />
</LinearLayout>
<!-- Creation Date -->
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5px"
android:src="@android:drawable/divider_horizontal_bright" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5px"
android:text="@string/taskView_creationDate"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView android:id="@+id/cell_creationDate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="5px"
android:textAppearance="?android:attr/textAppearanceSmall"
android:colorForeground="@color/view_table_values" />
</LinearLayout>
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="5px" />
<Button android:id="@+id/edit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/edit_label"/>
</LinearLayout>
</ScrollView>

@ -56,16 +56,16 @@
<item quantity="other">%d Tags</item>
</plurals>
<!-- Time Constants -->
<string name="daysVertical">D\na\ny\ns</string>
<string name="hoursVertical">H\no\nu\nr\ns</string>
<plurals name="Ndays">
<item quantity="one">1 Day</item>
<item quantity="other">%d Days</item>
</plurals>
<string name="daysVertical">D\na\ny\ns</string>
<plurals name="Nhours">
<item quantity="one">1 Hour</item>
<item quantity="other">%d Hours</item>
</plurals>
<string name="hoursVertical">H\no\nu\nr\ns</string>
<plurals name="Nminutes">
<item quantity="one">1 Minute</item>
<item quantity="other">%d Minutes</item>
@ -74,6 +74,19 @@
<item quantity="one">1 Second</item>
<item quantity="other">%d Seconds</item>
</plurals>
<plurals name="NhoursShort">
<item quantity="one">1 Hr</item>
<item quantity="other">%d Hrs</item>
</plurals>
<plurals name="NminutesShort">
<item quantity="one">1 Min</item>
<item quantity="other">%d Min</item>
</plurals>
<plurals name="NsecondsShort">
<item quantity="one">1 Sec</item>
<item quantity="other">%d Sec</item>
</plurals>
<string name="ago_suffix">Ago</string>
<!-- TaskList -->
<skip />
@ -91,9 +104,10 @@
<string name="taskList_elapsedTimePrefix">Spent:</string>
<string name="taskList_periodicReminderPrefix">Reminder Every</string>
<string name="taskList_repeatPrefix">Repeats Every</string>
<string name="taskList_alarmSuffix">Set</string>
<string name="taskList_alarmPrefix">Next Alarm:</string>
<string name="taskList_tagsPrefix">Tags:</string>
<string name="taskList_notesPrefix">Notes:</string>
<string name="taskList_createdPrefix">Created:</string>
<string name="taskList_menu_insert">Add</string>
<string name="taskList_menu_tags">Tags</string>
@ -175,30 +189,18 @@ If you don\'t want to see the new task right after you complete the old one, you
<!-- buttons -->
<string name="save_label">Save</string>
<string name="discard_label">Discard</string>
<string name="edit_label">Edit</string>
<string name="delete_label">Delete</string>
<string name="blank_button_title">Click to Set</string>
<string name="startTimer_label">Start Timer</string>
<string name="stopTimer_label">Stop Timer</string>
<string name="taskEdit_menu_save">Save</string>
<!-- TaskView -->
<skip />
<string name="taskView_title">Astrid: Task Properties</string>
<string name="taskView_notifyTitle">Astrid says...</string>
<string name="startTimer_label">Start Timer</string>
<string name="stopTimer_label">Stop Timer</string>
<string name="progress_suffix">% Done</string>
<string name="edit_label">Edit Task</string>
<string name="taskView_elapsed">Elapsed Time</string>
<string name="taskView_estimated">Estimated Time</string>
<string name="taskView_definiteDueDate">Absolute Deadline</string>
<string name="taskView_preferredDueDate">Goal Deadline</string>
<string name="taskView_creationDate">Creation Date</string>
<string name="taskView_tags">Tags</string>
<string name="taskView_notes">Task Notes</string>
<string name="overdue_suffix"> Overdue</string>
<string name="ago_suffix"> Ago</string>
<string name="progress_dialog">% of Task Finished</string>
<!-- Tag List -->
<skip />
@ -257,9 +259,10 @@ Wish me luck!\n
<skip />
<string name="information_title">Information</string>
<string name="question_title">Question</string>
<string name="notify_yes">Let\'s do it!</string>
<string name="notify_snooze">Snooze!</string>
<string name="notify_no">No, quit.</string>
<string name="notify_yes">View Task</string>
<string name="notify_done">Already Done!</string>
<string name="notify_snooze">Snooze</string>
<string name="notify_no">Quit</string>
<string name="notify_snooze_title">Hours/minutes to snooze?</string>
<string name="delete_title">Delete</string>

@ -42,11 +42,6 @@
<PreferenceScreen
android:title="@string/displayedFields_PrefScreen_Title"
android:summary="@string/displayedFields_PrefScreen_Desc">
<CheckBoxPreference
android:key="@string/prefs_titleVisible"
android:title="@string/prefs_titleVisible_title"
android:summary="@string/prefs_titleVisible_desc"
android:defaultValue="@string/prefs_titleVisible_default" />
<CheckBoxPreference
android:key="@string/prefs_deadlineVisible"
android:title="@string/prefs_deadlineVisible_title"

@ -8,14 +8,12 @@ import android.content.res.Resources;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
@ -31,21 +29,21 @@ import com.timsu.astrid.utilities.StartupReceiver;
/**
* Main activity uses a ViewFlipper to flip between child views.
*
*
* @author Tim Su (timsu@stanfordalumni.org)
*/
public class TaskList extends Activity {
/**
* Interface for views that are displayed from the main view page
*
*
* @author timsu
*/
abstract public static class SubActivity {
private TaskList parent;
private ActivityCode code;
private View view;
public SubActivity(TaskList parent, ActivityCode code, View view) {
this.parent = parent;
this.code = code;
@ -54,105 +52,107 @@ public class TaskList extends Activity {
}
// --- pass-through to activity listeners
/** Called when this subactivity is displayed to the user */
void onDisplay(Bundle variables) {
//
}
boolean onPrepareOptionsMenu(Menu menu) {
return false;
}
void onActivityResult(int requestCode, int resultCode, Intent data) {
//
}
boolean onMenuItemSelected(int featureId, MenuItem item) {
return false;
}
void onWindowFocusChanged(boolean hasFocus) {
//
}
boolean onKeyDown(int keyCode, KeyEvent event) {
return false;
}
// --- pass-through to activity methods
public Resources getResources() {
return parent.getResources();
}
public View findViewById(int id) {
return view.findViewById(id);
}
public void startManagingCursor(Cursor c) {
parent.startManagingCursor(c);
}
public void setTitle(CharSequence title) {
parent.setTitle(title);
}
public void closeActivity() {
parent.finish();
}
public void launchActivity(Intent intent, int requestCode) {
parent.startActivityForResult(intent, requestCode);
}
// --- helper methods
public Activity getParent() {
return parent;
}
public TaskController getTaskController() {
return parent.taskController;
}
public TagController getTagController() {
return parent.tagController;
}
public View.OnTouchListener getGestureListener() {
return parent.gestureListener;
}
public void switchToActivity(ActivityCode activity, Bundle state) {
parent.switchToActivity(activity, state);
}
// --- internal methods
protected ActivityCode getActivityCode() {
return code;
}
protected View getView() {
return view;
}
}
/* ======================================================================
* ======================================================= internal stuff
* ====================================================================== */
public enum ActivityCode {
TASK_LIST,
TAG_LIST,
TASK_LIST_W_TAG
};
private static final String TAG_LAST_ACTIVITY = "l";
private static final String TAG_LAST_BUNDLE = "b";
private static final String LAST_ACTIVITY_TAG = "l";
private static final String LAST_BUNDLE_TAG = "b";
public static final String VARIABLES_TAG = "v";
private static final int FLING_DIST_THRESHOLD = 100;
private static final int FLING_VEL_THRESHOLD = 300;
@ -164,20 +164,20 @@ public class TaskList extends Activity {
private SubActivity tagList;
private SubActivity taskListWTag;
private Bundle lastActivityBundle;
// animations
private Animation mInAnimationForward;
private Animation mOutAnimationForward;
private Animation mInAnimationBackward;
private Animation mOutAnimationBackward;
// data controllers
private TaskController taskController;
private TagController tagController;
// static variables
static boolean shouldCloseInstance = false;
@Override
/** Called when loading up the activity for the first time */
public void onCreate(Bundle savedInstanceState) {
@ -195,13 +195,16 @@ public class TaskList extends Activity {
Synchronizer.setTaskController(taskController);
setupUIComponents();
if(savedInstanceState != null && savedInstanceState.containsKey(TAG_LAST_ACTIVITY)) {
viewFlipper.setDisplayedChild(savedInstanceState.getInt(TAG_LAST_ACTIVITY));
Bundle variables = savedInstanceState.getBundle(TAG_LAST_BUNDLE);
if(savedInstanceState != null && savedInstanceState.containsKey(LAST_ACTIVITY_TAG)) {
viewFlipper.setDisplayedChild(savedInstanceState.getInt(LAST_ACTIVITY_TAG));
Bundle variables = savedInstanceState.getBundle(LAST_BUNDLE_TAG);
getCurrentSubActivity().onDisplay(variables);
} else {
getCurrentSubActivity().onDisplay(null);
Bundle variables = null;
if(getIntent().hasExtra(VARIABLES_TAG))
variables = getIntent().getBundleExtra(VARIABLES_TAG);
getCurrentSubActivity().onDisplay(variables);
}
// auto sync if requested
@ -215,23 +218,23 @@ public class TaskList extends Activity {
}
}
}
/** Set up user interface components */
private void setupUIComponents() {
gestureDetector = new GestureDetector(new AstridGestureDetector());
viewFlipper = (ViewFlipper)findViewById(R.id.main);
taskList = new TaskListSubActivity(this, ActivityCode.TASK_LIST,
taskList = new TaskListSubActivity(this, ActivityCode.TASK_LIST,
findViewById(R.id.tasklist_layout));
tagList = new TagListSubActivity(this, ActivityCode.TAG_LIST,
tagList = new TagListSubActivity(this, ActivityCode.TAG_LIST,
findViewById(R.id.taglist_layout));
taskListWTag = new TaskListSubActivity(this, ActivityCode.TASK_LIST_W_TAG,
taskListWTag = new TaskListSubActivity(this, ActivityCode.TASK_LIST_W_TAG,
findViewById(R.id.tasklistwtag_layout));
mInAnimationForward = AnimationUtils.loadAnimation(this, R.anim.slide_left_in);
mOutAnimationForward = AnimationUtils.loadAnimation(this, R.anim.slide_left_out);
mInAnimationBackward = AnimationUtils.loadAnimation(this, R.anim.slide_right_in);
mOutAnimationBackward = AnimationUtils.loadAnimation(this, R.anim.slide_right_out);
gestureListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
@ -241,7 +244,7 @@ public class TaskList extends Activity {
}
};
}
private class AstridGestureDetector extends SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
@ -252,7 +255,7 @@ public class TaskList extends Activity {
// flick R to L
if(e1.getX() - e2.getX() > FLING_DIST_THRESHOLD &&
Math.abs(velocityX) > FLING_VEL_THRESHOLD) {
switch(getCurrentSubActivity().getActivityCode()) {
case TASK_LIST:
switchToActivity(ActivityCode.TAG_LIST, null);
@ -288,10 +291,10 @@ public class TaskList extends Activity {
/* ======================================================================
* ==================================================== subactivity stuff
* ====================================================================== */
private void switchToActivity(ActivityCode activity, Bundle variables) {
closeOptionsMenu();
// and flip to them
switch(getCurrentSubActivity().getActivityCode()) {
case TASK_LIST:
@ -305,7 +308,7 @@ public class TaskList extends Activity {
viewFlipper.setDisplayedChild(taskListWTag.code.ordinal());
}
break;
case TAG_LIST:
switch(activity) {
case TASK_LIST:
@ -320,7 +323,7 @@ public class TaskList extends Activity {
break;
}
break;
case TASK_LIST_W_TAG:
viewFlipper.setInAnimation(mInAnimationBackward);
viewFlipper.setOutAnimation(mOutAnimationBackward);
@ -333,7 +336,7 @@ public class TaskList extends Activity {
}
break;
}
// initialize the components
switch(activity) {
case TASK_LIST:
@ -345,25 +348,25 @@ public class TaskList extends Activity {
case TASK_LIST_W_TAG:
taskListWTag.onDisplay(variables);
}
lastActivityBundle = variables;
}
private SubActivity getCurrentSubActivity() {
return (SubActivity)viewFlipper.getCurrentView().getTag();
}
/* ======================================================================
* ======================================================= event handling
* ====================================================================== */
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(TAG_LAST_ACTIVITY, getCurrentSubActivity().code.ordinal());
outState.putBundle(TAG_LAST_BUNDLE, lastActivityBundle);
outState.putInt(LAST_ACTIVITY_TAG, getCurrentSubActivity().code.ordinal());
outState.putBundle(LAST_BUNDLE_TAG, lastActivityBundle);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(getCurrentSubActivity().onKeyDown(keyCode, event))
@ -371,7 +374,7 @@ public class TaskList extends Activity {
else
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
@ -381,7 +384,7 @@ public class TaskList extends Activity {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == Constants.RESULT_GO_HOME) {
switchToActivity(ActivityCode.TASK_LIST, null);
} else
@ -391,13 +394,13 @@ public class TaskList extends Activity {
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus && shouldCloseInstance) { // user wants to quit
finish();
} else
getCurrentSubActivity().onWindowFocusChanged(hasFocus);
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
if(getCurrentSubActivity().onMenuItemSelected(featureId, item))
@ -405,7 +408,7 @@ public class TaskList extends Activity {
else
return super.onMenuItemSelected(featureId, item);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (gestureDetector.onTouchEvent(event))

@ -17,6 +17,8 @@
*/
package com.timsu.astrid.activities;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
@ -38,9 +40,11 @@ import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
import android.view.View.OnKeyListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.CompoundButton.OnCheckedChangeListener;
@ -50,13 +54,14 @@ import com.timsu.astrid.data.enums.Importance;
import com.timsu.astrid.data.tag.TagController;
import com.timsu.astrid.data.tag.TagModelForView;
import com.timsu.astrid.data.task.TaskController;
import com.timsu.astrid.data.task.TaskIdentifier;
import com.timsu.astrid.data.task.TaskModelForList;
import com.timsu.astrid.data.task.AbstractTaskModel.RepeatInfo;
import com.timsu.astrid.utilities.DateUtilities;
import com.timsu.astrid.utilities.Preferences;
import com.timsu.astrid.utilities.TaskFieldsVisibility;
/**
/**
* Adapter for displaying a list of TaskModelForList entities
*
* @author timsu
@ -78,9 +83,15 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
private static final int KEY_TIMES = 5;
private static final int KEY_TAGS = 6;
private static final int KEY_HIDDEN = 7;
private static final int KEY_EXPANDED = 8;
private static final int KEY_CREATION = 9;
private static final String CACHE_TRUE = "y";
// alarm date formatter
private static final Format alarmFormat = new SimpleDateFormat(
"MM/dd hh:mm");
/** Threshold under which to display a task as red, in millis */
private static final long TASK_OVERDUE_THRESHOLD = 30 * 60 * 1000L;
@ -96,8 +107,8 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
private TaskModelForList recentlyCompleted = null;
/**
* Callback interface for interacting with parent activity
*
* Call-back interface for interacting with parent activity
*
* @author timsu
*
*/
@ -108,11 +119,15 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
TagController tagController();
void performItemClick(View v, int position);
void onCreatedTaskListView(View v, TaskModelForList task);
void editItem(TaskModelForList task);
void toggleTimerOnItem(TaskModelForList task);
void setSelectedItem(TaskIdentifier taskId);
}
/**
* Constructor
*
*
* @param activity
* @param context
* @param resource
@ -134,6 +149,20 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
alarmController = new AlertController(activity);
}
/** Toggle the expanded state of this task */
public void toggleExpanded(View view, TaskModelForList task) {
if(CACHE_TRUE.equals(task.getCachedLabel(KEY_EXPANDED))) {
task.putCachedLabel(KEY_EXPANDED, null);
hooks.setSelectedItem(null);
} else {
task.putCachedLabel(KEY_EXPANDED, CACHE_TRUE);
hooks.setSelectedItem(task.getTaskIdentifier());
}
setFieldContentsAndVisibility(view, task);
((ListView)view.getParent()).setSelection(objects.indexOf(task));
}
// ----------------------------------------------------------------------
// --- code for setting up each view
// ----------------------------------------------------------------------
@ -145,16 +174,17 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
if(view == null) {
view = inflater.inflate(resource, parent, false);
initializeView(view);
addListeners(view);
}
setupView(view, objects.get(position));
addListeners(position, view);
return view;
}
/**
* Perform initial setup on the row
*
* Perform initial setup on the row, stuff is constant for every row
*
* @param view
*/
private void initializeView(View view) {
@ -165,28 +195,31 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
/**
* Setup the given view for the specified task
*
*
* @param view
* @param task
*/
private void setupView(View view, final TaskModelForList task) {
Resources r = activity.getResources();
final CheckBox progress = ((CheckBox)view.findViewById(R.id.cb1));
final ImageView timer = ((ImageView)view.findViewById(R.id.imageLeft));
final TextView name = ((TextView)view.findViewById(R.id.task_name));
view.setTag(task);
progress.setTag(task);
setFieldContentsAndVisibility(view, task);
if(task.getTimerStart() != null)
final CheckBox progress = ((CheckBox)view.findViewById(R.id.cb1));
progress.setChecked(task.isTaskCompleted());
final ImageView timer = ((ImageView)view.findViewById(R.id.imageLeft));
if(task.getTimerStart() != null) {
timer.setImageDrawable(r.getDrawable(R.drawable.icon_timer));
else
view.setMinimumHeight(80);
} else {
timer.setImageDrawable(null);
progress.setChecked(task.isTaskCompleted());
view.setMinimumHeight(45);
}
setFieldContentsAndVisibility(view, task);
final TextView name = ((TextView)view.findViewById(R.id.task_name));
setTaskAppearance(task, name, progress);
hooks.onCreatedTaskListView(view, task);
}
@ -198,14 +231,30 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
v.setVisibility(View.GONE);
}
/** Helper method to add a line and maybe a newline */
private static void appendLine(StringBuilder sb, String line) {
if(line.length() == 0)
return;
if(sb.length() > 0)
sb.append("\n");
sb.append(line);
}
/** Helper method to set the contents and visibility of each field */
private void setFieldContentsAndVisibility(View view, TaskModelForList task) {
TaskFieldsVisibility visibleFields = Preferences.getTaskFieldsVisibility(activity);
Resources r = getContext().getResources();
TaskFieldsVisibility visibleFields = Preferences.getTaskFieldsVisibility(activity);
boolean isExpanded = CACHE_TRUE.equals(task.getCachedLabel(KEY_EXPANDED));
StringBuilder details = new StringBuilder();
StringBuilder expandedDetails = new StringBuilder();
// expanded container
final View expandedContainer = view.findViewById(R.id.expanded_layout);
expandedContainer.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
// name
final TextView name = ((TextView)view.findViewById(R.id.task_name));
if(visibleFields.TITLE) {
final TextView name = ((TextView)view.findViewById(R.id.task_name)); {
String cachedResult = task.getCachedLabel(KEY_NAME);
if(cachedResult == null) {
String nameValue = task.getName();
@ -222,8 +271,6 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
else
name.setTypeface(Typeface.DEFAULT_BOLD);
}
setVisibility(name);
// importance
final View importance = (View)view.findViewById(R.id.importance);
@ -235,7 +282,7 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
// due date / completion date
final TextView deadlines = ((TextView)view.findViewById(R.id.text_deadlines));
if(visibleFields.DEADLINE) {
if(visibleFields.DEADLINE || isExpanded) {
String cachedResult = task.getCachedLabel(KEY_DEADLINE);
if(cachedResult == null) {
StringBuilder label = new StringBuilder();
@ -282,17 +329,21 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
cachedResult = label.toString();
task.putCachedLabel(KEY_DEADLINE, cachedResult);
}
deadlines.setText(cachedResult);
if(CACHE_TRUE.equals(task.getCachedLabel(KEY_OVERDUE)))
deadlines.setTextColor(r.getColor(R.color.taskList_dueDateOverdue));
else
deadlines.setTextColor(r.getColor(R.color.taskList_details));
if(visibleFields.DEADLINE) {
deadlines.setText(cachedResult);
if(CACHE_TRUE.equals(task.getCachedLabel(KEY_OVERDUE)))
deadlines.setTextColor(r.getColor(R.color.taskList_dueDateOverdue));
else
deadlines.setTextColor(r.getColor(R.color.taskList_details));
} else {
expandedDetails.append(cachedResult);
}
}
setVisibility(deadlines);
// estimated / elapsed time
final TextView times = ((TextView)view.findViewById(R.id.text_times));
if(visibleFields.TIMES) {
if(visibleFields.TIMES || isExpanded) {
String cachedResult = task.getCachedLabel(KEY_TIMES);
if(cachedResult == null) {
Integer elapsed = task.getElapsedSeconds();
@ -310,18 +361,19 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
if(elapsed > 0) {
label.append(r.getString(R.string.taskList_elapsedTimePrefix)).
append(" ").
append(DateUtilities.getDurationString(r, elapsed, 2));
append(DateUtilities.getAbbreviatedDurationString(r, elapsed, 2));
}
cachedResult = label.toString();
task.putCachedLabel(KEY_TIMES, cachedResult);
}
times.setText(cachedResult);
if(visibleFields.TIMES)
appendLine(details, cachedResult);
else
appendLine(expandedDetails, cachedResult);
}
setVisibility(times);
// reminders
final TextView reminders = ((TextView)view.findViewById(R.id.text_reminders));
if(visibleFields.REMINDERS) {
if(visibleFields.REMINDERS || isExpanded) {
String cachedResult = task.getCachedLabel(KEY_REMINDERS);
if(cachedResult == null) {
Integer notifyEvery = task.getNotificationIntervalSeconds();
@ -335,10 +387,21 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
alarmController.open();
List<Date> alerts = alarmController.getTaskAlerts(task.getTaskIdentifier());
if(alerts.size() > 0) {
if(label.length() > 0)
label.append(". ");
label.append(r.getQuantityString(R.plurals.Nalarms, alerts.size(),
alerts.size())).append(" ").append(r.getString(R.string.taskList_alarmSuffix));
Date nextAlarm = null;
Date now = new Date();
for(Date alert : alerts) {
if(alert.after(now) && (nextAlarm == null ||
alert.before(nextAlarm)))
nextAlarm = alert;
}
if(nextAlarm != null) {
if(label.length() > 0)
label.append(". ");
String alarmString = alarmFormat.format(nextAlarm);
label.append(r.getString(R.string.taskList_alarmPrefix) +
" " + alarmString);
}
}
} finally {
alarmController.close();
@ -346,13 +409,14 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
cachedResult = label.toString();
task.putCachedLabel(KEY_REMINDERS, cachedResult);
}
reminders.setText(cachedResult);
if(visibleFields.REMINDERS)
appendLine(details, cachedResult);
else
appendLine(expandedDetails, cachedResult);
}
setVisibility(reminders);
// repeats
final TextView repeats = ((TextView)view.findViewById(R.id.text_repeats));
if(visibleFields.REPEATS) {
if(visibleFields.REPEATS || isExpanded) {
String cachedResult = task.getCachedLabel(KEY_REPEAT);
if(cachedResult == null) {
RepeatInfo repeatInfo = task.getRepeat();
@ -364,13 +428,14 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
cachedResult = "";
task.putCachedLabel(KEY_REPEAT, cachedResult);
}
repeats.setText(cachedResult);
if(visibleFields.REPEATS)
appendLine(details, cachedResult);
else
appendLine(expandedDetails, cachedResult);
}
setVisibility(repeats);
// tags
final TextView tags = ((TextView)view.findViewById(R.id.text_tags));
if(visibleFields.TAGS) {
if(visibleFields.TAGS || isExpanded) {
String cachedResult = task.getCachedLabel(KEY_TAGS);
if(cachedResult == null) {
List<TagModelForView> alltags = hooks.getTagsFor(task);
@ -382,24 +447,66 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
tagString.append(", ");
}
if(alltags.size() > 0)
cachedResult = r.getString(R.string.taskList_tagsPrefix) + " " + tagString;
cachedResult = r.getString(R.string.taskList_tagsPrefix) +
" " + tagString;
else
cachedResult = "";
task.putCachedLabel(KEY_TAGS, cachedResult);
}
tags.setText(cachedResult);
if(visibleFields.TAGS)
appendLine(details, cachedResult);
else
appendLine(expandedDetails, cachedResult);
}
setVisibility(tags);
// notes
final TextView notes = ((TextView)view.findViewById(R.id.text_notes));
if(visibleFields.NOTES) {
notes.setText(r.getString(R.string.taskList_notesPrefix) + " " + task.getNotes());
if(visibleFields.NOTES || isExpanded) {
if(task.getNotes() != null && task.getNotes().length() > 0) {
String notes = r.getString(R.string.taskList_notesPrefix) +
" " + task.getNotes();
if(visibleFields.NOTES)
appendLine(details, notes);
else
appendLine(expandedDetails, notes);
}
}
setVisibility(notes);
final TextView detailsView = ((TextView)view.findViewById(R.id.details));
detailsView.setText(details.toString());
setVisibility(detailsView);
// expanded-only fields: creation date, ...
if(isExpanded) {
if(task.getCreationDate() != null) {
String cachedResult = task.getCachedLabel(KEY_CREATION);
if(cachedResult == null) {
int secondsAgo = (int) ((System.currentTimeMillis() -
task.getCreationDate().getTime())/1000);
cachedResult = r.getString(R.string.taskList_createdPrefix) + " " +
DateUtilities.getDurationString(r, Math.abs(secondsAgo), 1) +
" " + r.getString(R.string.ago_suffix);
task.putCachedLabel(KEY_CREATION, cachedResult);
}
appendLine(expandedDetails, cachedResult);
}
final Button timerButton =
((Button)view.findViewById(R.id.timer));
if(task.getTimerStart() == null)
timerButton.setText(r.getString(R.string.startTimer_label));
else
timerButton.setText(r.getString(R.string.stopTimer_label));
final TextView expandedDetailsView =
((TextView)view.findViewById(R.id.expanded_details));
expandedDetailsView.setText(expandedDetails.toString());
}
}
private void addListeners(final int position, final View view) {
/** Set listeners for this view. This is called once total */
private void addListeners(View view) {
final CheckBox progress = ((CheckBox)view.findViewById(R.id.cb1));
// clicking the check box
@ -407,7 +514,8 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
TaskModelForList task = (TaskModelForList)buttonView.getTag();
View parent = (View)buttonView.getParent();
TaskModelForList task = (TaskModelForList)parent.getTag();
int newProgressPercentage;
if(isChecked)
@ -417,8 +525,8 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
newProgressPercentage = 0;
if(newProgressPercentage != task.getProgressPercentage()) {
setTaskProgress(task, view, newProgressPercentage);
setupView(view, task);
setTaskProgress(task, parent, newProgressPercentage);
setupView(parent, task);
}
}
});
@ -427,16 +535,18 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
hooks.performItemClick(view, position);
TaskModelForList task = (TaskModelForList)v.getTag();
toggleExpanded(v, task);
}
});
// typing while selected something
view.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(event.getAction() != KeyEvent.ACTION_UP)
return false;
// hotkey to set task priority
// hot-key to set task priority
if(keyCode >= KeyEvent.KEYCODE_1 && keyCode <= KeyEvent.KEYCODE_4) {
Importance i = Importance.values()[keyCode - KeyEvent.KEYCODE_1];
TaskModelForList task = (TaskModelForList)v.getTag();
@ -455,6 +565,7 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
TaskModelForList task = (TaskModelForList)v.getTag();
int position = objects.indexOf(task);
menu.add(position, CONTEXT_EDIT_ID, Menu.NONE,
R.string.taskList_context_edit);
@ -476,6 +587,27 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
menu.setHeaderTitle(task.getName());
}
});
// clicking one of the expanded buttons
Button editButton = (Button)view.findViewById(R.id.edit);
editButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View parent = (View)v.getParent().getParent().getParent().getParent();
TaskModelForList task = (TaskModelForList)parent.getTag();
hooks.editItem(task);
}
});
Button deleteButton = (Button)view.findViewById(R.id.timer);
deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View parent = (View)v.getParent().getParent().getParent().getParent();
TaskModelForList task = (TaskModelForList)parent.getTag();
hooks.toggleTimerOnItem(task);
}
});
}
private void setTaskProgress(final TaskModelForList task, View view, int progress) {
@ -521,14 +653,20 @@ public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
name.setPaintFlags(name.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
name.setTextColor(r.getColor(task.getTaskColorResource(getContext())));
if(task.getProgressPercentage() >= 75)
progress.setButtonDrawable(R.drawable.btn_check75);
else if(task.getProgressPercentage() >= 50)
progress.setButtonDrawable(R.drawable.btn_check50);
else if(task.getProgressPercentage() >= 25)
float completedPercentage = 0;
if(task.getEstimatedSeconds() > 0) {
completedPercentage = task.getElapsedSeconds() /
task.getEstimatedSeconds();
}
if(completedPercentage < 0.25f)
progress.setButtonDrawable(R.drawable.btn_check0);
else if(completedPercentage < 0.5f)
progress.setButtonDrawable(R.drawable.btn_check25);
else if(completedPercentage < 0.75f)
progress.setButtonDrawable(R.drawable.btn_check50);
else
progress.setButtonDrawable(R.drawable.btn_check0);
progress.setButtonDrawable(R.drawable.btn_check75);
}
}

@ -0,0 +1,19 @@
package com.timsu.astrid.activities;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class TaskListNotify extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, TaskList.class);
intent.putExtra(TaskList.VARIABLES_TAG, getIntent().getExtras());
startActivity(intent);
finish();
}
}

@ -27,6 +27,7 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import android.app.AlertDialog;
import android.content.DialogInterface;
@ -35,6 +36,7 @@ import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.Menu;
@ -42,10 +44,8 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnCreateContextMenuListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;
import com.timsu.astrid.R;
import com.timsu.astrid.activities.TaskList.ActivityCode;
@ -61,11 +61,12 @@ import com.timsu.astrid.sync.Synchronizer;
import com.timsu.astrid.sync.Synchronizer.SynchronizerListener;
import com.timsu.astrid.utilities.Constants;
import com.timsu.astrid.utilities.DialogUtilities;
import com.timsu.astrid.utilities.Notifications;
import com.timsu.astrid.utilities.Preferences;
import com.timsu.astrid.widget.NNumberPickerDialog.OnNNumberPickedListener;
/**
/**
* Primary view for the Astrid Application. Lists all of the tasks in the
* system, and allows users to edit them.
*
@ -75,14 +76,17 @@ import com.timsu.astrid.widget.NNumberPickerDialog.OnNNumberPickedListener;
public class TaskListSubActivity extends SubActivity {
// bundle tokens
public static final String TAG_TOKEN = "tag";
public static final String TAG_TOKEN = "tag";
public static final String FROM_NOTIFICATION_TOKEN = "notify";
public static final String NOTIF_FLAGS_TOKEN = "notif_flags";
public static final String NOTIF_REPEAT_TOKEN = "notif_repeat";
public static final String LOAD_INSTANCE_TOKEN = "id";
// activities
private static final int ACTIVITY_CREATE = 0;
private static final int ACTIVITY_VIEW = 1;
private static final int ACTIVITY_EDIT = 2;
private static final int ACTIVITY_TAGS = 3;
private static final int ACTIVITY_SYNCHRONIZE = 4;
private static final int ACTIVITY_EDIT = 1;
private static final int ACTIVITY_TAGS = 2;
private static final int ACTIVITY_SYNCHRONIZE = 3;
// menu codes
private static final int INSERT_ID = Menu.FIRST;
@ -116,6 +120,8 @@ public class TaskListSubActivity extends SubActivity {
private Map<TagIdentifier, TagModelForView> tagMap;
private ArrayList<TaskModelForList> taskArray;
private HashMap<TaskModelForList, LinkedList<TagModelForView>> taskTags;
private Long selectedTaskId = null;
private TaskModelForList selectedTask = null;
// display filters
private static boolean filterShowHidden = false;
@ -127,26 +133,42 @@ public class TaskListSubActivity extends SubActivity {
/* ======================================================================
* ======================================================= initialization
* ====================================================================== */
public TaskListSubActivity(TaskList parent, ActivityCode code, View view) {
super(parent, code, view);
}
@Override
/** Called when loading up the activity */
public void onDisplay(Bundle variables) {
// load tag map
tagMap = getTagController().getAllTagsAsMap(getParent());
// process the tag to filter on, if any
// process tag to filter, if any
if(variables != null && variables.containsKey(TAG_TOKEN)) {
TagIdentifier identifier = new TagIdentifier(variables.getLong(TAG_TOKEN));
tagMap = getTagController().getAllTagsAsMap(getParent());
filterTag = tagMap.get(identifier);
}
// process task that's selected, if any
if(variables != null && variables.containsKey(LOAD_INSTANCE_TOKEN)) {
selectedTaskId = variables.getLong(LOAD_INSTANCE_TOKEN);
}
setupUIComponents();
loadTaskListSort();
fillData();
if(variables != null && variables.containsKey(NOTIF_FLAGS_TOKEN)) {
long repeatInterval = 0;
int flags = 0;
if(variables.containsKey(NOTIF_REPEAT_TOKEN))
repeatInterval = variables.getLong(NOTIF_REPEAT_TOKEN);
flags = variables.getInt(NOTIF_FLAGS_TOKEN);
if(selectedTask != null) {
showNotificationAlert(selectedTask, repeatInterval, flags);
}
}
}
/** Initialize UI components */
@ -173,7 +195,7 @@ public class TaskListSubActivity extends SubActivity {
}
});
}
@Override
/** Create options menu (displayed when user presses menu key) */
public boolean onPrepareOptionsMenu(Menu menu) {
@ -265,18 +287,81 @@ public class TaskListSubActivity extends SubActivity {
abstract int compareTo(TaskModelForList arg0, TaskModelForList arg1);
};
/* ======================================================================
* ======================================================== notifications
* ====================================================================== */
/** Called when user clicks on a notification to get here */
private void showNotificationAlert(final TaskModelForList task,
final long repeatInterval, final int flags) {
Resources r = getResources();
// clear notifications
Notifications.clearAllNotifications(getParent(), task.getTaskIdentifier());
String[] responses = r.getStringArray(R.array.reminder_responses);
String response = responses[new Random().nextInt(responses.length)];
new AlertDialog.Builder(getParent())
.setTitle(R.string.taskView_notifyTitle)
.setMessage(task.getName() + "\n\n" + response)
.setIcon(android.R.drawable.ic_dialog_alert)
// yes, i will do it: just closes this dialog
.setPositiveButton(R.string.notify_yes, null)
// no, i will ignore: quits application
.setNegativeButton(R.string.notify_no, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
TaskList.shouldCloseInstance = true;
closeActivity();
}
})
// snooze: sets a new temporary alert, closes application
.setNeutralButton(R.string.notify_snooze, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
snoozeAlert(task, repeatInterval, flags);
}
})
.show();
}
private void snoozeAlert(final TaskModelForList task,
final long repeatInterval, final int flags) {
DialogUtilities.hourMinutePicker(getParent(),
getResources().getString(R.string.notify_snooze_title),
new OnNNumberPickedListener() {
public void onNumbersPicked(int[] values) {
int snoozeSeconds = values[0] * 3600 + values[1] * 60;
Notifications.createSnoozeAlarm(getParent(),
task.getTaskIdentifier(), snoozeSeconds, flags,
repeatInterval);
TaskList.shouldCloseInstance = true;
closeActivity();
}
});
}
/* ======================================================================
* ====================================================== populating list
* ====================================================================== */
/** Helper method returns true if the task is considered 'hidden' */
private boolean isTaskHidden(TaskModelForList task) {
if(task == selectedTask)
return false;
if(task.isHidden())
return true;
if(filterTag == null) {
for(TagModelForView tags : taskTags.get(task)) {
if(tags.shouldHideFromMainList())
if(tags != null && tags.shouldHideFromMainList())
return true;
}
}
@ -306,7 +391,9 @@ public class TaskListSubActivity extends SubActivity {
// read tags and apply filters
int hiddenTasks = 0; // # of tasks hidden
int completedTasks = 0; // # of tasks on list that are done
tagMap = getTagController().getAllTagsAsMap(getParent());
taskTags = new HashMap<TaskModelForList, LinkedList<TagModelForView>>();
for(Iterator<TaskModelForList> i = taskArray.iterator(); i.hasNext();) {
TaskModelForList task = i.next();
@ -317,6 +404,10 @@ public class TaskListSubActivity extends SubActivity {
}
}
if(selectedTaskId != null && task.getTaskIdentifier().getId() == selectedTaskId) {
selectedTask = task;
}
// get list of tags
LinkedList<TagIdentifier> tagIds = getTagController().getTaskTags(getParent(),
task.getTaskIdentifier());
@ -414,23 +505,39 @@ public class TaskListSubActivity extends SubActivity {
public void onCreatedTaskListView(View v, TaskModelForList task) {
v.setOnTouchListener(getGestureListener());
}
@Override
public void editItem(TaskModelForList task) {
editTask(task);
}
@Override
public void toggleTimerOnItem(TaskModelForList task) {
toggleTimer(task);
}
@Override
public void setSelectedItem(TaskIdentifier taskId) {
selectedTask = null;
if(taskId == null)
selectedTaskId = null;
else
selectedTaskId = taskId.getId();
}
});
listView.setAdapter(tasks);
listView.setItemsCanFocus(true);
// list view listener
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
TaskModelForList task = (TaskModelForList)view.getTag();
Intent intent = new Intent(getParent(), TaskView.class);
intent.putExtra(TaskEdit.LOAD_INSTANCE_TOKEN, task.
getTaskIdentifier().getId());
launchActivity(intent, ACTIVITY_VIEW);
if(selectedTask != null) {
try {
int selectedPosition = tasks.getPosition(selectedTask);
View v = listView.getChildAt(selectedPosition);
tasks.toggleExpanded(v, selectedTask);
listView.setSelection(selectedPosition);
} catch (Exception e) {
Log.e("astrid", "error with selected task", e);
}
});
}
// filters context menu
listView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
@ -493,15 +600,15 @@ public class TaskListSubActivity extends SubActivity {
return true;
}
}
if(keyCode >= KeyEvent.KEYCODE_A && keyCode <= KeyEvent.KEYCODE_Z) {
createTask((char)('A' + (keyCode - KeyEvent.KEYCODE_A)));
return true;
}
return false;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == Constants.RESULT_SYNCHRONIZE) {
@ -554,6 +661,25 @@ public class TaskListSubActivity extends SubActivity {
.show();
}
/** Take you to the task edit page */
private void editTask(TaskModelForList task) {
Intent intent = new Intent(getParent(), TaskEdit.class);
intent.putExtra(TaskEdit.LOAD_INSTANCE_TOKEN,
task.getTaskIdentifier().getId());
launchActivity(intent, ACTIVITY_EDIT);
}
/** Toggle the timer */
private void toggleTimer(TaskModelForList task) {
if(task.getTimerStart() == null)
task.setTimerStart(new Date());
else {
task.stopTimerAndUpdateElapsedTime();
}
getTaskController().saveTask(task);
fillData();
}
/** Show the tags view */
public void showTagsView() {
switchToActivity(ActivityCode.TAG_LIST, null);
@ -592,7 +718,6 @@ public class TaskListSubActivity extends SubActivity {
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
Intent intent;
final TaskModelForList task;
Resources r = getResources();
@ -631,9 +756,7 @@ public class TaskListSubActivity extends SubActivity {
// --- list context menu items
case TaskListAdapter.CONTEXT_EDIT_ID:
task = taskArray.get(item.getGroupId());
intent = new Intent(getParent(), TaskEdit.class);
intent.putExtra(TaskEdit.LOAD_INSTANCE_TOKEN, task.getTaskIdentifier().getId());
launchActivity(intent, ACTIVITY_EDIT);
editTask(task);
return true;
case TaskListAdapter.CONTEXT_DELETE_ID:
task = taskArray.get(item.getGroupId());
@ -641,13 +764,7 @@ public class TaskListSubActivity extends SubActivity {
return true;
case TaskListAdapter.CONTEXT_TIMER_ID:
task = taskArray.get(item.getGroupId());
if(task.getTimerStart() == null)
task.setTimerStart(new Date());
else {
task.stopTimerAndUpdateElapsedTime();
}
getTaskController().saveTask(task);
fillData();
toggleTimer(task);
return true;
case TaskListAdapter.CONTEXT_POSTPONE_ID:
task = taskArray.get(item.getGroupId());

@ -1,366 +0,0 @@
/*
* ASTRID: Android's Simple Task Recording Dashboard
*
* Copyright (c) 2009 Tim Su
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.timsu.astrid.activities;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import com.timsu.astrid.R;
import com.timsu.astrid.data.task.TaskIdentifier;
import com.timsu.astrid.data.task.TaskModelForView;
import com.timsu.astrid.utilities.Constants;
import com.timsu.astrid.utilities.DateUtilities;
import com.timsu.astrid.widget.NumberPicker;
import com.timsu.astrid.widget.NumberPickerDialog;
/** Task Properties view for the Astrid Application.
*
* @author Tim Su (timsu@stanfordalumni.org)
*
*/
public class TaskView extends TaskModificationActivity<TaskModelForView> {
// activities
private static final int ACTIVITY_EDIT = 0;
// menu codes
private static final int EDIT_ID = Menu.FIRST;
private static final int DELETE_ID = Menu.FIRST + 1;
// UI components
private TextView name;
private TextView elapsed;
private TextView estimated;
private TextView definiteDueDate;
private TextView preferredDueDate;
private TextView creationDate;
private TextView notes;
private Button timerButton;
private Button progress;
private NumberPickerDialog progressDialog;
// other instance variables
private Handler handler;
private Timer updateTimer = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.task_view);
handler = new Handler();
setUpUIComponents();
setUpListeners();
populateFields();
}
@Override
protected TaskModelForView getModel(TaskIdentifier identifier) {
if(identifier == null)
throw new IllegalArgumentException("Can't view null task!");
return controller.fetchTaskForView(this, identifier);
}
/* ======================================================================
* =================================================== reading from model
* ====================================================================== */
private void populateFields() {
final Resources r = getResources();
name.setText(model.getName());
estimated.setText(DateUtilities.getDurationString(r,
model.getEstimatedSeconds(), 2));
elapsed.setText(DateUtilities.getDurationString(r,
model.getElapsedSeconds(), 2));
formatDate(model.getCreationDate(), creationDate);
updateTimerButtonText();
updateProgressComponents();
if(model.getNotes().length() == 0)
((View)notes.getParent()).setVisibility(View.GONE);
else
notes.setText(model.getNotes());
}
private void formatDeadline(Date deadline, TextView view) {
Resources r = getResources();
if(deadline == null || model.isTaskCompleted()) {
((View)view.getParent()).setVisibility(View.GONE);
return;
}
int secondsToDeadline = (int) ((deadline.getTime() -
System.currentTimeMillis())/1000);
String text = DateUtilities.getDurationString(r,
Math.abs(secondsToDeadline), 2) + " ";
if(secondsToDeadline < 0) {
view.setTextColor(r.getColor(R.color.view_table_overdue));
view.setText(text + r.getString(R.string.overdue_suffix));
} else
view.setText(text);
}
private void formatDate(Date date, TextView view) {
Resources r = getResources();
if(date == null || model.isTaskCompleted()) {
((View)view.getParent()).setVisibility(View.GONE);
return;
}
int secondsAgo = (int) ((System.currentTimeMillis() - date.getTime())/1000);
String text = DateUtilities.getDurationString(r,
Math.abs(secondsAgo), 2) + " ";
view.setText(text + r.getString(R.string.ago_suffix));
}
/* ======================================================================
* ==================================================== UI initialization
* ====================================================================== */
private void setUpUIComponents() {
Resources r = getResources();
name = (TextView)findViewById(R.id.name);
elapsed = (TextView)findViewById(R.id.cell_elapsed);
estimated = (TextView)findViewById(R.id.cell_estimated);
definiteDueDate = (TextView)findViewById(R.id.cell_definiteDueDate);
preferredDueDate = (TextView)findViewById(R.id.cell_preferredDueDate);
creationDate = (TextView)findViewById(R.id.cell_creationDate);
notes = (TextView)findViewById(R.id.cell_notes);
timerButton = (Button)findViewById(R.id.timerButton);
progress = (Button)findViewById(R.id.progress);
progressDialog = new NumberPickerDialog(this,
new NumberPickerDialog.OnNumberPickedListener() {
@Override
public void onNumberPicked(NumberPicker view, int number) {
model.setProgressPercentage(number);
controller.saveTask(model);
updateProgressComponents();
}
}, r.getString(R.string.progress_dialog), 0, 25, 0, 100);
name.setTextSize(36);
}
private void setUpListeners() {
Button edit = (Button)findViewById(R.id.edit);
edit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
editButtonClick();
}
});
timerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(model.getTimerStart() == null) {
model.setTimerStart(new Date());
controller.saveTask(model);
} else {
model.stopTimerAndUpdateElapsedTime();
controller.saveTask(model);
}
updateTimerButtonText();
}
});
progress.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progressDialog.show();
}
});
}
@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
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(hasFocus && TaskList.shouldCloseInstance) { // user wants to quit
finish();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
switch(resultCode) {
case Constants.RESULT_GO_HOME:
case RESULT_CANCELED:
setResult(resultCode);
finish();
break;
default:
populateFields();
}
}
@Override
protected void onPause() {
super.onPause();
updateTimer.cancel(); // stop the timer
updateTimer = null;
}
@Override
protected void onResume() {
super.onResume();
populateFields();
if(updateTimer != null)
return;
updateTimer = new Timer(); // start timer
updateTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
updateElapsedTimeText();
}
});
}
}, 0, 1000);
}
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);
}
/* ======================================================================
* ================================================ UI component updating
* ====================================================================== */
/** Update components that depend on elapsed time */
private void updateElapsedTimeText() {
Resources r = getResources();
int timeElapsed = model.getElapsedSeconds();
if(model.getTimerStart() != null) {
timeElapsed += (int) (System.currentTimeMillis() -
model.getTimerStart().getTime())/1000;
}
elapsed.setText(DateUtilities.getDurationString(r,
timeElapsed, Integer.MAX_VALUE));
}
/** Update components that depend on timer status */
private void updateTimerButtonText() {
Resources r = getResources();
if(model.getTimerStart() == null)
timerButton.setText(r.getString(R.string.startTimer_label));
else
timerButton.setText(r.getString(R.string.stopTimer_label));
}
/** Update components that depend on task progress */
private void updateProgressComponents() {
Resources r = getResources();
progress.setText(model.getProgressPercentage() +
r.getString(R.string.progress_suffix));
if(model.isTaskCompleted())
name.setBackgroundColor(r.getColor(R.color.view_header_done));
else
name.setBackgroundColor(r.getColor(model.getImportance().getColorResource()));
progressDialog.setInitialValue(model.getProgressPercentage());
formatDeadline(model.getDefiniteDueDate(), definiteDueDate);
formatDeadline(model.getPreferredDueDate(), preferredDueDate);
}
}

@ -1,114 +0,0 @@
/*
* ASTRID: Android's Simple Task Recording Dashboard
*
* Copyright (c) 2009 Tim Su
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.timsu.astrid.activities;
import java.util.Random;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Bundle;
import com.timsu.astrid.R;
import com.timsu.astrid.utilities.Constants;
import com.timsu.astrid.utilities.DialogUtilities;
import com.timsu.astrid.utilities.Notifications;
import com.timsu.astrid.widget.NNumberPickerDialog.OnNNumberPickedListener;
public class TaskViewNotifier extends TaskView {
// bundle tokens
public static final String FROM_NOTIFICATION_TOKEN = "notify";
public static final String NOTIF_FLAGS_TOKEN = "notif_flags";
public static final String NOTIF_REPEAT_TOKEN = "notif_repeat";
// properties of the alarm that was triggered
private long repeatInterval = 0;
private int flags = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
if(extras != null && extras.containsKey(FROM_NOTIFICATION_TOKEN)) {
if(extras.containsKey(NOTIF_REPEAT_TOKEN))
repeatInterval = extras.getLong(NOTIF_REPEAT_TOKEN);
if(extras.containsKey(NOTIF_FLAGS_TOKEN))
flags = extras.getInt(NOTIF_FLAGS_TOKEN);
showNotificationAlert();
}
}
/** Called when user clicks on a notification to get here */
private void showNotificationAlert() {
Resources r = getResources();
// clear notifications
Notifications.clearAllNotifications(this, model.getTaskIdentifier());
String[] responses = r.getStringArray(R.array.reminder_responses);
String response = responses[new Random().nextInt(responses.length)];
new AlertDialog.Builder(this)
.setTitle(R.string.taskView_notifyTitle)
.setMessage(response)
.setIcon(android.R.drawable.ic_dialog_alert)
// yes, i will do it: just closes this dialog
.setPositiveButton(R.string.notify_yes, null)
// no, i will ignore: quits application
.setNegativeButton(R.string.notify_no, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
setResult(Constants.RESULT_GO_HOME);
TaskList.shouldCloseInstance = true;
finish();
}
})
// snooze: sets a new temporary alert, closes application
.setNeutralButton(R.string.notify_snooze, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
snoozeAlert();
}
})
.show();
}
private void snoozeAlert() {
DialogUtilities.hourMinutePicker(this,
getResources().getString(R.string.notify_snooze_title),
new OnNNumberPickedListener() {
public void onNumbersPicked(int[] values) {
int snoozeSeconds = values[0] * 3600 + values[1] * 60;
Notifications.createSnoozeAlarm(TaskViewNotifier.this,
model.getTaskIdentifier(), snoozeSeconds, flags,
repeatInterval);
setResult(Constants.RESULT_GO_HOME);
TaskList.shouldCloseInstance = true;
finish();
}
});
}
}

@ -46,6 +46,7 @@ public class TaskModelForList extends AbstractTaskModel {
NOTIFICATION_FLAGS,
PROGRESS_PERCENTAGE,
COMPLETION_DATE,
CREATION_DATE,
HIDDEN_UNTIL,
NOTES,
REPEAT,
@ -202,6 +203,11 @@ public class TaskModelForList extends AbstractTaskModel {
return super.getNotificationFlags();
}
@Override
public Date getCreationDate() {
return super.getCreationDate();
}
// --- setters
@Override
@ -232,7 +238,7 @@ public class TaskModelForList extends AbstractTaskModel {
public void setDefiniteDueDate(Date definiteDueDate) {
super.setDefiniteDueDate(definiteDueDate);
}
@Override
public void setImportance(Importance importance) {
super.setImportance(importance);

@ -75,6 +75,56 @@ public class DateUtilities {
return result.toString().trim();
}
/**
* Format a time into the format: 5 days, 3 hrs, 2 min
*
* @param r Resources to get strings from
* @param timeInSeconds
* @param unitsToShow number of units to show (i.e. if 2, then 5 hours
* 3 minutes 2 seconds is truncated to 5 hours 3 minutes)
* @return
*/
public static String getAbbreviatedDurationString(Resources r, int timeInSeconds,
int unitsToShow) {
short days, hours, minutes, seconds;
short unitsDisplayed = 0;
if(timeInSeconds == 0)
return r.getQuantityString(R.plurals.Nseconds, 0, 0);
days = (short)(timeInSeconds / 24 / 3600);
timeInSeconds -= days*24*3600;
hours = (short)(timeInSeconds / 3600);
timeInSeconds -= hours * 3600;
minutes = (short)(timeInSeconds / 60);
timeInSeconds -= minutes * 60;
seconds = (short)timeInSeconds;
StringBuilder result = new StringBuilder();
if(days > 0) {
result.append(r.getQuantityString(R.plurals.Ndays, days, days)).
append(" ");
unitsDisplayed++;
}
if(unitsDisplayed < unitsToShow && hours > 0) {
result.append(r.getQuantityString(R.plurals.NhoursShort, hours,
hours)).
append(" ");
unitsDisplayed++;
}
if(unitsDisplayed < unitsToShow && minutes > 0) {
result.append(r.getQuantityString(R.plurals.NminutesShort, minutes,
minutes)).append(" ");
unitsDisplayed++;
}
if(unitsDisplayed < unitsToShow && seconds > 0) {
result.append(r.getQuantityString(R.plurals.NsecondsShort, seconds,
seconds)).append(" ");
}
return result.toString().trim();
}
/**
* Format a time into the format: 5 d, 3 h, 2 m
*

@ -20,8 +20,8 @@ import android.net.Uri;
import android.util.Log;
import com.timsu.astrid.R;
import com.timsu.astrid.activities.TaskView;
import com.timsu.astrid.activities.TaskViewNotifier;
import com.timsu.astrid.activities.TaskListNotify;
import com.timsu.astrid.activities.TaskListSubActivity;
import com.timsu.astrid.data.alerts.AlertController;
import com.timsu.astrid.data.task.TaskController;
import com.timsu.astrid.data.task.TaskIdentifier;
@ -136,7 +136,7 @@ public class Notifications extends BroadcastReceiver {
if(task.getTaskIdentifier() == null)
return;
// return if we don't need to go any further
// return if we don't need to go any further
if(shouldDeleteAlarm(task)) {
deleteAlarm(context, task.getTaskIdentifier().getId());
return;
@ -376,12 +376,11 @@ public class Notifications extends BroadcastReceiver {
.getSystemService(Context.NOTIFICATION_SERVICE);
Resources r = context.getResources();
Intent notifyIntent = new Intent(context, TaskViewNotifier.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
notifyIntent.putExtra(TaskViewNotifier.LOAD_INSTANCE_TOKEN, id);
notifyIntent.putExtra(TaskViewNotifier.FROM_NOTIFICATION_TOKEN, true);
notifyIntent.putExtra(TaskViewNotifier.NOTIF_FLAGS_TOKEN, flags);
notifyIntent.putExtra(TaskViewNotifier.NOTIF_REPEAT_TOKEN, repeatInterval);
Intent notifyIntent = new Intent(context, TaskListNotify.class);
notifyIntent.putExtra(TaskListSubActivity.LOAD_INSTANCE_TOKEN, id);
notifyIntent.putExtra(TaskListSubActivity.FROM_NOTIFICATION_TOKEN, true);
notifyIntent.putExtra(TaskListSubActivity.NOTIF_FLAGS_TOKEN, flags);
notifyIntent.putExtra(TaskListSubActivity.NOTIF_REPEAT_TOKEN, repeatInterval);
PendingIntent pendingIntent = PendingIntent.getActivity(context,
(int)id, notifyIntent, PendingIntent.FLAG_ONE_SHOT);
@ -437,7 +436,7 @@ public class Notifications extends BroadcastReceiver {
}
/** Show a notification when a user is "on-the-clock" for a given task */
public static boolean showTimingNotification(Context context,
public static boolean showTimingNotification(Context context,
TaskIdentifier taskId, String taskName) {
String text = context.getResources().getString(R.string.notif_timerStarted) +
@ -446,10 +445,9 @@ public class Notifications extends BroadcastReceiver {
.getSystemService(Context.NOTIFICATION_SERVICE);
Resources r = context.getResources();
Intent notifyIntent = new Intent(context, TaskView.class);
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
notifyIntent.putExtra(TaskViewNotifier.LOAD_INSTANCE_TOKEN, taskId.getId());
notifyIntent.putExtra(TaskViewNotifier.FROM_NOTIFICATION_TOKEN, true);
Intent notifyIntent = new Intent(context, TaskListNotify.class);
notifyIntent.putExtra(TaskListSubActivity.LOAD_INSTANCE_TOKEN, taskId.getId());
notifyIntent.putExtra(TaskListSubActivity.FROM_NOTIFICATION_TOKEN, true);
PendingIntent pendingIntent = PendingIntent.getActivity(context,
(int)taskId.getId(), notifyIntent, PendingIntent.FLAG_ONE_SHOT);
@ -462,7 +460,9 @@ public class Notifications extends BroadcastReceiver {
appName,
text,
pendingIntent);
notification.flags |= Notification.FLAG_ONGOING_EVENT;
notification.flags |= Notification.FLAG_ONGOING_EVENT |
Notification.FLAG_NO_CLEAR;
notification.flags &= ~Notification.FLAG_AUTO_CANCEL;
Log.w("Astrid", "Logging timing notification: " + text);
nm.notify((int)taskId.getId(), notification);
@ -470,5 +470,5 @@ public class Notifications extends BroadcastReceiver {
return true;
}
}
Loading…
Cancel
Save