From 1e48dc55c035a92a2afd4711745dac0186ee5b2e Mon Sep 17 00:00:00 2001 From: Arne Jans Date: Sun, 12 Dec 2010 21:33:18 +0100 Subject: [PATCH] PDV-recurrent tasks display and handling first version. No conflict-handling yet between Astrid-repeats and PDV-repeats other than disabling PDV-repeats for tasks that have Astrid-repeats enabled. But still, duplicates might be produced by this. Another glitch is, if a task is completed on webinterface and in Astrid in parallel, and synced, then PDV-recurrent tasks' duedate on webinterface gets added one day (could be due to faulty timezone-handling in producteev.api.ApiUtilities (SimpleDateFormat-instances are hardcoded on Locale.US and thus dont write +0100-timezone for me in Europe/Berlin but +0000) --- .../producteev/ProducteevControlSet.java | 7 ++- .../producteev/ProducteevDetailExposer.java | 62 +++++++++++++++++++ .../producteev/api/ProducteevInvoker.java | 34 ++++++++++ .../sync/ProducteevSyncProvider.java | 42 ++++++++++++- .../producteev/sync/ProducteevTask.java | 7 ++- .../sync/ProducteevTaskContainer.java | 24 ++++++- 6 files changed, 171 insertions(+), 5 deletions(-) diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevControlSet.java b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevControlSet.java index add37dbec..e84fd9059 100644 --- a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevControlSet.java +++ b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevControlSet.java @@ -13,11 +13,11 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.Spinner; import android.widget.TextView; -import android.widget.AdapterView.OnItemSelectedListener; import com.timsu.astrid.R; import com.todoroo.andlib.service.Autowired; @@ -265,6 +265,11 @@ public class ProducteevControlSet implements TaskEditControlSet { else metadata.setValue(ProducteevTask.RESPONSIBLE_ID, responsibleUser.getId()); + // Erase PDTV-repeating-info if task itself is repeating with Astrid-repeat + if (task.containsNonNullValue(Task.RECURRENCE) && task.getValue(Task.RECURRENCE).length()>0) { + metadata.setValue(ProducteevTask.REPEATING_SETTING, ""); + } + if(metadata.getSetValues().size() > 0) { metadataService.save(metadata); task.setValue(Task.MODIFICATION_DATE, DateUtilities.now()); diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevDetailExposer.java b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevDetailExposer.java index 8371aa78e..7b1792cb4 100644 --- a/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevDetailExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/producteev/ProducteevDetailExposer.java @@ -3,6 +3,9 @@ */ package com.todoroo.astrid.producteev; +import java.text.DateFormatSymbols; +import java.util.Calendar; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -75,6 +78,9 @@ public class ProducteevDetailExposer extends BroadcastReceiver { long creatorId = -1; if(metadata.containsNonNullValue(ProducteevTask.CREATOR_ID)) creatorId = metadata.getValue(ProducteevTask.CREATOR_ID); + String repeatSetting = null; + if(metadata.containsNonNullValue(ProducteevTask.REPEATING_SETTING)) + repeatSetting = metadata.getValue(ProducteevTask.REPEATING_SETTING); // display dashboard if not "no sync" or "default" StoreObject ownerDashboard = null; @@ -112,6 +118,62 @@ public class ProducteevDetailExposer extends BroadcastReceiver { append(TaskAdapter.DETAIL_SEPARATOR); } + // display repeating task information + if (repeatSetting != null && repeatSetting.length() > 0) { + String interval = null; + String[] pdvRepeating = repeatSetting.split(","); + int pdvRepeatingValue = 0; + String pdvRepeatingDay = null; + try { + pdvRepeatingValue = Integer.parseInt(pdvRepeating[0]); + } catch (Exception e) { + pdvRepeatingDay = pdvRepeating[0]; + pdvRepeatingValue = 1; + } + String pdvRepeatingInterval = pdvRepeating[1]; + + if (pdvRepeatingInterval.startsWith("day")) { + interval = context.getResources().getQuantityString(R.plurals.DUt_days, pdvRepeatingValue, + pdvRepeatingValue); + } else if (pdvRepeatingInterval.startsWith("weekday")) { + interval = context.getResources().getQuantityString(R.plurals.DUt_weekdays, pdvRepeatingValue, + pdvRepeatingValue); + } else if (pdvRepeatingInterval.startsWith("week")) { + interval = context.getResources().getQuantityString(R.plurals.DUt_weeks, pdvRepeatingValue, + pdvRepeatingValue); + } else if (pdvRepeatingInterval.startsWith("month")) { + interval = context.getResources().getQuantityString(R.plurals.DUt_months, pdvRepeatingValue, + pdvRepeatingValue); + } else if (pdvRepeatingInterval.startsWith("year")) { + interval = context.getResources().getQuantityString(R.plurals.DUt_years, pdvRepeatingValue, + pdvRepeatingValue); + } + interval = "" + interval + ""; //$NON-NLS-1$//$NON-NLS-2$ + if (pdvRepeatingDay != null) { + DateFormatSymbols dfs = new DateFormatSymbols(); + String[] weekdays = dfs.getShortWeekdays(); + if (pdvRepeatingDay.equals("monday")) { + pdvRepeatingDay = weekdays[Calendar.MONDAY]; + } else if (pdvRepeatingDay.equals("tuesday")) { + pdvRepeatingDay = weekdays[Calendar.TUESDAY]; + } else if (pdvRepeatingDay.equals("wednesday")) { + pdvRepeatingDay = weekdays[Calendar.WEDNESDAY]; + } else if (pdvRepeatingDay.equals("thursday")) { + pdvRepeatingDay = weekdays[Calendar.THURSDAY]; + } else if (pdvRepeatingDay.equals("friday")) { + pdvRepeatingDay = weekdays[Calendar.FRIDAY]; + } else if (pdvRepeatingDay.equals("saturday")) { + pdvRepeatingDay = weekdays[Calendar.SATURDAY]; + } else if (pdvRepeatingDay.equals("sunday")) { + pdvRepeatingDay = weekdays[Calendar.SUNDAY]; + } + interval = context.getResources().getString(R.string.repeat_detail_byday).replace("$I", //$NON-NLS-1$ + interval).replace("$D", pdvRepeatingDay); //$NON-NLS-1$ + } + String detail = context.getString(R.string.repeat_detail_duedate, interval); + builder.append(" ").append(detail). //$NON-NLS-1$ + append(TaskAdapter.DETAIL_SEPARATOR); + } } if(Preferences.getBoolean(R.string.p_showNotes, false) == !extended) { diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevInvoker.java b/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevInvoker.java index 85fbc3b89..2b0830770 100644 --- a/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevInvoker.java +++ b/astrid/plugin-src/com/todoroo/astrid/producteev/api/ProducteevInvoker.java @@ -273,6 +273,40 @@ public class ProducteevInvoker { "id_task", idTask); } + /** + * set repeating + * + * @param idTask + * @param repeatInterval + * @param repeatValue + * + * @return array tasks/view + * @throws IOException + * @throws ApiServiceException + */ + public JSONObject tasksSetRepeating(long idTask, String repeatInterval, Integer repeatValue) throws ApiServiceException, IOException { + return callAuthenticated("tasks/set_repeating.json", + "token", token, + "id_task", idTask, + "repeat_interval", repeatInterval, + "repeat_value", (repeatValue == null ? 1 : repeatValue)); + } + + /** + * unset repeating + * + * @param idTask + * + * @return array tasks/view + * @throws IOException + * @throws ApiServiceException + */ + public JSONObject tasksUnsetRepeating(long idTask) throws ApiServiceException, IOException { + return callAuthenticated("tasks/unset_repeating.json", + "token", token, + "id_task", idTask); + } + /** * set a workspace * diff --git a/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java b/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java index 3bbd26678..8cbb0a954 100644 --- a/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java +++ b/astrid/plugin-src/com/todoroo/astrid/producteev/sync/ProducteevSyncProvider.java @@ -364,6 +364,7 @@ public class ProducteevSyncProvider extends SyncProvider0) || + (remote != null && remote.pdvTask.containsNonNullValue(ProducteevTask.REPEATING_SETTING) && + remote.pdvTask.getValue(ProducteevTask.REPEATING_SETTING).length()>0)); + + boolean isAstridRepeating = local.task.containsNonNullValue(Task.RECURRENCE) && + local.task.getValue(Task.RECURRENCE).length() > 0; + + if (isAstridRepeating && isPDVRepeating) { + // Astrid-repeat overrides PDV-repeat + invoker.tasksUnsetRepeating(idTask); + } + + if(shouldTransmit(local, Task.COMPLETION_DATE, remote)) { invoker.tasksSetStatus(idTask, local.task.isCompleted() ? 2 : 1); + if (local.task.isCompleted() && !isAstridRepeating && + isPDVRepeating) { + local.task.setValue(Task.COMPLETION_DATE, 0L); + remerge = true; + } + } try { @@ -562,6 +585,19 @@ public class ProducteevSyncProvider extends SyncProvider metadata, Metadata pdvTask) { this.task = task; @@ -31,11 +32,21 @@ public class ProducteevTaskContainer extends SyncContainer { @SuppressWarnings("nls") public ProducteevTaskContainer(Task task, ArrayList metadata, JSONObject remoteTask) { this(task, metadata, new Metadata()); +// res = ContextManager.getContext().getResources(); pdvTask.setValue(Metadata.KEY, ProducteevTask.METADATA_KEY); pdvTask.setValue(ProducteevTask.ID, remoteTask.optLong("id_task")); pdvTask.setValue(ProducteevTask.DASHBOARD_ID, remoteTask.optLong("id_dashboard")); pdvTask.setValue(ProducteevTask.RESPONSIBLE_ID, remoteTask.optLong("id_responsible")); pdvTask.setValue(ProducteevTask.CREATOR_ID, remoteTask.optLong("id_creator")); + String repeatingValue = remoteTask.optString("repeating_value"); + String repeatingInterval = remoteTask.optString("repeating_interval"); + if (!"0".equals(repeatingValue) && repeatingValue.length() > 0 && + repeatingInterval != null && repeatingInterval.length() > 0) { + pdvTask.setValue(ProducteevTask.REPEATING_SETTING, repeatingValue+","+repeatingInterval); +// "PDV "+("1".equals(repeatingValue) ? +// res.getString(R.string.repeat_every).replaceAll(" %d", "") : +// res.getString(R.string.repeat_every, Integer.parseInt(repeatingValue)))+" "+getLocalizedRepeatInterval(repeatingInterval)); + } } public ProducteevTaskContainer(Task task, ArrayList metadata) { @@ -55,5 +66,16 @@ public class ProducteevTaskContainer extends SyncContainer { } } - +// private String getLocalizedRepeatInterval(String pdvRepeatInterval) { +// String localizedRepeatInterval = ""; +// if (pdvRepeatInterval.startsWith("day")) +// localizedRepeatInterval = res.getStringArray(R.array.repeat_interval)[0]; +// else if (pdvRepeatInterval.equals("week") || pdvRepeatInterval.equals("weeks")) +// localizedRepeatInterval = res.getStringArray(R.array.repeat_interval)[1]; +// else if (pdvRepeatInterval.startsWith("month")) +// localizedRepeatInterval = res.getStringArray(R.array.repeat_interval)[2]; +// else +// localizedRepeatInterval = pdvRepeatInterval; // TODO: localize year and weekday in strings-producteev.xml +// return localizedRepeatInterval; +// } } \ No newline at end of file