AST-182 - if google calendar event deleted, allow users to re-create it from Astrid.

also incidental re-write of alarm and tag logic to leverage metadataService.synchronize call, as well as allowing writeToModel to return a string. currently unused, but will use it in the next step.
pull/14/head
Tim Su 14 years ago
parent fac536ad5c
commit 8ba1d75ec6

@ -13,6 +13,7 @@ import android.widget.LinearLayout;
import com.timsu.astrid.R;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.widget.DateControlSet;
import com.todoroo.astrid.activity.TaskEditActivity.TaskEditControlSet;
import com.todoroo.astrid.data.Metadata;
@ -50,14 +51,14 @@ public final class AlarmControlSet implements TaskEditControlSet {
TodorooCursor<Metadata> cursor = AlarmService.getInstance().getAlarms(task.getId());
try {
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext())
addAlarm(new Date(cursor.get(Alarm.TIME)));
addAlarm(new Date(cursor.get(AlarmFields.TIME)));
} finally {
cursor.close();
}
}
@Override
public void writeToModel(Task task) {
public String writeToModel(Task task) {
LinkedHashSet<Long> alarms = new LinkedHashSet<Long>();
for(int i = 0; i < alertsContainer.getChildCount(); i++) {
DateControlSet set = (DateControlSet) alertsContainer.getChildAt(i).getTag();
@ -67,7 +68,11 @@ public final class AlarmControlSet implements TaskEditControlSet {
if(date != null)
alarms.add(set.getDate().getTime());
}
AlarmService.getInstance().synchronizeAlarms(task.getId(), alarms);
if(AlarmService.getInstance().synchronizeAlarms(task.getId(), alarms))
task.setValue(Task.MODIFICATION_DATE, DateUtilities.now());
return null;
}
private boolean addAlarm(Date alert) {

@ -51,7 +51,7 @@ public class AlarmDetailExposer extends BroadcastReceiver {
long nextTime = -1;
try {
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
long time = cursor.get(Alarm.TIME);
long time = cursor.get(AlarmFields.TIME);
if(time > DateUtilities.now()) {
nextTime = time;
break;

@ -10,7 +10,7 @@ import com.todoroo.astrid.data.Metadata;
* @author Tim Su <tim@todoroo.com>
*
*/
public class Alarm {
public class AlarmFields {
/** metadata key */
public static final String METADATA_KEY = "alarm"; //$NON-NLS-1$

@ -1,5 +1,6 @@
package com.todoroo.astrid.alarms;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
@ -55,50 +56,28 @@ public class AlarmService {
public TodorooCursor<Metadata> getAlarms(long taskId) {
return PluginServices.getMetadataService().query(Query.select(
Metadata.PROPERTIES).where(MetadataCriteria.byTaskAndwithKey(
taskId, Alarm.METADATA_KEY)).orderBy(Order.asc(Alarm.TIME)));
taskId, AlarmFields.METADATA_KEY)).orderBy(Order.asc(AlarmFields.TIME)));
}
/**
* Save the given array of tags into the database
* Save the given array of alarms into the database
* @param taskId
* @param tags
* @return true if data was changed
*/
public void synchronizeAlarms(long taskId, LinkedHashSet<Long> alarms) {
public boolean synchronizeAlarms(long taskId, LinkedHashSet<Long> alarms) {
MetadataService service = PluginServices.getMetadataService();
if(alarmsIdentical(taskId, alarms))
return;
service.deleteWhere(Criterion.and(MetadataCriteria.byTask(taskId),
MetadataCriteria.withKey(Alarm.METADATA_KEY)));
Metadata metadata = new Metadata();
metadata.setValue(Metadata.KEY, Alarm.METADATA_KEY);
metadata.setValue(Metadata.TASK, taskId);
ArrayList<Metadata> metadata = new ArrayList<Metadata>();
for(Long alarm : alarms) {
metadata.clearValue(Metadata.ID);
metadata.setValue(Alarm.TIME, alarm);
metadata.setValue(Alarm.TYPE, Alarm.TYPE_SINGLE);
service.save(metadata);
scheduleAlarm(metadata);
}
}
private boolean alarmsIdentical(long taskId, LinkedHashSet<Long> alarms) {
TodorooCursor<Metadata> cursor = getAlarms(taskId);
try {
if(cursor.getCount() != alarms.size())
return false;
for(Long alarm : alarms) {
cursor.moveToNext();
if(alarm != cursor.get(Alarm.TIME))
return false;
}
} finally {
cursor.close();
Metadata item = new Metadata();
item.setValue(Metadata.KEY, AlarmFields.METADATA_KEY);
item.setValue(AlarmFields.TIME, alarm);
item.setValue(AlarmFields.TYPE, AlarmFields.TYPE_SINGLE);
metadata.add(item);
}
return true;
return service.synchronizeMetadata(taskId, metadata, Metadata.KEY.eq(AlarmFields.METADATA_KEY)) > 0;
}
// --- alarm scheduling
@ -109,9 +88,9 @@ public class AlarmService {
* @return todoroo cursor. PLEASE CLOSE THIS CURSOR!
*/
private TodorooCursor<Metadata> getActiveAlarms() {
return PluginServices.getMetadataService().query(Query.select(Alarm.TIME).
return PluginServices.getMetadataService().query(Query.select(AlarmFields.TIME).
join(Join.inner(Task.TABLE, Metadata.TASK.eq(Task.ID))).
where(Criterion.and(TaskCriteria.isActive(), MetadataCriteria.withKey(Alarm.METADATA_KEY))));
where(Criterion.and(TaskCriteria.isActive(), MetadataCriteria.withKey(AlarmFields.METADATA_KEY))));
}
/**
@ -120,10 +99,10 @@ public class AlarmService {
* @return todoroo cursor. PLEASE CLOSE THIS CURSOR!
*/
private TodorooCursor<Metadata> getAlarmsForTask(long taskId) {
return PluginServices.getMetadataService().query(Query.select(Alarm.TIME).
return PluginServices.getMetadataService().query(Query.select(AlarmFields.TIME).
join(Join.inner(Task.TABLE, Metadata.TASK.eq(Task.ID))).
where(Criterion.and(TaskCriteria.isActive(),
MetadataCriteria.byTaskAndwithKey(taskId, Alarm.METADATA_KEY))));
MetadataCriteria.byTaskAndwithKey(taskId, AlarmFields.METADATA_KEY))));
}
/**
@ -190,7 +169,7 @@ public class AlarmService {
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
intent, 0);
long time = alarm.getValue(Alarm.TIME);
long time = alarm.getValue(AlarmFields.TIME);
if(time == 0 || time == NO_ALARM)
am.cancel(pendingIntent);
else if(time > DateUtilities.now()) {

@ -35,7 +35,7 @@ public class AlarmTaskRepeatListener extends BroadcastReceiver {
LinkedHashSet<Long> alarms = new LinkedHashSet<Long>(cursor.getCount());
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
metadata.readFromCursor(cursor);
alarms.add(metadata.getValue(Alarm.TIME) + (newDueDate - oldDueDate));
alarms.add(metadata.getValue(AlarmFields.TIME) + (newDueDate - oldDueDate));
}
AlarmService.getInstance().synchronizeAlarms(taskId, alarms);

@ -10,15 +10,15 @@ import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.CompoundButton.OnCheckedChangeListener;
import com.flurry.android.FlurryAgent;
import com.timsu.astrid.R;
@ -122,6 +122,17 @@ public class GCalControlSet implements TaskEditControlSet {
if(!TextUtils.isEmpty(uri)) {
try {
calendarUri = Uri.parse(uri);
// try to load calendar
ContentResolver cr = activity.getContentResolver();
Cursor cursor = cr.query(calendarUri, new String[] { "dtstart" }, null, null, null); //$NON-NLS-1$
boolean deleted = cursor.getCount() == 0;
cursor.close();
if(deleted) {
calendarUri = null;
return;
}
addToCalendar.setVisibility(View.GONE);
calendarSelector.setVisibility(View.GONE);
viewCalendarEvent.setVisibility(View.VISIBLE);
@ -134,7 +145,7 @@ public class GCalControlSet implements TaskEditControlSet {
@SuppressWarnings("nls")
@Override
public void writeToModel(Task task) {
public String writeToModel(Task task) {
if(addToCalendar.isChecked() && calendarUri == null) {
FlurryAgent.onEvent("create-calendar-event");
@ -167,6 +178,7 @@ public class GCalControlSet implements TaskEditControlSet {
activity.getString(R.string.gcal_TEA_error), e);
}
}
return null;
}
@SuppressWarnings("nls")

@ -243,7 +243,7 @@ public class ProducteevControlSet implements TaskEditControlSet {
}
@Override
public void writeToModel(Task task) {
public String writeToModel(Task task) {
Metadata metadata = ProducteevDataService.getInstance().getTaskMetadata(task.getId());
try {
if (metadata == null) {
@ -270,5 +270,6 @@ public class ProducteevControlSet implements TaskEditControlSet {
} catch (Exception e) {
Log.e("error-saving-pdv", "Error Saving Metadata", e); //$NON-NLS-1$ //$NON-NLS-2$
}
return null;
}
}

@ -234,7 +234,7 @@ public class RepeatControlSet implements TaskEditControlSet {
@Override
public void writeToModel(Task task) {
public String writeToModel(Task task) {
String result;
if(!enabled.isChecked())
result = ""; //$NON-NLS-1$
@ -276,5 +276,6 @@ public class RepeatControlSet implements TaskEditControlSet {
if(task.getFlag(Task.FLAGS, Task.FLAG_REPEAT_AFTER_COMPLETION))
type.setSelection(1);
return null;
}
}

@ -1,5 +1,6 @@
package com.todoroo.astrid.tags;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import com.todoroo.andlib.data.Property.CountProperty;
@ -12,11 +13,13 @@ import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.Order;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.astrid.core.PluginServices;
import com.todoroo.astrid.dao.MetadataDao;
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.MetadataService;
/**
* Provides operations for working with tags
@ -179,17 +182,17 @@ public final class TagService {
* @param taskId
* @param tags
*/
public void synchronizeTags(long taskId, LinkedHashSet<String> tags) {
metadataDao.deleteWhere(Criterion.and(MetadataCriteria.byTask(taskId),
MetadataCriteria.withKey(KEY)));
public boolean synchronizeTags(long taskId, LinkedHashSet<String> tags) {
MetadataService service = PluginServices.getMetadataService();
Metadata metadata = new Metadata();
metadata.setValue(Metadata.KEY, KEY);
metadata.setValue(Metadata.TASK, taskId);
ArrayList<Metadata> metadata = new ArrayList<Metadata>();
for(String tag : tags) {
metadata.clearValue(Metadata.ID);
metadata.setValue(TAG, tag.trim());
metadataDao.createNew(metadata);
Metadata item = new Metadata();
item.setValue(Metadata.KEY, KEY);
item.setValue(TAG, tag);
metadata.add(item);
}
return service.synchronizeMetadata(taskId, metadata, Metadata.KEY.eq(KEY)) > 0;
}
}

@ -44,7 +44,6 @@ public final class TagsControlSet implements TaskEditControlSet {
private final Spinner tagSpinner;
private final TagService tagService = TagService.getInstance();
private final Tag[] allTags;
private String[] loadedTags;
private final LinearLayout tagsContainer;
private final Activity activity;
@ -91,12 +90,9 @@ public final class TagsControlSet implements TaskEditControlSet {
if(task.getId() != AbstractModel.NO_ID) {
TodorooCursor<Metadata> cursor = tagService.getTags(task.getId());
try {
loadedTags = new String[cursor.getCount()];
for(int i = 0; i < loadedTags.length; i++) {
cursor.moveToNext();
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
String tag = cursor.get(TagService.TAG);
addTag(tag, true);
loadedTags[i] = tag;
}
} finally {
cursor.close();
@ -106,31 +102,24 @@ public final class TagsControlSet implements TaskEditControlSet {
}
@Override
public void writeToModel(Task task) {
public String writeToModel(Task task) {
// this is a case where we're asked to save but the UI was not yet populated
if(tagsContainer.getChildCount() == 0)
return;
return null;
LinkedHashSet<String> tags = new LinkedHashSet<String>();
boolean identical = true;
for(int i = 0; i < tagsContainer.getChildCount(); i++) {
TextView tagName = (TextView)tagsContainer.getChildAt(i).findViewById(R.id.text1);
if(tagName.getText().length() == 0)
continue;
String tag = tagName.getText().toString();
tags.add(tag);
if(loadedTags.length <= i || !loadedTags[i].equals(tag))
identical = false;
tags.add(tagName.getText().toString());
}
if(loadedTags == null || tags.size() != loadedTags.length)
identical = false;
if(!identical) {
tagService.synchronizeTags(task.getId(), tags);
if(TagService.getInstance().synchronizeTags(task.getId(), tags))
task.setValue(Task.MODIFICATION_DATE, DateUtilities.now());
}
return null;
}
/** Adds a tag to the tag field */

@ -44,9 +44,10 @@ public class TimerControlSet implements TaskEditControlSet {
}
@Override
public void writeToModel(Task task) {
public String writeToModel(Task task) {
estimated.writeToModel(task);
elapsed.writeToModel(task);
return null;
}
// --- TimeDurationTaskEditControlSet
@ -73,8 +74,9 @@ public class TimerControlSet implements TaskEditControlSet {
}
@Override
public void writeToModel(Task task) {
public String writeToModel(Task task) {
task.setValue(property, controlSet.getTimeDurationInSeconds());
return null;
}
}

@ -600,8 +600,9 @@ public final class TaskEditActivity extends TabActivity {
/**
* Write data from control set to model
* @return text appended to the toast
*/
public void writeToModel(Task task);
public String writeToModel(Task task);
}
// --- EditTextControlSet
@ -626,8 +627,9 @@ public final class TaskEditActivity extends TabActivity {
}
@Override
public void writeToModel(Task task) {
public String writeToModel(Task task) {
task.setValue(property, editText.getText().toString());
return null;
}
}
@ -710,9 +712,10 @@ public final class TaskEditActivity extends TabActivity {
}
@Override
public void writeToModel(Task task) {
public String writeToModel(Task task) {
if(getImportance() != null)
task.setValue(Task.IMPORTANCE, getImportance());
return null;
}
}
@ -921,10 +924,11 @@ public final class TaskEditActivity extends TabActivity {
}
@Override
public void writeToModel(Task task) {
public String writeToModel(Task task) {
UrgencyValue item = urgencyAdapter.getItem(spinner.getSelectedItemPosition());
if(item.dueDate != SPECIFIC_DATE) // user canceled specific date
task.setValue(Task.DUE_DATE, item.dueDate);
return null;
}
}
@ -1082,10 +1086,11 @@ public final class TaskEditActivity extends TabActivity {
}
@Override
public void writeToModel(Task task) {
public String writeToModel(Task task) {
HideUntilValue item = adapter.getItem(spinner.getSelectedItemPosition());
long value = task.createHideUntil(item.setting, item.date);
task.setValue(Task.HIDE_UNTIL, value);
return null;
}
}
@ -1140,8 +1145,9 @@ public final class TaskEditActivity extends TabActivity {
}
@Override
public void writeToModel(Task task) {
public String writeToModel(Task task) {
task.setValue(Task.REMINDER_FLAGS, getValue());
return null;
}
}
@ -1211,12 +1217,13 @@ public final class TaskEditActivity extends TabActivity {
}
@Override
public void writeToModel(Task task) {
public String writeToModel(Task task) {
if(settingCheckbox.isChecked()) {
int hourValue = hours[periodSpinner.getSelectedItemPosition()];
task.setValue(Task.REMINDER_PERIOD, hourValue * DateUtilities.ONE_HOUR);
} else
task.setValue(Task.REMINDER_PERIOD, 0L);
return null;
}
}

@ -29,7 +29,7 @@ import com.todoroo.andlib.service.DependencyInjectionService;
import com.todoroo.andlib.service.ExceptionService;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.alarms.Alarm;
import com.todoroo.astrid.alarms.AlarmFields;
import com.todoroo.astrid.backup.TasksXmlImporter;
import com.todoroo.astrid.dao.Database;
import com.todoroo.astrid.dao.MetadataDao;
@ -491,14 +491,14 @@ public class Astrid2To3UpgradeHelper {
return;
Metadata metadata = new Metadata();
metadata.setValue(Metadata.KEY, Alarm.METADATA_KEY);
metadata.setValue(Metadata.KEY, AlarmFields.METADATA_KEY);
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
long task = cursor.get(TransitionalAlarm.TASK);
long time = cursor.get(TransitionalAlarm.TIME);
metadata.setValue(Metadata.TASK, task);
metadata.setValue(Alarm.TIME, time);
metadata.setValue(Alarm.TYPE, Alarm.TYPE_SINGLE);
metadata.setValue(AlarmFields.TIME, time);
metadata.setValue(AlarmFields.TYPE, AlarmFields.TYPE_SINGLE);
metadataDao.createNew(metadata);
metadata.clearValue(Metadata.ID);
}

@ -79,8 +79,9 @@ public class MetadataService {
* @param id
* @param metadata
* @param metadataKeys
* @return number of items saved
*/
public void synchronizeMetadata(long taskId, ArrayList<Metadata> metadata,
public int synchronizeMetadata(long taskId, ArrayList<Metadata> metadata,
Criterion metadataCriterion) {
HashSet<ContentValues> newMetadataValues = new HashSet<ContentValues>();
for(Metadata metadatum : metadata) {
@ -114,10 +115,14 @@ public class MetadataService {
}
// everything that remains shall be written
int written = 0;
for(ContentValues values : newMetadataValues) {
item.clear();
item.mergeWith(values);
metadataDao.persist(item);
++written;
}
return written;
}
}

Loading…
Cancel
Save