mirror of https://github.com/tasks/tasks
Deleted unused layouts and activities
parent
bafbbf7307
commit
fc25791878
@ -1,42 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2008 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<Button android:id="@+id/date"
|
|
||||||
android:layout_weight="0.7"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
<Button android:id="@+id/time"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
<ImageButton android:id="@+id/button1"
|
|
||||||
style="?android:attr/buttonStyleInset"
|
|
||||||
android:src="@android:drawable/ic_delete"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:layout_marginTop="2dip"
|
|
||||||
android:layout_marginRight="2dip"
|
|
||||||
android:layout_marginBottom="2dip"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
/>
|
|
||||||
</LinearLayout>
|
|
@ -1,26 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2008 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<ToggleButton android:id="@+id/button"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="18dip"
|
|
||||||
android:disabledAlpha="0.3"/>
|
|
||||||
</FrameLayout>
|
|
@ -1,29 +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
|
|
||||||
|
|
||||||
-->
|
|
||||||
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@android:id/text1"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
|
||||||
android:textColor="@android:color/black"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:paddingLeft="10dip"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="50dip" />
|
|
@ -1,139 +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
|
|
||||||
|
|
||||||
-->
|
|
||||||
<com.timsu.astrid.widget.ViewFlipper android:id="@+id/main"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent" >
|
|
||||||
|
|
||||||
<!-- task list -->
|
|
||||||
<LinearLayout android:id="@+id/tasklist_layout"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/loading"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/loading"
|
|
||||||
style="@style/TextAppearance.TaskList_Task"
|
|
||||||
android:gravity="center_vertical"/>
|
|
||||||
|
|
||||||
<ListView android:id="@+id/tasklist"
|
|
||||||
android:layout_weight="100"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
<!-- Footer -->
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<!-- Quick Add Task -->
|
|
||||||
<EditText android:id="@+id/quickAddText"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="100"
|
|
||||||
android:hint="@string/quick_add_hint"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:autoText="true"
|
|
||||||
android:capitalize="sentences"/>
|
|
||||||
|
|
||||||
<!-- Quick Add Button -->
|
|
||||||
<ImageButton android:id="@+id/quickAddButton"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:src="@android:drawable/ic_input_add"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- tag list -->
|
|
||||||
<LinearLayout android:id="@+id/taglist_layout"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/loading"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:text="@string/loading"
|
|
||||||
style="@style/TextAppearance.TaskList_Task"
|
|
||||||
android:gravity="center_vertical"/>
|
|
||||||
|
|
||||||
<ListView android:id="@+id/taglist"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- task list w/ tag-->
|
|
||||||
<LinearLayout android:id="@+id/tasklistwtag_layout"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/loading"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/loading"
|
|
||||||
style="@style/TextAppearance.TaskList_Task"
|
|
||||||
android:gravity="center_vertical"/>
|
|
||||||
|
|
||||||
<ListView android:id="@+id/tasklist"
|
|
||||||
android:layout_weight="100"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
<!-- Footer -->
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<!-- Quick Add Task -->
|
|
||||||
<EditText android:id="@+id/quickAddText"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="100"
|
|
||||||
android:hint="@string/quick_add_hint"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:autoText="true"
|
|
||||||
android:capitalize="sentences"/>
|
|
||||||
|
|
||||||
<!-- Quick Add Button -->
|
|
||||||
<ImageButton android:id="@+id/quickAddButton"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:src="@android:drawable/ic_input_add"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
</com.timsu.astrid.widget.ViewFlipper>
|
|
@ -1,24 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="5dip"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/message"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:paddingBottom="5dip" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="2dip"
|
|
||||||
android:background="#888888"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ListView android:id="@+id/items"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:textSize="12sp" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
@ -1,135 +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
|
|
||||||
|
|
||||||
-->
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/row_layout"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:focusable="true"
|
|
||||||
android:background="@android:drawable/list_selector_background"
|
|
||||||
android:paddingLeft="6dip"
|
|
||||||
android:paddingTop="2dip"
|
|
||||||
android:paddingBottom="2dip"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="45dip" >
|
|
||||||
|
|
||||||
<!-- icons on the left -->
|
|
||||||
<LinearLayout android:id="@+id/icon_layout"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:minWidth="41dip"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="fill_parent">
|
|
||||||
|
|
||||||
<CheckBox android:id="@+id/cb1"
|
|
||||||
android:paddingBottom="5dip"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_width="48dip"
|
|
||||||
android:layout_height="52dip"
|
|
||||||
android:scaleType="center" />
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/imageLeft"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:scaleType="center"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- all text -->
|
|
||||||
<LinearLayout android:id="@+id/text_layout"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingLeft="5dip"
|
|
||||||
android:paddingTop="6dip"
|
|
||||||
android:paddingBottom="6dip"
|
|
||||||
android:layout_weight="1.0"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<!-- task name -->
|
|
||||||
<TextView android:id="@+id/task_name"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
style="@style/TextAppearance.TaskList_Task"
|
|
||||||
android:gravity="center_vertical"/>
|
|
||||||
|
|
||||||
<!-- absolute / goal deadline -->
|
|
||||||
<TextView android:id="@+id/text_deadlines"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
style="@style/TextAppearance.TaskList_Detail"
|
|
||||||
color="@color/taskList_dueDate"
|
|
||||||
android:singleLine="true"/>
|
|
||||||
|
|
||||||
<!-- other details (gray) -->
|
|
||||||
<TextView android:id="@+id/details"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
style="@style/TextAppearance.TaskList_Detail"/>
|
|
||||||
|
|
||||||
<LinearLayout android:id="@+id/expanded_layout"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingTop="5dip"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<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_gravity="top"
|
|
||||||
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:layout_gravity="top"
|
|
||||||
android:text="@string/edit_label"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<!-- importance -->
|
|
||||||
<View android:id="@+id/importance"
|
|
||||||
android:layout_width="12dip"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:paddingLeft="6dip"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
@ -1,49 +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
|
|
||||||
|
|
||||||
-->
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent">
|
|
||||||
|
|
||||||
<TextView android:id="@+id/greeting"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
<TextView android:id="@+id/taskname"
|
|
||||||
android:paddingTop="20dip"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"/>
|
|
||||||
|
|
||||||
<Button android:id="@+id/btn_viewtask"
|
|
||||||
android:paddingTop="40dip"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/addtask_label"/>
|
|
||||||
|
|
||||||
<Button android:id="@+id/btn_tasklist"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/addtask_label"/>
|
|
||||||
</LinearLayout>
|
|
@ -1,68 +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 android.os.Bundle;
|
|
||||||
import android.preference.ListPreference;
|
|
||||||
import android.preference.Preference;
|
|
||||||
import android.preference.PreferenceActivity;
|
|
||||||
|
|
||||||
import com.flurry.android.FlurryAgent;
|
|
||||||
import com.timsu.astrid.R;
|
|
||||||
import com.timsu.astrid.utilities.Calendars;
|
|
||||||
import com.timsu.astrid.utilities.Constants;
|
|
||||||
import com.timsu.astrid.utilities.Preferences;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays the preference screen for users to edit their preferences
|
|
||||||
*
|
|
||||||
* @author timsu
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class EditPreferences extends PreferenceActivity {
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
addPreferencesFromResource(R.xml.preferences);
|
|
||||||
|
|
||||||
Preference backupPreference = findPreference(getString(R.string.p_backup));
|
|
||||||
String backupSummary = Preferences.getBackupSummary(this);
|
|
||||||
if(backupSummary != null && backupPreference != null)
|
|
||||||
backupPreference.setSummary(backupSummary);
|
|
||||||
|
|
||||||
ListPreference defaultCalendarPreference = (ListPreference) findPreference(getString(R.string.prefs_defaultCalendar));
|
|
||||||
Calendars.initCalendarsPreference(this, defaultCalendarPreference);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
|
|
||||||
// set up flurry
|
|
||||||
FlurryAgent.onStartSession(this, Constants.FLURRY_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
FlurryAgent.onEndSession(this);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,150 +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 android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
import com.timsu.astrid.data.tag.TagController;
|
|
||||||
import com.timsu.astrid.data.task.TaskController;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for views that are displayed from the main view page.
|
|
||||||
*
|
|
||||||
* @author timsu
|
|
||||||
*/
|
|
||||||
abstract public class SubActivity {
|
|
||||||
private TaskList parent;
|
|
||||||
int code;
|
|
||||||
private View view;
|
|
||||||
|
|
||||||
public SubActivity(TaskList parent, int code, View view) {
|
|
||||||
this.parent = parent;
|
|
||||||
this.code = code;
|
|
||||||
this.view = view;
|
|
||||||
view.setTag(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void onSaveInstanceState(Bundle outState) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
Object onRetainNonConfigurationInstance() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- 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) {
|
|
||||||
if(c != null)
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getLastNonConfigurationInstance() {
|
|
||||||
return parent.getLastNonConfigurationInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- 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(int activity, Bundle state) {
|
|
||||||
parent.switchToActivity(activity, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- internal methods
|
|
||||||
|
|
||||||
protected int getActivityCode() {
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected View getView() {
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,492 +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.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.database.StaleDataException;
|
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.ContextMenu;
|
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.View.OnCreateContextMenuListener;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
|
||||||
import android.widget.AdapterView.OnItemClickListener;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.ListAdapter;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.flurry.android.FlurryAgent;
|
|
||||||
import com.timsu.astrid.R;
|
|
||||||
import com.timsu.astrid.data.tag.TagIdentifier;
|
|
||||||
import com.timsu.astrid.data.tag.TagModelForView;
|
|
||||||
import com.timsu.astrid.data.task.TaskIdentifier;
|
|
||||||
import com.timsu.astrid.utilities.DialogUtilities;
|
|
||||||
import com.timsu.astrid.utilities.Preferences;
|
|
||||||
import com.todoroo.astrid.activity.TaskEditActivity;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List all tags and allows a user to see all tasks for a given tag
|
|
||||||
*
|
|
||||||
* @author timsu
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class TagListSubActivity extends SubActivity {
|
|
||||||
private static final int ACTIVITY_CREATE = 0;
|
|
||||||
|
|
||||||
private static final int MENU_SORT_ALPHA_ID = Menu.FIRST;
|
|
||||||
private static final int MENU_SORT_SIZE_ID = Menu.FIRST + 1;
|
|
||||||
private static final int CONTEXT_CREATE_ID = Menu.FIRST + 10;
|
|
||||||
private static final int CONTEXT_DELETE_ID = Menu.FIRST + 11;
|
|
||||||
private static final int CONTEXT_SHOWHIDE_ID = Menu.FIRST + 12;
|
|
||||||
private static final int CONTEXT_SHORTCUT_ID = Menu.FIRST + 13;
|
|
||||||
|
|
||||||
protected ListView listView;
|
|
||||||
protected LinkedList<TagModelForView> tagArray;
|
|
||||||
HashMap<TagModelForView, Integer> tagToTaskCount;
|
|
||||||
protected Handler handler;
|
|
||||||
protected TextView loadingText;
|
|
||||||
protected boolean untaggedTagDisplayed;
|
|
||||||
|
|
||||||
protected static SortMode sortMode = SortMode.SIZE;
|
|
||||||
protected static boolean sortReverse = false;
|
|
||||||
|
|
||||||
public TagListSubActivity(TaskList parent, int code, View view) {
|
|
||||||
super(parent, code, view);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisplay(Bundle variables) {
|
|
||||||
listView = (ListView)findViewById(R.id.taglist);
|
|
||||||
handler = new Handler();
|
|
||||||
loadingText = (TextView)findViewById(R.id.loading);
|
|
||||||
|
|
||||||
// time to go!
|
|
||||||
new Thread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
loadTagListSort();
|
|
||||||
fillData();
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
|
|
||||||
FlurryAgent.onEvent("view-tags"); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- stuff for sorting
|
|
||||||
|
|
||||||
private enum SortMode {
|
|
||||||
ALPHA {
|
|
||||||
@Override
|
|
||||||
int compareTo(TagListSubActivity self, TagModelForView arg0, TagModelForView arg1) {
|
|
||||||
return arg0.getName().compareTo(arg1.getName());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
SIZE {
|
|
||||||
@Override
|
|
||||||
int compareTo(TagListSubActivity self, TagModelForView arg0, TagModelForView arg1) {
|
|
||||||
synchronized(self) {
|
|
||||||
return self.tagToTaskCount.get(arg1) - self.tagToTaskCount.get(arg0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
abstract int compareTo(TagListSubActivity self, TagModelForView arg0, TagModelForView arg1);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Counts how many tasks appear in active task list */
|
|
||||||
public static int countActiveTasks(HashSet<TaskIdentifier> activeTasks, LinkedList<TaskIdentifier> tasks) {
|
|
||||||
int count = 0;
|
|
||||||
if(tasks != null) {
|
|
||||||
for(TaskIdentifier task : tasks)
|
|
||||||
if(activeTasks.contains(task))
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void sortTagArray() {
|
|
||||||
// get all tasks
|
|
||||||
HashSet<TaskIdentifier> activeTasks =
|
|
||||||
getTaskController().getActiveTaskIdentifiers();
|
|
||||||
if(activeTasks == null)
|
|
||||||
activeTasks = new HashSet<TaskIdentifier>();
|
|
||||||
|
|
||||||
// get task count for each tag
|
|
||||||
tagToTaskCount = new HashMap<TagModelForView, Integer>();
|
|
||||||
|
|
||||||
for(TagModelForView tag : tagArray) {
|
|
||||||
LinkedList<TaskIdentifier> tasks;
|
|
||||||
tasks = getTagController().getTaggedTasks(tag.getTagIdentifier());
|
|
||||||
int count = countActiveTasks(activeTasks, tasks);
|
|
||||||
tagToTaskCount.put(tag, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
// do sort
|
|
||||||
Collections.sort(tagArray, new Comparator<TagModelForView>() {
|
|
||||||
public int compare(TagModelForView arg0, TagModelForView arg1) {
|
|
||||||
return sortMode.compareTo(TagListSubActivity.this, arg0, arg1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// show "untagged" as a category at the top, in the proper language/localization
|
|
||||||
String untaggedLabel = getResources().getString(R.string.tagList_untagged);
|
|
||||||
TagModelForView untaggedModel = TagModelForView.getUntaggedModel(untaggedLabel);
|
|
||||||
int count = countActiveTasks(activeTasks, getTagController().getUntaggedTasks());
|
|
||||||
if(count > 0) {
|
|
||||||
untaggedTagDisplayed = true;
|
|
||||||
tagArray.addFirst(untaggedModel);
|
|
||||||
tagToTaskCount.put(untaggedModel, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sortReverse)
|
|
||||||
Collections.reverse(tagArray);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Save the sorting mode to the preferences */
|
|
||||||
private void saveTagListSort() {
|
|
||||||
int sortId = sortMode.ordinal() + 1;
|
|
||||||
|
|
||||||
if (sortReverse)
|
|
||||||
sortId *= -1;
|
|
||||||
|
|
||||||
Preferences.setTagListSort(getParent(), sortId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Save the sorting mode to the preferences */
|
|
||||||
protected void loadTagListSort() {
|
|
||||||
try {
|
|
||||||
int sortId = Preferences.getTagListSort(getParent());
|
|
||||||
if (sortId == 0)
|
|
||||||
return;
|
|
||||||
sortReverse = sortId < 0;
|
|
||||||
sortId = Math.abs(sortId) - 1;
|
|
||||||
|
|
||||||
sortMode = SortMode.values()[sortId];
|
|
||||||
} catch (Exception e) {
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// --- fill data
|
|
||||||
|
|
||||||
/** Fill in the Tag List with our tags */
|
|
||||||
protected synchronized void fillData() {
|
|
||||||
try {
|
|
||||||
tagArray = getTagController().getAllTags();
|
|
||||||
|
|
||||||
sortTagArray(); // count and sort each tag
|
|
||||||
} catch (StaleDataException e) {
|
|
||||||
// happens when you rotate the screen while the thread is
|
|
||||||
// still running. i don't think it's avoidable?
|
|
||||||
Log.w("astrid", "StaleDataException", e); //$NON-NLS-1$ //$NON-NLS-2$
|
|
||||||
return;
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("astrid", "Error loading list", e); //$NON-NLS-1$ //$NON-NLS-2$
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.post(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
synchronized(TagListSubActivity.this) {
|
|
||||||
// set up our adapter
|
|
||||||
final TagListAdapter tagAdapter = new TagListAdapter(getParent(),
|
|
||||||
android.R.layout.simple_list_item_1, tagArray,
|
|
||||||
tagToTaskCount);
|
|
||||||
// set up ui components
|
|
||||||
setUpListUI(tagAdapter);
|
|
||||||
}
|
|
||||||
loadingText.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set up list handlers and adapter. run on the UI thread */
|
|
||||||
protected void setUpListUI(ListAdapter adapter) {
|
|
||||||
// set up the title
|
|
||||||
Resources r = getResources();
|
|
||||||
int tags = tagArray.size();
|
|
||||||
if(untaggedTagDisplayed && tags > 0)
|
|
||||||
tags--;
|
|
||||||
StringBuilder title = new StringBuilder().
|
|
||||||
append(r.getString(R.string.tagList_titlePrefix)).
|
|
||||||
append(" ").append(r.getQuantityString(R.plurals.Ntags,
|
|
||||||
tags, tags));
|
|
||||||
final CharSequence finalTitle = title;
|
|
||||||
handler.post(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
setTitle(finalTitle);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
listView.setAdapter(adapter);
|
|
||||||
|
|
||||||
// list view listener
|
|
||||||
listView.setOnItemClickListener(new OnItemClickListener() {
|
|
||||||
public void onItemClick(AdapterView<?> parent, View view,
|
|
||||||
int position, long id) {
|
|
||||||
TagModelForView tag = (TagModelForView)view.getTag();
|
|
||||||
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putLong(TaskListSubActivity.TAG_TOKEN, tag.getTagIdentifier().getId());
|
|
||||||
switchToActivity(TaskList.AC_TASK_LIST_W_TAG, bundle);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
listView.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
|
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v,
|
|
||||||
ContextMenuInfo menuInfo) {
|
|
||||||
AdapterContextMenuInfo adapterMenuInfo =
|
|
||||||
(AdapterContextMenuInfo)menuInfo;
|
|
||||||
int position = adapterMenuInfo.position;
|
|
||||||
|
|
||||||
menu.add(position, CONTEXT_CREATE_ID, Menu.NONE,
|
|
||||||
R.string.tagList_context_create);
|
|
||||||
menu.add(position, CONTEXT_DELETE_ID, Menu.NONE,
|
|
||||||
R.string.tagList_context_delete);
|
|
||||||
|
|
||||||
int showHideLabel = R.string.tagList_context_hideTag;
|
|
||||||
if(tagArray.get(position).shouldHideFromMainList())
|
|
||||||
showHideLabel = R.string.tagList_context_showTag;
|
|
||||||
menu.add(position, CONTEXT_SHOWHIDE_ID, Menu.NONE,
|
|
||||||
showHideLabel);
|
|
||||||
|
|
||||||
menu.add(position, CONTEXT_SHORTCUT_ID, Menu.NONE,
|
|
||||||
R.string.tagList_context_shortcut);
|
|
||||||
|
|
||||||
menu.setHeaderTitle(tagArray.get(position).getName());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
listView.setOnTouchListener(getGestureListener());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode,
|
|
||||||
Intent intent) {
|
|
||||||
fillData();
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- list adapter
|
|
||||||
|
|
||||||
private void createTask(TagModelForView tag) {
|
|
||||||
Intent intent = new Intent(getParent(), TaskEditActivity.class);
|
|
||||||
launchActivity(intent, ACTIVITY_CREATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void deleteTag(final TagIdentifier tagId) {
|
|
||||||
new AlertDialog.Builder(getParent())
|
|
||||||
.setTitle(R.string.delete_title)
|
|
||||||
.setMessage(R.string.delete_this_tag_title)
|
|
||||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
|
||||||
.setPositiveButton(android.R.string.ok,
|
|
||||||
new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
getTagController().deleteTag(tagId);
|
|
||||||
fillData();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
/** Handle back button by moving to task list */
|
|
||||||
protected boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
||||||
if(keyCode == KeyEvent.KEYCODE_BACK) {
|
|
||||||
switchToActivity(TaskList.AC_TASK_LIST, null);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
/** Picked item in the options list */
|
|
||||||
public boolean onMenuItemSelected(int featureId, MenuItem item) {
|
|
||||||
switch(item.getItemId()) {
|
|
||||||
case MENU_SORT_ALPHA_ID:
|
|
||||||
if(sortMode == SortMode.ALPHA)
|
|
||||||
sortReverse = !sortReverse;
|
|
||||||
else {
|
|
||||||
sortMode = SortMode.ALPHA;
|
|
||||||
sortReverse = false;
|
|
||||||
}
|
|
||||||
saveTagListSort();
|
|
||||||
fillData();
|
|
||||||
return true;
|
|
||||||
case MENU_SORT_SIZE_ID:
|
|
||||||
if(sortMode == SortMode.SIZE)
|
|
||||||
sortReverse = !sortReverse;
|
|
||||||
else {
|
|
||||||
sortMode = SortMode.SIZE;
|
|
||||||
sortReverse = false;
|
|
||||||
}
|
|
||||||
saveTagListSort();
|
|
||||||
fillData();
|
|
||||||
return true;
|
|
||||||
case CONTEXT_CREATE_ID:
|
|
||||||
TagModelForView tag = tagArray.get(item.getGroupId());
|
|
||||||
createTask(tag);
|
|
||||||
return true;
|
|
||||||
case CONTEXT_DELETE_ID:
|
|
||||||
tag = tagArray.get(item.getGroupId());
|
|
||||||
deleteTag(tag.getTagIdentifier());
|
|
||||||
return true;
|
|
||||||
case CONTEXT_SHOWHIDE_ID:
|
|
||||||
tag = tagArray.get(item.getGroupId());
|
|
||||||
tag.toggleHideFromMainList();
|
|
||||||
try {
|
|
||||||
getTagController().saveTag(tag);
|
|
||||||
} catch (Exception e) {
|
|
||||||
DialogUtilities.okDialog(getParent(), "Error: You probably " +
|
|
||||||
"already have a tag named '" + tag.getName() + "'!",
|
|
||||||
null);
|
|
||||||
}
|
|
||||||
fillData();
|
|
||||||
return true;
|
|
||||||
case CONTEXT_SHORTCUT_ID:
|
|
||||||
tag = tagArray.get(item.getGroupId());
|
|
||||||
Resources r = getResources();
|
|
||||||
Intent shortcutIntent = new Intent(Intent.ACTION_VIEW);
|
|
||||||
shortcutIntent.setComponent(new ComponentName(
|
|
||||||
getParent().getApplicationContext(), TagView.class));
|
|
||||||
shortcutIntent.setData(Uri.parse("tag:" + tag.getTagIdentifier().getId())); //$NON-NLS-1$
|
|
||||||
|
|
||||||
Intent createShortcutIntent = new Intent();
|
|
||||||
createShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
|
|
||||||
String label = tag.getName();
|
|
||||||
if(tag.shouldHideFromMainList())
|
|
||||||
label = label.substring(1);
|
|
||||||
|
|
||||||
// add the @ sign if the task starts with a letter, for clarity
|
|
||||||
if(Character.isLetterOrDigit(label.charAt(0)))
|
|
||||||
label = "@" + label; //$NON-NLS-1$
|
|
||||||
|
|
||||||
createShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, label);
|
|
||||||
createShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON,
|
|
||||||
((BitmapDrawable)r.getDrawable(R.drawable.icon_blank)).getBitmap());
|
|
||||||
createShortcutIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); //$NON-NLS-1$
|
|
||||||
|
|
||||||
getParent().sendBroadcast(createShortcutIntent);
|
|
||||||
Toast.makeText(getParent(), R.string.tagList_shortcut_created, Toast.LENGTH_SHORT).show();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- creating stuff
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
|
||||||
MenuItem item;
|
|
||||||
|
|
||||||
item = menu.add(Menu.NONE, MENU_SORT_ALPHA_ID, Menu.NONE,
|
|
||||||
R.string.tagList_menu_sortAlpha);
|
|
||||||
item.setIcon(android.R.drawable.ic_menu_sort_alphabetically);
|
|
||||||
item.setAlphabeticShortcut('a');
|
|
||||||
|
|
||||||
item = menu.add(Menu.NONE, MENU_SORT_SIZE_ID, Menu.NONE,
|
|
||||||
R.string.tagList_menu_sortSize);
|
|
||||||
item.setIcon(android.R.drawable.ic_menu_sort_by_size);
|
|
||||||
item.setAlphabeticShortcut('s');
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------- tag list adapter
|
|
||||||
|
|
||||||
class TagListAdapter extends ArrayAdapter<TagModelForView> {
|
|
||||||
|
|
||||||
private final List<TagModelForView> objects;
|
|
||||||
private final int resource;
|
|
||||||
private final LayoutInflater inflater;
|
|
||||||
private HashMap<TagModelForView, Integer> tagCount;
|
|
||||||
|
|
||||||
public TagListAdapter(Context context, int resource,
|
|
||||||
List<TagModelForView> objects, HashMap<TagModelForView, Integer>
|
|
||||||
tagToTaskCount) {
|
|
||||||
super(context, resource, objects);
|
|
||||||
|
|
||||||
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
this.objects = objects;
|
|
||||||
this.resource = resource;
|
|
||||||
this.tagCount = tagToTaskCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
|
||||||
View view = convertView;
|
|
||||||
|
|
||||||
if(view == null) {
|
|
||||||
view = inflater.inflate(resource, parent, false);
|
|
||||||
}
|
|
||||||
setupView(view, objects.get(position), false);
|
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setupView(View view, final TagModelForView tag, boolean retry) {
|
|
||||||
Resources r = getResources();
|
|
||||||
view.setTag(tag);
|
|
||||||
|
|
||||||
final TextView name = ((TextView)view.findViewById(android.R.id.text1));
|
|
||||||
try {
|
|
||||||
if(tagCount == null)
|
|
||||||
tagCount = tagToTaskCount;
|
|
||||||
|
|
||||||
name.setText(new StringBuilder(tag.getName()).
|
|
||||||
append(" (").append(tagCount.get(tag)).append(")"));
|
|
||||||
|
|
||||||
if(tagCount == null || tagCount.get(tag) == null || tagCount.get(tag) == 0)
|
|
||||||
name.setTextColor(r.getColor(R.color.task_list_done));
|
|
||||||
else
|
|
||||||
name.setTextColor(r.getColor(android.R.color.white));
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("astrid", "Error loading tag list", e); //$NON-NLS-1$ //$NON-NLS-2$
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,62 +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 android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This activity is launched from a desktop shortcut and takes the user to
|
|
||||||
* view a specific tag
|
|
||||||
*
|
|
||||||
* @author timsu
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class TagView extends Activity {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
launchTaskList(getIntent());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onNewIntent(Intent intent) {
|
|
||||||
super.onNewIntent(intent);
|
|
||||||
|
|
||||||
launchTaskList(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void launchTaskList(Intent intent) {
|
|
||||||
String tag = intent.getData().toString();
|
|
||||||
long tagId = Long.parseLong(tag.substring(tag.indexOf(":")+1));
|
|
||||||
|
|
||||||
Bundle variables = new Bundle();
|
|
||||||
variables.putLong(TaskListSubActivity.TAG_TOKEN, tagId);
|
|
||||||
|
|
||||||
Intent taskListIntent = new Intent(this, TaskList.class);
|
|
||||||
taskListIntent.putExtra(TaskList.VARIABLES_TAG, variables);
|
|
||||||
startActivity(taskListIntent);
|
|
||||||
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,384 +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 android.app.Activity;
|
|
||||||
import android.appwidget.AppWidgetManager;
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
|
||||||
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.GestureDetector.SimpleOnGestureListener;
|
|
||||||
import android.view.animation.Animation;
|
|
||||||
import android.view.animation.AnimationUtils;
|
|
||||||
import android.widget.RemoteViews;
|
|
||||||
import android.widget.ViewFlipper;
|
|
||||||
|
|
||||||
import com.flurry.android.FlurryAgent;
|
|
||||||
import com.timsu.astrid.R;
|
|
||||||
import com.timsu.astrid.appwidget.AstridAppWidgetProvider;
|
|
||||||
import com.timsu.astrid.data.tag.TagController;
|
|
||||||
import com.timsu.astrid.data.task.TaskController;
|
|
||||||
import com.timsu.astrid.sync.Synchronizer;
|
|
||||||
import com.timsu.astrid.utilities.Constants;
|
|
||||||
import com.timsu.astrid.utilities.AstridUtilities.AstridUncaughtExceptionHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TaskList is the main launched activity for Astrid. It uses a ViewFlipper
|
|
||||||
* to flip between child views, which in this case are the TaskListSubActivity
|
|
||||||
* and the TagListSubActivity.
|
|
||||||
*
|
|
||||||
* @author timsu
|
|
||||||
*/
|
|
||||||
public class TaskList extends Activity {
|
|
||||||
|
|
||||||
// constants for the different pages that we can display
|
|
||||||
public static final int AC_TASK_LIST = 0;
|
|
||||||
public static final int AC_TAG_LIST = 1;
|
|
||||||
public static final int AC_TASK_LIST_W_TAG = 2;
|
|
||||||
|
|
||||||
/** Bundle Key: activity code id of current activity */
|
|
||||||
private static final String LAST_ACTIVITY_TAG = "l";
|
|
||||||
|
|
||||||
/** Bundle Key: variables of current activity */
|
|
||||||
private static final String LAST_BUNDLE_TAG = "b";
|
|
||||||
|
|
||||||
/** Bundle Key: variables to pass to the sub-activity */
|
|
||||||
public static final String VARIABLES_TAG = "v";
|
|
||||||
|
|
||||||
/** Minimum distance a fling must cover to trigger motion */
|
|
||||||
private static final int FLING_DIST_THRESHOLD = 120;
|
|
||||||
|
|
||||||
/** Maximum distance in the other axis for a fling */
|
|
||||||
private static final int MAX_FLING_OTHER_AXIS = 300;
|
|
||||||
|
|
||||||
/** Minimum velocity a fling must have to trigger motion */
|
|
||||||
private static final int FLING_VEL_THRESHOLD = 200;
|
|
||||||
|
|
||||||
// view components
|
|
||||||
private ViewFlipper viewFlipper;
|
|
||||||
private GestureDetector gestureDetector;
|
|
||||||
View.OnTouchListener gestureListener;
|
|
||||||
private SubActivity taskList;
|
|
||||||
private SubActivity tagList;
|
|
||||||
private SubActivity taskListWTag;
|
|
||||||
private Bundle lastActivityBundle;
|
|
||||||
|
|
||||||
// animations
|
|
||||||
private Animation mFadeInAnim;
|
|
||||||
private Animation mFadeOutAnim;
|
|
||||||
|
|
||||||
// data controllers
|
|
||||||
TaskController taskController;
|
|
||||||
TagController tagController;
|
|
||||||
|
|
||||||
// static variables
|
|
||||||
public static boolean synchronizeNow = false;
|
|
||||||
|
|
||||||
/** If set, the application will close when this activity gets focus */
|
|
||||||
static boolean shouldCloseInstance = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
/** Called when loading up the activity for the first time */
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.main);
|
|
||||||
|
|
||||||
// set uncaught exception handler
|
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new AstridUncaughtExceptionHandler());
|
|
||||||
|
|
||||||
// open controllers & perform application startup rituals
|
|
||||||
// StartupReceiver.onStartupApplication(this);
|
|
||||||
shouldCloseInstance = false;
|
|
||||||
taskController = new TaskController(this);
|
|
||||||
taskController.open();
|
|
||||||
tagController = new TagController(this);
|
|
||||||
tagController.open();
|
|
||||||
|
|
||||||
setupUIComponents();
|
|
||||||
|
|
||||||
Bundle variables = new Bundle();
|
|
||||||
|
|
||||||
if(savedInstanceState != null && savedInstanceState.containsKey(LAST_ACTIVITY_TAG)) {
|
|
||||||
viewFlipper.setDisplayedChild(savedInstanceState.getInt(LAST_ACTIVITY_TAG));
|
|
||||||
Bundle lastBundle = savedInstanceState.getBundle(LAST_BUNDLE_TAG);
|
|
||||||
if(lastBundle != null)
|
|
||||||
variables.putAll(lastBundle);
|
|
||||||
}
|
|
||||||
if(getIntent().hasExtra(VARIABLES_TAG))
|
|
||||||
variables.putAll(getIntent().getBundleExtra(VARIABLES_TAG));
|
|
||||||
|
|
||||||
getCurrentSubActivity().onDisplay(variables);
|
|
||||||
|
|
||||||
// sync now if requested
|
|
||||||
if(synchronizeNow) {
|
|
||||||
synchronizeNow = false;
|
|
||||||
Synchronizer sync = new Synchronizer(false);
|
|
||||||
sync.setTagController(tagController);
|
|
||||||
sync.setTaskController(taskController);
|
|
||||||
sync.synchronize(this, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we have no filter tag, we're not on the last task
|
|
||||||
if(getCurrentSubActivity() == taskListWTag &&
|
|
||||||
((TaskListSubActivity)taskListWTag).getFilterTag() == null) {
|
|
||||||
switchToActivity(AC_TASK_LIST, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
|
|
||||||
// set up flurry
|
|
||||||
FlurryAgent.onStartSession(this, Constants.FLURRY_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
updateWidget();
|
|
||||||
|
|
||||||
FlurryAgent.onEndSession(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateWidget()
|
|
||||||
{
|
|
||||||
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this);
|
|
||||||
|
|
||||||
RemoteViews views = AstridAppWidgetProvider.UpdateService.buildUpdate(this);
|
|
||||||
ComponentName widgetName = new ComponentName(this, AstridAppWidgetProvider.class);
|
|
||||||
appWidgetManager.updateAppWidget(widgetName, views);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set up user interface components */
|
|
||||||
private void setupUIComponents() {
|
|
||||||
gestureDetector = new GestureDetector(new AstridGestureDetector());
|
|
||||||
viewFlipper = (ViewFlipper)findViewById(R.id.main);
|
|
||||||
taskList = new TaskListSubActivity(this, AC_TASK_LIST,
|
|
||||||
findViewById(R.id.tasklist_layout));
|
|
||||||
tagList = new TagListSubActivity(this, AC_TAG_LIST,
|
|
||||||
findViewById(R.id.taglist_layout));
|
|
||||||
taskListWTag = new TaskListSubActivity(this, AC_TASK_LIST_W_TAG,
|
|
||||||
findViewById(R.id.tasklistwtag_layout));
|
|
||||||
|
|
||||||
mFadeInAnim = AnimationUtils.loadAnimation(this, R.anim.fade_in);
|
|
||||||
mFadeOutAnim = AnimationUtils.loadAnimation(this, R.anim.fade_out);
|
|
||||||
viewFlipper.setInAnimation(mFadeInAnim);
|
|
||||||
viewFlipper.setOutAnimation(mFadeOutAnim);
|
|
||||||
|
|
||||||
gestureListener = new View.OnTouchListener() {
|
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
|
||||||
if (gestureDetector.onTouchEvent(event)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Gesture detector switches between sub-activities */
|
|
||||||
class AstridGestureDetector extends SimpleOnGestureListener {
|
|
||||||
@Override
|
|
||||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
|
||||||
try {
|
|
||||||
if(Math.abs(e1.getY() - e2.getY()) > MAX_FLING_OTHER_AXIS)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Log.i("astrid", "Got fling. X: " + (e2.getX() - e1.getX()) +
|
|
||||||
", vel: " + velocityX + " Y: " + (e2.getY() - e1.getY()));
|
|
||||||
|
|
||||||
// flick R to L
|
|
||||||
if(e1.getX() - e2.getX() > FLING_DIST_THRESHOLD &&
|
|
||||||
Math.abs(velocityX) > FLING_VEL_THRESHOLD) {
|
|
||||||
|
|
||||||
switch(getCurrentSubActivity().getActivityCode()) {
|
|
||||||
case AC_TASK_LIST:
|
|
||||||
switchToActivity(AC_TAG_LIST, null);
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// flick L to R
|
|
||||||
else if(e2.getX() - e1.getX() > FLING_DIST_THRESHOLD &&
|
|
||||||
Math.abs(velocityX) > FLING_VEL_THRESHOLD) {
|
|
||||||
|
|
||||||
switch(getCurrentSubActivity().getActivityCode()) {
|
|
||||||
case AC_TASK_LIST_W_TAG:
|
|
||||||
switchToActivity(AC_TAG_LIST, null);
|
|
||||||
return true;
|
|
||||||
case AC_TAG_LIST:
|
|
||||||
switchToActivity(AC_TASK_LIST, null);
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// ignore!
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ======================================================================
|
|
||||||
* ==================================================== subactivity stuff
|
|
||||||
* ====================================================================== */
|
|
||||||
|
|
||||||
/** Switches to another activity, with appropriate animation */
|
|
||||||
void switchToActivity(int activity, Bundle variables) {
|
|
||||||
closeOptionsMenu();
|
|
||||||
|
|
||||||
// and flip to them
|
|
||||||
switch(getCurrentSubActivity().getActivityCode()) {
|
|
||||||
case AC_TASK_LIST:
|
|
||||||
switch(activity) {
|
|
||||||
case AC_TAG_LIST:
|
|
||||||
viewFlipper.showNext();
|
|
||||||
break;
|
|
||||||
case AC_TASK_LIST_W_TAG:
|
|
||||||
viewFlipper.setDisplayedChild(taskListWTag.code);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AC_TAG_LIST:
|
|
||||||
switch(activity) {
|
|
||||||
case AC_TASK_LIST:
|
|
||||||
viewFlipper.showPrevious();
|
|
||||||
break;
|
|
||||||
case AC_TASK_LIST_W_TAG:
|
|
||||||
viewFlipper.showNext();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AC_TASK_LIST_W_TAG:
|
|
||||||
switch(activity) {
|
|
||||||
case AC_TAG_LIST:
|
|
||||||
viewFlipper.showPrevious();
|
|
||||||
break;
|
|
||||||
case AC_TASK_LIST:
|
|
||||||
viewFlipper.setDisplayedChild(taskList.code);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize the components
|
|
||||||
switch(activity) {
|
|
||||||
case AC_TASK_LIST:
|
|
||||||
taskList.onDisplay(variables);
|
|
||||||
break;
|
|
||||||
case AC_TAG_LIST:
|
|
||||||
tagList.onDisplay(variables);
|
|
||||||
break;
|
|
||||||
case AC_TASK_LIST_W_TAG:
|
|
||||||
taskListWTag.onDisplay(variables);
|
|
||||||
}
|
|
||||||
|
|
||||||
lastActivityBundle = variables;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Helper method gets the currently visible subactivity */
|
|
||||||
private SubActivity getCurrentSubActivity() {
|
|
||||||
return (SubActivity)viewFlipper.getCurrentView().getTag();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ======================================================================
|
|
||||||
* ======================================================= event handling
|
|
||||||
* ====================================================================== */
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
outState.putInt(LAST_ACTIVITY_TAG, getCurrentSubActivity().code);
|
|
||||||
outState.putBundle(LAST_BUNDLE_TAG, lastActivityBundle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
|
||||||
if(getCurrentSubActivity().onKeyDown(keyCode, event))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return super.onKeyDown(keyCode, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
|
||||||
menu.clear();
|
|
||||||
return getCurrentSubActivity().onPrepareOptionsMenu(menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
|
|
||||||
if(resultCode == Constants.RESULT_GO_HOME) {
|
|
||||||
switchToActivity(AC_TASK_LIST, null);
|
|
||||||
} else
|
|
||||||
getCurrentSubActivity().onActivityResult(requestCode, resultCode, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@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))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return super.onMenuItemSelected(featureId, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
|
||||||
if (gestureDetector.onTouchEvent(event))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object onRetainNonConfigurationInstance() {
|
|
||||||
return getCurrentSubActivity().onRetainNonConfigurationInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
taskController.close();
|
|
||||||
tagController.close();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,741 +0,0 @@
|
|||||||
/*
|
|
||||||
* ASTRID: Android's Simple Task Recording Dashboard
|
|
||||||
*
|
|
||||||
* 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.text.Format;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Typeface;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.ContextMenu;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
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.ImageView;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.flurry.android.FlurryAgent;
|
|
||||||
import com.timsu.astrid.R;
|
|
||||||
import com.timsu.astrid.data.alerts.AlertController;
|
|
||||||
import com.timsu.astrid.data.enums.Importance;
|
|
||||||
import com.timsu.astrid.data.tag.TagController;
|
|
||||||
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.AstridUtilities;
|
|
||||||
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
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class TaskListAdapter extends ArrayAdapter<TaskModelForList> {
|
|
||||||
|
|
||||||
public static final int CONTEXT_EDIT_ID = Menu.FIRST + 50;
|
|
||||||
public static final int CONTEXT_DELETE_ID = Menu.FIRST + 51;
|
|
||||||
public static final int CONTEXT_TIMER_ID = Menu.FIRST + 52;
|
|
||||||
public static final int CONTEXT_POSTPONE_ID = Menu.FIRST + 53;
|
|
||||||
|
|
||||||
// keys for caching task properties
|
|
||||||
private static final int KEY_NAME = 0;
|
|
||||||
private static final int KEY_DEADLINE = 1;
|
|
||||||
private static final int KEY_OVERDUE = 2;
|
|
||||||
private static final int KEY_REPEAT = 3;
|
|
||||||
private static final int KEY_REMINDERS = 4;
|
|
||||||
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";
|
|
||||||
|
|
||||||
/** Number of seconds after which we display the full date deadline */
|
|
||||||
private static final int FULL_DATE_THRESHOLD = 7*24*3600;
|
|
||||||
|
|
||||||
// alarm date formatter
|
|
||||||
private static Format alarmFormat = null;
|
|
||||||
|
|
||||||
private final Activity activity;
|
|
||||||
private final List<TaskModelForList> objects;
|
|
||||||
private final int resource;
|
|
||||||
private final LayoutInflater inflater;
|
|
||||||
private final TaskListAdapterHooks hooks;
|
|
||||||
private final TextView deletedItemView = new TextView(getContext());
|
|
||||||
|
|
||||||
private final Integer fontSizePreference;
|
|
||||||
private final AlertController alarmController;
|
|
||||||
|
|
||||||
private TaskModelForList recentlyCompleted = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call-back interface for interacting with parent activity
|
|
||||||
*
|
|
||||||
* @author timsu
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface TaskListAdapterHooks {
|
|
||||||
List<TaskModelForList> getTaskArray();
|
|
||||||
String getTagsFor(TaskModelForList task);
|
|
||||||
TaskController taskController();
|
|
||||||
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
|
|
||||||
* @param objects
|
|
||||||
* @param hooks
|
|
||||||
*/
|
|
||||||
public TaskListAdapter(Activity activity, int resource,
|
|
||||||
List<TaskModelForList> objects, TaskListAdapterHooks hooks) {
|
|
||||||
super(activity, resource, objects);
|
|
||||||
|
|
||||||
inflater = (LayoutInflater)activity.getSystemService(
|
|
||||||
Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
this.objects = objects;
|
|
||||||
this.resource = resource;
|
|
||||||
this.activity = activity;
|
|
||||||
this.hooks = hooks;
|
|
||||||
|
|
||||||
fontSizePreference = Preferences.getTaskListFontSize(getContext());
|
|
||||||
alarmController = new AlertController(activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets the expanded state as desired */
|
|
||||||
public void setExpanded(View view, TaskModelForList task, boolean state) {
|
|
||||||
try {
|
|
||||||
if(state) {
|
|
||||||
task.clearCache();
|
|
||||||
task.putCachedLabel(KEY_EXPANDED, CACHE_TRUE);
|
|
||||||
hooks.setSelectedItem(task.getTaskIdentifier());
|
|
||||||
} else {
|
|
||||||
task.putCachedLabel(KEY_EXPANDED, null);
|
|
||||||
hooks.setSelectedItem(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(view != null) {
|
|
||||||
setFieldContentsAndVisibility(view, task);
|
|
||||||
|
|
||||||
// if the item is near the bottom of the list, we need to give
|
|
||||||
// it focus so that the list knows there's new stuff down there
|
|
||||||
int position = objects.indexOf(task);
|
|
||||||
if(objects.size() - position < 2 && view.getParent() != null)
|
|
||||||
((ListView)view.getParent()).setSelection(position);
|
|
||||||
view.requestFocus();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
AstridUtilities.reportFlurryError("task-adapter-set-expanded", e);
|
|
||||||
Log.e("astrid", "Error in setExpanded", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Toggle the expanded state of this task */
|
|
||||||
public void toggleExpanded(View view, TaskModelForList task) {
|
|
||||||
if(CACHE_TRUE.equals(task.getCachedLabel(KEY_EXPANDED))) {
|
|
||||||
setExpanded(view, task, false);
|
|
||||||
} else {
|
|
||||||
setExpanded(view, task, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
// --- code for setting up each view
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
@Override
|
|
||||||
/** Creates or reuses the view for a row in the list */
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
|
||||||
View view = convertView;
|
|
||||||
|
|
||||||
if(objects.size() <= position || objects.get(position) == null)
|
|
||||||
return deletedItemView;
|
|
||||||
|
|
||||||
if(view == null) {
|
|
||||||
view = inflater.inflate(resource, parent, false);
|
|
||||||
initializeView(view);
|
|
||||||
addListeners(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
setupView(view, objects.get(position));
|
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform initial setup on the row. Called once for the whole list
|
|
||||||
*
|
|
||||||
* @param view
|
|
||||||
*/
|
|
||||||
private void initializeView(View view) {
|
|
||||||
final TextView name = ((TextView)view.findViewById(R.id.task_name));
|
|
||||||
if(fontSizePreference != null && fontSizePreference > 0)
|
|
||||||
name.setTextSize(fontSizePreference);
|
|
||||||
deletedItemView.setText(getContext().getResources().getString(R.string.taskList_deleted));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup the given view for the specified task. Called every row
|
|
||||||
*
|
|
||||||
* @param view
|
|
||||||
* @param task
|
|
||||||
*/
|
|
||||||
private void setupView(View view, final TaskModelForList task) {
|
|
||||||
Resources r = activity.getResources();
|
|
||||||
|
|
||||||
view.setTag(task);
|
|
||||||
setFieldContentsAndVisibility(view, task);
|
|
||||||
|
|
||||||
if(task == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
view.setMinimumHeight(90);
|
|
||||||
} else {
|
|
||||||
timer.setImageDrawable(null);
|
|
||||||
view.setMinimumHeight(45);
|
|
||||||
}
|
|
||||||
|
|
||||||
final TextView name = ((TextView)view.findViewById(R.id.task_name));
|
|
||||||
setTaskAppearance(task, name, progress);
|
|
||||||
|
|
||||||
hooks.onCreatedTaskListView(view, task);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Helper method to set the visibility based on if there's stuff inside */
|
|
||||||
private static void setVisibility(TextView v) {
|
|
||||||
if(v.getText().length() > 0)
|
|
||||||
v.setVisibility(View.VISIBLE);
|
|
||||||
else
|
|
||||||
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) {
|
|
||||||
if(task == null) {
|
|
||||||
view.setVisibility(View.GONE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
if(expandedContainer != null)
|
|
||||||
expandedContainer.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
|
|
||||||
|
|
||||||
// name
|
|
||||||
final TextView name = ((TextView)view.findViewById(R.id.task_name)); {
|
|
||||||
String cachedResult = task.getCachedLabel(KEY_NAME);
|
|
||||||
if(cachedResult == null) {
|
|
||||||
String nameValue = task.getName();
|
|
||||||
if(task.getHiddenUntil() != null && task.getHiddenUntil().getTime() > System.currentTimeMillis()) {
|
|
||||||
nameValue = "(" + r.getString(R.string.taskList_hiddenPrefix) + ") " + nameValue;
|
|
||||||
task.putCachedLabel(KEY_HIDDEN, CACHE_TRUE);
|
|
||||||
}
|
|
||||||
cachedResult = nameValue;
|
|
||||||
task.putCachedLabel(KEY_NAME, cachedResult);
|
|
||||||
}
|
|
||||||
name.setText(cachedResult);
|
|
||||||
if(CACHE_TRUE.equals(task.getCachedLabel(KEY_HIDDEN)))
|
|
||||||
name.setTypeface(Typeface.DEFAULT, Typeface.ITALIC);
|
|
||||||
else
|
|
||||||
name.setTypeface(Typeface.DEFAULT, Typeface.BOLD);
|
|
||||||
}
|
|
||||||
|
|
||||||
// importance
|
|
||||||
final View importance = view.findViewById(R.id.importance);
|
|
||||||
if(visibleFields.IMPORTANCE) {
|
|
||||||
importance.setBackgroundColor(r.getColor(
|
|
||||||
task.getImportance().getColorResource()));
|
|
||||||
} else
|
|
||||||
importance.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
// due date / completion date
|
|
||||||
final TextView deadlines = ((TextView)view.findViewById(R.id.text_deadlines));
|
|
||||||
if(visibleFields.DEADLINE || isExpanded) {
|
|
||||||
String cachedResult = task.getCachedLabel(KEY_DEADLINE);
|
|
||||||
if(cachedResult == null) {
|
|
||||||
StringBuilder label = new StringBuilder();
|
|
||||||
if(task.isTaskCompleted()) {
|
|
||||||
if(task.getCompletionDate() != null) {
|
|
||||||
int secondsLeft = (int)((task.getCompletionDate().getTime() -
|
|
||||||
System.currentTimeMillis()) / 1000);
|
|
||||||
String finishedTime;
|
|
||||||
if(Math.abs(secondsLeft) < FULL_DATE_THRESHOLD)
|
|
||||||
finishedTime = r.getString(R.string.ago_string,
|
|
||||||
DateUtilities.getDurationString(r,
|
|
||||||
Math.abs(secondsLeft), 1));
|
|
||||||
else
|
|
||||||
finishedTime = DateUtilities.getFormattedDate(activity,
|
|
||||||
task.getCompletionDate());
|
|
||||||
label.append(r.getString(R.string.taskList_completedPrefix,
|
|
||||||
finishedTime));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
boolean taskOverdue = false;
|
|
||||||
if(task.getDefiniteDueDate() != null) {
|
|
||||||
long timeLeft = (task.getDefiniteDueDate().getTime() -
|
|
||||||
System.currentTimeMillis())/1000;
|
|
||||||
if(timeLeft > 0) {
|
|
||||||
if(timeLeft < FULL_DATE_THRESHOLD)
|
|
||||||
label.append(r.getString(R.string.taskList_dueRelativeTime)).append(" ");
|
|
||||||
else
|
|
||||||
label.append(r.getString(R.string.taskList_dueAbsoluteDate)).append(" ");
|
|
||||||
} else {
|
|
||||||
taskOverdue = true;
|
|
||||||
label.append(r.getString(R.string.taskList_overdueBy)).append(" ");
|
|
||||||
task.putCachedLabel(KEY_OVERDUE, CACHE_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(timeLeft < FULL_DATE_THRESHOLD)
|
|
||||||
label.append(DateUtilities.getDurationString(r,
|
|
||||||
(int)Math.abs(timeLeft), 1, true));
|
|
||||||
else
|
|
||||||
label.append(DateUtilities.getFormattedDate(activity,
|
|
||||||
task.getDefiniteDueDate()));
|
|
||||||
}
|
|
||||||
if(!taskOverdue && task.getPreferredDueDate() != null) {
|
|
||||||
if(task.getDefiniteDueDate() != null)
|
|
||||||
label.append(" / ");
|
|
||||||
long timeLeft = (task.getPreferredDueDate().getTime() -
|
|
||||||
System.currentTimeMillis())/1000;
|
|
||||||
label.append(r.getString(R.string.taskList_goalPrefix)).append(" ");
|
|
||||||
if(timeLeft > 0) {
|
|
||||||
if(timeLeft < FULL_DATE_THRESHOLD)
|
|
||||||
label.append(r.getString(R.string.taskList_dueRelativeTime)).append(" ");
|
|
||||||
else
|
|
||||||
label.append(r.getString(R.string.taskList_dueAbsoluteDate)).append(" ");
|
|
||||||
} else {
|
|
||||||
label.append(r.getString(R.string.taskList_overdueBy)).append(" ");
|
|
||||||
task.putCachedLabel(KEY_OVERDUE, CACHE_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(timeLeft < FULL_DATE_THRESHOLD)
|
|
||||||
label.append(DateUtilities.getDurationString(r,
|
|
||||||
(int)Math.abs(timeLeft), 1, true));
|
|
||||||
else
|
|
||||||
label.append(DateUtilities.getFormattedDate(activity,
|
|
||||||
task.getPreferredDueDate()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cachedResult = label.toString();
|
|
||||||
task.putCachedLabel(KEY_DEADLINE, cachedResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
if(visibleFields.TIMES || isExpanded) {
|
|
||||||
String cachedResult = task.getCachedLabel(KEY_TIMES);
|
|
||||||
if(cachedResult == null) {
|
|
||||||
Integer elapsed = task.getElapsedSeconds();
|
|
||||||
if(task.getTimerStart() != null)
|
|
||||||
elapsed += (int)((System.currentTimeMillis() - task.getTimerStart().getTime())/1000L);
|
|
||||||
Integer estimated = task.getEstimatedSeconds();
|
|
||||||
StringBuilder label = new StringBuilder();
|
|
||||||
if(estimated > 0) {
|
|
||||||
label.append(r.getString(R.string.taskList_estimatedTimePrefix)).
|
|
||||||
append(" ").
|
|
||||||
append(DateUtilities.getDurationString(r, estimated, 2));
|
|
||||||
if(elapsed > 0)
|
|
||||||
label.append(" / ");
|
|
||||||
}
|
|
||||||
if(elapsed > 0) {
|
|
||||||
label.append(r.getString(R.string.taskList_elapsedTimePrefix)).
|
|
||||||
append(" ").
|
|
||||||
append(DateUtilities.getAbbreviatedDurationString(r, elapsed, 2));
|
|
||||||
}
|
|
||||||
cachedResult = label.toString();
|
|
||||||
task.putCachedLabel(KEY_TIMES, cachedResult);
|
|
||||||
}
|
|
||||||
if(visibleFields.TIMES)
|
|
||||||
appendLine(details, cachedResult);
|
|
||||||
else
|
|
||||||
appendLine(expandedDetails, cachedResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
// reminders
|
|
||||||
if(visibleFields.REMINDERS || isExpanded) {
|
|
||||||
String cachedResult = task.getCachedLabel(KEY_REMINDERS);
|
|
||||||
if(cachedResult == null) {
|
|
||||||
Integer notifyEvery = task.getNotificationIntervalSeconds();
|
|
||||||
StringBuilder label = new StringBuilder();
|
|
||||||
if(notifyEvery != null && notifyEvery > 0) {
|
|
||||||
label.append(r.getString(R.string.taskList_periodicReminderPrefix)).
|
|
||||||
append(" ").append(DateUtilities.getDurationString(r, notifyEvery, 1, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
alarmController.open();
|
|
||||||
List<Date> alerts = alarmController.getTaskAlerts(task.getTaskIdentifier());
|
|
||||||
if(alerts.size() > 0) {
|
|
||||||
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(". ");
|
|
||||||
if(alarmFormat == null)
|
|
||||||
alarmFormat = Preferences.getDateWithTimeFormat(activity);
|
|
||||||
String alarmString = alarmFormat.format(nextAlarm);
|
|
||||||
label.append(r.getString(R.string.taskList_alarmPrefix) +
|
|
||||||
" " + alarmString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
alarmController.close();
|
|
||||||
}
|
|
||||||
cachedResult = label.toString();
|
|
||||||
task.putCachedLabel(KEY_REMINDERS, cachedResult);
|
|
||||||
}
|
|
||||||
if(visibleFields.REMINDERS)
|
|
||||||
appendLine(details, cachedResult);
|
|
||||||
else
|
|
||||||
appendLine(expandedDetails, cachedResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
// repeats
|
|
||||||
if(visibleFields.REPEATS || isExpanded) {
|
|
||||||
String cachedResult = task.getCachedLabel(KEY_REPEAT);
|
|
||||||
if(cachedResult == null) {
|
|
||||||
RepeatInfo repeatInfo = task.getRepeat();
|
|
||||||
if((task.getFlags() & TaskModelForList.FLAG_SYNC_ON_COMPLETE) > 0) {
|
|
||||||
cachedResult = r.getString(R.string.taskList_repeatsRemotely);
|
|
||||||
} else if(repeatInfo != null) {
|
|
||||||
cachedResult = r.getString(R.string.taskList_repeatPrefix) +
|
|
||||||
" " + repeatInfo.getValue() + " " +
|
|
||||||
r.getString(repeatInfo.getInterval().getLabelResource());
|
|
||||||
} else {
|
|
||||||
cachedResult = "";
|
|
||||||
}
|
|
||||||
task.putCachedLabel(KEY_REPEAT, cachedResult);
|
|
||||||
}
|
|
||||||
if(visibleFields.REPEATS)
|
|
||||||
appendLine(details, cachedResult);
|
|
||||||
else
|
|
||||||
appendLine(expandedDetails, cachedResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
// tags
|
|
||||||
if(visibleFields.TAGS || isExpanded) {
|
|
||||||
String cachedResult = task.getCachedLabel(KEY_TAGS);
|
|
||||||
if(cachedResult == null) {
|
|
||||||
String tagString = hooks.getTagsFor(task);
|
|
||||||
if(tagString != null && !tagString.equals(""))
|
|
||||||
cachedResult = r.getString(R.string.taskList_tagsPrefix) +
|
|
||||||
" " + tagString;
|
|
||||||
else
|
|
||||||
cachedResult = "";
|
|
||||||
task.putCachedLabel(KEY_TAGS, cachedResult);
|
|
||||||
}
|
|
||||||
if(visibleFields.TAGS)
|
|
||||||
appendLine(details, cachedResult);
|
|
||||||
else
|
|
||||||
appendLine(expandedDetails, cachedResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
// notes
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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) + " " +
|
|
||||||
r.getString(R.string.ago_string, DateUtilities.getDurationString(r, Math.abs(secondsAgo), 1));
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Refresh the item given at the specified position in the list (not
|
|
||||||
* related to task identifier number)
|
|
||||||
*
|
|
||||||
* @param listView the parent view to refresh
|
|
||||||
* @param position the index of the item
|
|
||||||
*/
|
|
||||||
public void refreshItem(ListView listView, int position) {
|
|
||||||
TaskModelForList task = hooks.getTaskArray().get(position);
|
|
||||||
task.clearCache();
|
|
||||||
listView.invalidateViews();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 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
|
|
||||||
progress.setOnClickListener(new View.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
View parent = (View)v.getParent().getParent();
|
|
||||||
TaskModelForList task = (TaskModelForList)parent.getTag();
|
|
||||||
|
|
||||||
int newProgressPercentage;
|
|
||||||
if(progress.isChecked())
|
|
||||||
newProgressPercentage =
|
|
||||||
TaskModelForList.getCompletedPercentage();
|
|
||||||
else
|
|
||||||
newProgressPercentage = 0;
|
|
||||||
|
|
||||||
if(newProgressPercentage != task.getProgressPercentage()) {
|
|
||||||
setTaskProgress(task, parent, newProgressPercentage);
|
|
||||||
setupView(parent, task);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// clicking the text field
|
|
||||||
view.setOnClickListener(new View.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
TaskModelForList task = (TaskModelForList)v.getTag();
|
|
||||||
toggleExpanded(v, task);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// typing while selected something
|
|
||||||
view.setOnKeyListener(new OnKeyListener() {
|
|
||||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
|
||||||
if(event.getAction() != KeyEvent.ACTION_UP)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// hot-key to set task priority - 1-4 or ALT + Q-R
|
|
||||||
Importance importance = null;
|
|
||||||
if(event.getNumber() >= '1' && event.getNumber() <= '4')
|
|
||||||
importance = Importance.values()[event.getNumber() - '1'];
|
|
||||||
|
|
||||||
if(importance != null) {
|
|
||||||
TaskModelForList task = (TaskModelForList)v.getTag();
|
|
||||||
task.setImportance(importance);
|
|
||||||
hooks.taskController().saveTask(task, false);
|
|
||||||
setFieldContentsAndVisibility(v, task);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// long-clicking the text field
|
|
||||||
view.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
|
|
||||||
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,
|
|
||||||
R.string.taskList_context_edit);
|
|
||||||
menu.add(id, 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(id, CONTEXT_TIMER_ID, Menu.NONE, timerTitle);
|
|
||||||
|
|
||||||
if(task.getDefiniteDueDate() != null ||
|
|
||||||
task.getPreferredDueDate() != null)
|
|
||||||
menu.add(id, CONTEXT_POSTPONE_ID, Menu.NONE,
|
|
||||||
R.string.taskList_context_postpone);
|
|
||||||
|
|
||||||
menu.setHeaderTitle(task.getName());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// clicking one of the expanded buttons
|
|
||||||
Button editButton = (Button)view.findViewById(R.id.edit);
|
|
||||||
editButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
View parent = (View)v.getParent().getParent().getParent().getParent();
|
|
||||||
TaskModelForList task = (TaskModelForList)parent.getTag();
|
|
||||||
hooks.editItem(task);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Button toggleTimerButton = (Button)view.findViewById(R.id.timer);
|
|
||||||
toggleTimerButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
View parent = (View)v.getParent().getParent().getParent().getParent();
|
|
||||||
TaskModelForList task = (TaskModelForList)parent.getTag();
|
|
||||||
hooks.toggleTimerOnItem(task);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Helper method to set a task's progress and then adjust its appearance
|
|
||||||
*
|
|
||||||
* @param task
|
|
||||||
* @param view
|
|
||||||
* @param progress
|
|
||||||
*/
|
|
||||||
private void setTaskProgress(final TaskModelForList task, View view, int progress) {
|
|
||||||
final ImageView timer = ((ImageView)view.findViewById(R.id.imageLeft));
|
|
||||||
task.setProgressPercentage(progress);
|
|
||||||
hooks.taskController().saveTask(task, false);
|
|
||||||
|
|
||||||
// show this task as completed even if it has repeats
|
|
||||||
if(progress == 100) {
|
|
||||||
recentlyCompleted = task;
|
|
||||||
FlurryAgent.onEvent("complete-task");
|
|
||||||
} else {
|
|
||||||
FlurryAgent.onEvent("uncomplete-task");
|
|
||||||
recentlyCompleted = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if our timer is on, ask if we want to stop
|
|
||||||
if(progress == 100 && task.getTimerStart() != null) {
|
|
||||||
new AlertDialog.Builder(activity)
|
|
||||||
.setTitle(R.string.question_title)
|
|
||||||
.setMessage(R.string.stop_timer_title)
|
|
||||||
.setIcon(android.R.drawable.ic_dialog_alert)
|
|
||||||
.setPositiveButton(android.R.string.ok,
|
|
||||||
new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
task.stopTimerAndUpdateElapsedTime();
|
|
||||||
hooks.taskController().saveTask(task, false);
|
|
||||||
timer.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Helper method to adjust a tasks' apperance if the task is completed or
|
|
||||||
* uncompleted.
|
|
||||||
*
|
|
||||||
* @param task
|
|
||||||
* @param name
|
|
||||||
* @param progress
|
|
||||||
*/
|
|
||||||
private void setTaskAppearance(TaskModelForList task, TextView name, CheckBox progress) {
|
|
||||||
Resources r = activity.getResources();
|
|
||||||
|
|
||||||
if(task.isTaskCompleted() || task == recentlyCompleted) {
|
|
||||||
name.setPaintFlags(name.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
|
|
||||||
name.setTextColor(r.getColor(R.color.task_list_done));
|
|
||||||
progress.setButtonDrawable(R.drawable.btn_check);
|
|
||||||
progress.setChecked(true);
|
|
||||||
} else {
|
|
||||||
name.setPaintFlags(name.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
|
|
||||||
name.setTextColor(r.getColor(task.getTaskColorResource(getContext())));
|
|
||||||
progress.setButtonDrawable(R.drawable.btn_check);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,108 +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 android.app.Activity;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import com.flurry.android.FlurryAgent;
|
|
||||||
import com.timsu.astrid.R;
|
|
||||||
import com.timsu.astrid.data.task.AbstractTaskModel;
|
|
||||||
import com.timsu.astrid.data.task.TaskController;
|
|
||||||
import com.timsu.astrid.data.task.TaskIdentifier;
|
|
||||||
import com.timsu.astrid.utilities.Constants;
|
|
||||||
import com.timsu.astrid.utilities.DialogUtilities;
|
|
||||||
|
|
||||||
/** Abstract activity that operates on a single task. Use the generic parameter
|
|
||||||
* to pass in the model class you are working with.
|
|
||||||
*
|
|
||||||
* @author timsu
|
|
||||||
*/
|
|
||||||
public abstract class TaskModificationActivity<MODEL_TYPE extends
|
|
||||||
AbstractTaskModel> extends Activity {
|
|
||||||
public static final String LOAD_INSTANCE_TOKEN = "id";
|
|
||||||
protected TaskController controller;
|
|
||||||
protected MODEL_TYPE model;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
try {
|
|
||||||
controller = new TaskController(this);
|
|
||||||
controller.open();
|
|
||||||
|
|
||||||
// check if we have a TaskIdentifier
|
|
||||||
TaskIdentifier identifier = null;
|
|
||||||
Bundle extras = getIntent().getExtras();
|
|
||||||
if(savedInstanceState != null && savedInstanceState.containsKey(LOAD_INSTANCE_TOKEN)) {
|
|
||||||
identifier = new TaskIdentifier(savedInstanceState.getLong(
|
|
||||||
LOAD_INSTANCE_TOKEN));
|
|
||||||
} else if(extras != null && extras.containsKey(LOAD_INSTANCE_TOKEN))
|
|
||||||
identifier = new TaskIdentifier(extras.getLong(
|
|
||||||
LOAD_INSTANCE_TOKEN));
|
|
||||||
|
|
||||||
model = getModel(identifier);
|
|
||||||
} catch (Exception e) {
|
|
||||||
showErrorAndFinish(R.string.error_opening, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
|
|
||||||
// set up flurry
|
|
||||||
FlurryAgent.onStartSession(this, Constants.FLURRY_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
FlurryAgent.onEndSession(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void showErrorAndFinish(int prefix, Throwable e) {
|
|
||||||
Resources r = getResources();
|
|
||||||
DialogUtilities.okDialog(this,
|
|
||||||
r.getString(prefix) + " " +
|
|
||||||
e.getLocalizedMessage(), new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected MODEL_TYPE getModel(TaskIdentifier identifier);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
controller.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
if(model.getTaskIdentifier() != null)
|
|
||||||
outState.putLong(LOAD_INSTANCE_TOKEN, model.getTaskIdentifier().getId());
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,130 +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 android.app.TabActivity;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import com.flurry.android.FlurryAgent;
|
|
||||||
import com.timsu.astrid.R;
|
|
||||||
import com.timsu.astrid.data.task.AbstractTaskModel;
|
|
||||||
import com.timsu.astrid.data.task.TaskController;
|
|
||||||
import com.timsu.astrid.data.task.TaskIdentifier;
|
|
||||||
import com.timsu.astrid.utilities.AstridUtilities;
|
|
||||||
import com.timsu.astrid.utilities.Constants;
|
|
||||||
import com.timsu.astrid.utilities.DialogUtilities;
|
|
||||||
|
|
||||||
/** Hack hack for tabbed activity. Should provide better interaction
|
|
||||||
*
|
|
||||||
* @author timsu
|
|
||||||
*/
|
|
||||||
public abstract class TaskModificationTabbedActivity<MODEL_TYPE extends
|
|
||||||
AbstractTaskModel> extends TabActivity {
|
|
||||||
public static final String LOAD_INSTANCE_TOKEN = TaskModificationActivity.LOAD_INSTANCE_TOKEN;
|
|
||||||
|
|
||||||
protected TaskController controller;
|
|
||||||
protected MODEL_TYPE model;
|
|
||||||
|
|
||||||
protected class Context {
|
|
||||||
protected MODEL_TYPE cModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
controller = new TaskController(this);
|
|
||||||
controller.open();
|
|
||||||
|
|
||||||
// if we've saved our model, use that instead
|
|
||||||
if(getLastNonConfigurationInstance() != null) {
|
|
||||||
Context context = (Context)getLastNonConfigurationInstance();
|
|
||||||
model = context.cModel;
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
// check if we have a TaskIdentifier
|
|
||||||
TaskIdentifier identifier = null;
|
|
||||||
Bundle extras = getIntent().getExtras();
|
|
||||||
if(savedInstanceState != null && savedInstanceState.containsKey(LOAD_INSTANCE_TOKEN)) {
|
|
||||||
identifier = new TaskIdentifier(savedInstanceState.getLong(
|
|
||||||
LOAD_INSTANCE_TOKEN));
|
|
||||||
} else if(extras != null && extras.containsKey(LOAD_INSTANCE_TOKEN))
|
|
||||||
identifier = new TaskIdentifier(extras.getLong(
|
|
||||||
LOAD_INSTANCE_TOKEN));
|
|
||||||
|
|
||||||
model = getModel(identifier);
|
|
||||||
} catch (Exception e) {
|
|
||||||
showErrorAndFinish(R.string.error_opening, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when screen is rotated. We return the model we are editing so that
|
|
||||||
* we will have access to it instead of having to re-read from the database
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Object onRetainNonConfigurationInstance() {
|
|
||||||
Context context = new Context();
|
|
||||||
context.cModel = model;
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
FlurryAgent.onStartSession(this, Constants.FLURRY_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
FlurryAgent.onEndSession(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void showErrorAndFinish(int prefix, Throwable e) {
|
|
||||||
AstridUtilities.reportFlurryError("taskedit", e);
|
|
||||||
Resources r = getResources();
|
|
||||||
DialogUtilities.okDialog(this,
|
|
||||||
r.getString(prefix) + " " +
|
|
||||||
e.getLocalizedMessage(), new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected MODEL_TYPE getModel(TaskIdentifier identifier);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
controller.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onSaveInstanceState(Bundle outState) {
|
|
||||||
super.onSaveInstanceState(outState);
|
|
||||||
if(model.getTaskIdentifier() != null)
|
|
||||||
outState.putLong(LOAD_INSTANCE_TOKEN, model.getTaskIdentifier().getId());
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue