From 8e02edab687d27e690a4aae77c6c6dd36cee4514 Mon Sep 17 00:00:00 2001 From: Tim Su Date: Fri, 9 Jul 2010 04:49:43 -0700 Subject: [PATCH] Repeats. woot --- astrid/AndroidManifest.xml | 23 +- .../astrid/api/{Plugin.java => Addon.java} | 26 +- .../astrid/api/AstridApiConstants.java | 51 ++-- .../com/todoroo/astrid/api/EditOperation.java | 2 +- .../com/todoroo/astrid/api/Filter.java | 4 +- .../todoroo/astrid/api/FilterCategory.java | 4 +- .../todoroo/astrid/api/FilterListHeader.java | 4 +- .../com/todoroo/astrid/api/TaskDetail.java | 2 +- astrid/astrid.launch | 8 +- astrid/default.properties | 2 +- .../astrid/core/CoreFilterExposer.java | 2 +- .../com/todoroo/astrid/core/CorePlugin.java | 8 +- .../astrid/core/ExtendedFilterExposer.java | 2 +- .../todoroo/astrid/core/ExtendedPlugin.java | 8 +- .../astrid/notes/NoteDetailExposer.java | 4 +- .../com/todoroo/astrid/notes/NotesPlugin.java | 8 +- .../astrid/repeats/RepeatControlSet.java | 214 ++++++++++++++++ .../todoroo/astrid/repeats/RepeatsPlugin.java | 26 ++ .../todoroo/astrid/tags/TagDetailExposer.java | 4 +- .../todoroo/astrid/tags/TagFilterExposer.java | 2 +- .../com/todoroo/astrid/tags/TagsPlugin.java | 8 +- astrid/res/layout/repeat_control.xml | 53 ++++ astrid/res/layout/task_edit_activity.xml | 43 +--- astrid/res/values/strings-3.0.xml | 8 +- astrid/res/values/strings-repeat.xml | 36 +++ .../astrid/activity/FilterListActivity.java | 4 +- .../astrid/activity/TaskEditActivity.java | 229 ++++++++---------- .../astrid/activity/TaskListActivity.java | 18 +- .../com/todoroo/astrid/api/SearchFilter.java | 4 +- .../src/com/todoroo/astrid/dao/Database.java | 13 +- .../src/com/todoroo/astrid/dao/TaskDao.java | 64 +++++ astrid/src/com/todoroo/astrid/model/Task.java | 14 +- .../service/Astrid2To3UpgradeHelper.java | 4 +- .../service/AstridDependencyInjector.java | 9 + .../astrid/service/UpgradeService.java | 4 + 35 files changed, 652 insertions(+), 263 deletions(-) rename astrid/api-src/com/todoroo/astrid/api/{Plugin.java => Addon.java} (67%) create mode 100644 astrid/plugin-src/com/todoroo/astrid/repeats/RepeatControlSet.java create mode 100644 astrid/plugin-src/com/todoroo/astrid/repeats/RepeatsPlugin.java create mode 100644 astrid/res/layout/repeat_control.xml create mode 100644 astrid/res/values/strings-repeat.xml diff --git a/astrid/AndroidManifest.xml b/astrid/AndroidManifest.xml index eec3ca76e..8ab344d7a 100644 --- a/astrid/AndroidManifest.xml +++ b/astrid/AndroidManifest.xml @@ -1,7 +1,7 @@ + android:versionName="3.0.0-beta" android:versionCode="137"> @@ -45,13 +45,14 @@ - + + android:debuggable="true"> + @@ -147,7 +148,7 @@ - + @@ -168,7 +169,7 @@ - + @@ -182,7 +183,7 @@ - + @@ -198,6 +199,14 @@ + + + + + + + + diff --git a/astrid/api-src/com/todoroo/astrid/api/Plugin.java b/astrid/api-src/com/todoroo/astrid/api/Addon.java similarity index 67% rename from astrid/api-src/com/todoroo/astrid/api/Plugin.java rename to astrid/api-src/com/todoroo/astrid/api/Addon.java index 81f280ff7..98c98e7e5 100644 --- a/astrid/api-src/com/todoroo/astrid/api/Plugin.java +++ b/astrid/api-src/com/todoroo/astrid/api/Addon.java @@ -7,18 +7,18 @@ import android.os.Parcel; import android.os.Parcelable; /** - * Represents a plug-in for Astrid. Users can enable or disable plug-ins, + * Represents an add-onn for Astrid. Users can enable or disable add-ons, * which affect all other extension points that share the same identifier. * * @author Tim Su * */ -public class Plugin implements Parcelable { +public class Addon implements Parcelable { /** - * Plug-in Identifier + * Add-on Identifier */ - public String plugin = null; + public String addon = null; /** * Plug-in Title @@ -38,13 +38,13 @@ public class Plugin implements Parcelable { /** * Convenience constructor to generate a plug-in object * - * @param plugin + * @param addon * @param title * @param author * @param description */ - public Plugin(String plugin, String title, String author, String description) { - this.plugin = plugin; + public Addon(String addon, String title, String author, String description) { + this.addon = addon; this.title = title; this.author = author; this.description = description; @@ -64,7 +64,7 @@ public class Plugin implements Parcelable { * {@inheritDoc} */ public void writeToParcel(Parcel dest, int flags) { - dest.writeString(plugin); + dest.writeString(addon); dest.writeString(title); dest.writeString(author); dest.writeString(description); @@ -73,20 +73,20 @@ public class Plugin implements Parcelable { /** * Parcelable creator */ - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { /** * {@inheritDoc} */ - public Plugin createFromParcel(Parcel source) { - return new Plugin(source.readString(), source.readString(), + public Addon createFromParcel(Parcel source) { + return new Addon(source.readString(), source.readString(), source.readString(), source.readString()); } /** * {@inheritDoc} */ - public Plugin[] newArray(int size) { - return new Plugin[size]; + public Addon[] newArray(int size) { + return new Addon[size]; }; }; diff --git a/astrid/api-src/com/todoroo/astrid/api/AstridApiConstants.java b/astrid/api-src/com/todoroo/astrid/api/AstridApiConstants.java index 8749368df..afc1a0f4f 100644 --- a/astrid/api-src/com/todoroo/astrid/api/AstridApiConstants.java +++ b/astrid/api-src/com/todoroo/astrid/api/AstridApiConstants.java @@ -3,6 +3,8 @@ */ package com.todoroo.astrid.api; +import android.widget.RemoteViews; + /** * Constants for interfacing with Astrid. * @@ -28,32 +30,35 @@ public class AstridApiConstants { */ public static final String PERMISSION_WRITE = PACKAGE + ".WRITE"; + // --- Broadcast Extras + /** - * Extras name for Task id + * Extras name for task id */ public static final String EXTRAS_TASK_ID = "task"; /** - * Extras name for an array of response items + * Extras name for a response item broadcast to astrid */ - public static final String EXTRAS_ITEMS = "items"; + public static final String EXTRAS_RESPONSE = "response"; /** - * Extras name for plug-in object + * Extras name for plug-in identifier */ - public static final String EXTRAS_PLUGIN = "plugin"; + public static final String EXTRAS_ADDON = "addon"; - // --- Plug-ins API + // --- Add-ons API /** - * Action name for broadcast intent requesting filters + * Action name for broadcast intent requesting add-ons */ - public static final String BROADCAST_REQUEST_PLUGINS = PACKAGE + ".REQUEST_PLUGINS"; + public static final String BROADCAST_REQUEST_ADDONS = PACKAGE + ".REQUEST_ADDONS"; /** - * Action name for broadcast intent sending filters back to Astrid + * Action name for broadcast intent sending add-ons back to Astrid + * @extra EXTRAS_RESPONSE an {@link Addon} object */ - public static final String BROADCAST_SEND_PLUGINS = PACKAGE + ".SEND_PLUGINS"; + public static final String BROADCAST_SEND_ADDONS = PACKAGE + ".SEND_ADDONS"; // --- Filters API @@ -64,30 +69,39 @@ public class AstridApiConstants { /** * Action name for broadcast intent sending filters back to Astrid + * @extra EXTRAS_ADDON your add-on identifier + * @extra EXTRAS_RESPONSE an array of {@link FilterListItem}s */ public static final String BROADCAST_SEND_FILTERS = PACKAGE + ".SEND_FILTERS"; - // --- Edit Operations API + // --- Edit Controls API /** - * Action name for broadcast intent requesting task edit operations + * Action name for broadcast intent requesting task edit controls + * @extra EXTRAS_TASK_ID id of the task user is editing */ - public static final String BROADCAST_REQUEST_EDIT_OPERATIONS = PACKAGE + ".REQUEST_EDIT_OPERATIONS"; + public static final String BROADCAST_REQUEST_EDIT_CONTROLS = PACKAGE + ".REQUEST_EDIT_CONTROLS"; /** - * Action name for broadcast intent sending task edit operations back to Astrid + * Action name for broadcast intent sending task edit controls back to Astrid + * @extra EXTRAS_ADDON your add-on identifier + * @extra EXTRAS_RESPONSE a {@link RemoteViews} with your edit controls */ - public static final String BROADCAST_SEND_EDIT_OPERATIONS = PACKAGE + ".SEND_EDIT_OPERATIONS"; + public static final String BROADCAST_SEND_EDIT_CONTROLS = PACKAGE + ".SEND_EDIT_CONTROLS"; // --- Task List Details API /** * Action name for broadcast intent requesting task list details for a task + * @extra EXTRAS_TASK_ID id of the task */ public static final String BROADCAST_REQUEST_DETAILS = PACKAGE + ".REQUEST_DETAILS"; /** * Action name for broadcast intent sending details back to Astrid + * @extra EXTRAS_ADDON your add-on identifier + * @extra EXTRAS_TASK_ID id of the task + * @extra EXTRAS_RESPONSE a {@link TaskDetail} object */ public static final String BROADCAST_SEND_DETAILS = PACKAGE + ".SEND_DETAILS"; @@ -95,14 +109,19 @@ public class AstridApiConstants { /** * Action name for intents to be displayed on task context menu + * @extra EXTRAS_TASK_ID id of the task */ public static final String ACTION_TASK_CONTEXT_MENU = PACKAGE + ".CONTEXT_MENU"; /** * Action name for intents to be displayed on Astrid's task list menu + * @extra EXTRAS_ADDON your add-on identifier + * @extra EXTRAS_RESPONSE an array of {@link Intent}s */ public static final String ACTION_TASK_LIST_MENU = PACKAGE + ".TASK_LIST_MENU"; + // --- Settings API + /** * Action name for intents to be displayed in Astrid's settings */ @@ -112,11 +131,13 @@ public class AstridApiConstants { /** * Action name for broadcast intent notifying that task was completed + * @extra EXTRAS_TASK_ID id of the task */ public static final String BROADCAST_EVENT_TASK_COMPLETED = PACKAGE + ".TASK_COMPLETED"; /** * Action name for broadcast intent notifying that task was created + * @extra EXTRAS_TASK_ID id of the task */ public static final String BROADCAST_EVENT_TASK_CREATED = PACKAGE + ".TASK_CREATED"; diff --git a/astrid/api-src/com/todoroo/astrid/api/EditOperation.java b/astrid/api-src/com/todoroo/astrid/api/EditOperation.java index 84af715dd..94fb63c3d 100644 --- a/astrid/api-src/com/todoroo/astrid/api/EditOperation.java +++ b/astrid/api-src/com/todoroo/astrid/api/EditOperation.java @@ -34,7 +34,7 @@ public final class EditOperation implements Parcelable { * Create an EditOperation object * * @param plugin - * {@link Plugin} identifier that encompasses object + * {@link Addon} identifier that encompasses object * @param text * label to display * @param intent diff --git a/astrid/api-src/com/todoroo/astrid/api/Filter.java b/astrid/api-src/com/todoroo/astrid/api/Filter.java index 0ae269f25..7cb103cbf 100644 --- a/astrid/api-src/com/todoroo/astrid/api/Filter.java +++ b/astrid/api-src/com/todoroo/astrid/api/Filter.java @@ -64,7 +64,7 @@ public final class Filter extends FilterListItem { * Utility constructor for creating a TaskList object * * @param plugin - * {@link Plugin} identifier that encompasses object + * {@link Addon} identifier that encompasses object * @param listingTitle * Title of this item as displayed on the lists page, e.g. Inbox * @param title @@ -88,7 +88,7 @@ public final class Filter extends FilterListItem { * Utility constructor * * @param plugin - * {@link Plugin} identifier that encompasses object + * {@link Addon} identifier that encompasses object */ protected Filter(String plugin) { this.plugin = plugin; diff --git a/astrid/api-src/com/todoroo/astrid/api/FilterCategory.java b/astrid/api-src/com/todoroo/astrid/api/FilterCategory.java index ffaa9cb35..3f5b6d111 100644 --- a/astrid/api-src/com/todoroo/astrid/api/FilterCategory.java +++ b/astrid/api-src/com/todoroo/astrid/api/FilterCategory.java @@ -29,7 +29,7 @@ public class FilterCategory extends FilterListItem { * Constructor for creating a new FilterCategory * * @param plugin - * {@link Plugin} identifier that encompasses object + * {@link Addon} identifier that encompasses object * @param listingTitle * Title of this item as displayed on the lists page, e.g. Inbox * @param children @@ -46,7 +46,7 @@ public class FilterCategory extends FilterListItem { * Constructor for creating a new FilterCategory * * @param plugin - * {@link Plugin} identifier that encompasses object + * {@link Addon} identifier that encompasses object */ protected FilterCategory(String plugin) { this.plugin = plugin; diff --git a/astrid/api-src/com/todoroo/astrid/api/FilterListHeader.java b/astrid/api-src/com/todoroo/astrid/api/FilterListHeader.java index e1d38b87b..03e979233 100644 --- a/astrid/api-src/com/todoroo/astrid/api/FilterListHeader.java +++ b/astrid/api-src/com/todoroo/astrid/api/FilterListHeader.java @@ -23,7 +23,7 @@ public class FilterListHeader extends FilterListItem { * Constructor for creating a new FilterListHeader * * @param plugin - * {@link Plugin} identifier that encompasses object + * {@link Addon} identifier that encompasses object * @param listingTitle * @param listingIconResource * @param priority @@ -37,7 +37,7 @@ public class FilterListHeader extends FilterListItem { * Constructor for creating a new FilterListHeader * * @param plugin - * {@link Plugin} identifier that encompasses object + * {@link Addon} identifier that encompasses object */ protected FilterListHeader(String plugin) { this.plugin = plugin; diff --git a/astrid/api-src/com/todoroo/astrid/api/TaskDetail.java b/astrid/api-src/com/todoroo/astrid/api/TaskDetail.java index be118ea8c..15bbfaf90 100644 --- a/astrid/api-src/com/todoroo/astrid/api/TaskDetail.java +++ b/astrid/api-src/com/todoroo/astrid/api/TaskDetail.java @@ -33,7 +33,7 @@ public final class TaskDetail implements Parcelable { * Creates a TaskDetail object * * @param plugin - * {@link Plugin} identifier that encompasses object + * {@link Addon} identifier that encompasses object * @param text * text to display * @param color diff --git a/astrid/astrid.launch b/astrid/astrid.launch index f9929e151..25130c50f 100644 --- a/astrid/astrid.launch +++ b/astrid/astrid.launch @@ -4,20 +4,22 @@ - + - + - + + + diff --git a/astrid/default.properties b/astrid/default.properties index a72fa071c..08ad68f11 100644 --- a/astrid/default.properties +++ b/astrid/default.properties @@ -10,5 +10,5 @@ # Indicates whether an apk should be generated for each density. split.density=false # Project target. -target=Google Inc.:Google APIs:8 +target=android-4 apk-configurations= diff --git a/astrid/plugin-src/com/todoroo/astrid/core/CoreFilterExposer.java b/astrid/plugin-src/com/todoroo/astrid/core/CoreFilterExposer.java index f03813585..2c26828b0 100644 --- a/astrid/plugin-src/com/todoroo/astrid/core/CoreFilterExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/core/CoreFilterExposer.java @@ -54,7 +54,7 @@ public final class CoreFilterExposer extends BroadcastReceiver { list[1] = all; list[2] = searchFilter; Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_FILTERS); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ITEMS, list); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, list); context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } diff --git a/astrid/plugin-src/com/todoroo/astrid/core/CorePlugin.java b/astrid/plugin-src/com/todoroo/astrid/core/CorePlugin.java index 3d3d8f757..599224342 100644 --- a/astrid/plugin-src/com/todoroo/astrid/core/CorePlugin.java +++ b/astrid/plugin-src/com/todoroo/astrid/core/CorePlugin.java @@ -5,7 +5,7 @@ import android.content.Context; import android.content.Intent; import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.Plugin; +import com.todoroo.astrid.api.Addon; public class CorePlugin extends BroadcastReceiver { @@ -13,11 +13,11 @@ public class CorePlugin extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - Plugin plugin = new Plugin(IDENTIFIER, "Core Filters", "Todoroo", + Addon plugin = new Addon(IDENTIFIER, "Core Filters", "Todoroo", "Provides 'Inbox' and 'All Tasks' Filters"); - Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_PLUGINS); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_PLUGIN, plugin); + Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_ADDONS); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, plugin); context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } diff --git a/astrid/plugin-src/com/todoroo/astrid/core/ExtendedFilterExposer.java b/astrid/plugin-src/com/todoroo/astrid/core/ExtendedFilterExposer.java index d5df1696c..5b7600f24 100644 --- a/astrid/plugin-src/com/todoroo/astrid/core/ExtendedFilterExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/core/ExtendedFilterExposer.java @@ -82,7 +82,7 @@ public final class ExtendedFilterExposer extends BroadcastReceiver { list[3] = hidden; list[4] = deleted; Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_FILTERS); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ITEMS, list); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, list); context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } diff --git a/astrid/plugin-src/com/todoroo/astrid/core/ExtendedPlugin.java b/astrid/plugin-src/com/todoroo/astrid/core/ExtendedPlugin.java index bdf2a030b..fba45cc9f 100644 --- a/astrid/plugin-src/com/todoroo/astrid/core/ExtendedPlugin.java +++ b/astrid/plugin-src/com/todoroo/astrid/core/ExtendedPlugin.java @@ -5,7 +5,7 @@ import android.content.Context; import android.content.Intent; import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.Plugin; +import com.todoroo.astrid.api.Addon; public class ExtendedPlugin extends BroadcastReceiver { @@ -13,11 +13,11 @@ public class ExtendedPlugin extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - Plugin plugin = new Plugin(IDENTIFIER, "Extended Filters", "Todoroo", + Addon plugin = new Addon(IDENTIFIER, "Extended Filters", "Todoroo", "Provides extended filters for viewing subsets of your tasks"); - Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_PLUGINS); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_PLUGIN, plugin); + Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_ADDONS); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, plugin); context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } diff --git a/astrid/plugin-src/com/todoroo/astrid/notes/NoteDetailExposer.java b/astrid/plugin-src/com/todoroo/astrid/notes/NoteDetailExposer.java index 5a8a3ceea..320279e87 100644 --- a/astrid/plugin-src/com/todoroo/astrid/notes/NoteDetailExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/notes/NoteDetailExposer.java @@ -51,10 +51,8 @@ public class NoteDetailExposer extends BroadcastReceiver { TaskDetail taskDetail = new TaskDetail(NotesPlugin.IDENTIFIER, notes); // transmit - TaskDetail[] details = new TaskDetail[1]; - details[0] = taskDetail; Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_DETAILS); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ITEMS, details); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, taskDetail); broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } diff --git a/astrid/plugin-src/com/todoroo/astrid/notes/NotesPlugin.java b/astrid/plugin-src/com/todoroo/astrid/notes/NotesPlugin.java index de8b5e77b..01a245897 100644 --- a/astrid/plugin-src/com/todoroo/astrid/notes/NotesPlugin.java +++ b/astrid/plugin-src/com/todoroo/astrid/notes/NotesPlugin.java @@ -5,7 +5,7 @@ import android.content.Context; import android.content.Intent; import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.Plugin; +import com.todoroo.astrid.api.Addon; public class NotesPlugin extends BroadcastReceiver { @@ -13,11 +13,11 @@ public class NotesPlugin extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - Plugin plugin = new Plugin(IDENTIFIER, "Notes", "Todoroo", + Addon plugin = new Addon(IDENTIFIER, "Notes", "Todoroo", "Lets you add and view notes for a task."); - Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_PLUGINS); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_PLUGIN, plugin); + Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_ADDONS); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, plugin); context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } diff --git a/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatControlSet.java b/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatControlSet.java new file mode 100644 index 000000000..98caab507 --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatControlSet.java @@ -0,0 +1,214 @@ +package com.todoroo.astrid.repeats; + +import java.text.DateFormatSymbols; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Calendar; + +import android.app.Activity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewGroup.LayoutParams; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.LinearLayout; +import android.widget.Spinner; + +import com.google.ical.values.Frequency; +import com.google.ical.values.RRule; +import com.google.ical.values.Weekday; +import com.google.ical.values.WeekdayNum; +import com.timsu.astrid.R; +import com.timsu.astrid.widget.NumberPicker; +import com.timsu.astrid.widget.NumberPickerDialog; +import com.timsu.astrid.widget.NumberPickerDialog.OnNumberPickedListener; +import com.todoroo.astrid.activity.TaskEditActivity.TaskEditControlSet; +import com.todoroo.astrid.model.Task; + +/** + * Control Set for managing repeats + * + * @author Tim Su + * + */ +public class RepeatControlSet implements TaskEditControlSet { + + private static final int INTERVAL_DAYS = 0; + private static final int INTERVAL_WEEKS = 1; + private static final int INTERVAL_MONTHS = 2; + private static final int INTERVAL_YEARS = 3; + + private final Activity activity; + private final CheckBox enabled; + private final Button value; + private final Spinner interval; + private final Spinner type; + private final LinearLayout repeatContainer; + private final LinearLayout daysOfWeekContainer; + private final CompoundButton[] daysOfWeek = new CompoundButton[7]; + + public RepeatControlSet(final Activity activity, ViewGroup parent) { + this.activity = activity; + LayoutInflater.from(activity).inflate(R.layout.repeat_control, parent, true); + + enabled = (CheckBox) activity.findViewById(R.id.repeatEnabled); + value = (Button) activity.findViewById(R.id.repeatValue); + interval = (Spinner) activity.findViewById(R.id.repeatInterval); + type = (Spinner) activity.findViewById(R.id.repeatType); + repeatContainer = (LinearLayout) activity.findViewById(R.id.repeatContainer); + daysOfWeekContainer = (LinearLayout) activity.findViewById(R.id.repeatDayOfWeekContainer); + setRepeatValue(1); + + // set up days of week + DateFormatSymbols dfs = new DateFormatSymbols(); + Calendar calendar = Calendar.getInstance(); + int currentDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); + calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek()); + LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 1.0f/7); + for(int i = 0; i < 7; i++) { + CheckBox checkBox = new CheckBox(activity); + int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); + checkBox.setText(dfs.getShortWeekdays()[dayOfWeek].substring(0, 1)); + checkBox.setLayoutParams(lp); + checkBox.setTextSize(10); + checkBox.setTag(Weekday.values()[dayOfWeek - 1]); + if(dayOfWeek == currentDayOfWeek) + checkBox.setChecked(true); + daysOfWeek[i] = checkBox; + calendar.add(Calendar.DATE, 1); + daysOfWeekContainer.addView(checkBox); + } + + // set up listeners + enabled.setOnCheckedChangeListener(new OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + repeatContainer.setVisibility(isChecked ? View.VISIBLE : View.GONE); + } + }); + value.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + repeatValueClick(); + } + }); + interval.setOnItemSelectedListener(new OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parentView, View view, int position, long id) { + daysOfWeekContainer.setVisibility(position == INTERVAL_WEEKS ? View.VISIBLE : View.GONE); + } + + @Override + public void onNothingSelected(AdapterView arg0) { + // + } + }); + } + + /** Set up the repeat value button */ + private void setRepeatValue(int newValue) { + value.setText(activity.getString(R.string.repeat_every, newValue)); + value.setTag(newValue); + } + + protected void repeatValueClick() { + final int tagValue = (Integer)value.getTag(); + + final Runnable openDialogRunnable = new Runnable() { + public void run() { + int dialogValue = tagValue; + if(dialogValue == 0) + dialogValue = 1; + + new NumberPickerDialog(activity, new OnNumberPickedListener() { + @Override + public void onNumberPicked(NumberPicker view, + int number) { + setRepeatValue(number); + } + }, activity.getResources().getString(R.string.repeat_picker_title), + dialogValue, 1, 1, 365).show(); + } + }; + + openDialogRunnable.run(); + } + + + @Override + public void readFromTask(Task task) { + String recurrence = task.getValue(Task.RECURRENCE); + + if(recurrence.length() > 0) { + try { + RRule rrule = new RRule(recurrence); + + setRepeatValue(rrule.getInterval()); + switch(rrule.getFreq()) { + case DAILY: + interval.setSelection(INTERVAL_DAYS); + break; + case WEEKLY: { + interval.setSelection(INTERVAL_WEEKS); + + for(WeekdayNum day : rrule.getByDay()) { + for(int i = 0; i < 7; i++) + if(daysOfWeek[i].getTag() == day.wday) + daysOfWeek[i].setChecked(true); + } + + break; + } + case MONTHLY: + interval.setSelection(INTERVAL_MONTHS); + break; + case YEARLY: + interval.setSelection(INTERVAL_YEARS); + break; + } + } catch (ParseException e) { + recurrence = ""; //$NON-NLS-1$ + } + } + + enabled.setChecked(recurrence.length() > 0); + repeatContainer.setVisibility(enabled.isChecked() ? View.VISIBLE : View.GONE); + } + + + @Override + public void writeToModel(Task task) { + String result; + if(!enabled.isChecked()) + result = ""; //$NON-NLS-1$ + else { + RRule rrule = new RRule(); + rrule.setInterval((Integer)value.getTag()); + switch(interval.getSelectedItemPosition()) { + case INTERVAL_DAYS: + rrule.setFreq(Frequency.DAILY); + break; + case INTERVAL_WEEKS: { + rrule.setFreq(Frequency.WEEKLY); + ArrayList days = new ArrayList(); + for(int i = 0; i < daysOfWeek.length; i++) + if(daysOfWeek[i].isChecked()) + days.add(new WeekdayNum(0, (Weekday)daysOfWeek[i].getTag())); + rrule.setByDay(days); + break; + } + case INTERVAL_MONTHS: + rrule.setFreq(Frequency.MONTHLY); + break; + case INTERVAL_YEARS: + rrule.setFreq(Frequency.YEARLY); + } + result = rrule.toIcal(); + } + task.setValue(Task.RECURRENCE, result); + } +} \ No newline at end of file diff --git a/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatsPlugin.java b/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatsPlugin.java new file mode 100644 index 000000000..1ceac7e56 --- /dev/null +++ b/astrid/plugin-src/com/todoroo/astrid/repeats/RepeatsPlugin.java @@ -0,0 +1,26 @@ +package com.todoroo.astrid.repeats; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import com.timsu.astrid.R; +import com.todoroo.astrid.api.AstridApiConstants; +import com.todoroo.astrid.api.Addon; + +public class RepeatsPlugin extends BroadcastReceiver { + + static final String IDENTIFIER = "repeats"; //$NON-NLS-1$ + + @Override + public void onReceive(Context context, Intent intent) { + Addon plugin = new Addon(IDENTIFIER, context.getString(R.string.repeat_plugin), + context.getString(R.string.AOA_internal_author), + context.getString(R.string.repeat_plugin_desc)); + + Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_ADDONS); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, plugin); + context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); + } + +} diff --git a/astrid/plugin-src/com/todoroo/astrid/tags/TagDetailExposer.java b/astrid/plugin-src/com/todoroo/astrid/tags/TagDetailExposer.java index dcd08bcbd..147d91c70 100644 --- a/astrid/plugin-src/com/todoroo/astrid/tags/TagDetailExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/tags/TagDetailExposer.java @@ -39,10 +39,8 @@ public class TagDetailExposer extends BroadcastReceiver { context.getString(R.string.tag_TLA_detail, tagList)); // transmit - TaskDetail[] details = new TaskDetail[1]; - details[0] = taskDetail; Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_DETAILS); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ITEMS, details); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, taskDetail); broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } diff --git a/astrid/plugin-src/com/todoroo/astrid/tags/TagFilterExposer.java b/astrid/plugin-src/com/todoroo/astrid/tags/TagFilterExposer.java index ca0a96c24..1f48c3234 100644 --- a/astrid/plugin-src/com/todoroo/astrid/tags/TagFilterExposer.java +++ b/astrid/plugin-src/com/todoroo/astrid/tags/TagFilterExposer.java @@ -97,7 +97,7 @@ public class TagFilterExposer extends BroadcastReceiver { list[2] = tagsCategoryBySize; list[3] = tagsCategoryByAlpha; Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_FILTERS); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ITEMS, list); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_RESPONSE, list); context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } diff --git a/astrid/plugin-src/com/todoroo/astrid/tags/TagsPlugin.java b/astrid/plugin-src/com/todoroo/astrid/tags/TagsPlugin.java index b29a045c1..8cd3b73a5 100644 --- a/astrid/plugin-src/com/todoroo/astrid/tags/TagsPlugin.java +++ b/astrid/plugin-src/com/todoroo/astrid/tags/TagsPlugin.java @@ -5,7 +5,7 @@ import android.content.Context; import android.content.Intent; import com.todoroo.astrid.api.AstridApiConstants; -import com.todoroo.astrid.api.Plugin; +import com.todoroo.astrid.api.Addon; public class TagsPlugin extends BroadcastReceiver { @@ -13,11 +13,11 @@ public class TagsPlugin extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - Plugin plugin = new Plugin(IDENTIFIER, "Tags", "Todoroo", + Addon plugin = new Addon(IDENTIFIER, "Tags", "Todoroo", "Provides tagging support for tasks."); - Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_PLUGINS); - broadcastIntent.putExtra(AstridApiConstants.EXTRAS_PLUGIN, plugin); + Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_SEND_ADDONS); + broadcastIntent.putExtra(AstridApiConstants.EXTRAS_ADDON, plugin); context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); } diff --git a/astrid/res/layout/repeat_control.xml b/astrid/res/layout/repeat_control.xml new file mode 100644 index 000000000..c204dcda0 --- /dev/null +++ b/astrid/res/layout/repeat_control.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + +