Refactored Task Edit page into four tabs and added styling

- added sharing tab from edit people activity
- changed due date picker into two buttons
- refactored Task Edit Activity into multiple smaller files
- new UI elements for save/cancel buttons, tabs, and other small parts
pull/14/head
Tim Su 14 years ago
parent a524922cc4
commit fd4d178827

@ -106,6 +106,9 @@
<!-- error dialog title --> <!-- error dialog title -->
<string name="DLG_error_title">Error!</string> <string name="DLG_error_title">Error!</string>
<!-- general dialog save-->
<string name="DLG_save">Save</string>
<!-- general dialog yes--> <!-- general dialog yes-->
<string name="DLG_yes">Yes</string> <string name="DLG_yes">Yes</string>

@ -323,9 +323,10 @@ public final class Task extends RemoteModel {
public static final int URGENCY_TOMORROW = 2; public static final int URGENCY_TOMORROW = 2;
public static final int URGENCY_DAY_AFTER = 3; public static final int URGENCY_DAY_AFTER = 3;
public static final int URGENCY_NEXT_WEEK = 4; public static final int URGENCY_NEXT_WEEK = 4;
public static final int URGENCY_NEXT_MONTH = 5; public static final int URGENCY_IN_TWO_WEEKS = 5;
public static final int URGENCY_SPECIFIC_DAY = 6; public static final int URGENCY_NEXT_MONTH = 6;
public static final int URGENCY_SPECIFIC_DAY_TIME = 7; public static final int URGENCY_SPECIFIC_DAY = 7;
public static final int URGENCY_SPECIFIC_DAY_TIME = 8;
/** hide until array index -> significance */ /** hide until array index -> significance */
public static final int HIDE_UNTIL_NONE = 0; public static final int HIDE_UNTIL_NONE = 0;
@ -344,7 +345,7 @@ public final class Task extends RemoteModel {
* @param customDate * @param customDate
* if specific day or day & time is set, this value * if specific day or day & time is set, this value
*/ */
public long createDueDate(int setting, long customDate) { public static long createDueDate(int setting, long customDate) {
long date; long date;
switch(setting) { switch(setting) {
@ -363,6 +364,9 @@ public final class Task extends RemoteModel {
case URGENCY_NEXT_WEEK: case URGENCY_NEXT_WEEK:
date = DateUtilities.now() + DateUtilities.ONE_WEEK; date = DateUtilities.now() + DateUtilities.ONE_WEEK;
break; break;
case URGENCY_IN_TWO_WEEKS:
date = DateUtilities.now() + 2 * DateUtilities.ONE_WEEK;
break;
case URGENCY_NEXT_MONTH: case URGENCY_NEXT_MONTH:
date = DateUtilities.oneMonthFromNow(); date = DateUtilities.oneMonthFromNow();
break; break;
@ -455,7 +459,7 @@ public final class Task extends RemoteModel {
* Checks whether provided due date has a due time or only a date * Checks whether provided due date has a due time or only a date
*/ */
public static boolean hasDueTime(long dueDate) { public static boolean hasDueTime(long dueDate) {
return !isEndOfDay(new Date(dueDate)); return dueDate > 0 && !isEndOfDay(new Date(dueDate));
} }
} }

@ -433,9 +433,6 @@
<activity android:name="com.todoroo.astrid.actfm.TagViewActivity" <activity android:name="com.todoroo.astrid.actfm.TagViewActivity"
android:windowSoftInputMode="stateHidden" android:windowSoftInputMode="stateHidden"
android:theme="@style/Theme" /> android:theme="@style/Theme" />
<activity android:name="com.todoroo.astrid.actfm.EditPeopleActivity"
android:windowSoftInputMode="stateHidden"
android:theme="@style/Theme" />
<receiver android:name="com.todoroo.astrid.actfm.EditPeopleExposer"> <receiver android:name="com.todoroo.astrid.actfm.EditPeopleExposer">
<intent-filter> <intent-filter>
<action android:name="com.todoroo.astrid.REQUEST_ACTIONS" /> <action android:name="com.todoroo.astrid.REQUEST_ACTIONS" />

@ -13,7 +13,6 @@ import android.app.Activity;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Intent; import android.content.Intent;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
@ -37,6 +36,7 @@ import com.todoroo.astrid.actfm.sync.ActFmInvoker;
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService; import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
import com.todoroo.astrid.actfm.sync.ActFmSyncService; import com.todoroo.astrid.actfm.sync.ActFmSyncService;
import com.todoroo.astrid.actfm.sync.ActFmSyncService.JsonHelper; import com.todoroo.astrid.actfm.sync.ActFmSyncService.JsonHelper;
import com.todoroo.astrid.activity.TaskEditActivity.TaskEditControlSet;
import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria; import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Metadata;
@ -47,18 +47,15 @@ import com.todoroo.astrid.service.MetadataService;
import com.todoroo.astrid.service.StatisticsService; import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.service.TagDataService; import com.todoroo.astrid.service.TagDataService;
import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.service.ThemeService;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagService;
import com.todoroo.astrid.ui.PeopleContainer; import com.todoroo.astrid.ui.PeopleContainer;
import com.todoroo.astrid.ui.PeopleContainer.OnAddNewPersonListener; import com.todoroo.astrid.ui.PeopleContainer.OnAddNewPersonListener;
import com.todoroo.astrid.utility.Flags; import com.todoroo.astrid.utility.Flags;
public class EditPeopleActivity extends Activity { public class EditPeopleControlSet implements TaskEditControlSet {
public static final String EXTRA_TASK_ID = "task"; //$NON-NLS-1$ public static final String EXTRA_TASK_ID = "task"; //$NON-NLS-1$
private static final int REQUEST_LOG_IN = 0;
private Task task; private Task task;
private final ArrayList<Metadata> nonSharedTags = new ArrayList<Metadata>(); private final ArrayList<Metadata> nonSharedTags = new ArrayList<Metadata>();
@ -87,41 +84,39 @@ public class EditPeopleActivity extends Activity {
private final ArrayList<AssignedToUser> spinnerValues = new ArrayList<AssignedToUser>(); private final ArrayList<AssignedToUser> spinnerValues = new ArrayList<AssignedToUser>();
private Activity activity;
private String saveToast = null;
private int loginRequestCode;
static { static {
AstridDependencyInjector.initialize(); AstridDependencyInjector.initialize();
} }
public EditPeopleActivity() { public EditPeopleControlSet() {
DependencyInjectionService.getInstance().inject(this); DependencyInjectionService.getInstance().inject(this);
} }
// --- UI initialization // --- UI initialization
@Override public EditPeopleControlSet(Activity activity, int loginRequestCode) {
protected void onCreate(Bundle savedInstanceState) { this.activity = activity;
super.onCreate(savedInstanceState); this.loginRequestCode = loginRequestCode;
setContentView(R.layout.edit_people_activity);
setTitle(getString(R.string.actfm_EPA_title));
ThemeService.applyTheme(this);
task = taskService.fetchById(
getIntent().getLongExtra(EXTRA_TASK_ID, 41L), Task.ID, Task.REMOTE_ID,
Task.TITLE, Task.USER, Task.USER_ID, Task.SHARED_WITH, Task.FLAGS);
if(task == null) {
finish();
return;
}
((TextView) findViewById(R.id.title)).setText(task.getValue(Task.TITLE)); sharedWithContainer = (PeopleContainer) activity.findViewById(R.id.share_container);
sharedWithContainer = (PeopleContainer) findViewById(R.id.share_container); assignedCustom = (EditText) activity.findViewById(R.id.assigned_custom);
assignedCustom = (EditText) findViewById(R.id.assigned_custom); assignedSpinner = (Spinner) activity.findViewById(R.id.assigned_spinner);
assignedSpinner = (Spinner) findViewById(R.id.assigned_spinner); cbFacebook = (CheckBox) activity.findViewById(R.id.checkbox_facebook);
cbFacebook = (CheckBox) findViewById(R.id.checkbox_facebook); cbTwitter = (CheckBox) activity.findViewById(R.id.checkbox_twitter);
cbTwitter = (CheckBox) findViewById(R.id.checkbox_twitter);
sharedWithContainer.addPerson(""); //$NON-NLS-1$ sharedWithContainer.addPerson(""); //$NON-NLS-1$
setUpListeners(); setUpListeners();
}
@Override
public void readFromTask(Task sourceTask) {
task = sourceTask;
setUpData(); setUpData();
} }
@ -159,7 +154,7 @@ public class EditPeopleActivity extends Activity {
final String tag = metadata.getValue(TagService.TAG); final String tag = metadata.getValue(TagService.TAG);
TagData tagData = tagDataService.getTag(tag, TagData.MEMBER_COUNT, TagData.MEMBERS, TagData.USER); TagData tagData = tagDataService.getTag(tag, TagData.MEMBER_COUNT, TagData.MEMBERS, TagData.USER);
if(tagData != null && tagData.getValue(TagData.MEMBER_COUNT) > 0) { if(tagData != null && tagData.getValue(TagData.MEMBER_COUNT) > 0) {
runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
TextView textView = sharedWithContainer.addPerson("#" + tag); TextView textView = sharedWithContainer.addPerson("#" + tag);
@ -238,7 +233,7 @@ public class EditPeopleActivity extends Activity {
String name = person.optString("name"); String name = person.optString("name");
if(id == 0) if(id == 0)
name = getString(R.string.actfm_EPA_assign_me); name = activity.getString(R.string.actfm_EPA_assign_me);
AssignedToUser atu = new AssignedToUser(name, person); AssignedToUser atu = new AssignedToUser(name, person);
spinnerValues.add(atu); spinnerValues.add(atu);
if(names.containsKey(name)) { if(names.containsKey(name)) {
@ -258,13 +253,13 @@ public class EditPeopleActivity extends Activity {
names.put(name, atu); names.put(name, atu);
} }
spinnerValues.add(new AssignedToUser(getString(R.string.actfm_EPA_assign_custom), null)); spinnerValues.add(new AssignedToUser(activity.getString(R.string.actfm_EPA_assign_custom), null));
final ArrayAdapter<AssignedToUser> usersAdapter = new ArrayAdapter<AssignedToUser>(this, final ArrayAdapter<AssignedToUser> usersAdapter = new ArrayAdapter<AssignedToUser>(activity,
android.R.layout.simple_spinner_item, spinnerValues); android.R.layout.simple_spinner_item, spinnerValues);
usersAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); usersAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
assignedSpinner.setAdapter(usersAdapter); assignedSpinner.setAdapter(usersAdapter);
@ -273,7 +268,7 @@ public class EditPeopleActivity extends Activity {
} }
private void setUpListeners() { private void setUpListeners() {
final View assignedClear = findViewById(R.id.assigned_clear); final View assignedClear = activity.findViewById(R.id.assigned_clear);
assignedSpinner.setOnItemSelectedListener(new OnItemSelectedListener() { assignedSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override @Override
@ -291,20 +286,6 @@ public class EditPeopleActivity extends Activity {
// //
} }
}); });
findViewById(R.id.discard).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
findViewById(R.id.discard).requestFocus();
findViewById(R.id.save).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
save();
}
});
assignedClear.setOnClickListener(new OnClickListener() { assignedClear.setOnClickListener(new OnClickListener() {
@Override @Override
@ -320,10 +301,10 @@ public class EditPeopleActivity extends Activity {
sharedWithContainer.setOnAddNewPerson(new OnAddNewPersonListener() { sharedWithContainer.setOnAddNewPerson(new OnAddNewPersonListener() {
@Override @Override
public void textChanged(String text) { public void textChanged(String text) {
findViewById(R.id.share_additional).setVisibility(View.VISIBLE); activity.findViewById(R.id.share_additional).setVisibility(View.VISIBLE);
if(text.indexOf('@') > -1) { if(text.indexOf('@') > -1) {
findViewById(R.id.tag_label).setVisibility(View.VISIBLE); activity.findViewById(R.id.tag_label).setVisibility(View.VISIBLE);
findViewById(R.id.tag_name).setVisibility(View.VISIBLE); activity.findViewById(R.id.tag_name).setVisibility(View.VISIBLE);
} }
} }
}); });
@ -331,48 +312,71 @@ public class EditPeopleActivity extends Activity {
// --- events // --- events
/** Save sharing settings */ @Override
@SuppressWarnings("nls") public String writeToModel(Task model) {
private void save() { // do nothing, we use a separate method
if(!actFmPreferenceService.isLoggedIn()) { return null;
startActivityForResult(new Intent(this, ActFmLoginActivity.class),
REQUEST_LOG_IN);
return;
} }
setResult(RESULT_OK); /**
Flags.set(Flags.REFRESH); * Save sharing settings
* @param toast toast to show after saving is finished
* @return false if login is required & save should be halted
*/
@SuppressWarnings("nls")
public boolean saveSharingSettings(String toast) {
saveToast = toast;
boolean dirty = false;
try { try {
JSONObject userJson; JSONObject userJson;
if(assignedCustom.getVisibility() == View.VISIBLE) if(assignedCustom.getVisibility() == View.VISIBLE)
userJson = PeopleContainer.createUserJson(assignedCustom); userJson = PeopleContainer.createUserJson(assignedCustom);
else else
userJson = ((AssignedToUser) assignedSpinner.getSelectedItem()).user; userJson = ((AssignedToUser) assignedSpinner.getSelectedItem()).user;
if(userJson == null || userJson.optLong("id", -1) == 0) { if(userJson == null || userJson.optLong("id", -1) == 0) {
dirty = task.getValue(Task.USER_ID) == 0L ? dirty : true;
task.setValue(Task.USER_ID, 0L); task.setValue(Task.USER_ID, 0L);
task.setValue(Task.USER, "{}"); task.setValue(Task.USER, "{}");
} else { } else {
String user = userJson.toString();
dirty = task.getValue(Task.USER).equals(user) ? dirty : true;
task.setValue(Task.USER_ID, userJson.optLong("id", -1)); task.setValue(Task.USER_ID, userJson.optLong("id", -1));
task.setValue(Task.USER, userJson.toString()); task.setValue(Task.USER, user);
} }
ArrayList<Metadata> metadata = new ArrayList<Metadata>(nonSharedTags); JSONObject sharedWith = parseSharedWithAndTags();
JSONObject sharedWith = parseSharedWithAndTags(metadata); dirty = sharedWith.has("p");
task.setValue(Task.SHARED_WITH, sharedWith.toString()); task.setValue(Task.SHARED_WITH, sharedWith.toString());
metadataService.synchronizeMetadata(task.getId(), metadata, MetadataCriteria.withKey(TagService.KEY)); if(dirty)
Flags.set(Flags.SUPPRESS_SYNC);
taskService.save(task); taskService.save(task);
shareTask(sharedWith, metadata);
if(dirty && !actFmPreferenceService.isLoggedIn()) {
activity.startActivityForResult(new Intent(activity, ActFmLoginActivity.class),
loginRequestCode);
return false;
}
if(dirty)
shareTask(sharedWith);
else
showSaveToast();
return true;
} catch (JSONException e) { } catch (JSONException e) {
exceptionService.displayAndReportError(this, "save-people", e); exceptionService.displayAndReportError(activity, "save-people", e);
} catch (ParseSharedException e) { } catch (ParseSharedException e) {
e.view.setTextColor(Color.RED); e.view.setTextColor(Color.RED);
e.view.requestFocus(); e.view.requestFocus();
System.err.println(e.message); DialogUtilities.okDialog(activity, e.message, null);
DialogUtilities.okDialog(this, e.message, null);
} }
return false;
}
private void showSaveToast() {
int length = saveToast.indexOf('\n') > -1 ? Toast.LENGTH_LONG : Toast.LENGTH_SHORT;
Toast.makeText(activity, saveToast, length).show();
} }
private class ParseSharedException extends Exception { private class ParseSharedException extends Exception {
@ -387,7 +391,7 @@ public class EditPeopleActivity extends Activity {
} }
@SuppressWarnings("nls") @SuppressWarnings("nls")
private JSONObject parseSharedWithAndTags(ArrayList<Metadata> metadata) throws private JSONObject parseSharedWithAndTags() throws
JSONException, ParseSharedException { JSONException, ParseSharedException {
JSONObject sharedWith = new JSONObject(); JSONObject sharedWith = new JSONObject();
if(cbFacebook.isChecked()) if(cbFacebook.isChecked())
@ -398,41 +402,29 @@ public class EditPeopleActivity extends Activity {
JSONArray peopleList = new JSONArray(); JSONArray peopleList = new JSONArray();
for(int i = 0; i < sharedWithContainer.getChildCount(); i++) { for(int i = 0; i < sharedWithContainer.getChildCount(); i++) {
TextView textView = sharedWithContainer.getTextView(i); TextView textView = sharedWithContainer.getTextView(i);
textView.setTextAppearance(this, android.R.style.TextAppearance_Medium_Inverse); textView.setTextAppearance(activity, android.R.style.TextAppearance_Medium_Inverse);
String text = textView.getText().toString(); String text = textView.getText().toString();
if(text.length() == 0) if(text.length() == 0)
continue; continue;
if(text.startsWith("#")) {
text = text.substring(1);
TagData tagData = tagDataService.getTag(text, TagData.REMOTE_ID);
if(tagData == null)
throw new ParseSharedException(textView,
getString(R.string.actfm_EPA_invalid_tag, text));
Metadata tag = new Metadata();
tag.setValue(Metadata.KEY, TagService.KEY);
tag.setValue(TagService.TAG, text);
tag.setValue(TagService.REMOTE_ID, tagData.getValue(TagData.REMOTE_ID));
metadata.add(tag);
} else {
if(text.indexOf('@') == -1) if(text.indexOf('@') == -1)
throw new ParseSharedException(textView, throw new ParseSharedException(textView,
getString(R.string.actfm_EPA_invalid_email, text)); activity.getString(R.string.actfm_EPA_invalid_email, text));
peopleList.put(text); peopleList.put(text);
} }
} if(peopleList.length() > 0)
sharedWith.put("p", peopleList); sharedWith.put("p", peopleList);
return sharedWith; return sharedWith;
} }
@SuppressWarnings("nls") @SuppressWarnings("nls")
private void shareTask(final JSONObject sharedWith, final ArrayList<Metadata> metadata) { private void shareTask(final JSONObject sharedWith) {
final JSONArray emails = sharedWith.optJSONArray("p"); final JSONArray emails = sharedWith.optJSONArray("p");
final ProgressDialog pd = DialogUtilities.progressDialog(this, final ProgressDialog pd = DialogUtilities.progressDialog(activity,
getString(R.string.DLG_please_wait)); activity.getString(R.string.DLG_please_wait));
new Thread() { new Thread() {
@Override @Override
public void run() { public void run() {
@ -444,12 +436,12 @@ public class EditPeopleActivity extends Activity {
Task.REMOTE_ID).getValue(Task.REMOTE_ID)); Task.REMOTE_ID).getValue(Task.REMOTE_ID));
} }
if(task.getValue(Task.REMOTE_ID) == 0) { if(task.getValue(Task.REMOTE_ID) == 0) {
DialogUtilities.okDialog(EditPeopleActivity.this, "We had an error saving " + DialogUtilities.okDialog(activity, "We had an error saving " +
"this task to Astrid.com. Could you let us know why this happened?", null); "this task to Astrid.com. Could you let us know why this happened?", null);
return; return;
} }
Object[] args = buildSharingArgs(emails, metadata); Object[] args = buildSharingArgs(emails);
JSONObject result = invoker.invoke("task_share", args); JSONObject result = invoker.invoke("task_share", args);
sharedWith.remove("p"); sharedWith.remove("p");
@ -463,31 +455,32 @@ public class EditPeopleActivity extends Activity {
taskService.save(task); taskService.save(task);
int count = result.optInt("shared", 0); int count = result.optInt("shared", 0);
final String toast;
if(count > 0) { if(count > 0) {
toast = getString(R.string.actfm_EPA_emailed_toast, saveToast += "\n" +
getResources().getQuantityString(R.plurals.Npeople, count, count)); activity.getString(R.string.actfm_EPA_emailed_toast,
activity.getResources().getQuantityString(R.plurals.Npeople, count, count));
StatisticsService.reportEvent("actfm-task-shared"); //$NON-NLS-1$ StatisticsService.reportEvent("actfm-task-shared"); //$NON-NLS-1$
} else }
toast = getString(R.string.actfm_EPA_saved_toast);
Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH); Intent broadcastIntent = new Intent(AstridApiConstants.BROADCAST_EVENT_REFRESH);
ContextManager.getContext().sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); ContextManager.getContext().sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
public void run() { public void run() {
Toast.makeText(EditPeopleActivity.this, toast, Toast.LENGTH_LONG).show(); showSaveToast();
finish(); activity.finish();
} }
}); });
} catch (IOException e) { } catch (IOException e) {
DialogUtilities.okDialog(EditPeopleActivity.this, getString(R.string.SyP_ioerror), DialogUtilities.okDialog(activity,
activity.getString(R.string.SyP_ioerror),
android.R.drawable.ic_dialog_alert, e.toString(), null); android.R.drawable.ic_dialog_alert, e.toString(), null);
} catch (JSONException e) { } catch (JSONException e) {
DialogUtilities.okDialog(EditPeopleActivity.this, getString(R.string.SyP_ioerror), DialogUtilities.okDialog(activity,
activity.getString(R.string.SyP_ioerror),
android.R.drawable.ic_dialog_alert, e.toString(), null); android.R.drawable.ic_dialog_alert, e.toString(), null);
} finally { } finally {
runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
public void run() { public void run() {
pd.dismiss(); pd.dismiss();
} }
@ -520,13 +513,13 @@ public class EditPeopleActivity extends Activity {
} }
@SuppressWarnings("nls") @SuppressWarnings("nls")
protected Object[] buildSharingArgs(JSONArray emails, ArrayList<Metadata> protected Object[] buildSharingArgs(JSONArray emails) throws JSONException {
tags) throws JSONException {
ArrayList<Object> values = new ArrayList<Object>(); ArrayList<Object> values = new ArrayList<Object>();
long currentTaskID = task.getValue(Task.REMOTE_ID); long currentTaskID = task.getValue(Task.REMOTE_ID);
values.add("id"); values.add("id");
values.add(currentTaskID); values.add(currentTaskID);
if(emails != null) {
for(int i = 0; i < emails.length(); i++) { for(int i = 0; i < emails.length(); i++) {
String email = emails.optString(i); String email = emails.optString(i);
if(email == null || email.indexOf('@') == -1) if(email == null || email.indexOf('@') == -1)
@ -534,17 +527,6 @@ public class EditPeopleActivity extends Activity {
values.add("emails[]"); values.add("emails[]");
values.add(email); values.add(email);
} }
for(int i = 0; i < tags.size(); i++) {
Metadata tag = tags.get(i);
if(tag.containsNonNullValue(TagService.REMOTE_ID) &&
tag.getValue(TagService.REMOTE_ID) > 0) {
values.add("tag_ids[]");
values.add(tag.getValue(TagService.REMOTE_ID));
} else {
values.add("tags[]");
values.add(tag.getValue(TagService.TAG));
}
} }
values.add("assignee"); values.add("assignee");
@ -559,13 +541,13 @@ public class EditPeopleActivity extends Activity {
} }
} }
String message = ((TextView) findViewById(R.id.message)).getText().toString(); String message = ((TextView) activity.findViewById(R.id.message)).getText().toString();
if(!TextUtils.isEmpty(message) && findViewById(R.id.share_additional).getVisibility() == View.VISIBLE) { if(!TextUtils.isEmpty(message) && activity.findViewById(R.id.share_additional).getVisibility() == View.VISIBLE) {
values.add("message"); values.add("message");
values.add(message); values.add(message);
} }
String tag = ((TextView) findViewById(R.id.tag_name)).getText().toString(); String tag = ((TextView) activity.findViewById(R.id.tag_name)).getText().toString();
if(!TextUtils.isEmpty(tag)) { if(!TextUtils.isEmpty(tag)) {
values.add("tag"); values.add("tag");
values.add(tag); values.add(tag);
@ -574,14 +556,12 @@ public class EditPeopleActivity extends Activity {
return values.toArray(new Object[values.size()]); return values.toArray(new Object[values.size()]);
} }
@Override /** Resume save
protected void onActivityResult(int requestCode, int resultCode, Intent data) { * @param data */
if(requestCode == REQUEST_LOG_IN) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK) if(requestCode == loginRequestCode) {
save(); if(resultCode == Activity.RESULT_OK)
return; saveSharingSettings(saveToast);
} }
super.onActivityResult(requestCode, resultCode, data);
} }
} }

@ -11,6 +11,7 @@ import android.content.Intent;
import com.timsu.astrid.R; import com.timsu.astrid.R;
import com.todoroo.andlib.service.ContextManager; import com.todoroo.andlib.service.ContextManager;
import com.todoroo.astrid.actfm.sync.ActFmPreferenceService; import com.todoroo.astrid.actfm.sync.ActFmPreferenceService;
import com.todoroo.astrid.activity.TaskEditActivity;
import com.todoroo.astrid.api.AstridApiConstants; import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.TaskAction; import com.todoroo.astrid.api.TaskAction;
import com.todoroo.astrid.api.TaskDecoration; import com.todoroo.astrid.api.TaskDecoration;
@ -53,8 +54,9 @@ public class EditPeopleExposer extends BroadcastReceiver {
broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId); broadcastIntent.putExtra(AstridApiConstants.EXTRAS_TASK_ID, taskId);
context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ); context.sendBroadcast(broadcastIntent, AstridApiConstants.PERMISSION_READ);
} else if(ACTION.equals(intent.getAction())) { } else if(ACTION.equals(intent.getAction())) {
Intent launchIntent = new Intent(context, EditPeopleActivity.class); Intent launchIntent = new Intent(context, TaskEditActivity.class);
launchIntent.putExtra(EditPeopleActivity.EXTRA_TASK_ID, taskId); launchIntent.putExtra(TaskEditActivity.TOKEN_ID, taskId);
launchIntent.putExtra(TaskEditActivity.TOKEN_TAB, TaskEditActivity.TAB_SHARE);
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ContextManager.getContext().startActivity(launchIntent); ContextManager.getContext().startActivity(launchIntent);
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Enabled states -->
<item android:state_checked="true" android:state_pressed="true"
android:state_enabled="true"
android:drawable="@android:drawable/checkbox_off_background" />
<item android:state_checked="false" android:state_pressed="true"
android:state_enabled="true"
android:drawable="@android:drawable/checkbox_on_background" />
<item android:state_checked="false"
android:state_enabled="true"
android:drawable="@android:drawable/checkbox_off_background" />
<item android:state_checked="true"
android:state_enabled="true"
android:drawable="@android:drawable/checkbox_on_background" />
</selector>

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/btn_dismiss_pressed" />
<item android:drawable="@drawable/btn_dismiss_normal" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 997 B

After

Width:  |  Height:  |  Size: 983 B

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/footer_greenbtn_pressed" />
<item android:drawable="@drawable/footer_greenbtn_normal" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 849 B

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/footer_redbtn_pressed" />
<item android:drawable="@drawable/footer_redbtn_normal" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#008d43"
android:endColor="#00522b"/>
</shape>

@ -30,13 +30,10 @@
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
<ImageButton android:id="@+id/button1" <ImageButton android:id="@+id/button1"
style="?android:attr/buttonStyleInset" android:background="@drawable/btn_dismiss"
android:src="@android:drawable/ic_delete" android:layout_width="32dip"
android:layout_width="wrap_content" android:layout_height="32dip"
android:layout_height="fill_parent" android:layout_gravity="center"
android:layout_marginTop="2dip" android:layout_margin="4dip"
android:layout_marginRight="2dip"
android:layout_marginBottom="2dip"
android:gravity="center_vertical"
/> />
</LinearLayout> </LinearLayout>

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- See the file "LICENSE" for the full license governing this code. --> <!-- See the file "LICENSE" for the full license governing this code. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@android:drawable/list_selector_background" android:background="@android:drawable/list_selector_background"
@ -13,15 +13,27 @@
android:layout_width="40dip" android:layout_width="40dip"
android:layout_height="40dip" android:layout_height="40dip"
android:gravity="center" android:gravity="center"
android:layout_marginRight="5dip"
android:scaleType="fitCenter" /> android:scaleType="fitCenter" />
<!-- person or tag name --> <!-- person name -->
<TextView android:id="@android:id/text1" <TextView android:id="@android:id/text1"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="50dip"
style="@android:attr/dropDownItemStyle" style="@android:attr/dropDownItemStyle"
android:textAppearance="@android:attr/textAppearanceLargeInverse" android:textAppearance="@android:attr/textAppearanceLargeInverse"
android:textSize="20sp"/> android:singleLine="true"
android:textSize="18sp"/>
</LinearLayout> <!-- person email -->
<TextView android:id="@android:id/text2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="50dip"
android:layout_below="@android:id/text1"
style="@android:attr/dropDownItemStyle"
android:textAppearance="@android:attr/textAppearanceInverse"
android:singleLine="true"
android:textSize="14sp"/>
</RelativeLayout>

@ -27,13 +27,10 @@
android:hint="@string/actfm_person_hint" /> android:hint="@string/actfm_person_hint" />
<ImageButton android:id="@+id/button1" <ImageButton android:id="@+id/button1"
style="?android:attr/buttonStyleInset" android:background="@drawable/btn_dismiss"
android:src="@android:drawable/ic_delete" android:layout_width="32dip"
android:layout_width="wrap_content" android:layout_height="32dip"
android:layout_height="fill_parent" android:layout_gravity="center"
android:layout_marginTop="2dip" android:layout_margin="4dip"
android:layout_marginRight="2dip"
android:layout_marginBottom="2dip"
android:gravity="center_vertical"
/> />
</LinearLayout> </LinearLayout>

@ -18,6 +18,8 @@
android:id="@+id/add_to_calendar" android:id="@+id/add_to_calendar"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:button="@drawable/btn_check_small"
android:text="@string/gcal_TEA_addToCalendar_label" /> android:text="@string/gcal_TEA_addToCalendar_label" />
<Spinner <Spinner
@ -35,11 +37,5 @@
</LinearLayout> </LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:padding="5dip"
android:background="@android:drawable/divider_horizontal_dark" />
</merge> </merge>

@ -2,15 +2,11 @@
<!-- See the file "LICENSE" for the full license governing this code. --> <!-- See the file "LICENSE" for the full license governing this code. -->
<merge xmlns:android="http://schemas.android.com/apk/res/android"> <merge xmlns:android="http://schemas.android.com/apk/res/android">
<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:padding="5dip"
android:background="@android:drawable/divider_horizontal_dark" />
<CheckBox android:id="@+id/repeatEnabled" <CheckBox android:id="@+id/repeatEnabled"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:button="@drawable/btn_check_small"
android:text="@string/repeat_enabled"/> android:text="@string/repeat_enabled"/>
<LinearLayout android:id="@+id/repeatContainer" <LinearLayout android:id="@+id/repeatContainer"

@ -26,13 +26,10 @@
android:layout_gravity="center_vertical"/> android:layout_gravity="center_vertical"/>
<ImageButton android:id="@+id/button1" <ImageButton android:id="@+id/button1"
style="?android:attr/buttonStyleInset" android:background="@drawable/btn_dismiss"
android:src="@android:drawable/ic_delete" android:layout_width="32dip"
android:layout_width="wrap_content" android:layout_height="32dip"
android:layout_height="fill_parent" android:layout_gravity="center"
android:layout_marginTop="2dip" android:layout_margin="4dip"
android:layout_marginRight="2dip"
android:layout_marginBottom="2dip"
android:gravity="center_vertical"
/> />
</LinearLayout> </LinearLayout>

@ -1,24 +1,58 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout <RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:astrid="http://schemas.android.com/apk/res/com.timsu.astrid"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:background="@drawable/background_gradient"> android:background="@drawable/background_gradient">
<!-- ======================================================= tab: basic == --> <View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:background="@color/task_edit_selected" />
<!-- buttons -->
<LinearLayout android:id="@+id/edit_footer"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="48dip"
android:layout_alignParentBottom="true"
android:padding="5dip"
android:background="@drawable/footer_background"
android:baselineAligned="false">
<Button
android:id="@+id/save"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginRight="5dip"
android:background="@drawable/footer_greenbtn"
android:text="@string/DLG_save"
android:textStyle="bold"
style="@style/TextAppearance.TEA_action"
android:layout_weight="1" />
<Button
android:id="@+id/discard"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="5dip"
android:background="@drawable/footer_redbtn"
android:text="@android:string/cancel"
style="@style/TextAppearance.TEA_action"
android:layout_weight="1" />
</LinearLayout>
<!-- ======================================================= tab: basic == -->
<ScrollView <ScrollView
android:id="@+id/tab_basic" android:id="@+id/tab_basic"
android:layout_above="@id/edit_footer"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent">
android:layout_weight="100">
<LinearLayout <LinearLayout
android:id="@+id/event" android:padding="4dip"
android:paddingRight="8dip"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent"> android:layout_height="fill_parent">
<!-- title --> <!-- title -->
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -33,7 +67,6 @@
android:autoText="true" android:autoText="true"
android:text="" android:text=""
android:capitalize="sentences" /> android:capitalize="sentences" />
<!-- importance --> <!-- importance -->
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -46,18 +79,35 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
</LinearLayout> </LinearLayout>
<!-- urgency --> <!-- urgency -->
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/TEA_urgency_label" android:text="@string/TEA_urgency_label"
style="@style/TextAppearance.GEN_EditLabel" /> style="@style/TextAppearance.GEN_EditLabel" />
<Spinner <LinearLayout
android:id="@+id/urgency" android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content">
<Button
android:id="@+id/urgency_date"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableLeft="@drawable/gl_date" />
<Button
android:id="@+id/urgency_time"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableLeft="@drawable/gl_time" />
</LinearLayout>
<!-- add-ons -->
<LinearLayout
android:id="@+id/addons_urgency"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
<!-- tags --> <!-- tags -->
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -75,16 +125,9 @@
android:entries="@array/TEA_loading" android:entries="@array/TEA_loading"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<!-- separator -->
<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:padding="5dip"
android:background="@android:drawable/divider_horizontal_dark" />
<!-- notes --> <!-- notes -->
<TextView android:id="@+id/notes_label" <TextView
android:id="@+id/notes_label"
android:paddingTop="5dip" android:paddingTop="5dip"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -95,13 +138,14 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<!-- Voice Add Note Button --> <!-- Voice Add Note Button -->
<ImageButton android:id="@+id/voiceAddNoteButton" <ImageButton
android:id="@+id/voiceAddNoteButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:src="@drawable/tango_microphone" android:src="@drawable/tango_microphone"
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:visibility="gone"/> android:visibility="gone" />
<EditText <EditText
android:id="@+id/notes" android:id="@+id/notes"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -114,46 +158,153 @@
android:capitalize="sentences" android:capitalize="sentences"
android:singleLine="false" /> android:singleLine="false" />
</LinearLayout> </LinearLayout>
</LinearLayout>
</ScrollView>
<!-- buttons --> <!-- ===================================================== tab: sharing == -->
<ScrollView
android:id="@+id/tab_share"
android:layout_above="@id/edit_footer"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout <LinearLayout
android:orientation="horizontal" android:padding="4dip"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingBottom="5dip"
style="@style/TextAppearance.GEN_EditLabel"
android:text="@string/actfm_EPA_assign_label" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Spinner
android:id="@+id/assigned_spinner"
android:layout_width="fill_parent"
android:layout_height="45dip"
android:layout_weight="1" android:layout_weight="1"
android:layout_marginTop="10dip" android:layout_gravity="center_vertical"
android:padding="5dip" android:hint="@string/actfm_person_hint" />
android:background="@drawable/edit_header" <com.todoroo.astrid.ui.ContactsAutoComplete
android:baselineAligned="false"> android:id="@+id/assigned_custom"
<ImageButton
android:id="@+id/save_basic"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:src="@drawable/tango_save" /> android:layout_gravity="center_vertical"
android:visibility="gone"
android:hint="@string/actfm_person_hint" />
<ImageButton <ImageButton
android:id="@+id/discard_basic" android:id="@+id/assigned_clear"
style="?android:attr/buttonStyleInset"
android:src="@android:drawable/ic_delete"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginTop="2dip"
android:layout_marginRight="2dip"
android:layout_marginBottom="2dip"
android:visibility="gone"
android:gravity="center_vertical" />
</LinearLayout>
<TextView
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:paddingTop="5dip"
android:src="@drawable/tango_stop" /> android:paddingBottom="5dip"
style="@style/TextAppearance.GEN_EditLabel"
android:text="@string/actfm_EPA_share_with" />
<com.todoroo.astrid.ui.PeopleContainer
android:id="@+id/share_container"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/share_additional"
android:orientation="vertical"
android:padding="5dip"
android:visibility="gone"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:background="@android:drawable/divider_horizontal_dark" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="5dip"
android:paddingBottom="5dip"
android:text="@string/actfm_EPA_message_text" />
<EditText
android:id="@+id/message"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:text="@string/actfm_EPA_message_body"
android:autoText="true"
android:capitalize="sentences"
android:singleLine="false" />
<TextView
android:id="@+id/tag_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="5dip"
android:visibility="gone"
android:text="@string/actfm_EPA_tag_label" />
<EditText
android:id="@+id/tag_name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:hint="@string/actfm_EPA_tag_hint" />
<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:background="@android:drawable/divider_horizontal_dark" />
</LinearLayout> </LinearLayout>
<CheckBox
android:id="@+id/checkbox_facebook"
android:text="@string/actfm_EPA_facebook"
android:paddingLeft="45dip"
android:visibility="gone"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<CheckBox
android:id="@+id/checkbox_twitter"
android:text="@string/actfm_EPA_twitter"
android:paddingLeft="45dip"
android:visibility="gone"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:layout_margin="15dip"
android:background="@android:drawable/divider_horizontal_dark" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="15dip"
android:text="@string/actfm_EPA_intro"
android:gravity="center"
android:textColor="#ffaa00" />
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
<!-- ======================================================= tab: extra == --> <!-- ====================================================== tab: alarms == -->
<ScrollView <ScrollView
android:id="@+id/tab_extra" android:id="@+id/tab_alarms"
android:layout_above="@id/edit_footer"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent">
android:layout_weight="100">
<LinearLayout <LinearLayout
android:paddingRight="8dip" android:padding="4dip"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent"> android:layout_height="fill_parent">
<!-- reminders --> <!-- reminders -->
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -164,11 +315,15 @@
android:id="@+id/reminder_due" android:id="@+id/reminder_due"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:button="@drawable/btn_check_small"
android:text="@string/TEA_reminder_due" /> android:text="@string/TEA_reminder_due" />
<CheckBox <CheckBox
android:id="@+id/reminder_overdue" android:id="@+id/reminder_overdue"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:button="@drawable/btn_check_small"
android:text="@string/TEA_reminder_overdue" /> android:text="@string/TEA_reminder_overdue" />
<LinearLayout <LinearLayout
android:orientation="horizontal" android:orientation="horizontal"
@ -178,13 +333,14 @@
android:id="@+id/reminder_random" android:id="@+id/reminder_random"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:button="@drawable/btn_check_small"
android:text="@string/TEA_reminder_random" /> android:text="@string/TEA_reminder_random" />
<Spinner <Spinner
android:id="@+id/reminder_random_interval" android:id="@+id/reminder_random_interval"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
</LinearLayout> </LinearLayout>
<!-- reminder mode --> <!-- reminder mode -->
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -195,14 +351,26 @@
android:id="@+id/reminder_alarm" android:id="@+id/reminder_alarm"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<!-- add-ons -->
<!-- separator --> <LinearLayout
<View android:id="@+id/addons_alarms"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="1dip" android:layout_height="wrap_content"
android:padding="5dip" android:orientation="vertical" />
android:background="@android:drawable/divider_horizontal_dark" /> </LinearLayout>
</ScrollView>
<!-- ======================================================= tab: more == -->
<ScrollView
android:id="@+id/tab_more"
android:layout_above="@id/edit_footer"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:padding="4dip"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- hide until --> <!-- hide until -->
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -213,72 +381,25 @@
android:id="@+id/hideUntil" android:id="@+id/hideUntil"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<!-- add-ons --> <!-- add-ons -->
<LinearLayout android:id="@+id/tab_extra_addons"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
<!-- buttons -->
<LinearLayout <LinearLayout
android:orientation="horizontal" android:id="@+id/addons_more"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginTop="10dip"
android:padding="5dip"
android:background="@drawable/edit_header"
android:baselineAligned="false">
<ImageButton
android:id="@+id/save_extra"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/tango_save" />
<ImageButton
android:id="@+id/discard_extra"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/tango_stop" />
</LinearLayout>
</LinearLayout>
</ScrollView>
<!-- ===================================================== tab: add-ons == -->
<LinearLayout
android:id="@+id/tab_addons"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical"> android:orientation="vertical">
<LinearLayout
<ScrollView android:id="@+id/addons_empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="100">
<!-- add-ons -->
<LinearLayout android:id="@+id/tab_addons_addons"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout android:id="@+id/addons_empty"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:layout_weight="100" android:layout_weight="100"
android:gravity="center" android:gravity="center"
android:visibility="gone" android:visibility="gone"
android:orientation="vertical"> android:orientation="vertical">
<ImageView <ImageView
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="20dip" android:padding="20dip"
android:src="@drawable/icon_pp" /> android:src="@drawable/icon_pp" />
<TextView <TextView
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -286,44 +407,16 @@
android:padding="10dip" android:padding="10dip"
android:gravity="center" android:gravity="center"
style="@style/TextAppearance.TLA_NoItems" /> style="@style/TextAppearance.TLA_NoItems" />
<Button
<Button android:id="@+id/addons_button" android:id="@+id/addons_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="10dip" android:padding="10dip"
android:text="@string/TEA_addons_button" /> android:text="@string/TEA_addons_button" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginTop="10dip"
android:padding="5dip"
android:orientation="horizontal"
android:background="@drawable/edit_header"
android:baselineAligned="false">
<ImageButton
android:id="@+id/save_addons"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/tango_save" />
<ImageButton
android:id="@+id/discard_addons"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/tango_stop" />
</LinearLayout> </LinearLayout>
</ScrollView>
</LinearLayout>
</FrameLayout> </RelativeLayout>

@ -24,11 +24,5 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:padding="5dip"
android:background="@android:drawable/divider_horizontal_dark" />
</merge> </merge>

@ -22,5 +22,7 @@
<color name="view_table_values">#ffbbbbbb</color> <color name="view_table_values">#ffbbbbbb</color>
<color name="view_table_overdue">#ffff0000</color> <color name="view_table_overdue">#ffff0000</color>
<color name="task_edit_selected">#438cb6</color>
</resources> </resources>

@ -88,7 +88,7 @@
<string name="actfm_EPA_assign_custom">Custom...</string> <string name="actfm_EPA_assign_custom">Custom...</string>
<!-- task sharing dialog: shared with label --> <!-- task sharing dialog: shared with label -->
<string name="actfm_EPA_share_with">Shared With:</string> <string name="actfm_EPA_share_with">Add Collaborators:</string>
<!-- task sharing dialog: assigned hint --> <!-- task sharing dialog: assigned hint -->
<string name="actfm_EPA_assigned_hint">Contact Name</string> <string name="actfm_EPA_assigned_hint">Contact Name</string>

@ -230,10 +230,13 @@
<string name="TEA_tab_basic">Basic</string> <string name="TEA_tab_basic">Basic</string>
<!-- Second Tab - extra details --> <!-- Second Tab - extra details -->
<string name="TEA_tab_extra">Advanced</string> <string name="TEA_tab_share">Share</string>
<!-- Second Tab - extra details -->
<string name="TEA_tab_alarms">Alarms</string>
<!-- Third Tab - add-ons --> <!-- Third Tab - add-ons -->
<string name="TEA_tab_addons">Add-ons</string> <string name="TEA_tab_more">More</string>
<!-- Task title label --> <!-- Task title label -->
<string name="TEA_title_label">Title</string> <string name="TEA_title_label">Title</string>
@ -251,7 +254,7 @@
<string name="TEA_urgency_specific_time">At specific time?</string> <string name="TEA_urgency_specific_time">At specific time?</string>
<!-- Task urgency specific time title when specific time false --> <!-- Task urgency specific time title when specific time false -->
<string name="TEA_urgency_time_none">No Time Set</string> <string name="TEA_urgency_none">None</string>
<!-- Task hide until label --> <!-- Task hide until label -->
<string name="TEA_hideUntil_label">Hide Until</string> <string name="TEA_hideUntil_label">Hide Until</string>
@ -294,12 +297,14 @@
<string-array name="TEA_urgency"> <string-array name="TEA_urgency">
<!-- urgency: labels for edit page. item #4 -> auto filled --> <!-- urgency: labels for edit page. item #4 -> auto filled -->
<item>No Deadline</item>
<item>Specific Day/Time</item> <item>Specific Day/Time</item>
<item>Today</item> <item>Today</item>
<item>Tomorrow</item> <item>Tomorrow</item>
<item>(day after)</item> <item>(day after)</item>
<item>Next Week</item> <item>Next Week</item>
<item>No Deadline</item> <item>In Two Weeks</item>
<item>Next Month</item>
</string-array> </string-array>
<string-array name="TEA_hideUntil"> <string-array name="TEA_hideUntil">

@ -7,16 +7,16 @@
<!-- =============================================== task edit activity == --> <!-- =============================================== task edit activity == -->
<!-- Task Edit: Reminder header label --> <!-- Task Edit: Reminder header label -->
<string name="TEA_reminder_label">Remind me...</string> <string name="TEA_reminder_label">Remind Me:</string>
<!-- Task Edit: Reminder @ deadline --> <!-- Task Edit: Reminder @ deadline -->
<string name="TEA_reminder_due">... when task is due</string> <string name="TEA_reminder_due">When task is due</string>
<!-- Task Edit: Reminder after deadline --> <!-- Task Edit: Reminder after deadline -->
<string name="TEA_reminder_overdue">... when task is overdue</string> <string name="TEA_reminder_overdue">When task is overdue</string>
<!-- Task Edit: Reminder at random times (%s => time plural)--> <!-- Task Edit: Reminder at random times (%s => time plural)-->
<string name="TEA_reminder_random">... randomly once</string> <string name="TEA_reminder_random">Randomly once</string>
<!-- Task Edit: Reminder alarm clock label --> <!-- Task Edit: Reminder alarm clock label -->
<string name="TEA_reminder_alarm_label">Ring/Vibrate Type:</string> <string name="TEA_reminder_alarm_label">Ring/Vibrate Type:</string>

@ -51,6 +51,13 @@
<item name="android:textColor">#000000</item> <item name="android:textColor">#000000</item>
</style> </style>
<!-- =============================================== TaskEditActivity == -->
<style name="TextAppearance.TEA_action">
<item name="android:textSize">16sp</item>
<item name="android:textColor">#ffffff</item>
</style>
<!-- ==================================================== TaskAdapter == --> <!-- ==================================================== TaskAdapter == -->
<style name="TextAppearance.TAd_ItemTitle"> <style name="TextAppearance.TAd_ItemTitle">

File diff suppressed because it is too large Load Diff

@ -68,11 +68,20 @@ public class ContactListAdapter extends CursorAdapter {
@Override @Override
public void bindView(View view, Context context, Cursor cursor) { public void bindView(View view, Context context, Cursor cursor) {
TextView text = (TextView) view.findViewById(android.R.id.text1); TextView text1 = (TextView) view.findViewById(android.R.id.text1);
TextView text2 = (TextView) view.findViewById(android.R.id.text2);
ImageView imageView = (ImageView) view.findViewById(android.R.id.icon); ImageView imageView = (ImageView) view.findViewById(android.R.id.icon);
if(cursor.getColumnNames().length == PEOPLE_PROJECTION.length) { if(cursor.getColumnNames().length == PEOPLE_PROJECTION.length) {
text.setText(convertToString(cursor)); int name = cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
int email = cursor.getColumnIndexOrThrow(Email.DATA);
if(cursor.isNull(name)) {
text1.setText(cursor.getString(email));
text2.setText("");
} else {
text1.setText(cursor.getString(name));
text2.setText(cursor.getString(email));
}
imageView.setImageResource(android.R.drawable.ic_menu_gallery); imageView.setImageResource(android.R.drawable.ic_menu_gallery);
Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, cursor.getLong(0)); Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, cursor.getLong(0));
imageView.setTag(uri); imageView.setTag(uri);
@ -80,7 +89,7 @@ public class ContactListAdapter extends CursorAdapter {
ciTask.execute(uri); ciTask.execute(uri);
} else { } else {
int name = cursor.getColumnIndexOrThrow(TagData.NAME.name); int name = cursor.getColumnIndexOrThrow(TagData.NAME.name);
text.setText(cursor.getString(name)); text1.setText(cursor.getString(name));
imageView.setImageResource(R.drawable.med_tag); imageView.setImageResource(R.drawable.med_tag);
} }
} }

@ -126,7 +126,7 @@ public class DeadlineTimePickerDialog extends AlertDialog implements OnClickList
if(isChecked) if(isChecked)
updateTitle(); updateTitle();
else else
setTitle(R.string.TEA_urgency_time_none); setTitle(R.string.TEA_urgency_none);
} }
}; };
mHasTime.setOnCheckedChangeListener(listener); mHasTime.setOnCheckedChangeListener(listener);

@ -0,0 +1,34 @@
package com.todoroo.astrid.ui;
import android.app.Activity;
import android.widget.EditText;
import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.astrid.activity.TaskEditActivity.TaskEditControlSet;
import com.todoroo.astrid.data.Task;
/**
* Control set for mapping a Property to an EditText
* @author Tim Su <tim@todoroo.com>
*
*/
public class EditTextControlSet implements TaskEditControlSet {
private final EditText editText;
private final StringProperty property;
public EditTextControlSet(Activity activity, StringProperty property, int editText) {
this.property = property;
this.editText = (EditText)activity.findViewById(editText);
}
@Override
public void readFromTask(Task task) {
editText.setText(task.getValue(property));
}
@Override
public String writeToModel(Task task) {
task.setValue(property, editText.getText().toString());
return null;
}
}

@ -0,0 +1,251 @@
package com.todoroo.astrid.ui;
import java.util.Date;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnDismissListener;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TimePicker;
import com.timsu.astrid.R;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.activity.TaskEditActivity.TaskEditControlSet;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.ui.DeadlineTimePickerDialog.OnDeadlineTimeSetListener;
/**
* Control set for specifying when a task should be hidden
*
* @author Tim Su <tim@todoroo.com>
*
*/
public class HideUntilControlSet implements TaskEditControlSet,
OnItemSelectedListener, OnCancelListener,
OnDeadlineTimeSetListener {
private static final int SPECIFIC_DATE = -1;
private static final int EXISTING_TIME_UNSET = -2;
private final Spinner spinner;
private int previousSetting = Task.HIDE_UNTIL_NONE;
private long existingDate = EXISTING_TIME_UNSET;
private int existingDateHour = EXISTING_TIME_UNSET;
private int existingDateMinutes = EXISTING_TIME_UNSET;
private final Activity activity;
private boolean cancelled = false;
public HideUntilControlSet(Activity activity, int hideUntil) {
this.activity = activity;
this.spinner = (Spinner) activity.findViewById(hideUntil);
this.spinner.setOnItemSelectedListener(this);
}
private ArrayAdapter<HideUntilValue> adapter;
/**
* Container class for urgencies
*
* @author Tim Su <tim@todoroo.com>
*
*/
private class HideUntilValue {
public String label;
public int setting;
public long date;
public HideUntilValue(String label, int setting) {
this(label, setting, 0);
}
public HideUntilValue(String label, int setting, long date) {
this.label = label;
this.setting = setting;
this.date = date;
}
@Override
public String toString() {
return label;
}
}
private HideUntilValue[] createHideUntilList(long specificDate) {
// set up base values
String[] labels = activity.getResources().getStringArray(R.array.TEA_hideUntil);
HideUntilValue[] values = new HideUntilValue[labels.length];
values[0] = new HideUntilValue(labels[0], Task.HIDE_UNTIL_NONE);
values[1] = new HideUntilValue(labels[1], Task.HIDE_UNTIL_DUE);
values[2] = new HideUntilValue(labels[2], Task.HIDE_UNTIL_DAY_BEFORE);
values[3] = new HideUntilValue(labels[3], Task.HIDE_UNTIL_WEEK_BEFORE);
values[4] = new HideUntilValue(labels[4], Task.HIDE_UNTIL_SPECIFIC_DAY, -1);
if(specificDate > 0) {
HideUntilValue[] updated = new HideUntilValue[values.length + 1];
for(int i = 0; i < values.length; i++)
updated[i+1] = values[i];
Date hideUntilAsDate = new Date(specificDate);
if(hideUntilAsDate.getHours() == 0 && hideUntilAsDate.getMinutes() == 0 && hideUntilAsDate.getSeconds() == 0) {
updated[0] = new HideUntilValue(DateUtilities.getDateString(activity, new Date(specificDate)),
Task.HIDE_UNTIL_SPECIFIC_DAY, specificDate);
existingDate = specificDate;
existingDateHour = SPECIFIC_DATE;
} else {
updated[0] = new HideUntilValue(DateUtilities.getDateStringWithTime(activity, new Date(specificDate)),
Task.HIDE_UNTIL_SPECIFIC_DAY_TIME, specificDate);
existingDate = specificDate;
existingDateHour = hideUntilAsDate.getHours();
existingDateMinutes = hideUntilAsDate.getMinutes();
}
values = updated;
}
return values;
}
// --- listening for events
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// if specific date selected, show dialog
// ... at conclusion of dialog, update our list
HideUntilValue item = adapter.getItem(position);
if(item.date == SPECIFIC_DATE) {
customDate = new Date(existingDate == EXISTING_TIME_UNSET ? DateUtilities.now() : existingDate);
customDate.setSeconds(0);
final CalendarDialog calendarDialog = new CalendarDialog(activity, customDate);
calendarDialog.show();
calendarDialog.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss(DialogInterface arg0) {
if (!cancelled) {
setDate(calendarDialog);
}
cancelled = false;
}
});
calendarDialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
cancelled = true;
}
});
spinner.setSelection(previousSetting);
} else {
previousSetting = position;
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// ignore
}
Date customDate;
private void setDate(CalendarDialog calendarDialog) {
customDate = calendarDialog.getCalendarDate();
boolean specificTime = existingDateHour != SPECIFIC_DATE;
if(existingDateHour < 0) {
existingDateHour = customDate.getHours();
existingDateMinutes= customDate.getMinutes();
}
DeadlineTimePickerDialog timePicker = new DeadlineTimePickerDialog(activity, this,
existingDateHour, existingDateMinutes,
DateUtilities.is24HourFormat(activity),
specificTime);
timePicker.setOnCancelListener(this);
timePicker.show();
}
public void onTimeSet(TimePicker view, boolean hasTime, int hourOfDay, int minute) {
if(!hasTime) {
customDate.setHours(0);
customDate.setMinutes(0);
customDate.setSeconds(0);
} else {
customDate.setHours(hourOfDay);
customDate.setMinutes(minute);
existingDateHour = hourOfDay;
existingDateMinutes = minute;
}
customDateFinished();
}
@Override
public void onCancel(DialogInterface dialog) {
// user canceled, restore previous choice
spinner.setSelection(previousSetting);
}
private void customDateFinished() {
HideUntilValue[] list = createHideUntilList(customDate.getTime());
adapter = new ArrayAdapter<HideUntilValue>(
activity, android.R.layout.simple_spinner_item,
list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setSelection(0);
}
// --- setting up values
@Override
public void readFromTask(Task task) {
long date = task.getValue(Task.HIDE_UNTIL);
Date dueDay = new Date(task.getValue(Task.DUE_DATE)/1000L*1000L);
dueDay.setHours(0);
dueDay.setMinutes(0);
dueDay.setSeconds(0);
int selection = 0;
if(date == 0) {
selection = 0;
date = 0;
} else if(date == dueDay.getTime()) {
selection = 1;
date = 0;
} else if(date + DateUtilities.ONE_DAY == dueDay.getTime()) {
selection = 2;
date = 0;
} else if(date + DateUtilities.ONE_WEEK == dueDay.getTime()) {
selection = 3;
date = 0;
}
HideUntilValue[] list = createHideUntilList(date);
adapter = new ArrayAdapter<HideUntilValue>(
activity, android.R.layout.simple_spinner_item, list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setSelection(selection);
}
@Override
public String writeToModel(Task task) {
if(adapter == null || spinner == null)
return null;
HideUntilValue item = adapter.getItem(spinner.getSelectedItemPosition());
if(item == null)
return null;
long value = task.createHideUntil(item.setting, item.date);
task.setValue(Task.HIDE_UNTIL, value);
return null;
}
}

@ -0,0 +1,99 @@
package com.todoroo.astrid.ui;
import java.util.LinkedList;
import java.util.List;
import android.app.Activity;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.ToggleButton;
import com.timsu.astrid.R;
import com.todoroo.astrid.activity.TaskEditActivity.TaskEditControlSet;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.opencrx.OpencrxCoreUtils;
import com.todoroo.astrid.producteev.ProducteevUtilities;
/**
* Control Set for setting task importance
*
* @author Tim Su <tim@todoroo.com>
*
*/
public class ImportanceControlSet implements TaskEditControlSet {
private final List<CompoundButton> buttons = new LinkedList<CompoundButton>();
private final int[] colors;
public ImportanceControlSet(Activity activity, int containerId) {
LinearLayout layout = (LinearLayout)activity.findViewById(containerId);
colors = Task.getImportanceColors(activity.getResources());
int min = Task.IMPORTANCE_MOST;
int max = Task.IMPORTANCE_LEAST;
if(ProducteevUtilities.INSTANCE.isLoggedIn() || OpencrxCoreUtils.INSTANCE.isLoggedIn())
max = 5;
for(int i = min; i <= max; i++) {
final ToggleButton button = new ToggleButton(activity);
button.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 1));
StringBuilder label = new StringBuilder();
if(ProducteevUtilities.INSTANCE.isLoggedIn() || OpencrxCoreUtils.INSTANCE.isLoggedIn())
label.append(5 - i).append("\n\u2605"); //$NON-NLS-1$
else {
for(int j = Task.IMPORTANCE_LEAST; j >= i; j--)
label.append('!');
}
button.setTextColor(colors[i]);
button.setTextOff(label);
button.setTextOn(label);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
setImportance((Integer)button.getTag());
}
});
button.setTag(i);
buttons.add(button);
layout.addView(button);
}
}
public void setImportance(Integer i) {
for(CompoundButton b : buttons) {
if(b.getTag() == i) {
b.setTextSize(24);
b.setChecked(true);
b.setBackgroundResource(R.drawable.btn_selected);
} else {
b.setTextSize(16);
b.setChecked(false);
b.setBackgroundResource(android.R.drawable.btn_default);
}
}
}
public Integer getImportance() {
for(CompoundButton b : buttons)
if(b.isChecked())
return (Integer) b.getTag();
return null;
}
@Override
public void readFromTask(Task task) {
setImportance(task.getValue(Task.IMPORTANCE));
}
@Override
public String writeToModel(Task task) {
if(getImportance() != null)
task.setValue(Task.IMPORTANCE, getImportance());
return null;
}
}

@ -0,0 +1,90 @@
package com.todoroo.astrid.ui;
import android.app.Activity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.Spinner;
import com.timsu.astrid.R;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.activity.TaskEditActivity.TaskEditControlSet;
import com.todoroo.astrid.data.Task;
/**
* Control set dealing with random reminder settings
*
* @author Tim Su <tim@todoroo.com>
*
*/
public class RandomReminderControlSet implements TaskEditControlSet {
/** default interval for spinner if date is unselected */
private final long DEFAULT_INTERVAL = DateUtilities.ONE_WEEK * 2;
private final CheckBox settingCheckbox;
private final Spinner periodSpinner;
private boolean periodSpinnerInitialized = false;
private final int[] hours;
public RandomReminderControlSet(Activity activity, int settingCheckboxId, int periodButtonId) {
settingCheckbox = (CheckBox)activity.findViewById(settingCheckboxId);
periodSpinner = (Spinner)activity.findViewById(periodButtonId);
periodSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
if(periodSpinnerInitialized)
settingCheckbox.setChecked(true);
periodSpinnerInitialized = true;
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// ignore
}
});
// create adapter
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
activity, android.R.layout.simple_spinner_item,
activity.getResources().getStringArray(R.array.TEA_reminder_random));
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
periodSpinner.setAdapter(adapter);
// create hour array
String[] hourStrings = activity.getResources().getStringArray(R.array.TEA_reminder_random_hours);
hours = new int[hourStrings.length];
for(int i = 0; i < hours.length; i++)
hours[i] = Integer.parseInt(hourStrings[i]);
}
@Override
public void readFromTask(Task task) {
long time = task.getValue(Task.REMINDER_PERIOD);
boolean enabled = time > 0;
if(time <= 0) {
time = DEFAULT_INTERVAL;
}
int i;
for(i = 0; i < hours.length - 1; i++)
if(hours[i] * DateUtilities.ONE_HOUR >= time)
break;
periodSpinner.setSelection(i);
settingCheckbox.setChecked(enabled);
}
@Override
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;
}
}

@ -0,0 +1,84 @@
package com.todoroo.astrid.ui;
import android.app.Activity;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.Spinner;
import com.timsu.astrid.R;
import com.todoroo.astrid.activity.TaskEditActivity.TaskEditControlSet;
import com.todoroo.astrid.data.Task;
/**
* Control set dealing with reminder settings
*
* @author Tim Su <tim@todoroo.com>
*
*/
public class ReminderControlSet implements TaskEditControlSet {
private final CheckBox during, after;
private final Spinner mode;
public ReminderControlSet(Activity activity, int duringId, int afterId, int modeId) {
during = (CheckBox)activity.findViewById(duringId);
after = (CheckBox)activity.findViewById(afterId);
mode = (Spinner)activity.findViewById(modeId);
String[] list = new String[] {
activity.getString(R.string.TEA_reminder_mode_once),
activity.getString(R.string.TEA_reminder_mode_five),
activity.getString(R.string.TEA_reminder_mode_nonstop),
};
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
activity, android.R.layout.simple_spinner_item, list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
mode.setAdapter(adapter);
}
});
}
public void setValue(int flags) {
during.setChecked((flags & Task.NOTIFY_AT_DEADLINE) > 0);
after.setChecked((flags &
Task.NOTIFY_AFTER_DEADLINE) > 0);
if((flags & Task.NOTIFY_MODE_NONSTOP) > 0)
mode.setSelection(2);
else if((flags & Task.NOTIFY_MODE_FIVE) > 0)
mode.setSelection(1);
else
mode.setSelection(0);
}
public int getValue() {
int value = 0;
if(during.isChecked())
value |= Task.NOTIFY_AT_DEADLINE;
if(after.isChecked())
value |= Task.NOTIFY_AFTER_DEADLINE;
value &= ~(Task.NOTIFY_MODE_FIVE | Task.NOTIFY_MODE_NONSTOP);
if(mode.getSelectedItemPosition() == 2)
value |= Task.NOTIFY_MODE_NONSTOP;
else if(mode.getSelectedItemPosition() == 1)
value |= Task.NOTIFY_MODE_FIVE;
return value;
}
@Override
public void readFromTask(Task task) {
setValue(task.getValue(Task.REMINDER_FLAGS));
}
@Override
public String writeToModel(Task task) {
task.setValue(Task.REMINDER_FLAGS, getValue());
// clear snooze if task is being edited
task.setValue(Task.REMINDER_SNOOZE, 0L);
return null;
}
}

@ -0,0 +1,275 @@
package com.todoroo.astrid.ui;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.atomic.AtomicBoolean;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnDismissListener;
import android.text.format.DateUtils;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TimePicker;
import com.timsu.astrid.R;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.activity.TaskEditActivity.TaskEditControlSet;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.ui.DeadlineTimePickerDialog.OnDeadlineTimeSetListener;
public class UrgencyControlSet implements TaskEditControlSet,
OnDeadlineTimeSetListener {
private static final int SPECIFIC_DATE = -1;
private final Button dateButton;
private final Button timeButton;
private ArrayAdapter<UrgencyValue> urgencyAdapter;
private final Activity activity;
private long dueDateValue = 0;
private long dueTimeValue = 0;
/**
* Container class for urgencies
*
* @author Tim Su <tim@todoroo.com>
*
*/
private class UrgencyValue {
public String label;
public int setting;
public long dueDate;
public UrgencyValue(String label, int setting) {
this.label = label;
this.setting = setting;
dueDate = Task.createDueDate(setting, 0);
}
public UrgencyValue(String label, int setting, long dueDate) {
this.label = label;
this.setting = setting;
this.dueDate = dueDate;
}
@Override
public String toString() {
return label;
}
}
public UrgencyControlSet(Activity activity, int date, int time) {
this.activity = activity;
this.dateButton = (Button)activity.findViewById(date);
this.timeButton = (Button)activity.findViewById(time);
dateButton.setOnClickListener(dateButtonClick);
timeButton.setOnClickListener(timeButtonClick);
}
// --- events
View.OnClickListener dateButtonClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
showUrgencySpinner(dueDateValue);
}
};
View.OnClickListener timeButtonClick = new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean hasTime = Task.hasDueTime(dueTimeValue);
int hour = 18, minute = 0;
if(hasTime) {
Date date = new Date(dueTimeValue);
hour = date.getHours();
minute = date.getMinutes();
}
DeadlineTimePickerDialog timePicker = new DeadlineTimePickerDialog(activity,
UrgencyControlSet.this,
hour, minute,
DateUtilities.is24HourFormat(activity),
hasTime);
timePicker.show();
}
};
/**
* set up urgency adapter and picks the right selected item
* @param dueDate
*/
private void showUrgencySpinner(long dueDate) {
// set up base urgency list
String[] labels = activity.getResources().getStringArray(R.array.TEA_urgency);
UrgencyValue[] urgencyValues = new UrgencyValue[labels.length];
urgencyValues[0] = new UrgencyValue(labels[0],
Task.URGENCY_NONE);
urgencyValues[1] = new UrgencyValue(labels[1],
Task.URGENCY_SPECIFIC_DAY_TIME, SPECIFIC_DATE);
urgencyValues[2] = new UrgencyValue(labels[2],
Task.URGENCY_TODAY);
urgencyValues[3] = new UrgencyValue(labels[3],
Task.URGENCY_TOMORROW);
String dayAfterTomorrow = DateUtils.getDayOfWeekString(
new Date(DateUtilities.now() + 2 * DateUtilities.ONE_DAY).getDay() +
Calendar.SUNDAY, DateUtils.LENGTH_LONG);
urgencyValues[4] = new UrgencyValue(dayAfterTomorrow,
Task.URGENCY_DAY_AFTER);
urgencyValues[5] = new UrgencyValue(labels[5],
Task.URGENCY_NEXT_WEEK);
urgencyValues[6] = new UrgencyValue(labels[6],
Task.URGENCY_IN_TWO_WEEKS);
urgencyValues[7] = new UrgencyValue(labels[7],
Task.URGENCY_NEXT_MONTH);
// search for setting
int selection = -1;
for(int i = 0; i < urgencyValues.length; i++)
if(urgencyValues[i].dueDate == dueDate) {
selection = i;
break;
}
if(selection == -1) {
UrgencyValue[] updated = new UrgencyValue[labels.length + 1];
for(int i = 0; i < labels.length; i++)
updated[i+1] = urgencyValues[i];
if(Task.hasDueTime(dueDate)) {
Date dueDateAsDate = new Date(dueDate);
updated[0] = new UrgencyValue(DateUtilities.getDateStringWithTime(activity, dueDateAsDate),
Task.URGENCY_SPECIFIC_DAY_TIME, dueDate);
} else {
updated[0] = new UrgencyValue(DateUtilities.getDateString(activity, new Date(dueDate)),
Task.URGENCY_SPECIFIC_DAY, dueDate);
}
selection = 0;
urgencyValues = updated;
}
urgencyAdapter = new ArrayAdapter<UrgencyValue>(
activity, android.R.layout.simple_dropdown_item_1line,
urgencyValues);
new AlertDialog.Builder(activity)
.setTitle(R.string.TEA_urgency_label)
.setAdapter(urgencyAdapter, spinnerClickListener)
.setIcon(R.drawable.gl_date_blue)
.show().setOwnerActivity(activity);
}
DialogInterface.OnClickListener spinnerClickListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int position) {
UrgencyValue item = urgencyAdapter.getItem(position);
if(item.dueDate == SPECIFIC_DATE) {
customSetting = item.setting;
Date date = new Date(dueDateValue == 0 ? DateUtilities.now() : dueDateValue);
date.setSeconds(0);
final CalendarDialog calendarDialog = new CalendarDialog(activity, date);
final AtomicBoolean cancelled = new AtomicBoolean(false);
calendarDialog.show();
calendarDialog.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss(DialogInterface arg0) {
if (!cancelled.get())
setDateFromCalendar(calendarDialog);
}
});
calendarDialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface arg0) {
cancelled.set(true);
}
});
} else {
dueDateValue = item.dueDate;
if(dueDateValue == 0)
dueTimeValue = 0;
updateButtons();
}
}
};
// --- date setting logic
int customSetting;
private void setDateFromCalendar(CalendarDialog calendarDialog) {
Date date = calendarDialog.getCalendarDate();
date.setMinutes(0);
dueDateValue = Task.createDueDate(customSetting, date.getTime());
updateButtons();
}
public void onTimeSet(TimePicker view, boolean hasTime, int hourOfDay, int minute) {
if(!hasTime)
dueTimeValue = 0;
else {
Date date = new Date();
date.setHours(hourOfDay);
date.setMinutes(minute);
date.setSeconds(0);
dueTimeValue = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, date.getTime());
if(dueDateValue == 0)
dueDateValue = DateUtilities.now();
}
updateButtons();
}
private void updateButtons() {
if(dueDateValue == 0) {
dateButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.gl_date, 0, 0, 0);
dateButton.setText(R.string.TEA_urgency_none);
} else {
dateButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.gl_date_blue, 0, 0, 0);
dateButton.setText(DateUtilities.getDateString(activity, new Date(dueDateValue)));
}
if(dueTimeValue == 0 || !Task.hasDueTime(dueTimeValue)) {
timeButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.gl_time, 0, 0, 0);
timeButton.setText(R.string.TEA_urgency_none);
} else {
timeButton.setCompoundDrawablesWithIntrinsicBounds(R.drawable.gl_time_blue, 0, 0, 0);
timeButton.setText(DateUtilities.getTimeString(activity, new Date(dueTimeValue)));
}
}
// --- setting up values
@Override
public void readFromTask(Task task) {
dueTimeValue = dueDateValue = task.getValue(Task.DUE_DATE);
updateButtons();
}
@Override
public String writeToModel(Task task) {
Date date = new Date(dueDateValue);
if(dueTimeValue > 0) {
Date time = new Date(dueTimeValue);
date.setHours(time.getHours());
date.setMinutes(time.getMinutes());
date.setSeconds(time.getSeconds());
} else {
date.setTime(Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, dueDateValue));
}
task.setValue(Task.DUE_DATE, date.getTime());
return null;
}
}
Loading…
Cancel
Save