Fix for AST-242 - task editing cancelled when rotate on edit new task, AST-211 - new tag box doesn't always appear, AST-262 - tag drop down selector

pull/14/head
Tim Su 16 years ago
parent bfbd493fe9
commit c092436f4f

@ -2,9 +2,9 @@ package com.todoroo.astrid.tags;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.data.Property.CountProperty; import com.todoroo.andlib.data.Property.CountProperty;
import com.todoroo.andlib.data.Property.StringProperty; import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Criterion;
@ -71,6 +71,11 @@ public final class TagService {
public String tag; public String tag;
int count; int count;
public Tag(String tag, int count) {
this.tag = tag;
this.count = count;
}
@Override @Override
public String toString() { public String toString() {
return tag; return tag;
@ -114,9 +119,7 @@ public final class TagService {
Tag[] array = new Tag[cursor.getCount()]; Tag[] array = new Tag[cursor.getCount()];
for (int i = 0; i < array.length; i++) { for (int i = 0; i < array.length; i++) {
cursor.moveToNext(); cursor.moveToNext();
array[i] = new Tag(); array[i] = new Tag(cursor.get(TAG), cursor.get(COUNT));
array[i].tag = cursor.get(TAG);
array[i].count = cursor.get(COUNT);
} }
return array; return array;
} finally { } finally {

@ -1,16 +1,25 @@
package com.todoroo.astrid.tags; package com.todoroo.astrid.tags;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import android.app.Activity; import android.app.Activity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView; import android.widget.AutoCompleteTextView;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import com.timsu.astrid.R; import com.timsu.astrid.R;
import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.data.AbstractModel;
@ -32,6 +41,7 @@ public final class TagsControlSet implements TaskEditControlSet {
// --- instance variables // --- instance variables
private final Spinner tagSpinner;
private final TagService tagService = TagService.getInstance(); private final TagService tagService = TagService.getInstance();
private final Tag[] allTags; private final Tag[] allTags;
private String[] loadedTags; private String[] loadedTags;
@ -42,6 +52,36 @@ public final class TagsControlSet implements TaskEditControlSet {
allTags = tagService.getGroupedTags(TagService.GROUPED_TAGS_BY_SIZE, Criterion.all); allTags = tagService.getGroupedTags(TagService.GROUPED_TAGS_BY_SIZE, Criterion.all);
this.activity = activity; this.activity = activity;
this.tagsContainer = (LinearLayout) activity.findViewById(tagsContainer); this.tagsContainer = (LinearLayout) activity.findViewById(tagsContainer);
this.tagSpinner = (Spinner) activity.findViewById(R.id.tags_dropdown);
if(allTags.length == 0) {
tagSpinner.setVisibility(View.GONE);
} else {
ArrayList<Tag> dropDownList = new ArrayList<Tag>(Arrays.asList(allTags));
dropDownList.add(0, new Tag(activity.getString(R.string.TEA_tag_dropdown), 0));
ArrayAdapter<Tag> tagAdapter = new ArrayAdapter<Tag>(activity,
android.R.layout.simple_spinner_item,
dropDownList);
tagAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
tagSpinner.setAdapter(tagAdapter);
tagSpinner.setSelection(0);
tagSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int position, long arg3) {
if(position == 0 || position > allTags.length)
return;
addTag(allTags[position - 1].tag, true);
tagSpinner.setSelection(0);
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// nothing!
}
});
}
} }
@Override @Override
@ -55,16 +95,14 @@ public final class TagsControlSet implements TaskEditControlSet {
for(int i = 0; i < loadedTags.length; i++) { for(int i = 0; i < loadedTags.length; i++) {
cursor.moveToNext(); cursor.moveToNext();
String tag = cursor.get(TagService.TAG); String tag = cursor.get(TagService.TAG);
addTag(tag); addTag(tag, true);
loadedTags[i] = tag; loadedTags[i] = tag;
} }
} finally { } finally {
cursor.close(); cursor.close();
} }
} }
addTag("", false); //$NON-NLS-1$
if(tagsContainer.getChildCount() == 0)
addTag(""); //$NON-NLS-1$
} }
@Override @Override
@ -96,10 +134,25 @@ public final class TagsControlSet implements TaskEditControlSet {
} }
/** Adds a tag to the tag field */ /** Adds a tag to the tag field */
boolean addTag(String tagName) { boolean addTag(String tagName, boolean reuse) {
LayoutInflater inflater = activity.getLayoutInflater(); LayoutInflater inflater = activity.getLayoutInflater();
final View tagItem = inflater.inflate(R.layout.tag_edit_row, null);
// check if already exists
TextView lastText = null;
for(int i = 0; i < tagsContainer.getChildCount(); i++) {
View view = tagsContainer.getChildAt(i);
lastText = (TextView) view.findViewById(R.id.text1);
if(lastText.getText().equals(tagName))
return false;
}
final View tagItem;
if(reuse && lastText != null && lastText.getText().length() == 0) {
tagItem = (View) lastText.getParent();
} else {
tagItem = inflater.inflate(R.layout.tag_edit_row, null);
tagsContainer.addView(tagItem); tagsContainer.addView(tagItem);
}
final AutoCompleteTextView textView = (AutoCompleteTextView)tagItem. final AutoCompleteTextView textView = (AutoCompleteTextView)tagItem.
findViewById(R.id.text1); findViewById(R.id.text1);
@ -109,36 +162,46 @@ public final class TagsControlSet implements TaskEditControlSet {
android.R.layout.simple_dropdown_item_1line, allTags); android.R.layout.simple_dropdown_item_1line, allTags);
textView.setAdapter(tagsAdapter); textView.setAdapter(tagsAdapter);
textView.setOnClickListener(new OnClickListener() { textView.addTextChangedListener(new TextWatcher() {
@Override @Override
public void onClick(View arg0) { public void afterTextChanged(Editable s) {
View lastItem = tagsContainer.getChildAt(tagsContainer.getChildCount()-1); //
TextView lastText = (TextView) lastItem.findViewById(R.id.text1); }
if(lastText.getText().length() != 0) { @Override
addTag(""); //$NON-NLS-1$ public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
//
} }
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if(count > 0 && tagsContainer.getChildAt(tagsContainer.getChildCount()-1) ==
tagItem)
addTag("", false); //$NON-NLS-1$
} }
}); });
/*textView.setOnEditorActionListener(new OnEditorActionListener() { textView.setOnEditorActionListener(new OnEditorActionListener() {
@Override @Override
public boolean onEditorAction(TextView arg0, int actionId, KeyEvent arg2) { public boolean onEditorAction(TextView arg0, int actionId, KeyEvent arg2) {
if(actionId != EditorInfo.IME_NULL) if(actionId != EditorInfo.IME_NULL)
return false; return false;
View lastItem = tagsContainer.getChildAt(tagsContainer.getChildCount()-1); if(getLastTextView().getText().length() != 0) {
TextView lastText = (TextView) lastItem.findViewById(R.id.text1); addTag("", false); //$NON-NLS-1$
if(lastText.getText().length() != 0) {
addTag(""); //$NON-NLS-1$
} }
return true; return true;
} }
});*/ });
ImageButton reminderRemoveButton; ImageButton reminderRemoveButton;
reminderRemoveButton = (ImageButton)tagItem.findViewById(R.id.button1); reminderRemoveButton = (ImageButton)tagItem.findViewById(R.id.button1);
reminderRemoveButton.setOnClickListener(new View.OnClickListener() { reminderRemoveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { public void onClick(View v) {
if(tagsContainer.getChildCount() > 0) TextView lastView = getLastTextView();
if(lastView == textView && textView.getText().length() == 0)
return;
if(tagsContainer.getChildCount() > 1)
tagsContainer.removeView(tagItem); tagsContainer.removeView(tagItem);
else else
textView.setText(""); //$NON-NLS-1$ textView.setText(""); //$NON-NLS-1$
@ -147,4 +210,16 @@ public final class TagsControlSet implements TaskEditControlSet {
return true; return true;
} }
/**
* Get tags container last text view. might be null
* @return
*/
private TextView getLastTextView() {
if(tagsContainer.getChildCount() == 0)
return null;
View lastItem = tagsContainer.getChildAt(tagsContainer.getChildCount()-1);
TextView lastText = (TextView) lastItem.findViewById(R.id.text1);
return lastText;
}
} }

@ -65,6 +65,10 @@
<LinearLayout <LinearLayout
android:id="@+id/tags_container" android:id="@+id/tags_container"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Spinner
android:id="@+id/tags_dropdown"
android:paddingBottom="5dip" android:paddingBottom="5dip"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />

@ -12,6 +12,9 @@
<!-- Tags hint --> <!-- Tags hint -->
<string name="TEA_tag_hint">Tag Name</string> <string name="TEA_tag_hint">Tag Name</string>
<!-- Tags dropdown -->
<string name="TEA_tag_dropdown">Select a tag</string>
<!-- ========================================================== Filters == --> <!-- ========================================================== Filters == -->
<!-- filter header for tags --> <!-- filter header for tags -->

@ -27,15 +27,15 @@ import java.util.List;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.DatePickerDialog; import android.app.DatePickerDialog;
import android.app.TabActivity;
import android.app.DatePickerDialog.OnDateSetListener; import android.app.DatePickerDialog.OnDateSetListener;
import android.app.TabActivity;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.DialogInterface.OnCancelListener;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Bundle; import android.os.Bundle;
import android.text.format.DateUtils; import android.text.format.DateUtils;
@ -45,6 +45,7 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
@ -59,7 +60,6 @@ import android.widget.TabHost;
import android.widget.TimePicker; import android.widget.TimePicker;
import android.widget.Toast; import android.widget.Toast;
import android.widget.ToggleButton; import android.widget.ToggleButton;
import android.widget.AdapterView.OnItemSelectedListener;
import com.flurry.android.FlurryAgent; import com.flurry.android.FlurryAgent;
import com.timsu.astrid.R; import com.timsu.astrid.R;
@ -155,6 +155,9 @@ public final class TaskEditActivity extends TabActivity {
// --- other instance variables // --- other instance variables
/** true if editing started with a new task */
boolean isNewTask = false;
/** task model */ /** task model */
private Task model = null; private Task model = null;
@ -251,25 +254,10 @@ public final class TaskEditActivity extends TabActivity {
}); });
} }
// read data
populateFields();
// request add-on controls
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_REQUEST_EDIT_CONTROLS);
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, model.getId());
sendOrderedBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
// set up listeners // set up listeners
setUpListeners(); setUpListeners();
} }
/**
* @return true if task is newly created
*/
private boolean isNewTask() {
return model == null ? true : model.getValue(Task.TITLE).length() == 0;
}
/** Set up button listeners */ /** Set up button listeners */
private void setUpListeners() { private void setUpListeners() {
final View.OnClickListener mSaveListener = new View.OnClickListener() { final View.OnClickListener mSaveListener = new View.OnClickListener() {
@ -324,9 +312,13 @@ public final class TaskEditActivity extends TabActivity {
values = AndroidUtilities.contentValuesFromSerializedString(valuesAsString); values = AndroidUtilities.contentValuesFromSerializedString(valuesAsString);
model = TaskListActivity.createWithValues(values, null, taskService, metadataService); model = TaskListActivity.createWithValues(values, null, taskService, metadataService);
} }
if(model.getValue(Task.TITLE).length() == 0)
if(model.getValue(Task.TITLE).length() == 0) {
FlurryAgent.onEvent("create-task"); FlurryAgent.onEvent("create-task");
isNewTask = true;
} else {
FlurryAgent.onEvent("edit-task"); FlurryAgent.onEvent("edit-task");
}
if(model == null) { if(model == null) {
exceptionService.reportError("task-edit-no-task", exceptionService.reportError("task-edit-no-task",
@ -341,7 +333,7 @@ public final class TaskEditActivity extends TabActivity {
Resources r = getResources(); Resources r = getResources();
loadItem(getIntent()); loadItem(getIntent());
if(isNewTask()) if(isNewTask)
setTitle(R.string.TEA_view_titleNew); setTitle(R.string.TEA_view_titleNew);
else else
setTitle(r.getString(R.string.TEA_view_title, model.getValue(Task.TITLE))); setTitle(r.getString(R.string.TEA_view_title, model.getValue(Task.TITLE)));
@ -352,14 +344,6 @@ public final class TaskEditActivity extends TabActivity {
/** Save task model from values in UI components */ /** Save task model from values in UI components */
private void save() { private void save() {
// abandon editing in this case
if(title.getText().length() == 0) {
if(isNewTask())
taskService.delete(model);
discardButtonClick();
return;
}
for(TaskEditControlSet controlSet : controls) for(TaskEditControlSet controlSet : controls)
controlSet.writeToModel(model); controlSet.writeToModel(model);
@ -367,6 +351,18 @@ public final class TaskEditActivity extends TabActivity {
showSaveToast(); showSaveToast();
} }
@Override
public void finish() {
super.finish();
// abandon editing in this case
if(title.getText().length() == 0 && isNewTask) {
taskService.delete(model);
showCancelToast();
setResult(RESULT_CANCELED);
}
}
/* ====================================================================== /* ======================================================================
* ================================================ edit control handling * ================================================ edit control handling
* ====================================================================== */ * ====================================================================== */
@ -416,7 +412,7 @@ public final class TaskEditActivity extends TabActivity {
*/ */
private void showSaveToast() { private void showSaveToast() {
// if we have no title, or nothing's changed, don't show toast // if we have no title, or nothing's changed, don't show toast
if(isNewTask()) if(isNewTask)
return; return;
int stringResource; int stringResource;
@ -445,7 +441,7 @@ public final class TaskEditActivity extends TabActivity {
// abandon editing in this case // abandon editing in this case
if(title.getText().length() == 0) { if(title.getText().length() == 0) {
if(isNewTask()) if(isNewTask)
taskService.delete(model); taskService.delete(model);
} }
@ -540,6 +536,7 @@ public final class TaskEditActivity extends TabActivity {
super.onResume(); super.onResume();
registerReceiver(controlReceiver, registerReceiver(controlReceiver,
new IntentFilter(AstridApiConstants.BROADCAST_SEND_EDIT_CONTROLS)); new IntentFilter(AstridApiConstants.BROADCAST_SEND_EDIT_CONTROLS));
populateFields();
} }
@Override @Override
@ -552,14 +549,6 @@ public final class TaskEditActivity extends TabActivity {
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
FlurryAgent.onEndSession(this); FlurryAgent.onEndSession(this);
// don't save if user accidentally created a new task
if(title.getText().length() == 0) {
if(model.isSaved())
taskService.delete(model);
showCancelToast();
return;
}
} }
/* ====================================================================== /* ======================================================================

@ -223,7 +223,7 @@ public class TaskDao extends GenericDao<Task> {
* @param skipHooks whether this save occurs as part of a sync * @param skipHooks whether this save occurs as part of a sync
*/ */
private void afterSave(Task task, ContentValues values) { private void afterSave(Task task, ContentValues values) {
if(values.containsKey(Task.COMPLETION_DATE.name) && task.isCompleted()) if(values != null && values.containsKey(Task.COMPLETION_DATE.name) && task.isCompleted())
afterComplete(task, values); afterComplete(task, values);
else else
ReminderService.getInstance().scheduleAlarm(task); ReminderService.getInstance().scheduleAlarm(task);

@ -98,7 +98,9 @@ public class TasksWidget extends AppWidgetProvider {
TasksWidget.class); TasksWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this); AppWidgetManager manager = AppWidgetManager.getInstance(this);
int extrasId = intent.getIntExtra(EXTRA_WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); int extrasId = AppWidgetManager.INVALID_APPWIDGET_ID;
if(intent != null)
extrasId = intent.getIntExtra(EXTRA_WIDGET_ID, extrasId);
if(extrasId == AppWidgetManager.INVALID_APPWIDGET_ID) { if(extrasId == AppWidgetManager.INVALID_APPWIDGET_ID) {
for(int id : manager.getAppWidgetIds(thisWidget)) { for(int id : manager.getAppWidgetIds(thisWidget)) {
RemoteViews updateViews = buildUpdate(this, id); RemoteViews updateViews = buildUpdate(this, id);

Loading…
Cancel
Save