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