package com.google.code.andorganizer;
import java.util.Calendar;
import java.util.Date;
import android.app.Activity;
import android.app.SearchManager;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.style.UnderlineSpan;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.SimpleCursorAdapter.ViewBinder;
import android.widget.TextView;
/**
* TaskList
*
* Represents application home screen.
* Shows the current day tasks and navigation for previous or next ones
*/
public class TaskList extends Activity {
private static final int EDIT_EXISTING_TASK = 0;
private static final int EDIT_NEW_TAKS = EDIT_EXISTING_TASK +1;
private TextView dateText;
private Calendar currentDate = null;
private static final Calendar now = Calendar.getInstance();
private static final int now_year, now_day, now_month;
static {
now_year = now.get(Calendar.YEAR);
now_day = now.get(Calendar.DAY_OF_MONTH);
now_month = now.get(Calendar.MONTH);
}
/** Fields in the database with corresponding indexes to the fields in the layout. */
private static final String []from = new String[] {
TaskHelper.KEY_DESCRIPTION,
TaskHelper.KEY_COMPLETED,
TaskHelper.KEY_FROM_DATE,
TaskHelper.KEY_DURATION,
};
/** Fields in the layout with corresponding indexes to the fields in the database. */
private static final int []to = new int[] {
R.id.description,
R.id.completed_cb,
R.id.from_date,
R.id.duration_in_lv,
};
private static final String DATE_PH = "date_extra";
private Cursor c;
private ListView listView;
private Button nextDayButton;
private Button prevDayButton;
private String query;
private Button startTaskButton;
/** <b>onCreate</b><br />
*
* Called when the activity is first created.
*
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//gets the view in with current tasks will be shown
listView = (ListView)findViewById(R.id.tasks_list_view);
registerForContextMenu(listView);//long press present context menu
//edit the clicked event.
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
editTask(id);
}
});
startTaskButton = (Button)findViewById(R.id.start_task_button);
startTaskButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startNewTask();
}
});
dateText = (TextView)findViewById(R.id.date_text);
nextDayButton = (Button)findViewById(R.id.next_day_tasks);
nextDayButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
currentDate.set(Calendar.DAY_OF_MONTH, currentDate.get(Calendar.DAY_OF_MONTH)+1);
currentSearchChanged();
}
});
prevDayButton = (Button)findViewById(R.id.prev_day_tasks);
prevDayButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
currentDate.set(Calendar.DAY_OF_MONTH, currentDate.get(Calendar.DAY_OF_MONTH)-1);
currentSearchChanged();
}
});
}
/**
* <b>onStart</b><br />
*
* On start activity (event)
*
*/
@Override
public void onStart() {
super.onStart();
loadCurrentDate();
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
prevDayButton.setVisibility(View.INVISIBLE);
nextDayButton.setVisibility(View.INVISIBLE);
startTaskButton.setVisibility(View.INVISIBLE);
query = intent.getStringExtra(SearchManager.QUERY);
}
currentSearchChanged();
}
/** <b>onStop</b><br />
*
* On stopping activity event
*
*/
@Override
public void onStop() {
super.onStop();
c.deactivate();
}
/** <b>currentDateChanged</b><br />
*
* Refresh the listView and dateText members for the currentDate member
*
*/
private void currentSearchChanged() {
int y = currentDate.get(Calendar.YEAR);
int d = currentDate.get(Calendar.DAY_OF_MONTH);
int m = currentDate.get(Calendar.MONTH);
String text;
if (query == null) {
if (now_year == y && now_day == d && now_month == m) {
text = getString(R.string.today);
}
else if (now_year == y && (now_day-1) == d && now_month == m) {
text = getString(R.string.yesterday);
}
else if (now_year == y && (now_day+1) == d && now_month == m) {
text = getString(R.string.tomorrow);
}
else {
text = TaskHelper.DATE_FORMATTER.format(currentDate.getTime());
}
}
else {
text=getString(R.string.searching_for) + query;
}
//underline
SpannableString content = new SpannableString(text);
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
dateText.setText(content);
//refresh cursor
if (c!=null) {
// deactivate the old one
c.deactivate();
}
ContentResolver cr = getContentResolver();
c = cr.query(TasksProvider.CONTENT_URI, null, createSelectionQeury(y, m, d), null, TaskHelper.KEY_FROM_DATE + " DESC");
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.task_item, c, from, to);
adapter.setViewBinder(new ViewBinder() {
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
switch (columnIndex) {
case TasksProvider.COMPLETED_COLUMN:
IdentityCheckBox cb = (IdentityCheckBox)view;
cb.setOnCheckedChangeListener(null);
cb.setIdentity(cursor.getInt(TasksProvider.ID_COLUMN));
cb.setChecked(cursor.getInt(columnIndex)!=0);
cb.setOnCheckedChangeListener(checkListener);
return true;
case TasksProvider.FROM_DATE_COLUMN:
TextView dateView = (TextView)view;
dateView.setText(TaskHelper.DATE_FORMATTER.format(new Date(cursor.getLong(TasksProvider.FROM_DATE_COLUMN))));
return true;
case TasksProvider.DURATION_COLUMN:
TextView durationView = (TextView)view;
int duration = cursor.getInt(TasksProvider.DURATION_COLUMN) / (60 * 1000);
durationView.setText(TaskHelper.getFormatedDurationString(getApplicationContext(), duration / 60, duration % 60));
return true;
default: return false;
}
}
});
//construction complete. Set the adapter.
listView.setAdapter(adapter);
}
/**
* used for specifying if a task has been completed
*/
private final OnCheckedChangeListener checkListener = new OnCheckedChangeListener() {
/**
* <b>onCheckedChanged</b><br />
*
* On changing state of CheckBox checked value, updates current task state in database
*
* @param buttonView
* @param isChecked
*/
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
IdentityCheckBox cb = (IdentityCheckBox)buttonView;
getContentResolver().update(ContentUris.withAppendedId(TasksProvider.CONTENT_URI, cb.getIdentity()), isChecked ? TaskHelper.VALUES_COMPLETED_DONE : TaskHelper.VALUES_COMPLETED_NOTDONE, null, null);
TaskScheduler.doAll(getApplicationContext());
}
};
/**
* <b>createSelectionQeury</b><br />
*
* Creates query selection string for a given date
*
* @param y Date year
* @param m Date month
* @param d Date day
* @return generated query selector string
*/
private String createSelectionQeury(int y, int m, int d) {
if (query == null) {
Calendar c = Calendar.getInstance();
c.set(y, m, d, 0, 0, 0);
long start = c.getTimeInMillis();
c.set(y, m, d, 23, 59, 59);
long end = c.getTimeInMillis();
return TaskHelper.KEY_FROM_DATE + " >= " + start + " AND " + TaskHelper.KEY_FROM_DATE + " <= " + end;
}
else {
return TaskHelper.KEY_DESCRIPTION +" like '%" + query + "%'";
}
}
/**
* <b>loadCurrentDate</b><br />
*
* Initialize currentDate with Calendar instance.
*
*/
private void loadCurrentDate() {
currentDate = (Calendar) getIntent().getSerializableExtra(DATE_PH);
if (currentDate == null) {
currentDate = Calendar.getInstance();
}
}
/** <b>onActivityResult</b><br />
*
* Checks what activity is returning result and acts appropriatly.
*
* @param requestCode Resulting activity request code.
* @param resultCode Return code from the activity.
* @param data Additional data returned from the activity.
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case EDIT_EXISTING_TASK:
getContentResolver().update(data.getData(), (ContentValues)data.getExtras().get(TaskHelper.VALUES_EXTRA), null, null);
checkForRescheduling();
c.requery();
break;
case EDIT_NEW_TAKS:
ContentValues values = (ContentValues) data.getExtras().get(TaskHelper.VALUES_EXTRA);
Uri newData = getContentResolver().insert(TasksProvider.CONTENT_URI, values);
if (newData != null) {
values.put(TaskHelper.KEY_ID, newData.getPathSegments().get(1));
checkForRescheduling();
c.requery();
}
}
}
}
/** <b>checkForRescheduling</b><br />
*
* Checks weather scheduling is needed for current activity with the given values
*
* @param values
*/
private void checkForRescheduling() {
TaskScheduler.doAll(this);
}
/**
* <b>onCreateContextMenu</b><br />
*
* Creates context menu
*
* @param menu The context menu that is being build
* @param v View for which the context menu is being build
* @param menuInfo Additional info about the created menu. May varay depending on class of <b>v</b>
*/
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.item_menu, menu);
}
/**
* <b>onContextItemSelected</b><br />
*
* Finds what menu item is selected and activates proper action.
*
* @param item Contains the selected menu item
* @return true when selected valid item, false otherwise
*/
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.menu_new_task:
startNewTaskFromTask(info.id);
return true;
case R.id.menu_delete:
deleteTask(info.id);
return true;
case R.id.menu_edit:
editTask(info.id);
return true;
default:
return super.onContextItemSelected(item);
}
}
/** <b>editTask</b><br />
*
* Edits a task from a given id.
*
* @param id Id of task to edit
*/
private void editTask(long id) {
Uri uri = ContentUris.withAppendedId(TasksProvider.CONTENT_URI, id);
Cursor c = getContentResolver().query(uri, null, null, null, null);
Intent intent = new Intent(Intent.ACTION_EDIT, uri);
if (c.moveToFirst()) {
intent.putExtra(TaskHelper.VALUES_EXTRA, TaskHelper.createValuesFromCursor(c));
startActivityForResult(intent, EDIT_EXISTING_TASK);
}
c.deactivate();
}
/** <b>deleteTask</b><br />
*
* Deletes a task with given id.
*
* @param id Identifier of task to be deleted
*/
private void deleteTask(long id) {
Uri uri = ContentUris.withAppendedId(TasksProvider.CONTENT_URI, id);
getContentResolver().delete(uri, null, null);
TaskScheduler.doAll(getApplicationContext());
}
/** <b>startNewTaskFromTask</b><br />
*
* Creates a task from an existing task.
*
* @param id id of a task to create from
*/
private void startNewTaskFromTask(long id) {
//TODO implement some kind of copy
startNewTask();
}
/** <b>startNewTask</b><br />
*
* Creates and intent that should launch EditTaskActivity
*
*/
private void startNewTask() {
Uri uri = ContentUris.withAppendedId(TasksProvider.CONTENT_URI, 1);
Intent intent = new Intent(Intent.ACTION_EDIT, uri);
intent.putExtra(TaskHelper.VALUES_EXTRA, TaskHelper.createDefaultValuesAndDate(currentDate.getTimeInMillis()));
startActivityForResult(intent, EDIT_NEW_TAKS);
}
}
|