diff --git a/src/androidTest/java/com/todoroo/astrid/reminders/NotifyAtDeadlineTest.java b/src/androidTest/java/com/todoroo/astrid/reminders/NotifyAtDeadlineTest.java
index 0b570613a..e28e6bb39 100644
--- a/src/androidTest/java/com/todoroo/astrid/reminders/NotifyAtDeadlineTest.java
+++ b/src/androidTest/java/com/todoroo/astrid/reminders/NotifyAtDeadlineTest.java
@@ -19,7 +19,7 @@ public class NotifyAtDeadlineTest extends AndroidTestCase {
@Override
public void setUp() {
- Preferences preferences = new Preferences(getContext(), null, null);
+ Preferences preferences = new Preferences(getContext(), null);
reminderService = new ReminderService(getContext(), preferences, mock(AlarmManager.class));
freezeAt(new DateTime(2014, 1, 24, 17, 23, 37));
}
diff --git a/src/androidTest/java/com/todoroo/astrid/service/TitleParserTest.java b/src/androidTest/java/com/todoroo/astrid/service/TitleParserTest.java
index 6572577e0..3e5b7b5ac 100644
--- a/src/androidTest/java/com/todoroo/astrid/service/TitleParserTest.java
+++ b/src/androidTest/java/com/todoroo/astrid/service/TitleParserTest.java
@@ -233,14 +233,14 @@ public class TitleParserTest extends DatabaseTestCase {
String title = "Jog " + acceptedString;
task.setTitle(title); //test at end of task. should set importance.
taskService.createWithValues(task, null, title);
- assertEquals((int)task.getImportance(), Task.IMPORTANCE_LEAST);
+ assertEquals((int)task.getImportance(), Task.IMPORTANCE_NONE);
}
for (String acceptedString:acceptedStrings){
task = new Task();
String title = acceptedString + " jog";
task.setTitle(title); //test at beginning of task. should not set importance.
taskService.createWithValues(task, null, title);
- assertNotSame(task.getImportance(),Task.IMPORTANCE_LEAST);
+ assertNotSame(task.getImportance(),Task.IMPORTANCE_NONE);
}
}
diff --git a/src/generic/java/org/tasks/location/PlacePicker.java b/src/generic/java/org/tasks/location/PlacePicker.java
index 021ca0224..187568317 100644
--- a/src/generic/java/org/tasks/location/PlacePicker.java
+++ b/src/generic/java/org/tasks/location/PlacePicker.java
@@ -1,6 +1,7 @@
package org.tasks.location;
import android.app.Activity;
+import android.content.Context;
import android.content.Intent;
import org.tasks.preferences.Preferences;
@@ -10,7 +11,7 @@ public class PlacePicker {
return null;
}
- public static Geofence getPlace(Activity activity, Intent data, Preferences preferences) {
+ public static Geofence getPlace(Context context, Intent data, Preferences preferences) {
return null;
}
}
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index c5df556b3..9ed0ffe17 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -97,6 +97,10 @@
+
+
@@ -377,7 +381,7 @@
+ android:theme="@style/Theme.AppCompat.Dialog" />
controlSetMap = new HashMap<>();
- private FilesControlSet filesControlSet;
- private TimerActionControlSet timerAction;
+ private final Map controlSetFragments = new HashMap<>();
+ private final List displayedFragments = new ArrayList<>();
private EditNoteActivity editNotes;
- private HideUntilControlSet hideUntilControls;
- private ReminderControlSet reminderControlSet;
- @Bind(R.id.title) EditText title;
@Bind(R.id.pager) ViewPager mPager;
@Bind(R.id.updatesFooter) View commentsBar;
- @Bind(R.id.completeBox) CheckableImageView checkbox;
- @Bind(R.id.timer_container) LinearLayout timerShortcut;
@Bind(R.id.basic_controls) LinearLayout basicControls;
@Bind(R.id.edit_scroll) ScrollView scrollView;
@Bind(R.id.commentField) EditText commentField;
- private final List controls = Collections.synchronizedList(new ArrayList());
-
// --- other instance variables
/** true if editing started with a new task */
@@ -206,7 +176,6 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
private String uuid = RemoteModel.NO_UUID;
private boolean showEditComments;
- private boolean showTimerShortcut;
/*
* ======================================================================
@@ -231,9 +200,8 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
}
showEditComments = preferences.getBoolean(R.string.p_show_task_edit_comments, true);
- showTimerShortcut = preferences.getBoolean(R.string.p_show_timer_shortcut, false);
- getActivity().setResult(Activity.RESULT_OK);
+ getActivity().setResult(RESULT_OK);
}
/*
@@ -247,9 +215,90 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.task_edit_activity, container, false);
ButterKnife.bind(this, view);
+
+ loadItem(getActivity().getIntent());
+
+ registerFragment(R.string.TEA_ctrl_title_pref);
+ registerFragment(R.string.TEA_ctrl_when_pref);
+ registerFragment(R.string.TEA_ctrl_gcal);
+ registerFragment(R.string.TEA_ctrl_importance_pref);
+ registerFragment(R.string.TEA_ctrl_notes_pref);
+ registerFragment(R.string.TEA_ctrl_hide_until_pref);
+ registerFragment(R.string.TEA_ctrl_reminders_pref);
+ registerFragment(R.string.TEA_ctrl_files_pref);
+ registerFragment(R.string.TEA_ctrl_timer_pref);
+ registerFragment(R.string.TEA_ctrl_lists_pref);
+ registerFragment(R.string.TEA_ctrl_repeat_pref);
+
+ ArrayList controlOrder = BeastModePreferences.constructOrderedControlList(preferences, getActivity());
+ controlOrder.add(0, getString(R.string.TEA_ctrl_title_pref));
+
+ String hideAlwaysTrigger = getString(R.string.TEA_ctrl_hide_section_pref);
+
+ FragmentManager fragmentManager = getFragmentManager();
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+
+ for (String item : controlOrder) {
+ if (item.equals(hideAlwaysTrigger)) {
+ break;
+ }
+ Integer fragmentId = controlSetFragments.get(item);
+ if (fragmentId == null) {
+ Timber.e("Unknown task edit control %s", item);
+ continue;
+ }
+ displayedFragments.add(fragmentId);
+ if (fragmentManager.findFragmentByTag(item) == null) {
+ TaskEditControlFragment fragment = createFragment(controlSetFragments.get(item));
+ if (fragment != null) {
+ fragment.initialize(isNewTask, model);
+ fragmentTransaction.add(basicControls.getId(), fragment, item);
+ }
+ }
+ }
+
+ fragmentTransaction.commit();
+
+ if (!showEditComments) {
+ commentsBar.setVisibility(View.GONE);
+ }
+
return view;
}
+ private void registerFragment(int resId) {
+ controlSetFragments.put(getString(resId), resId);
+ }
+
+ private TaskEditControlFragment createFragment(int fragmentId) {
+ switch (fragmentId) {
+ case R.string.TEA_ctrl_title_pref:
+ return new EditTitleControlSet();
+ case R.string.TEA_ctrl_when_pref:
+ return new DeadlineControlSet();
+ case R.string.TEA_ctrl_importance_pref:
+ return new PriorityControlSet();
+ case R.string.TEA_ctrl_notes_pref:
+ return new DescriptionControlSet();
+ case R.string.TEA_ctrl_gcal:
+ return new CalendarControlSet();
+ case R.string.TEA_ctrl_hide_until_pref:
+ return new HideUntilControlSet();
+ case R.string.TEA_ctrl_reminders_pref:
+ return new ReminderControlSet();
+ case R.string.TEA_ctrl_files_pref:
+ return new FilesControlSet();
+ case R.string.TEA_ctrl_timer_pref:
+ return new TimerControlSet();
+ case R.string.TEA_ctrl_lists_pref:
+ return new TagsControlSet();
+ case R.string.TEA_ctrl_repeat_pref:
+ return new RepeatControlSet();
+ default:
+ throw new RuntimeException("Unsupported fragment");
+ }
+ }
+
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
@@ -267,81 +316,6 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
}
}
- // populate control set
- EditTitleControlSet editTitle = new EditTitleControlSet(
- taskService,
- getActivity(),
- title,
- checkbox);
- controls.add(editTitle);
-
- timerAction = new TimerActionControlSet(notificationManager, taskService, getActivity(), getView());
- controls.add(timerAction);
-
- TagsControlSet tagsControlSet = new TagsControlSet(metadataDao, tagDataDao, preferences, tagService, getActivity(), dialogBuilder);
- controls.add(tagsControlSet);
- controlSetMap.put(getString(R.string.TEA_ctrl_lists_pref), tagsControlSet);
-
- RepeatControlSet repeatControls = new RepeatControlSet(preferences, getActivity(), dialogBuilder);
- controlSetMap.put(getString(R.string.TEA_ctrl_repeat_pref), repeatControls);
-
- GCalControlSet gcalControl = new GCalControlSet(gcalHelper, preferences, this, permissionRequestor);
- controlSetMap.put(getString(R.string.TEA_ctrl_gcal), gcalControl);
-
- // The deadline control set contains the repeat controls and the
- // calendar controls.
- // NOTE: we add the gcalControl AFTER the
- // deadline control, because
- // otherwise the correct date may not be written to the calendar event.
- // Order matters!
- DeadlineControlSet deadlineControl = new DeadlineControlSet(getActivity(), preferences);
- controlSetMap.put(getString(R.string.TEA_ctrl_when_pref), deadlineControl);
- controls.add(repeatControls);
-
- repeatControls.addListener(editTitle);
- controls.add(deadlineControl);
- controls.add(gcalControl);
-
- PriorityControlSet importanceControl = new PriorityControlSet(getActivity());
- controls.add(importanceControl);
- importanceControl.addListener(editTitle);
- controlSetMap.put(getString(R.string.TEA_ctrl_importance_pref),
- importanceControl);
-
- DescriptionControlSet notesControlSet = new DescriptionControlSet(getActivity());
- controls.add(notesControlSet);
- controlSetMap.put(getString(R.string.TEA_ctrl_notes_pref),
- notesControlSet);
-
- reminderControlSet = new ReminderControlSet(alarmService, geofenceService, this, permissionRequestor, device);
- controls.add(reminderControlSet);
- controlSetMap.put(getString(R.string.TEA_ctrl_reminders_pref), reminderControlSet);
-
- hideUntilControls = new HideUntilControlSet(this);
- controls.add(hideUntilControls);
- controlSetMap.put(getString(R.string.TEA_ctrl_hide_until_pref), hideUntilControls);
-
- // TODO: Fix the fact that hideUntil doesn't update accordingly with date changes when lazy loaded. Until then, don't lazy load.
- hideUntilControls.getView();
-
- TimerControlSet timerControl = new TimerControlSet(preferences, getActivity(), dialogBuilder);
- timerAction.addListener(timerControl);
- controls.add(timerControl);
- controlSetMap.put(getString(R.string.TEA_ctrl_timer_pref), timerControl);
-
- filesControlSet = new FilesControlSet(preferences, taskAttachmentDao, this);
- controls.add(filesControlSet);
- controlSetMap.put(getString(R.string.TEA_ctrl_files_pref), filesControlSet);
-
- loadEditPageOrder();
-
- if (!showEditComments) {
- commentsBar.setVisibility(View.GONE);
- }
- if (!showTimerShortcut) {
- timerShortcut.setVisibility(View.GONE);
- }
-
// Load task data in background
new TaskEditBackgroundLoader().start();
}
@@ -349,7 +323,7 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
private void instantiateEditNotes() {
if (showEditComments) {
long idParam = getActivity().getIntent().getLongExtra(TOKEN_ID, -1L);
- editNotes = new EditNoteActivity(actFmCameraModule, preferences, metadataDao, userActivityDao,
+ editNotes = new EditNoteActivity(actFmCameraModule, metadataDao, userActivityDao,
taskService, this, getView(), idParam);
editNotes.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
@@ -373,12 +347,11 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
editNotes.loadViewForTaskID(idParam);
}
- if (timerAction != null && editNotes != null) {
- timerAction.removeListener(editNotes);
- timerAction.addListener(editNotes);
- }
-
if (editNotes != null) {
+ TimerControlSet timerControl = getTimerControl();
+ if (timerControl != null) {
+ timerControl.setEditNotes(editNotes);
+ }
editNotes.addListener(this);
}
@@ -406,40 +379,14 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
mPager.setCurrentItem(position);
}
- private void loadEditPageOrder() {
- ArrayList controlOrder = BeastModePreferences.constructOrderedControlList(preferences, getActivity());
- String[] itemOrder = controlOrder.toArray(new String[controlOrder.size()]);
-
- String hideAlwaysTrigger = getString(R.string.TEA_ctrl_hide_section_pref);
-
- Class> openControl = (Class>) getActivity().getIntent().getSerializableExtra(TOKEN_OPEN_CONTROL);
-
- for (String item : itemOrder) {
- if (item.equals(hideAlwaysTrigger)) {
- break; // As soon as we hit the hide section, we're done
- } else {
- View controlSet = null;
- TaskEditControlSet curr = controlSetMap.get(item);
-
- if (curr != null) {
- controlSet = curr.getView();
- }
-
- if (controlSet != null) {
- ImageView icon = (ImageView) controlSet.findViewById(R.id.icon);
- if (icon != null) {
- icon.setImageResource(curr.getIcon());
- }
- basicControls.addView(controlSet);
- }
-
- if (curr != null && curr.getClass().equals(openControl) && curr instanceof PopupControlSet) {
- curr.getView().performClick();
- }
- }
- }
+ public Task stopTimer() {
+ TimerPlugin.stopTimer(notificationManager, taskService, context, model);
+ return model;
+ }
- getActivity().getIntent().removeExtra(TOKEN_OPEN_CONTROL);
+ public Task startTimer() {
+ TimerPlugin.startTimer(notificationManager, taskService, context, model);
+ return model;
}
/**
@@ -538,61 +485,44 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
public void repopulateFromScratch(Intent intent) {
model = null;
uuid = RemoteModel.NO_UUID;
- populateFields(intent);
loadMoreContainer();
}
- /** Populate UI component values from the model */
- public void populateFields(Intent intent) {
- loadItem(intent);
-
- synchronized (controls) {
- for (TaskEditControlSet controlSet : controls) {
- controlSet.readFromTask(model);
- }
- }
+ private String getTitle() {
+ return getEditTitleControlSet().getTitle();
}
/** Save task model from values in UI components */
public void save(boolean onPause) {
+ String title = getTitle();
if (title == null) {
return;
}
- if (title.getText().length() > 0) {
+ if (title.length() > 0) {
model.setDeletionDate(0L);
}
- if (title.getText().length() == 0) {
+ if (title.length() == 0) {
return;
}
- synchronized (controls) {
- for (TaskEditControlSet controlSet : controls) {
- if (controlSet instanceof PopupControlSet) { // Save open control set
- PopupControlSet popup = (PopupControlSet) controlSet;
- Dialog d = popup.getDialog();
- if (d != null && d.isShowing()) {
- getActivity().getIntent().putExtra(TOKEN_OPEN_CONTROL, popup.getClass());
- }
- }
- controlSet.writeToModel(model);
+ if (!onPause) {
+ for (Integer fragmentId : displayedFragments) {
+ getFragment(fragmentId).apply(model);
}
- }
-
- boolean tagsChanged = Flags.check(Flags.TAGS_CHANGED);
- model.putTransitory(TaskService.TRANS_EDIT_SAVE, true); // TODO: not used?
- taskService.save(model);
+ taskService.save(model);
- if (!onPause) {
boolean taskEditActivity = (getActivity() instanceof TaskEditActivity);
+ boolean tagsChanged = Flags.check(Flags.TAGS_CHANGED);
+
if (taskEditActivity) {
Intent data = new Intent();
data.putExtra(TOKEN_TAGS_CHANGED, tagsChanged);
data.putExtra(TOKEN_ID, model.getId());
data.putExtra(TOKEN_UUID, model.getUuid());
- getActivity().setResult(Activity.RESULT_OK, data);
+ getActivity().setResult(RESULT_OK, data);
} else {
// Notify task list fragment in multi-column case
@@ -611,13 +541,29 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
removeExtrasFromIntent(getActivity().getIntent());
shouldSaveState = false;
getActivity().onBackPressed();
-
}
}
+ private EditTitleControlSet getEditTitleControlSet() {
+ return getFragment(R.string.TEA_ctrl_title_pref);
+ }
+
+ private FilesControlSet getFilesControlSet() {
+ return getFragment(R.string.TEA_ctrl_files_pref);
+ }
+
+ private TimerControlSet getTimerControl() {
+ return getFragment(R.string.TEA_ctrl_timer_pref);
+ }
+
+ @SuppressWarnings("unchecked")
+ private T getFragment(int tag) {
+ return (T) getFragmentManager().findFragmentByTag(getString(tag));
+ }
+
public boolean onKeyDown(int keyCode) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
- if(title.getText().length() == 0) {
+ if(getTitle().length() == 0) {
discardButtonClick();
} else {
saveButtonClick();
@@ -640,11 +586,11 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
}
if (activity instanceof TaskListActivity) {
- if (title.getText().length() == 0 && isNewTask && model != null && model.isSaved()) {
+ if (getTitle().length() == 0 && isNewTask && model != null && model.isSaved()) {
taskDeleter.delete(model);
}
} else if (activity instanceof TaskEditActivity) {
- if (title.getText().length() == 0 && isNewTask && model != null && model.isSaved()) {
+ if (getTitle().length() == 0 && isNewTask && model != null && model.isSaved()) {
taskDeleter.delete(model);
}
}
@@ -674,7 +620,7 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
shouldSaveState = false;
// abandon editing in this case
- if (title.getText().toString().trim().length() == 0 || TextUtils.isEmpty(model.getTitle())) {
+ if (getTitle().trim().length() == 0 || TextUtils.isEmpty(model.getTitle())) {
if (isNewTask) {
TimerPlugin.stopTimer(notificationManager, taskService, getActivity(), model);
taskDeleter.delete(model);
@@ -700,7 +646,7 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
Activity a = getActivity();
if (a instanceof TaskEditActivity) {
- getActivity().setResult(Activity.RESULT_OK);
+ getActivity().setResult(RESULT_OK);
getActivity().onBackPressed();
} else if (a instanceof TaskListActivity) {
discardButtonClick();
@@ -738,7 +684,7 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
deleteButtonClick();
return true;
case android.R.id.home:
- if (title.getText().toString().trim().length() == 0) {
+ if (getTitle().trim().length() == 0) {
discardButtonClick();
} else {
saveButtonClick();
@@ -768,59 +714,18 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
}
}
- @Override
- public void onStart() {
- super.onStart();
- populateFields(getActivity().getIntent());
- if (isNewTask) {
- title.requestFocus();
- title.setCursorVisible(true);
- getActivity().getWindow()
- .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
- | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
- }
- }
-
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (editNotes == null) {
instantiateEditNotes();
}
- if (requestCode == HideUntilControlSet.REQUEST_HIDE_UNTIL && resultCode == Activity.RESULT_OK) {
- long timestamp = data.getLongExtra(TimePickerActivity.EXTRA_TIMESTAMP, 0L);
- if (timestamp > 0) {
- hideUntilControls.setCustomDate(timestamp);
- } else {
- Timber.e("Invalid timestamp");
- }
- } else if (requestCode == ReminderControlSet.REQUEST_NEW_ALARM && resultCode == Activity.RESULT_OK) {
- long timestamp = data.getLongExtra(TimePickerActivity.EXTRA_TIMESTAMP, 0L);
- if (timestamp > 0) {
- reminderControlSet.addAlarmRow(timestamp);
- } else {
- Timber.e("Invalid timestamp");
- }
- } else if (requestCode == ReminderControlSet.REQUEST_LOCATION_REMINDER) {
- if (resultCode == Activity.RESULT_OK) {
- Geofence geofence = PlacePicker.getPlace(getActivity(), data, preferences);
- if (geofence != null) {
- reminderControlSet.addGeolocationReminder(geofence);
- } else {
- Timber.e("Invalid geofence");
- }
- }
- } else if (requestCode == REQUEST_CODE_RECORD && resultCode == Activity.RESULT_OK) {
+ if (requestCode == REQUEST_CODE_RECORD && resultCode == RESULT_OK) {
String recordedAudioPath = data.getStringExtra(AACRecordingActivity.RESULT_OUTFILE);
String recordedAudioName = data.getStringExtra(AACRecordingActivity.RESULT_FILENAME);
- filesControlSet.createNewFileAttachment(recordedAudioPath, recordedAudioName, TaskAttachment.FILE_TYPE_AUDIO + "m4a"); //$NON-NLS-1$
- } else if (requestCode == REQUEST_ADD_ATTACHMENT && resultCode == Activity.RESULT_OK) {
- String path = data.getStringExtra(AddAttachmentActivity.EXTRA_PATH);
- File file = new File(path);
- String extension = path.substring(path.lastIndexOf('.') + 1);
- filesControlSet.createNewFileAttachment(path, file.getName(), TaskAttachment.FILE_TYPE_IMAGE + extension);
+ getFilesControlSet().createNewFileAttachment(recordedAudioPath, recordedAudioName, TaskAttachment.FILE_TYPE_AUDIO + "m4a"); //$NON-NLS-1$
} else if (requestCode == REQUEST_CODE_CAMERA) {
- if (editNotes != null && resultCode == Activity.RESULT_OK) {
+ if (editNotes != null && resultCode == RESULT_OK) {
Uri uri = data.getParcelableExtra(CameraActivity.EXTRA_URI);
editNotes.setPictureUri(uri);
}
@@ -901,8 +806,16 @@ public final class TaskEditFragment extends InjectingFragment implements EditNot
}
private void hideKeyboard() {
- AndroidUtilities.hideSoftInputForViews(getActivity(), title, commentField);
- title.setCursorVisible(false);
+ getEditTitleControlSet().hideKeyboard();
+ AndroidUtilities.hideSoftInputForViews(getActivity(), commentField);
commentField.setCursorVisible(false);
}
+
+ public void onPriorityChange(int priority) {
+ getEditTitleControlSet().setPriority(priority);
+ }
+
+ public void onRepeatChanged(boolean repeat) {
+ getEditTitleControlSet().repeatChanged(repeat);
+ }
}
diff --git a/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.java b/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.java
index 45b20d91e..bd4d282c9 100644
--- a/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.java
+++ b/src/main/java/com/todoroo/astrid/adapter/TaskAdapter.java
@@ -391,11 +391,11 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
}
private void showFilesDialog(Task task) {
- FilesControlSet filesControlSet = new FilesControlSet(
- preferences, taskAttachmentDao, fragment);
- filesControlSet.hideAddAttachmentButton();
- filesControlSet.readFromTask(task);
- filesControlSet.getView().performClick();
+ // TODO: reimplement this
+// FilesControlSet filesControlSet = new FilesControlSet();
+// filesControlSet.hideAddAttachmentButton();
+// filesControlSet.readFromTask(task);
+// filesControlSet.getView().performClick();
}
/* ======================================================================
diff --git a/src/main/java/com/todoroo/astrid/core/DefaultsPreferences.java b/src/main/java/com/todoroo/astrid/core/DefaultsPreferences.java
index 68de8789e..0eed70a68 100644
--- a/src/main/java/com/todoroo/astrid/core/DefaultsPreferences.java
+++ b/src/main/java/com/todoroo/astrid/core/DefaultsPreferences.java
@@ -73,7 +73,9 @@ public class DefaultsPreferences extends InjectingPreferenceActivity {
}
private void startCalendarSelectionActivity() {
- startActivityForResult(new Intent(DefaultsPreferences.this, CalendarSelectionActivity.class), REQUEST_CALENDAR_SELECTION);
+ startActivityForResult(new Intent(DefaultsPreferences.this, CalendarSelectionActivity.class) {{
+ putExtra(CalendarSelectionActivity.EXTRA_SHOW_NONE, true);
+ }}, REQUEST_CALENDAR_SELECTION);
}
@Override
diff --git a/src/main/java/com/todoroo/astrid/dao/TagDataDao.java b/src/main/java/com/todoroo/astrid/dao/TagDataDao.java
index 787b6760a..9aa6a6ad9 100644
--- a/src/main/java/com/todoroo/astrid/dao/TagDataDao.java
+++ b/src/main/java/com/todoroo/astrid/dao/TagDataDao.java
@@ -55,6 +55,10 @@ public class TagDataDao {
.orderBy(Order.asc(TagData.ID)));
}
+ public TagData getByUuid(String uuid) {
+ return getByUuid(uuid, TagData.PROPERTIES);
+ }
+
public TagData getByUuid(String uuid, Property>... properties) {
return dao.getFirst(Query.select(properties).where(TagData.UUID.eq(uuid)));
}
diff --git a/src/main/java/com/todoroo/astrid/data/TagData.java b/src/main/java/com/todoroo/astrid/data/TagData.java
index 7516dec1b..c9a69d8d9 100644
--- a/src/main/java/com/todoroo/astrid/data/TagData.java
+++ b/src/main/java/com/todoroo/astrid/data/TagData.java
@@ -110,6 +110,7 @@ public final class TagData extends RemoteModel {
setValue(LAST_AUTOSYNC, lastAutosync);
}
+ // TODO: remove?
public String getUUID() {
return getValue(UUID);
}
diff --git a/src/main/java/com/todoroo/astrid/data/Task.java b/src/main/java/com/todoroo/astrid/data/Task.java
index ba0ebf83b..ea3aa7cd4 100644
--- a/src/main/java/com/todoroo/astrid/data/Task.java
+++ b/src/main/java/com/todoroo/astrid/data/Task.java
@@ -150,17 +150,6 @@ public class Task extends RemoteModel {
/**
* @return colors that correspond to importance values
*/
- public static int[] getImportanceColors(Resources r) {
- return new int[] {
- r.getColor(R.color.importance_1),
- r.getColor(R.color.importance_2),
- r.getColor(R.color.importance_3),
- r.getColor(R.color.importance_4)
- };
- }
-
- public static int IMPORTANCE_MOST = IMPORTANCE_DO_OR_DIE;
- public static int IMPORTANCE_LEAST = IMPORTANCE_NONE;
// --- defaults
@@ -544,10 +533,14 @@ public class Task extends RemoteModel {
return getValue(ESTIMATED_SECONDS);
}
- public void setELAPSED_SECONDS(Integer elapsedSeconds) {
+ public void setElapsedSeconds(Integer elapsedSeconds) {
setValue(ELAPSED_SECONDS, elapsedSeconds);
}
+ public void setEstimatedSeconds(Integer estimatedSeconds) {
+ setValue(ESTIMATED_SECONDS, estimatedSeconds);
+ }
+
public void setCalendarUri(String calendarUri) {
setValue(CALENDAR_URI, calendarUri);
}
diff --git a/src/main/java/com/todoroo/astrid/files/FilesControlSet.java b/src/main/java/com/todoroo/astrid/files/FilesControlSet.java
index ba6f878ad..c1bbe25ef 100644
--- a/src/main/java/com/todoroo/astrid/files/FilesControlSet.java
+++ b/src/main/java/com/todoroo/astrid/files/FilesControlSet.java
@@ -6,17 +6,20 @@
package com.todoroo.astrid.files;
import android.app.Activity;
-import android.app.Fragment;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
+import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
+import android.view.ViewGroup;
import android.webkit.MimeTypeMap;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -24,46 +27,112 @@ import android.widget.Toast;
import com.todoroo.andlib.data.Callback;
import com.todoroo.andlib.utility.AndroidUtilities;
-import com.todoroo.astrid.activity.TaskEditFragment;
import com.todoroo.astrid.dao.TaskAttachmentDao;
import com.todoroo.astrid.data.SyncFlags;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.TaskAttachment;
-import com.todoroo.astrid.helper.TaskEditControlSetBase;
import org.tasks.R;
import org.tasks.activities.AddAttachmentActivity;
import org.tasks.dialogs.DialogBuilder;
-import org.tasks.preferences.ActivityPreferences;
+import org.tasks.injection.ForActivity;
+import org.tasks.ui.TaskEditControlFragment;
import java.io.File;
import java.util.ArrayList;
+import java.util.List;
+import javax.inject.Inject;
+
+import butterknife.Bind;
+import butterknife.OnClick;
import timber.log.Timber;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastLollipop;
-public class FilesControlSet extends TaskEditControlSetBase {
-
- private final ArrayList files = new ArrayList<>();
- private final LayoutInflater inflater;
- private final TaskAttachmentDao taskAttachmentDao;
- private final Fragment fragment;
- private final DialogBuilder dialogBuilder;
- private LinearLayout attachmentContainer;
- private TextView addAttachment;
-
- public FilesControlSet(ActivityPreferences preferences, TaskAttachmentDao taskAttachmentDao,
- Fragment fragment) {
- super(fragment.getActivity(), R.layout.control_set_files);
- this.taskAttachmentDao = taskAttachmentDao;
- this.fragment = fragment;
- this.dialogBuilder = new DialogBuilder(activity, preferences);
- inflater = (LayoutInflater) activity.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
+public class FilesControlSet extends TaskEditControlFragment {
+
+ private static final int REQUEST_ADD_ATTACHMENT = 50;
+ private static final String EXTRA_UUID = "extra_uuid";
+
+ @Inject TaskAttachmentDao taskAttachmentDao;
+ @Inject DialogBuilder dialogBuilder;
+ @Inject @ForActivity Context context;
+
+ @Bind(R.id.attachment_container) LinearLayout attachmentContainer;
+ @Bind(R.id.add_attachment) TextView addAttachment;
+
+ private String taskUuid;
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = super.onCreateView(inflater, container, savedInstanceState);
+
+ if (savedInstanceState != null) {
+ taskUuid = savedInstanceState.getString(EXTRA_UUID);
+ }
+
+ final List files = new ArrayList<>();
+ taskAttachmentDao.getAttachments(taskUuid, new Callback() {
+ @Override
+ public void apply(TaskAttachment attachment) {
+ files.add(attachment);
+ addAttachment(attachment);
+ }
+ });
+ validateFiles(files);
+ return view;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putString(EXTRA_UUID, taskUuid);
+ }
+
+ @OnClick(R.id.add_attachment)
+ void addAttachment(View view) {
+ startActivityForResult(new Intent(context, AddAttachmentActivity.class), REQUEST_ADD_ATTACHMENT);
+ }
+
+ @Override
+ protected int getLayout() {
+ return R.layout.control_set_files;
+ }
+
+ @Override
+ public int getIcon() {
+ return R.drawable.ic_attachment_24dp;
+ }
+
+ @Override
+ public void initialize(boolean isNewTask, Task task) {
+ taskUuid = task.getUuid();
+ }
+
+ @Override
+ public void apply(Task task) {
+
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_ADD_ATTACHMENT) {
+ if (resultCode == Activity.RESULT_OK) {
+ String path = data.getStringExtra(AddAttachmentActivity.EXTRA_PATH);
+ File file = new File(path);
+ String extension = path.substring(path.lastIndexOf('.') + 1);
+ createNewFileAttachment(path, file.getName(), TaskAttachment.FILE_TYPE_IMAGE + extension);
+ }
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
}
private void addAttachment(TaskAttachment taskAttachment) {
- View fileRow = inflater.inflate(R.layout.file_row, null);
+ View fileRow = getActivity().getLayoutInflater().inflate(R.layout.file_row, null);
fileRow.setTag(taskAttachment);
attachmentContainer.addView(fileRow);
addAttachment(taskAttachment, fileRow);
@@ -71,7 +140,6 @@ public class FilesControlSet extends TaskEditControlSetBase {
private void addAttachment(final TaskAttachment taskAttachment, final View fileRow) {
TextView nameView = (TextView) fileRow.findViewById(R.id.file_text);
- nameView.setTextColor(themeColor);
String name = taskAttachment.getName();
nameView.setText(name);
nameView.setOnClickListener(new OnClickListener() {
@@ -93,7 +161,6 @@ public class FilesControlSet extends TaskEditControlSetBase {
File f = new File(taskAttachment.getFilePath());
f.delete();
}
- files.remove(taskAttachment);
attachmentContainer.removeView(fileRow);
}
})
@@ -103,28 +170,7 @@ public class FilesControlSet extends TaskEditControlSetBase {
});
}
- @Override
- public int getIcon() {
- return R.drawable.ic_attachment_24dp;
- }
-
- public void refreshMetadata() {
- if (model != null) {
- files.clear();
- taskAttachmentDao.getAttachments(model.getUuid(), new Callback() {
- @Override
- public void apply(TaskAttachment attachment) {
- files.add(attachment);
- }
- });
- validateFiles();
- if (initialized) {
- afterInflate();
- }
- }
- }
-
- private void validateFiles() {
+ private void validateFiles(List files) {
for (int i = 0; i < files.size(); i++) {
TaskAttachment m = files.get(i);
if (m.containsNonNullValue(TaskAttachment.FILE_PATH)) {
@@ -140,34 +186,6 @@ public class FilesControlSet extends TaskEditControlSetBase {
}
}
- @Override
- protected void readFromTaskOnInitialize() {
- attachmentContainer.removeAllViews();
- taskAttachmentDao.getAttachments(model.getUuid(), new Callback() {
- @Override
- public void apply(TaskAttachment entry) {
- addAttachment(entry);
- }
- });
- }
-
- @Override
- protected void writeToModelAfterInitialized(Task task) {
- // Nothing to write
- }
-
- @Override
- protected void afterInflate() {
- attachmentContainer = (LinearLayout) getView().findViewById(R.id.attachment_container);
- addAttachment = (TextView) getView().findViewById(R.id.add_attachment);
- addAttachment.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- fragment.startActivityForResult(new Intent(activity, AddAttachmentActivity.class), TaskEditFragment.REQUEST_ADD_ATTACHMENT);
- }
- });
- }
-
public void hideAddAttachmentButton() {
addAttachment.setVisibility(View.GONE);
}
@@ -210,10 +228,10 @@ public class FilesControlSet extends TaskEditControlSetBase {
if (atLeastLollipop()) {
intent.setClipData(ClipData.newRawUri(null, uri));
}
- activity.startActivity(intent);
+ getActivity().startActivity(intent);
} catch(ActivityNotFoundException e) {
Timber.e(e, e.getMessage());
- Toast.makeText(activity, R.string.no_application_found, Toast.LENGTH_SHORT).show();
+ Toast.makeText(context, R.string.no_application_found, Toast.LENGTH_SHORT).show();
}
} else {
String useType = fileType;
@@ -240,17 +258,16 @@ public class FilesControlSet extends TaskEditControlSetBase {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(file)), type);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- activity.startActivity(intent);
+ getActivity().startActivity(intent);
} catch (ActivityNotFoundException e) {
Timber.e(e, e.getMessage());
- Toast.makeText(activity, R.string.file_type_unhandled, Toast.LENGTH_LONG).show();
+ Toast.makeText(context, R.string.file_type_unhandled, Toast.LENGTH_LONG).show();
}
}
public void createNewFileAttachment(String path, String fileName, String fileType) {
- TaskAttachment attachment = TaskAttachment.createNewAttachment(model.getUuid(), path, fileName, fileType);
+ TaskAttachment attachment = TaskAttachment.createNewAttachment(taskUuid, path, fileName, fileType);
taskAttachmentDao.createNew(attachment);
- refreshMetadata();
addAttachment(attachment);
}
}
diff --git a/src/main/java/com/todoroo/astrid/gcal/Calendars.java b/src/main/java/com/todoroo/astrid/gcal/Calendars.java
index e56f54e26..ceb45c7be 100644
--- a/src/main/java/com/todoroo/astrid/gcal/Calendars.java
+++ b/src/main/java/com/todoroo/astrid/gcal/Calendars.java
@@ -19,7 +19,6 @@ public class Calendars {
public static final String ID_COLUMN_NAME = "_id";
public static final String CALENDARS_DISPLAY_COL = CalendarContract.Calendars.CALENDAR_DISPLAY_NAME;
- public static final String CALENDARS_ACCESS_LEVEL_COL = CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL;
public static final String EVENTS_DTSTART_COL = CalendarContract.Events.DTSTART;
public static final String EVENTS_DTEND_COL = CalendarContract.Events.DTEND;
public static final String EVENTS_NAME_COL = CalendarContract.Events.TITLE;
@@ -34,7 +33,7 @@ public class Calendars {
// Only show calendars that the user can modify. Access level 500
// corresponds to Calendars.CONTRIBUTOR_ACCESS
- public static final String CALENDARS_WHERE = CALENDARS_ACCESS_LEVEL_COL + ">= 500";
+ public static final String CALENDARS_WHERE = CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL + ">= 500";
public static final String CALENDARS_SORT = CALENDARS_DISPLAY_COL + " ASC";
diff --git a/src/main/java/com/todoroo/astrid/gcal/GCalControlSet.java b/src/main/java/com/todoroo/astrid/gcal/GCalControlSet.java
deleted file mode 100644
index 7af590c5a..000000000
--- a/src/main/java/com/todoroo/astrid/gcal/GCalControlSet.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/**
- * Copyright (c) 2012 Todoroo Inc
- *
- * See the file "LICENSE" for the full license governing this code.
- */
-package com.todoroo.astrid.gcal;
-
-import android.app.FragmentManager;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.text.TextUtils;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.todoroo.astrid.activity.TaskEditFragment;
-import com.todoroo.astrid.data.Task;
-import com.todoroo.astrid.helper.TaskEditControlSetBase;
-
-import org.tasks.R;
-import org.tasks.activities.CalendarSelectionDialog;
-import org.tasks.preferences.PermissionRequestor;
-import org.tasks.preferences.Preferences;
-
-import timber.log.Timber;
-
-/**
- * Control Set for managing repeats
- *
- * @author Tim Su
- *
- */
-public class GCalControlSet extends TaskEditControlSetBase implements CalendarSelectionDialog.CalendarSelectionHandler {
-
- private static final String FRAG_TAG_CALENDAR_SELECTION = "frag_tag_calendar_selection";
-
- // --- instance variables
-
- private final GCalHelper gcal;
- private Preferences preferences;
- private final TaskEditFragment taskEditFragment;
- private PermissionRequestor permissionRequestor;
-
- private Uri calendarUri = null;
-
- private boolean hasEvent = false;
- private TextView calendar;
- private ImageView cancelButton;
- private String calendarId;
- private String calendarName;
-
- public GCalControlSet(GCalHelper gcal, Preferences preferences,
- TaskEditFragment taskEditFragment, PermissionRequestor permissionRequestor) {
- super(taskEditFragment.getActivity(), R.layout.control_set_gcal_display);
- this.gcal = gcal;
- this.preferences = preferences;
- this.taskEditFragment = taskEditFragment;
- this.permissionRequestor = permissionRequestor;
- }
-
- @Override
- protected void afterInflate() {
- View view = getView();
- calendar = (TextView) view.findViewById(R.id.calendar_display_which);
- cancelButton = (ImageView) view.findViewById(R.id.clear);
- calendar.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (hasEvent) {
- viewCalendarEvent();
- } else {
- // TODO: show calendar selection if permission has just been granted
- // can't do this now because the app saves state when TEA is paused,
- // which triggers calendar creation if there is a default add to calendar.
- if (permissionRequestor.requestCalendarPermissions()) {
- showCalendarSelectionDialog();
- }
- }
- }
- });
- cancelButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- clearEvent();
- refreshDisplayView();
- }
- });
- }
-
- public void showCalendarSelectionDialog() {
- FragmentManager fragmentManager = taskEditFragment.getFragmentManager();
- CalendarSelectionDialog fragmentByTag = (CalendarSelectionDialog) fragmentManager.findFragmentByTag(FRAG_TAG_CALENDAR_SELECTION);
- if (fragmentByTag == null) {
- fragmentByTag = new CalendarSelectionDialog();
- fragmentByTag.show(fragmentManager, FRAG_TAG_CALENDAR_SELECTION);
- }
- fragmentByTag.setCalendarSelectionHandler(GCalControlSet.this);
- }
-
- @Override
- protected void readFromTaskOnInitialize() {
- String uri = gcal.getTaskEventUri(model);
- if(!TextUtils.isEmpty(uri)) {
- try {
- calendarUri = Uri.parse(uri);
-
- // try to load calendar
- ContentResolver cr = activity.getContentResolver();
- Cursor cursor = cr.query(calendarUri, new String[] { "dtstart" }, null, null, null); //$NON-NLS-1$
- try {
- boolean deleted = cursor.getCount() == 0;
-
- if(deleted) {
- clearEvent();
- hasEvent = false;
- } else {
- hasEvent = true;
- }
- } finally {
- cursor.close();
- }
- } catch (Exception e) {
- Timber.e(e, "unable-to-parse-calendar: %s", model.getCalendarURI());
- }
- } else {
- hasEvent = false;
- clearEvent();
- }
- refreshDisplayView();
- }
-
- private void clearEvent() {
- calendarId = null;
- calendarUri = null;
- calendarName = null;
- }
-
- @Override
- protected void writeToModelAfterInitialized(Task task) {
- if (!task.hasDueDate()) {
- return;
- }
-
- if ((preferences.isDefaultCalendarSet() || calendarId != null) && calendarUri == null) {
- try{
- ContentResolver cr = activity.getContentResolver();
-
- ContentValues values = new ContentValues();
- values.put("calendar_id", calendarId);
- calendarUri = gcal.createTaskEvent(task, cr, values);
- if(calendarUri != null) {
- task.setCalendarUri(calendarUri.toString());
-
- if (!hasEvent) {
- // pop up the new event
- Intent intent = new Intent(Intent.ACTION_VIEW, calendarUri);
- intent.putExtra("beginTime", values.getAsLong("dtstart"));
- intent.putExtra("endTime", values.getAsLong("dtend"));
- activity.startActivity(intent);
- }
- }
-
- } catch (Exception e) {
- Timber.e(e, e.getMessage());
- }
- } else if(calendarUri != null) {
- try {
- ContentValues updateValues = new ContentValues();
-
- // check if we need to update the item
- ContentValues setValues = task.getSetValues();
- if(setValues.containsKey(Task.TITLE.name)) {
- updateValues.put("title", task.getTitle());
- }
- if(setValues.containsKey(Task.NOTES.name)) {
- updateValues.put("description", task.getNotes());
- }
- if(setValues.containsKey(Task.DUE_DATE.name) || setValues.containsKey(Task.ESTIMATED_SECONDS.name)) {
- gcal.createStartAndEndDate(task, updateValues);
- }
-
- ContentResolver cr = activity.getContentResolver();
- cr.update(calendarUri, updateValues, null, null);
- } catch (Exception e) {
- Timber.e(e, "unable-to-update-calendar: %s", task.getCalendarURI());
- }
- }
- }
-
- private void viewCalendarEvent() {
- if(calendarUri == null) {
- return;
- }
-
- ContentResolver cr = activity.getContentResolver();
- Intent intent = new Intent(Intent.ACTION_VIEW, calendarUri);
- Cursor cursor = cr.query(calendarUri, new String[] { "dtstart", "dtend" },
- null, null, null);
- try {
- if(cursor.getCount() == 0) {
- // event no longer exists, recreate it
- calendarUri = null;
- writeToModel(model);
- return;
- }
- cursor.moveToFirst();
- intent.putExtra("beginTime", cursor.getLong(0));
- intent.putExtra("endTime", cursor.getLong(1));
-
- } catch (Exception e) {
- Timber.e(e, e.getMessage());
- Toast.makeText(activity, R.string.gcal_TEA_error, Toast.LENGTH_LONG).show();
- } finally {
- cursor.close();
- }
-
- activity.startActivity(intent);
- }
-
- private void refreshDisplayView() {
- calendar.setTextColor(themeColor);
- if (initialized) {
- if (hasEvent) {
- calendar.setText(R.string.gcal_TEA_showCalendar_label);
- cancelButton.setVisibility(View.GONE);
- } else if (calendarName != null) {
- calendar.setText(calendarName);
- cancelButton.setVisibility(View.VISIBLE);
- } else {
- calendar.setTextColor(unsetColor);
- calendar.setText(R.string.gcal_TEA_addToCalendar_label);
- cancelButton.setVisibility(View.GONE);
- }
- } else {
- cancelButton.setVisibility(View.GONE);
- if (TextUtils.isEmpty(model.getCalendarURI())) {
- calendar.setTextColor(unsetColor);
- calendar.setText(R.string.gcal_TEA_addToCalendar_label);
- } else {
- calendar.setText(R.string.gcal_TEA_showCalendar_label);
- }
- }
- }
-
- @Override
- public int getIcon() {
- return R.drawable.ic_event_24dp;
- }
-
- @Override
- public void selectedCalendar(AndroidCalendar androidCalendar) {
- this.calendarId = androidCalendar.getId();
- this.calendarName = androidCalendar.getName();
- refreshDisplayView();
- }
-
- @Override
- public void dismiss() {
-
- }
-}
diff --git a/src/main/java/com/todoroo/astrid/gcal/GCalHelper.java b/src/main/java/com/todoroo/astrid/gcal/GCalHelper.java
index 3dc5b9ab4..0571d34fd 100644
--- a/src/main/java/com/todoroo/astrid/gcal/GCalHelper.java
+++ b/src/main/java/com/todoroo/astrid/gcal/GCalHelper.java
@@ -194,7 +194,7 @@ public class GCalHelper {
return eventDeleted;
}
- void createStartAndEndDate(Task task, ContentValues values) {
+ public void createStartAndEndDate(Task task, ContentValues values) {
long dueDate = task.getDueDate();
long tzCorrectedDueDate = dueDate + TimeZone.getDefault().getOffset(dueDate);
long tzCorrectedDueDateNow = DateUtilities.now() + TimeZone.getDefault().getOffset(DateUtilities.now());
@@ -232,6 +232,26 @@ public class GCalHelper {
}
}
+ public AndroidCalendar getCalendar(String id) {
+ ContentResolver cr = context.getContentResolver();
+
+ Cursor c = cr.query(getCalendarContentUri(Calendars.CALENDAR_CONTENT_CALENDARS), Calendars.CALENDARS_PROJECTION,
+ Calendars.CALENDARS_WHERE + " AND Calendars._id=" + id, null, Calendars.CALENDARS_SORT);
+ try {
+ if (c.moveToFirst()) {
+ int nameColumn = c.getColumnIndex(Calendars.CALENDARS_DISPLAY_COL);
+ String name = c.getString(nameColumn);
+ return new AndroidCalendar(id, name);
+ }
+ } finally {
+ if(c != null) {
+ c.close();
+ }
+ }
+
+ return null;
+ }
+
/**
* Appends all user-modifiable calendars to listPreference.
*/
diff --git a/src/main/java/com/todoroo/astrid/helper/TaskEditControlSet.java b/src/main/java/com/todoroo/astrid/helper/TaskEditControlSet.java
deleted file mode 100644
index 4cbf2e169..000000000
--- a/src/main/java/com/todoroo/astrid/helper/TaskEditControlSet.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.todoroo.astrid.helper;
-
-import android.view.View;
-
-import com.todoroo.astrid.data.Task;
-
-public interface TaskEditControlSet {
- View getView();
-
- void readFromTask(Task task);
-
- void writeToModel(Task task);
-
- int getIcon();
-}
diff --git a/src/main/java/com/todoroo/astrid/helper/TaskEditControlSetBase.java b/src/main/java/com/todoroo/astrid/helper/TaskEditControlSetBase.java
deleted file mode 100644
index e1ef65ba7..000000000
--- a/src/main/java/com/todoroo/astrid/helper/TaskEditControlSetBase.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * Copyright (c) 2012 Todoroo Inc
- *
- * See the file "LICENSE" for the full license governing this code.
- */
-package com.todoroo.astrid.helper;
-
-import android.app.Activity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.todoroo.astrid.data.Task;
-
-import org.tasks.R;
-
-import static org.tasks.preferences.ResourceResolver.getData;
-
-// --- interface
-
-/**
- * Interface for working with controls that alter task data
- */
-public abstract class TaskEditControlSetBase implements TaskEditControlSet {
-
- protected final Activity activity;
- private final int viewLayout;
- private boolean useTemplate;
- private View view;
- protected Task model;
- protected boolean initialized = false;
- protected final int themeColor;
- protected final int unsetColor;
-
- public TaskEditControlSetBase(Activity activity, int viewLayout) {
- this(activity, viewLayout, true);
- }
-
- public TaskEditControlSetBase(Activity activity, int viewLayout, boolean useTemplate) {
- this.activity = activity;
- this.viewLayout = viewLayout;
- this.useTemplate = useTemplate;
- if (viewLayout == -1) {
- initialized = true;
- }
-
- themeColor = getData(activity, R.attr.asTextColor);
- unsetColor = getData(activity, R.attr.asTextColorHint);
- }
-
- protected View inflateWithTemplate(int layout) {
- LayoutInflater layoutInflater = LayoutInflater.from(activity);
- View template = layoutInflater.inflate(R.layout.control_set_template, null);
- LinearLayout content = (LinearLayout) template.findViewById(R.id.content);
- content.addView(layoutInflater.inflate(layout, null));
- return template;
- }
-
- @Override
- public View getView() {
- if (view == null && !initialized) {
- if (viewLayout != -1) {
- view = useTemplate ? inflateWithTemplate(viewLayout) : LayoutInflater.from(activity).inflate(viewLayout, null);
- afterInflate();
- }
- if (model != null) {
- readFromTaskOnInitialize();
- }
- this.initialized = true;
- }
- return view;
- }
-
- /**
- * Read data from model to update the control set
- */
- @Override
- public void readFromTask(Task task) {
- this.model = task;
- if (initialized) {
- readFromTaskOnInitialize();
- }
- }
-
-
- /**
- * Called once to setup the ui with data from the task
- */
- protected abstract void readFromTaskOnInitialize();
-
- /**
- * Write data from control set to model
- */
- @Override
- public void writeToModel(Task task) {
- if (initialized) {
- writeToModelAfterInitialized(task);
- }
- }
-
- /**
- * Write to model, if initialization logic has been called
- */
- protected abstract void writeToModelAfterInitialized(Task task);
-
- /**
- * Called when views need to be inflated
- */
- protected abstract void afterInflate();
-}
diff --git a/src/main/java/com/todoroo/astrid/notes/EditNoteActivity.java b/src/main/java/com/todoroo/astrid/notes/EditNoteActivity.java
index 19b38ab77..e0b3bfb9d 100644
--- a/src/main/java/com/todoroo/astrid/notes/EditNoteActivity.java
+++ b/src/main/java/com/todoroo/astrid/notes/EditNoteActivity.java
@@ -44,11 +44,10 @@ import com.todoroo.astrid.data.RemoteModel;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.UserActivity;
import com.todoroo.astrid.service.TaskService;
-import com.todoroo.astrid.timers.TimerActionControlSet.TimerActionListener;
+import com.todoroo.astrid.timers.TimerActionListener;
import org.json.JSONObject;
import org.tasks.R;
-import org.tasks.preferences.Preferences;
import java.util.ArrayList;
import java.util.Collections;
@@ -67,14 +66,12 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
private Task task;
private ActFmCameraModule actFmCameraModule;
- private final Preferences preferences;
private final MetadataDao metadataDao;
private final UserActivityDao userActivityDao;
private final TaskService taskService;
private final ArrayList items = new ArrayList<>();
private EditText commentField;
private final View commentsBar;
- private View timerView;
private View commentButton;
private int commentItems = 10;
private ImageButton pictureButton;
@@ -94,7 +91,6 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
public EditNoteActivity(
ActFmCameraModule actFmCameraModule,
- Preferences preferences,
MetadataDao metadataDao,
UserActivityDao userActivityDao,
TaskService taskService,
@@ -103,7 +99,6 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
long t) {
super(fragment.getActivity());
this.actFmCameraModule = actFmCameraModule;
- this.preferences = preferences;
this.metadataDao = metadataDao;
this.userActivityDao = userActivityDao;
this.taskService = taskService;
@@ -141,26 +136,9 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
// --- UI preparation
private void setUpInterface() {
- timerView = commentsBar.findViewById(R.id.timer_container);
commentButton = commentsBar.findViewById(R.id.commentButton);
commentField = (EditText) commentsBar.findViewById(R.id.commentField);
- final boolean showTimerShortcut = preferences.getBoolean(R.string.p_show_timer_shortcut, false);
-
- if (showTimerShortcut) {
- commentField.setOnFocusChangeListener(new OnFocusChangeListener() {
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- if (hasFocus) {
- timerView.setVisibility(View.GONE);
- commentButton.setVisibility(View.VISIBLE);
- } else {
- timerView.setVisibility(View.VISIBLE);
- commentButton.setVisibility(View.GONE);
- }
- }
- });
- }
commentField.setHorizontallyScrolling(false);
commentField.setMaxLines(Integer.MAX_VALUE);
commentField.setOnKeyListener(new OnKeyListener() {
@@ -185,10 +163,6 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
public void afterTextChanged(Editable s) {
commentButton.setVisibility((s.length() > 0 || pendingCommentPicture != null) ? View.VISIBLE
: View.GONE);
- if (showTimerShortcut) {
- timerView.setVisibility((s.length() > 0 || pendingCommentPicture != null) ? View.GONE
- : View.VISIBLE);
- }
}
@Override
@@ -241,7 +215,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
}
});
if(!TextUtils.isEmpty(task.getNotes())) {
- TextView notes = new TextView(getContext());
+ TextView notes = new TextView(activity);
notes.setLinkTextColor(Color.rgb(100, 160, 255));
notes.setTextSize(18);
notes.setText(task.getNotes());
@@ -294,7 +268,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
}
if (items.size() > commentItems) {
- Button loadMore = new Button(getContext());
+ Button loadMore = new Button(activity);
loadMore.setText(R.string.TEA_load_more);
loadMore.setTextColor(activity.getResources().getColor(R.color.task_edit_deadline_gray));
loadMore.setBackgroundColor(Color.alpha(0));
@@ -315,7 +289,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
}
public View getUpdateNotes(NoteOrUpdate note, ViewGroup parent) {
- View convertView = ((Activity)getContext()).getLayoutInflater().inflate(
+ View convertView = ((Activity)activity).getLayoutInflater().inflate(
R.layout.comment_adapter_row, parent, false);
bindView(convertView, note);
return convertView;
@@ -364,7 +338,7 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
private void addComment() {
addComment(commentField.getText().toString(), UserActivity.ACTION_TASK_COMMENT, task.getUuid(), true);
- AndroidUtilities.hideSoftInputForViews(getContext(), commentField);
+ AndroidUtilities.hideSoftInputForViews(activity, commentField);
commentField.setCursorVisible(false);
}
@@ -459,8 +433,8 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
@Override
public void timerStarted(Task t) {
addComment(String.format("%s %s", //$NON-NLS-1$
- getContext().getString(R.string.TEA_timer_comment_started),
- DateUtilities.getTimeString(getContext(), newDateTime())),
+ activity.getString(R.string.TEA_timer_comment_started),
+ DateUtilities.getTimeString(activity, newDateTime())),
UserActivity.ACTION_TASK_COMMENT,
t.getUuid(),
false);
@@ -470,9 +444,9 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
public void timerStopped(Task t) {
String elapsedTime = DateUtils.formatElapsedTime(t.getElapsedSeconds());
addComment(String.format("%s %s\n%s %s", //$NON-NLS-1$
- getContext().getString(R.string.TEA_timer_comment_stopped),
- DateUtilities.getTimeString(getContext(), newDateTime()),
- getContext().getString(R.string.TEA_timer_comment_spent),
+ activity.getString(R.string.TEA_timer_comment_stopped),
+ DateUtilities.getTimeString(activity, newDateTime()),
+ activity.getString(R.string.TEA_timer_comment_spent),
elapsedTime), UserActivity.ACTION_TASK_COMMENT,
t.getUuid(),
false);
diff --git a/src/main/java/com/todoroo/astrid/provider/Astrid2TaskProvider.java b/src/main/java/com/todoroo/astrid/provider/Astrid2TaskProvider.java
index c8ae08d9b..bbb487611 100644
--- a/src/main/java/com/todoroo/astrid/provider/Astrid2TaskProvider.java
+++ b/src/main/java/com/todoroo/astrid/provider/Astrid2TaskProvider.java
@@ -25,10 +25,12 @@ import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.tags.TagService;
import org.tasks.injection.InjectingContentProvider;
+import org.tasks.ui.CheckBoxes;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.util.List;
import javax.inject.Inject;
@@ -80,6 +82,7 @@ public class Astrid2TaskProvider extends InjectingContentProvider {
@Inject Lazy taskService;
@Inject Lazy tagService;
+ @Inject Lazy checkBoxes;
static {
URI_MATCHER.addURI(AUTHORITY, "tasks", URI_TASKS);
@@ -167,7 +170,7 @@ public class Astrid2TaskProvider extends InjectingContentProvider {
TaskCriteria.isVisible())).
orderBy(SortHelper.defaultTaskOrder()).limit(MAX_NUMBER_OF_TASKS));
try {
- int[] importanceColors = Task.getImportanceColors(getContext().getResources());
+ List importanceColors = checkBoxes.get().getPriorityColors();
for (int i = 0; i < cursor.getCount(); i++) {
cursor.moveToNext();
Task task = new Task(cursor);
@@ -176,7 +179,7 @@ public class Astrid2TaskProvider extends InjectingContentProvider {
Object[] values = new Object[7];
values[0] = task.getTitle();
- values[1] = importanceColors[task.getImportance()];
+ values[1] = importanceColors.get(task.getImportance());
values[2] = task.getDueDate();
values[3] = task.getDueDate();
values[4] = task.getImportance();
diff --git a/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.java b/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.java
index 2aaf1cdc2..285106632 100644
--- a/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.java
+++ b/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.java
@@ -7,10 +7,16 @@ package com.todoroo.astrid.repeats;
import android.app.Activity;
import android.app.Dialog;
+import android.content.Context;
import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
+import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup.LayoutParams;
+import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
@@ -22,6 +28,7 @@ import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
+import com.google.common.base.Strings;
import com.google.ical.values.Frequency;
import com.google.ical.values.RRule;
import com.google.ical.values.Weekday;
@@ -30,21 +37,24 @@ import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.ui.NumberPickerDialog;
import com.todoroo.astrid.ui.NumberPickerDialog.OnNumberPickedListener;
-import com.todoroo.astrid.ui.PopupControlSet;
-import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import org.tasks.R;
+import org.tasks.activities.DatePickerActivity;
import org.tasks.dialogs.DialogBuilder;
-import org.tasks.dialogs.MyDatePickerDialog;
+import org.tasks.injection.ForActivity;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.time.DateTime;
+import org.tasks.ui.TaskEditControlFragment;
import java.text.DateFormatSymbols;
import java.util.ArrayList;
import java.util.Calendar;
-import java.util.LinkedList;
import java.util.List;
+import javax.inject.Inject;
+
+import butterknife.Bind;
+import butterknife.OnClick;
import timber.log.Timber;
import static org.tasks.date.DateTimeUtils.newDateTime;
@@ -55,9 +65,16 @@ import static org.tasks.date.DateTimeUtils.newDateTime;
* @author Tim Su
*
*/
-public class RepeatControlSet extends PopupControlSet {
+public class RepeatControlSet extends TaskEditControlFragment {
+
+ public interface RepeatChangedListener {
+ void repeatChanged(boolean repeat);
+ }
- private static final String FRAG_TAG_REPEAT_UNTIL = "frag_tag_repeat_until";
+ private static final int REQUEST_PICK_DATE = 505;
+ private static final String EXTRA_RECURRENCE = "extra_recurrence";
+ private static final String EXTRA_REPEAT_UNTIL = "extra_repeat_until";
+ private static final String EXTRA_REPEAT_AFTER_COMPLETION = "extra_repeat_after_completion";
// --- spinner constants
@@ -77,7 +94,14 @@ public class RepeatControlSet extends PopupControlSet {
private Spinner interval;
private Spinner type;
private Spinner repeatUntil;
- private ImageView clear;
+
+ @Inject DialogBuilder dialogBuilder;
+ @Inject ActivityPreferences preferences;
+ @Inject @ForActivity Context context;
+
+ @Bind(R.id.clear) ImageView clear;
+ @Bind(R.id.display_row_edit) TextView displayView;
+
private ArrayAdapter repeatUntilAdapter;
private final List repeatUntilOptions = new ArrayList<>();
private LinearLayout daysOfWeekContainer;
@@ -87,227 +111,49 @@ public class RepeatControlSet extends PopupControlSet {
private int repeatValue;
private int intervalValue;
private long repeatUntilValue;
+ private View dialogView;
+ private AlertDialog dialog;
- private final List listeners = new LinkedList<>();
-
- public interface RepeatChangedListener {
- void repeatChanged(boolean repeat);
- }
-
- // --- implementation
-
- public RepeatControlSet(ActivityPreferences preferences, Activity activity, DialogBuilder dialogBuilder) {
- super(preferences, activity, R.layout.control_set_repeat, R.layout.control_set_repeat_display, R.string.repeat_enabled, dialogBuilder);
-
- clear = (ImageView) getView().findViewById(R.id.clear);
- }
-
- /** Set up the repeat value button */
- private void setRepeatValue(int newValue) {
- repeatValue = newValue;
- value.setText(activity.getString(R.string.repeat_every, newValue));
- }
-
- private void setRepeatUntilValue(long newValue) {
- repeatUntilValue = newValue;
- updateRepeatUntilOptions();
- }
-
- protected void repeatValueClick() {
- int dialogValue = repeatValue;
- if(dialogValue == 0) {
- dialogValue = 1;
- }
-
- new NumberPickerDialog(activity, preferences.getDialogTheme(), new OnNumberPickedListener() {
- @Override
- public void onNumberPicked(int number) {
- setRepeatValue(number);
- }
- }, activity.getResources().getString(R.string.repeat_interval_prompt),
- dialogValue, 1, 1, 365).show();
- }
-
- private void repeatUntilClick() {
- MyDatePickerDialog dialog = new MyDatePickerDialog();
- DateTime initial = repeatUntilValue > 0 ? newDateTime(repeatUntilValue) : newDateTime();
- dialog.initialize(new DatePickerDialog.OnDateSetListener() {
- @Override
- public void onDateSet(DatePickerDialog datePickerDialog, int year, int month, int day) {
- setRepeatUntilValue(new DateTime(year, month + 1, day, 0, 0, 0, 0).getMillis());
- }
- }, initial.getYear(), initial.getMonthOfYear() - 1, initial.getDayOfMonth());
- dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- setRepeatUntilValue(repeatUntilValue);
- }
- });
- dialog.show(activity.getFragmentManager(), FRAG_TAG_REPEAT_UNTIL);
- }
+ private RepeatChangedListener callback;
- public void addListener(RepeatChangedListener listener) {
- listeners.add(listener);
- }
+ private boolean repeatAfterCompletion;
+ @Nullable
@Override
- public void readFromTask(Task task) {
- super.readFromTask(task);
- recurrence = model.sanitizedRecurrence();
- if(recurrence == null) {
- recurrence = "";
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = super.onCreateView(inflater, container, savedInstanceState);
+ if (savedInstanceState != null) {
+ recurrence = savedInstanceState.getString(EXTRA_RECURRENCE);
+ repeatUntilValue = savedInstanceState.getLong(EXTRA_REPEAT_UNTIL);
+ repeatAfterCompletion = savedInstanceState.getBoolean(EXTRA_REPEAT_AFTER_COMPLETION);
}
- repeatUntilValue = model.getRepeatUntil();
-
- if(recurrence.length() > 0) {
- try {
- RRule rrule = new RRule(recurrence);
- repeatValue = rrule.getInterval();
- switch(rrule.getFreq()) {
- case DAILY:
- intervalValue = INTERVAL_DAYS;
- break;
- case WEEKLY: {
- intervalValue = INTERVAL_WEEKS;
- break;
- }
- case MONTHLY:
- intervalValue = INTERVAL_MONTHS;
- break;
- case HOURLY:
- intervalValue = INTERVAL_HOURS;
- break;
- case MINUTELY:
- intervalValue = INTERVAL_MINUTES;
- break;
- case YEARLY:
- intervalValue = INTERVAL_YEARS;
- break;
- default:
- Timber.e(new Exception("Unhandled rrule frequency: " + recurrence), "repeat-unhandled-rule");
- }
- } catch (Exception e) {
- // invalid RRULE
- recurrence = ""; //$NON-NLS-1$
- Timber.e(e, e.getMessage());
- }
- }
- doRepeat = recurrence.length() > 0;
- getDialogView();
- refreshDisplayView();
- }
-
- @Override
- public int getIcon() {
- return R.drawable.ic_repeat_24dp;
- }
-
- @Override
- protected void readFromTaskOnInitialize() {
- DateTime date;
- if(model.getDueDate() != 0) {
- date = newDateTime(model.getDueDate());
-
- int dayOfWeek = date.getDayOfWeek();
- for(int i = 0; i < 7; i++) {
- daysOfWeek[i].setChecked(i == dayOfWeek);
- }
- }
-
- // read recurrence rule
- if(recurrence.length() > 0) {
- try {
- RRule rrule = new RRule(recurrence);
-
- setRepeatValue(rrule.getInterval());
- setRepeatUntilValue(model.getRepeatUntil());
- interval.setSelection(intervalValue);
-
- // clear all day of week checks, then update them
- for(int i = 0; i < 7; i++) {
- daysOfWeek[i].setChecked(false);
- }
-
- for(WeekdayNum day : rrule.getByDay()) {
- for(int i = 0; i < 7; i++) {
- if (daysOfWeek[i].getTag().equals(day.wday)) {
- daysOfWeek[i].setChecked(true);
- }
- }
- }
- } catch (Exception e) {
- // invalid RRULE
- recurrence = ""; //$NON-NLS-1$
- Timber.e(e, e.getMessage());
- }
- }
- doRepeat = recurrence.length() > 0;
-
- // read flag
- if(model.repeatAfterCompletion()) {
- type.setSelection(TYPE_COMPLETION_DATE);
- } else {
- type.setSelection(TYPE_DUE_DATE);
- }
-
- refreshDisplayView();
- }
-
- @Override
- protected void afterInflate() {
- View dialogView = getDialogView();
+ dialogView = inflater.inflate(R.layout.control_set_repeat, null);
value = (Button) dialogView.findViewById(R.id.repeatValue);
interval = (Spinner) dialogView.findViewById(R.id.repeatInterval);
- interval.setAdapter(new ArrayAdapter(activity, android.R.layout.simple_spinner_item, activity.getResources().getStringArray(R.array.repeat_interval)) {{
+ interval.setAdapter(new ArrayAdapter(context, android.R.layout.simple_spinner_item, getResources().getStringArray(R.array.repeat_interval)) {{
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
}});
type = (Spinner) dialogView.findViewById(R.id.repeatType);
- type.setAdapter(new ArrayAdapter(activity, android.R.layout.simple_spinner_item, activity.getResources().getStringArray(R.array.repeat_type)) {{
+ type.setAdapter(new ArrayAdapter(context, android.R.layout.simple_spinner_item, getResources().getStringArray(R.array.repeat_type)) {{
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
}});
daysOfWeekContainer = (LinearLayout) dialogView.findViewById(R.id.repeatDayOfWeekContainer);
repeatUntil = (Spinner) dialogView.findViewById(R.id.repeat_until);
- repeatUntilAdapter = new ArrayAdapter<>(activity, android.R.layout.simple_spinner_item, repeatUntilOptions);
+ repeatUntilAdapter = new ArrayAdapter<>(context, android.R.layout.simple_spinner_item, repeatUntilOptions);
repeatUntilAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
repeatUntil.setAdapter(repeatUntilAdapter);
- setRepeatValue(1);
- setRepeatUntilValue(0);
- clear.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- doRepeat = false;
- refreshDisplayView();
-
- for (RepeatChangedListener l : listeners) {
- l.repeatChanged(doRepeat);
- }
- }
- });
// set up days of week
DateFormatSymbols dfs = new DateFormatSymbols();
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
- LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 1.0f/14);
- LinearLayout.LayoutParams textLp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 1.0f/14);
for(int i = 0; i < 7; i++) {
- CheckBox checkBox = new CheckBox(activity);
+ CheckBox checkBox = (CheckBox) daysOfWeekContainer.getChildAt(i);
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
- checkBox.setPadding(0, 0, 0, 0);
- checkBox.setLayoutParams(lp);
checkBox.setTag(Weekday.values()[dayOfWeek - 1]);
- checkBox.setButtonDrawable(R.drawable.btn_check_small);
-
- TextView label = new TextView(activity);
- label.setTextAppearance(activity, R.style.TextAppearance);
- label.setLayoutParams(textLp);
- label.setTextSize(14);
- label.setText(dfs.getShortWeekdays()[dayOfWeek].substring(0, 1));
-
+ checkBox.setText(dfs.getShortWeekdays()[dayOfWeek].substring(0, 1));
daysOfWeek[i] = checkBox;
calendar.add(Calendar.DATE, 1);
- daysOfWeekContainer.addView(checkBox);
- daysOfWeekContainer.addView(label);
}
// set up listeners
@@ -318,6 +164,7 @@ public class RepeatControlSet extends PopupControlSet {
}
});
+ setRepeatValue(1);
interval.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView> parentView, View view, int position, long id) {
@@ -331,6 +178,7 @@ public class RepeatControlSet extends PopupControlSet {
}
});
+ setRepeatUntilValue(repeatUntilValue);
repeatUntil.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView> adapterView, View view, int i, long l) {
@@ -356,10 +204,147 @@ public class RepeatControlSet extends PopupControlSet {
});
daysOfWeekContainer.setVisibility(View.GONE);
+ type.setSelection(repeatAfterCompletion ? TYPE_COMPLETION_DATE : TYPE_DUE_DATE);
+ applyRecurrence();
+ refreshDisplayView();
+ return view;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putString(EXTRA_RECURRENCE, getRecurrence());
+ outState.putLong(EXTRA_REPEAT_UNTIL, repeatUntilValue);
+ outState.putBoolean(EXTRA_REPEAT_AFTER_COMPLETION, repeatAfterCompletion);
}
@Override
- protected void writeToModelAfterInitialized(Task task) {
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+
+ callback = (RepeatChangedListener) activity;
+ }
+
+ @OnClick(R.id.clear)
+ void clearRepeat(View view) {
+ doRepeat = false;
+ refreshDisplayView();
+ callback.repeatChanged(doRepeat);
+ }
+
+ @OnClick(R.id.display_row_edit)
+ void openPopup(View view) {
+ if (dialog == null) {
+ buildDialog();
+ }
+ dialog.show();
+ }
+
+ protected Dialog buildDialog() {
+ AlertDialog.Builder builder = dialogBuilder.newDialog()
+ .setView(dialogView)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ doRepeat = true;
+
+ callback.repeatChanged(doRepeat);
+
+ refreshDisplayView();
+ }
+ })
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ refreshDisplayView();
+ }
+ });
+ dialog = builder.show();
+ return dialog;
+ }
+
+ @Override
+ protected int getLayout() {
+ return R.layout.control_set_repeat_display;
+ }
+
+ @Override
+ public int getIcon() {
+ return R.drawable.ic_repeat_24dp;
+ }
+
+ @Override
+ public void initialize(boolean isNewTask, Task task) {
+ repeatAfterCompletion = task.repeatAfterCompletion();
+ recurrence = task.sanitizedRecurrence();
+ repeatUntilValue = task.getRepeatUntil();
+ }
+
+ @Override
+ public void apply(Task task) {
+ String result = getRecurrence();
+
+ if (type.getSelectedItemPosition() == TYPE_COMPLETION_DATE && !TextUtils.isEmpty(result)) {
+ result += ";FROM=COMPLETION"; //$NON-NLS-1$
+ }
+
+ task.setRecurrence(result);
+ task.setRepeatUntil(repeatUntilValue);
+ }
+
+ private void applyRecurrence() {
+ doRepeat = !Strings.isNullOrEmpty(recurrence);
+ if (!doRepeat) {
+ return;
+ }
+
+ // read recurrence rule
+ try {
+ RRule rrule = new RRule(recurrence);
+
+ setRepeatValue(rrule.getInterval());
+
+ for(WeekdayNum day : rrule.getByDay()) {
+ for(int i = 0; i < 7; i++) {
+ if (daysOfWeek[i].getTag().equals(day.wday)) {
+ daysOfWeek[i].setChecked(true);
+ }
+ }
+ }
+
+ switch(rrule.getFreq()) {
+ case DAILY:
+ intervalValue = INTERVAL_DAYS;
+ break;
+ case WEEKLY:
+ intervalValue = INTERVAL_WEEKS;
+ break;
+ case MONTHLY:
+ intervalValue = INTERVAL_MONTHS;
+ break;
+ case HOURLY:
+ intervalValue = INTERVAL_HOURS;
+ break;
+ case MINUTELY:
+ intervalValue = INTERVAL_MINUTES;
+ break;
+ case YEARLY:
+ intervalValue = INTERVAL_YEARS;
+ break;
+ default:
+ Timber.e(new Exception("Unhandled rrule frequency: " + recurrence), "repeat-unhandled-rule");
+ }
+ interval.setSelection(intervalValue);
+
+ } catch (Exception e) {
+ // invalid RRULE
+ recurrence = ""; //$NON-NLS-1$
+ Timber.e(e, e.getMessage());
+ }
+ }
+
+ private String getRecurrence() {
String result;
if(!doRepeat) {
result = ""; //$NON-NLS-1$
@@ -367,60 +352,93 @@ public class RepeatControlSet extends PopupControlSet {
RRule rrule = new RRule();
rrule.setInterval(repeatValue);
switch(interval.getSelectedItemPosition()) {
- case INTERVAL_DAYS:
- rrule.setFreq(Frequency.DAILY);
- break;
- case INTERVAL_WEEKS: {
- rrule.setFreq(Frequency.WEEKLY);
-
- ArrayList days = new ArrayList<>();
- for (CompoundButton dayOfWeek : daysOfWeek) {
- if (dayOfWeek.isChecked()) {
- days.add(new WeekdayNum(0, (Weekday) dayOfWeek.getTag()));
+ case INTERVAL_DAYS:
+ rrule.setFreq(Frequency.DAILY);
+ break;
+ case INTERVAL_WEEKS: {
+ rrule.setFreq(Frequency.WEEKLY);
+
+ ArrayList days = new ArrayList<>();
+ for (CompoundButton dayOfWeek : daysOfWeek) {
+ if (dayOfWeek.isChecked()) {
+ days.add(new WeekdayNum(0, (Weekday) dayOfWeek.getTag()));
+ }
}
+ rrule.setByDay(days);
+ break;
}
- rrule.setByDay(days);
- break;
- }
- case INTERVAL_MONTHS:
- rrule.setFreq(Frequency.MONTHLY);
- break;
- case INTERVAL_HOURS:
- rrule.setFreq(Frequency.HOURLY);
- break;
- case INTERVAL_MINUTES:
- rrule.setFreq(Frequency.MINUTELY);
- break;
- case INTERVAL_YEARS:
- rrule.setFreq(Frequency.YEARLY);
- break;
+ case INTERVAL_MONTHS:
+ rrule.setFreq(Frequency.MONTHLY);
+ break;
+ case INTERVAL_HOURS:
+ rrule.setFreq(Frequency.HOURLY);
+ break;
+ case INTERVAL_MINUTES:
+ rrule.setFreq(Frequency.MINUTELY);
+ break;
+ case INTERVAL_YEARS:
+ rrule.setFreq(Frequency.YEARLY);
+ break;
}
result = rrule.toIcal();
}
- if (type.getSelectedItemPosition() == TYPE_COMPLETION_DATE && !TextUtils.isEmpty(result)) {
- result = result + ";FROM=COMPLETION"; //$NON-NLS-1$
- }
+ return result;
+ }
- task.setRecurrence(result);
- task.setRepeatUntil(repeatUntilValue);
+ /** Set up the repeat value button */
+ private void setRepeatValue(int newValue) {
+ repeatValue = newValue;
+ value.setText(getString(R.string.repeat_every, newValue));
+ }
- if(task.repeatAfterCompletion()) {
- type.setSelection(1);
+ private void setRepeatUntilValue(long newValue) {
+ repeatUntilValue = newValue;
+ updateRepeatUntilOptions();
+ }
+
+ protected void repeatValueClick() {
+ int dialogValue = repeatValue;
+ if(dialogValue == 0) {
+ dialogValue = 1;
}
+
+ new NumberPickerDialog(context, preferences.getDialogTheme(), new OnNumberPickedListener() {
+ @Override
+ public void onNumberPicked(int number) {
+ setRepeatValue(number);
+ }
+ }, getResources().getString(R.string.repeat_interval_prompt),
+ dialogValue, 1, 1, 365).show();
+ }
+
+ private void repeatUntilClick() {
+ startActivityForResult(new Intent(context, DatePickerActivity.class) {{
+ putExtra(DatePickerActivity.EXTRA_TIMESTAMP, repeatUntilValue > 0 ? repeatUntilValue : 0L);
+ }}, REQUEST_PICK_DATE);
}
@Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_PICK_DATE) {
+ if (resultCode == Activity.RESULT_OK) {
+ setRepeatUntilValue(data.getLongExtra(DatePickerActivity.EXTRA_TIMESTAMP, 0L));
+ } else {
+ setRepeatUntilValue(repeatUntilValue);
+ }
+ }
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+
protected void refreshDisplayView() {
- TextView repeatDisplay = (TextView) getView().findViewById(R.id.display_row_edit);
if (doRepeat) {
- repeatDisplay.setText(getRepeatString());
- repeatDisplay.setTextColor(themeColor);
+ displayView.setText(getRepeatString());
+ displayView.setAlpha(1.0f);
clear.setVisibility(View.VISIBLE);
} else {
- repeatDisplay.setTextColor(unsetColor);
- repeatDisplay.setText(R.string.repeat_never);
+ displayView.setAlpha(0.5f);
+ displayView.setText(R.string.repeat_never);
clear.setVisibility(View.GONE);
}
}
@@ -428,40 +446,23 @@ public class RepeatControlSet extends PopupControlSet {
private String getRepeatString() {
int arrayResource = R.array.repeat_interval;
- String[] dates = activity.getResources().getStringArray(
+ String[] dates = getResources().getStringArray(
arrayResource);
String date = String.format("%s %s", repeatValue, dates[intervalValue]); //$NON-NLS-1$
if (repeatUntilValue > 0) {
- return activity.getString(R.string.repeat_detail_duedate_until, date, getDisplayString());
+ return getString(R.string.repeat_detail_duedate_until, date, getDisplayString());
} else {
- return activity.getString(R.string.repeat_detail_duedate, date); // Every freq int
+ return getString(R.string.repeat_detail_duedate, date); // Every freq int
}
}
- @Override
- protected Dialog buildDialog(String title, final PopupDialogClickListener okListener, final DialogInterface.OnCancelListener cancelListener) {
- PopupDialogClickListener doRepeatButton = new PopupDialogClickListener() {
- @Override
- public boolean onClick(DialogInterface d, int which) {
- doRepeat = true;
-
- for (RepeatChangedListener l : listeners) {
- l.repeatChanged(doRepeat);
- }
- return okListener.onClick(d, which);
- }
- };
-
- return super.buildDialog(title, doRepeatButton, cancelListener);
- }
-
private void updateRepeatUntilOptions() {
repeatUntilOptions.clear();
if (repeatUntilValue > 0) {
- repeatUntilOptions.add(activity.getString(R.string.repeat_until, getDisplayString()));
+ repeatUntilOptions.add(getString(R.string.repeat_until, getDisplayString()));
}
- repeatUntilOptions.add(activity.getString(R.string.repeat_forever));
- repeatUntilOptions.add(activity.getString(R.string.repeat_until, "").trim());
+ repeatUntilOptions.add(getString(R.string.repeat_forever));
+ repeatUntilOptions.add(getString(R.string.repeat_until, "").trim());
repeatUntilAdapter.notifyDataSetChanged();
repeatUntil.setSelection(0);
}
@@ -473,7 +474,7 @@ public class RepeatControlSet extends PopupControlSet {
displayString.append(DateUtilities.getDateString(d));
if (Task.hasDueTime(repeatUntilValue)) {
displayString.append(", "); //$NON-NLS-1$ //$NON-NLS-2$
- displayString.append(DateUtilities.getTimeString(activity, repeatUntilValue));
+ displayString.append(DateUtilities.getTimeString(context, repeatUntilValue));
}
}
return displayString.toString();
diff --git a/src/main/java/com/todoroo/astrid/service/TaskService.java b/src/main/java/com/todoroo/astrid/service/TaskService.java
index 65c5308e5..9eacba998 100644
--- a/src/main/java/com/todoroo/astrid/service/TaskService.java
+++ b/src/main/java/com/todoroo/astrid/service/TaskService.java
@@ -49,8 +49,6 @@ import timber.log.Timber;
@Singleton
public class TaskService {
- public static final String TRANS_EDIT_SAVE = "task-edit-save"; //$NON-NLS-1$
-
public static final String TRANS_REPEAT_COMPLETE = "repeat-complete"; //$NON-NLS-1$
private final TagDataDao tagDataDao;
diff --git a/src/main/java/com/todoroo/astrid/tags/TagService.java b/src/main/java/com/todoroo/astrid/tags/TagService.java
index e7d45ca3a..7016ba85b 100644
--- a/src/main/java/com/todoroo/astrid/tags/TagService.java
+++ b/src/main/java/com/todoroo/astrid/tags/TagService.java
@@ -82,14 +82,14 @@ public final class TagService {
return tagDataDao.getByUuid(uuid, TagData.PROPERTIES);
}
- public List getTagNames(long taskId) {
+ public ArrayList getTagNames(long taskId) {
Query query = Query.select(TaskToTagMetadata.TAG_NAME, TaskToTagMetadata.TAG_UUID).where(
Criterion.and(
MetadataCriteria.withKey(TaskToTagMetadata.KEY),
Metadata.DELETION_DATE.eq(0),
MetadataCriteria.byTask(taskId)))
.orderBy(Order.asc(Functions.upper(TaskToTagMetadata.TAG_NAME)));
- final List tagNames = new ArrayList<>();
+ final ArrayList tagNames = new ArrayList<>();
metadataDao.query(query, new Callback() {
@Override
public void apply(Metadata entry) {
diff --git a/src/main/java/com/todoroo/astrid/tags/TagsControlSet.java b/src/main/java/com/todoroo/astrid/tags/TagsControlSet.java
index 4f2631ec4..a40091dd9 100644
--- a/src/main/java/com/todoroo/astrid/tags/TagsControlSet.java
+++ b/src/main/java/com/todoroo/astrid/tags/TagsControlSet.java
@@ -5,13 +5,18 @@
*/
package com.todoroo.astrid.tags;
-import android.app.Activity;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
@@ -20,12 +25,12 @@ import android.widget.ListView;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
-import com.google.common.base.Strings;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
+import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
-import com.todoroo.andlib.data.AbstractModel;
+import com.google.common.collect.Sets;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.DateUtilities;
@@ -34,21 +39,26 @@ import com.todoroo.astrid.dao.TagDataDao;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.Task;
-import com.todoroo.astrid.ui.PopupControlSet;
import com.todoroo.astrid.utility.Flags;
import org.tasks.R;
import org.tasks.dialogs.DialogBuilder;
-import org.tasks.preferences.ActivityPreferences;
+import org.tasks.ui.TaskEditControlFragment;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
+import javax.inject.Inject;
+
+import butterknife.Bind;
+import butterknife.OnClick;
+
+import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.Lists.transform;
import static com.google.common.collect.Sets.difference;
import static com.google.common.collect.Sets.newHashSet;
@@ -58,32 +68,23 @@ import static com.google.common.collect.Sets.newHashSet;
* @author Tim Su
*
*/
-public final class TagsControlSet extends PopupControlSet {
+public final class TagsControlSet extends TaskEditControlFragment {
- // --- instance variables
+ private static final String EXTRA_TAGS = "extra_tags";
- private static final String TRANSITORY_TAGS = "tags";//$NON-NLS-1$
+ @Inject MetadataDao metadataDao;
+ @Inject TagDataDao tagDataDao;
+ @Inject TagService tagService;
+ @Inject DialogBuilder dialogBuilder;
- private ArrayList allTagNames;
+ @Bind(R.id.display_row_edit) TextView tagsDisplay;
+ private long taskId;
+ private ArrayList allTagNames;
private LinearLayout newTags;
private ListView selectedTags;
- private boolean populated = false;
-
- //private final LinearLayout tagsContainer;
- private final TextView tagsDisplay;
-
- private final MetadataDao metadataDao;
- private final TagDataDao tagDataDao;
- private final TagService tagService;
-
- public TagsControlSet(MetadataDao metadataDao, TagDataDao tagDataDao, ActivityPreferences preferences, TagService tagService, Activity activity, DialogBuilder dialogBuilder) {
- super(preferences, activity, R.layout.control_set_tag_list, R.layout.control_set_tags, R.string.TEA_tags_label_long, dialogBuilder);
- this.metadataDao = metadataDao;
- this.tagDataDao = tagDataDao;
- this.tagService = tagService;
- tagsDisplay = (TextView) getView().findViewById(R.id.display_row_edit);
- }
+ private View dialogView;
+ private AlertDialog dialog;
private String buildTagString() {
StringBuilder builder = new StringBuilder();
@@ -103,6 +104,86 @@ public final class TagsControlSet extends PopupControlSet {
return builder.toString();
}
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = super.onCreateView(inflater, container, savedInstanceState);
+ ArrayList selected;
+ if (savedInstanceState != null) {
+ selected = savedInstanceState.getStringArrayList(EXTRA_TAGS);
+ } else {
+ selected = tagService.getTagNames(taskId);
+ }
+ allTagNames = newArrayList(ImmutableSet.copyOf(transform(tagService.getTagList(), new Function() {
+ @Override
+ public String apply(TagData tagData) {
+ return tagData.getName();
+ }
+ })));
+ dialogView = inflater.inflate(R.layout.control_set_tag_list, null);
+ newTags = (LinearLayout) dialogView.findViewById(R.id.newTags);
+ selectedTags = (ListView) dialogView.findViewById(R.id.existingTags);
+ selectedTags.setAdapter(new ArrayAdapter<>(getActivity(), R.layout.simple_list_item_multiple_choice_themed, allTagNames));
+ addTag("");
+ for (String tag : selected) {
+ setTagSelected(tag);
+ }
+ refreshDisplayView();
+ return view;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putStringArrayList(EXTRA_TAGS, getTagList());
+ }
+
+ @Override
+ protected int getLayout() {
+ return R.layout.control_set_tags;
+ }
+
+ @Override
+ public void initialize(boolean isNewTask, Task task) {
+ taskId = task.getId();
+ }
+
+ @Override
+ public void apply(Task task) {
+ if (synchronizeTags(task.getId(), task.getUUID())) {
+ Flags.set(Flags.TAGS_CHANGED);
+ task.setModificationDate(DateUtilities.now());
+ }
+ }
+
+ @OnClick(R.id.display_row_edit)
+ void openPopup(View view) {
+ if (dialog == null) {
+ buildDialog();
+ }
+ dialog.show();
+ }
+
+ protected Dialog buildDialog() {
+ android.support.v7.app.AlertDialog.Builder builder = dialogBuilder.newDialog()
+ .setView(dialogView)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ refreshDisplayView();
+ }
+ })
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ refreshDisplayView();
+ }
+ });
+ dialog = builder.show();
+ return dialog;
+ }
+
private void setTagSelected(String tag) {
int index = allTagNames.indexOf(tag);
if (index >= 0) {
@@ -113,37 +194,31 @@ public final class TagsControlSet extends PopupControlSet {
}
}
- private List getTagList() {
+ private ArrayList getTagList() {
Set tags = new LinkedHashSet<>();
- if (initialized) {
- for(int i = 0; i < selectedTags.getAdapter().getCount(); i++) {
- if (selectedTags.isItemChecked(i)) {
- tags.add(allTagNames.get(i));
- }
+ for(int i = 0; i < selectedTags.getAdapter().getCount(); i++) {
+ if (selectedTags.isItemChecked(i)) {
+ tags.add(allTagNames.get(i));
}
- for (int i = newTags.getChildCount() - 1 ; i >= 0 ; i--) {
- TextView tagName = (TextView) newTags.getChildAt(i).findViewById(R.id.text1);
- final String text = tagName.getText().toString();
- if (Strings.isNullOrEmpty(text)) {
- continue;
- }
- TagData tagByName = tagDataDao.getTagByName(text, TagData.PROPERTIES);
- if (tagByName != null) {
- setTagSelected(tagByName.getName());
- tags.add(tagByName.getName());
- newTags.removeViewAt(i);
- } else if (!Iterables.any(tags, new Predicate() {
- @Override
- public boolean apply(String input) {
- return text.equalsIgnoreCase(input);
- }
- })) {
- tags.add(text);
- }
+ }
+ for (int i = newTags.getChildCount() - 1 ; i >= 0 ; i--) {
+ TextView tagName = (TextView) newTags.getChildAt(i).findViewById(R.id.text1);
+ final String text = tagName.getText().toString();
+ if (Strings.isNullOrEmpty(text)) {
+ continue;
}
- } else {
- if (model.getTransitory(TRANSITORY_TAGS) != null) {
- return (List) model.getTransitory(TRANSITORY_TAGS);
+ TagData tagByName = tagDataDao.getTagByName(text, TagData.PROPERTIES);
+ if (tagByName != null) {
+ setTagSelected(tagByName.getName());
+ tags.add(tagByName.getName());
+ newTags.removeViewAt(i);
+ } else if (!Iterables.any(tags, new Predicate() {
+ @Override
+ public boolean apply(String input) {
+ return text.equalsIgnoreCase(input);
+ }
+ })) {
+ tags.add(text);
}
}
return newArrayList(tags);
@@ -151,7 +226,7 @@ public final class TagsControlSet extends PopupControlSet {
/** Adds a tag to the tag field */
void addTag(String tagName) {
- LayoutInflater inflater = activity.getLayoutInflater();
+ LayoutInflater inflater = getActivity().getLayoutInflater();
// check if already exists
TextView lastText;
@@ -235,142 +310,73 @@ public final class TagsControlSet extends PopupControlSet {
return (TextView) lastItem.findViewById(R.id.text1);
}
- @Override
- public void readFromTask(Task task) {
- super.readFromTask(task);
- if(model.getId() != AbstractModel.NO_ID) {
- model.putTransitory(TRANSITORY_TAGS, tagService.getTagNames(model.getId()));
- refreshDisplayView();
- }
- }
-
@Override
public int getIcon() {
return R.drawable.ic_label_24dp;
}
- @Override
- protected void readFromTaskOnInitialize() {
- newTags.removeAllViews();
-
- for (int i = 0; i < selectedTags.getCount(); i++) { // clear all selected items
- selectedTags.setItemChecked(i, false);
- }
- if(model.getId() != AbstractModel.NO_ID) {
- selectTagsFromModel();
- }
- addTag(""); //$NON-NLS-1$
- refreshDisplayView();
- populated = true;
- }
-
- private void selectTagsFromModel() {
- List tags = (List) model.getTransitory(TRANSITORY_TAGS);
- if (tags != null) {
- for (String tag : tags) {
- setTagSelected(tag);
- }
- }
- }
-
- @Override
- protected void afterInflate() {
- allTagNames = newArrayList(ImmutableSet.copyOf(transform(tagService.getTagList(), new Function() {
- @Override
- public String apply(TagData tagData) {
- return tagData.getName();
- }
- })));
-
- selectedTags = (ListView) getDialogView().findViewById(R.id.existingTags);
- selectedTags.setAdapter(new ArrayAdapter<>(activity,
- R.layout.simple_list_item_multiple_choice_themed, allTagNames));
- selectedTags.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
- newTags = (LinearLayout) getDialogView().findViewById(R.id.newTags);
- }
-
- @Override
- protected void writeToModelAfterInitialized(Task task) {
- // this is a case where we're asked to save but the UI was not yet populated
- if(!populated) {
- return;
- }
-
- synchronizeTags(task.getId(), task.getUUID());
- Flags.set(Flags.TAGS_CHANGED);
- task.setModificationDate(DateUtilities.now());
- }
-
- @Override
protected void refreshDisplayView() {
String tagString = buildTagString();
if (!TextUtils.isEmpty(tagString)) {
tagsDisplay.setText(tagString);
- tagsDisplay.setTextColor(themeColor);
+ tagsDisplay.setAlpha(1.0f);
} else {
tagsDisplay.setText(R.string.tag_FEx_untagged);
- tagsDisplay.setTextColor(unsetColor);
+ tagsDisplay.setAlpha(0.5f);
}
}
/**
* Save the given array of tags into the database
*/
- private void synchronizeTags(long taskId, String taskUuid) {
+ private boolean synchronizeTags(long taskId, String taskUuid) {
Query query = Query.select(Metadata.PROPERTIES).where(
Criterion.and(
TaskToTagMetadata.TASK_UUID.eq(taskUuid),
Metadata.DELETION_DATE.eq(0))
);
- Set existingTagIds = newHashSet(transform(metadataDao.toList(query), new Function() {
+ Set existingTags = newHashSet(transform(metadataDao.toList(query), new Function() {
@Override
- public String apply(Metadata tagData) {
- return tagData.getValue(TaskToTagMetadata.TAG_UUID);
+ public TagData apply(Metadata metadata) {
+ return tagDataDao.getByUuid(metadata.getValue(TaskToTagMetadata.TAG_UUID));
}
}));
- List tags = getTagList();
- // create missing tags
- for (String tag : tags) {
- TagData tagData = tagDataDao.getTagByName(tag, TagData.ID);
- if (tagData == null) {
- tagData = new TagData();
- tagData.setName(tag);
- tagDataDao.persist(tagData);
- }
- }
- List selectedTags = newArrayList(transform(tags, new Function() {
+ Set selectedTags = newHashSet(transform(getTagList(), new Function() {
@Override
- public TagData apply(String tag) {
- return tagDataDao.getTagByName(tag, TagData.PROPERTIES);
+ public TagData apply(String tagName) {
+ TagData tagData = tagDataDao.getTagByName(tagName, TagData.PROPERTIES);
+ if (tagData == null) {
+ // create missing tags
+ tagData = new TagData();
+ tagData.setName(tagName);
+ tagDataDao.persist(tagData);
+ }
+ return tagData;
}
}));
- deleteLinks(taskId, taskUuid, difference(existingTagIds, newHashSet(Iterables.transform(selectedTags, new Function() {
- @Override
- public String apply(TagData tagData) {
- return tagData.getUUID();
- }
- }))));
- for (TagData tagData : selectedTags) {
- if (!existingTagIds.contains(tagData.getUUID())) {
- Metadata newLink = TaskToTagMetadata.newTagMetadata(taskId, taskUuid, tagData.getName(), tagData.getUUID());
- metadataDao.createNew(newLink);
- }
+ Sets.SetView added = difference(selectedTags, existingTags);
+ Sets.SetView removed = difference(existingTags, selectedTags);
+ deleteLinks(taskId, taskUuid, removed);
+ for (TagData tagData : added) {
+ Metadata newLink = TaskToTagMetadata.newTagMetadata(taskId, taskUuid, tagData.getName(), tagData.getUuid());
+ metadataDao.createNew(newLink);
}
+ return !removed.isEmpty() || !added.isEmpty();
}
/**
* Delete all links between the specified task and the list of tags
*/
- private void deleteLinks(long taskId, String taskUuid, Iterable tagUuids) {
+ private void deleteLinks(long taskId, String taskUuid, Iterable tags) {
Metadata deleteTemplate = new Metadata();
deleteTemplate.setTask(taskId); // Need this for recording changes in outstanding table
deleteTemplate.setDeletionDate(DateUtilities.now());
- for (String uuid : tagUuids) {
+ for (TagData tag : tags) {
// TODO: Right now this is in a loop because each deleteTemplate needs the individual tagUuid in order to record
// the outstanding entry correctly. If possible, this should be improved to a single query
- deleteTemplate.setValue(TaskToTagMetadata.TAG_UUID, uuid); // Need this for recording changes in outstanding table
+ deleteTemplate.setValue(TaskToTagMetadata.TAG_UUID, tag.getUuid()); // Need this for recording changes in outstanding table
metadataDao.update(Criterion.and(MetadataDao.MetadataCriteria.withKey(TaskToTagMetadata.KEY), Metadata.DELETION_DATE.eq(0),
- TaskToTagMetadata.TASK_UUID.eq(taskUuid), TaskToTagMetadata.TAG_UUID.eq(uuid)), deleteTemplate);
+ TaskToTagMetadata.TASK_UUID.eq(taskUuid), TaskToTagMetadata.TAG_UUID.eq(tag.getUuid())), deleteTemplate);
}
}
}
diff --git a/src/main/java/com/todoroo/astrid/timers/TimerActionControlSet.java b/src/main/java/com/todoroo/astrid/timers/TimerActionControlSet.java
deleted file mode 100644
index e174ab534..000000000
--- a/src/main/java/com/todoroo/astrid/timers/TimerActionControlSet.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- * Copyright (c) 2012 Todoroo Inc
- *
- * See the file "LICENSE" for the full license governing this code.
- */
-package com.todoroo.astrid.timers;
-
-import android.app.Activity;
-import android.graphics.drawable.Drawable;
-import android.os.SystemClock;
-import android.support.v4.graphics.drawable.DrawableCompat;
-import android.text.format.DateFormat;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Chronometer;
-import android.widget.Chronometer.OnChronometerTickListener;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-
-import com.todoroo.andlib.utility.DateUtilities;
-import com.todoroo.astrid.data.Task;
-import com.todoroo.astrid.helper.TaskEditControlSetBase;
-import com.todoroo.astrid.service.TaskService;
-
-import org.tasks.R;
-import org.tasks.notifications.NotificationManager;
-
-import java.util.LinkedList;
-import java.util.List;
-
-public class TimerActionControlSet extends TaskEditControlSetBase {
-
- private final ImageView timerButton;
- private final Chronometer chronometer;
- private boolean timerActive;
- private final List listeners = new LinkedList<>();
-
- public TimerActionControlSet(final NotificationManager notificationManager, final TaskService taskService, final Activity activity, View parent) {
- super(activity, -1);
-
- LinearLayout timerContainer = (LinearLayout) parent.findViewById(R.id.timer_container);
- timerButton = (ImageView) parent.findViewById(R.id.timer_button);
- OnClickListener timerListener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (timerActive) {
- TimerPlugin.stopTimer(notificationManager, taskService, activity, model);
-
- for (TimerActionListener listener : listeners) {
- listener.timerStopped(model);
- }
- chronometer.stop();
- } else {
- TimerPlugin.startTimer(notificationManager, taskService, activity, model);
- for (TimerActionListener listener : listeners) {
- listener.timerStarted(model);
- }
- chronometer.start();
- }
- timerActive = !timerActive;
- updateDisplay();
- }
- };
- timerContainer.setOnClickListener(timerListener);
- chronometer = (Chronometer) parent.findViewById(R.id.timer);
- }
-
- @Override
- protected void readFromTaskOnInitialize() {
- timerActive = model.getTimerStart() != 0;
-
- updateDisplay();
- }
-
- @Override
- protected void afterInflate() {
- // Do nothing
- }
-
- @Override
- protected void writeToModelAfterInitialized(Task task) {
- // Nothing to do here
- }
-
- private void updateDisplay() {
- int drawableRes = timerActive ? R.drawable.ic_pause_24dp : R.drawable.ic_play_arrow_24dp;
- final Drawable drawable = DrawableCompat.wrap(activity.getResources().getDrawable(drawableRes));
- DrawableCompat.setTint(drawable, activity.getResources().getColor(android.R.color.white));
- timerButton.setImageDrawable(drawable);
-
- long elapsed = model.getElapsedSeconds() * 1000L;
- if (timerActive) {
- chronometer.setVisibility(View.VISIBLE);
- elapsed += DateUtilities.now() - model.getTimerStart();
- chronometer.setBase(SystemClock.elapsedRealtime() - elapsed);
- if (elapsed > DateUtilities.ONE_DAY) {
- chronometer.setOnChronometerTickListener(new OnChronometerTickListener() {
- @Override
- public void onChronometerTick(Chronometer cArg) {
- long t = SystemClock.elapsedRealtime() - cArg.getBase();
- cArg.setText(DateFormat.format("d'd' h:mm", t)); //$NON-NLS-1$
- }
- });
-
- }
- chronometer.start();
- } else {
- chronometer.setVisibility(View.GONE);
- chronometer.stop();
- }
- }
-
- @Override
- public int getIcon() {
- return -1;
- }
-
- public interface TimerActionListener {
- void timerStopped(Task task);
- void timerStarted(Task task);
- }
-
- public void addListener(TimerActionListener listener) {
- this.listeners.add(listener);
- }
-
- public void removeListener(TimerActionListener listener) {
- if (listeners.contains(listener)) {
- listeners.remove(listener);
- }
- }
-}
diff --git a/src/main/java/com/todoroo/astrid/timers/TimerActionListener.java b/src/main/java/com/todoroo/astrid/timers/TimerActionListener.java
new file mode 100644
index 000000000..536fcad74
--- /dev/null
+++ b/src/main/java/com/todoroo/astrid/timers/TimerActionListener.java
@@ -0,0 +1,8 @@
+package com.todoroo.astrid.timers;
+
+import com.todoroo.astrid.data.Task;
+
+public interface TimerActionListener {
+ void timerStopped(Task task);
+ void timerStarted(Task task);
+}
diff --git a/src/main/java/com/todoroo/astrid/timers/TimerControlSet.java b/src/main/java/com/todoroo/astrid/timers/TimerControlSet.java
index 71c4a544f..837021824 100644
--- a/src/main/java/com/todoroo/astrid/timers/TimerControlSet.java
+++ b/src/main/java/com/todoroo/astrid/timers/TimerControlSet.java
@@ -1,26 +1,46 @@
/**
* Copyright (c) 2012 Todoroo Inc
- *
+ *
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.timers;
import android.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.support.annotation.Nullable;
+import android.support.v7.app.AlertDialog;
import android.text.TextUtils;
+import android.text.format.DateFormat;
import android.text.format.DateUtils;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Chronometer;
+import android.widget.ImageView;
import android.widget.TextView;
-import com.todoroo.andlib.data.Property.IntegerProperty;
+import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.data.Task;
-import com.todoroo.astrid.helper.TaskEditControlSetBase;
-import com.todoroo.astrid.timers.TimerActionControlSet.TimerActionListener;
-import com.todoroo.astrid.ui.PopupControlSet;
+import com.todoroo.astrid.notes.EditNoteActivity;
import com.todoroo.astrid.ui.TimeDurationControlSet;
import org.tasks.R;
import org.tasks.dialogs.DialogBuilder;
+import org.tasks.injection.ForActivity;
import org.tasks.preferences.ActivityPreferences;
+import org.tasks.ui.TaskEditControlFragment;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import butterknife.Bind;
+import butterknife.OnClick;
/**
* Control Set for managing repeats
@@ -28,104 +48,162 @@ import org.tasks.preferences.ActivityPreferences;
* @author Tim Su
*
*/
-public class TimerControlSet extends PopupControlSet implements TimerActionListener {
+public class TimerControlSet extends TaskEditControlFragment {
- TimeDurationTaskEditControlSet estimated, elapsed;
- private final TextView displayEdit;
- private ActivityPreferences preferences;
+ public interface TimerControlSetCallback {
+ Task stopTimer();
+ Task startTimer();
+ }
- public TimerControlSet(ActivityPreferences preferences, final Activity activity, DialogBuilder dialogBuilder) {
- super(preferences, activity, R.layout.control_set_timers_dialog, R.layout.control_set_timers, R.string.TEA_timer_controls, dialogBuilder);
- this.preferences = preferences;
+ private static final String EXTRA_STARTED = "extra_started";
+ private static final String EXTRA_ESTIMATED = "extra_estimated";
+ private static final String EXTRA_ELAPSED = "extra_elapsed";
- displayEdit = (TextView) getView().findViewById(R.id.display_row_edit);
- displayEdit.setText(R.string.TEA_timer_controls);
- displayEdit.setTextColor(unsetColor);
+ @Inject ActivityPreferences preferences;
+ @Inject DialogBuilder dialogBuilder;
+ @Inject @ForActivity Context context;
- estimated = new TimeDurationTaskEditControlSet(activity, getDialogView(), Task.ESTIMATED_SECONDS,R.id.estimatedDuration);
- elapsed = new TimeDurationTaskEditControlSet(activity, getDialogView(), Task.ELAPSED_SECONDS, R.id.elapsedDuration);
- }
+ @Bind(R.id.display_row_edit) TextView displayEdit;
+ @Bind(R.id.timer) Chronometer chronometer;
+ @Bind(R.id.timer_button) ImageView timerButton;
- @Override
- protected void readFromTaskOnInitialize() {
- estimated.readFromTask(model);
- elapsed.readFromTask(model);
- }
-
- @Override
- protected void afterInflate() {
- // Nothing to do here
- }
+ private TimeDurationControlSet estimated;
+ private TimeDurationControlSet elapsed;
+ private long timerStarted;
+ private final List listeners = new LinkedList<>();
+ protected AlertDialog dialog;
+ private View dialogView;
+ private int elapsedSeconds;
+ private int estimatedSeconds;
+ private TimerControlSetCallback callback;
+ @Nullable
@Override
- protected void writeToModelAfterInitialized(Task task) {
- if (initialized) {
- estimated.writeToModel(task);
- elapsed.writeToModel(task);
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = super.onCreateView(inflater, container, savedInstanceState);
+ if (savedInstanceState != null) {
+ timerStarted = savedInstanceState.getLong(EXTRA_STARTED);
+ elapsedSeconds = savedInstanceState.getInt(EXTRA_ELAPSED);
+ estimatedSeconds = savedInstanceState.getInt(EXTRA_ESTIMATED);
}
+
+ dialogView = inflater.inflate(R.layout.control_set_timers_dialog, null);
+ estimated = new TimeDurationControlSet(context, dialogView, R.id.estimatedDuration, preferences);
+ elapsed = new TimeDurationControlSet(context, dialogView, R.id.elapsedDuration, preferences);
+ estimated.setTimeDuration(estimatedSeconds);
+ elapsed.setTimeDuration(elapsedSeconds);
+ refresh();
+ return view;
}
@Override
- public int getIcon() {
- return R.drawable.ic_timer_24dp;
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+
+ callback = (TimerControlSetCallback) activity;
}
- // --- TimeDurationTaskEditControlSet
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
- /**
- * Control set for mapping a Property to a TimeDurationControlSet
- * @author Tim Su
- *
- */
- public class TimeDurationTaskEditControlSet extends TaskEditControlSetBase {
- private final TimeDurationControlSet controlSet;
- private final IntegerProperty property;
+ outState.putInt(EXTRA_ELAPSED, elapsed.getTimeDurationInSeconds());
+ outState.putInt(EXTRA_ESTIMATED, estimated.getTimeDurationInSeconds());
+ outState.putLong(EXTRA_STARTED, timerStarted);
+ }
- public TimeDurationTaskEditControlSet(Activity activity, View v, IntegerProperty property, int timeButtonId) {
- super(activity, -1);
- this.property = property;
- this.controlSet = new TimeDurationControlSet(activity, v, property, timeButtonId, preferences);
+ @OnClick(R.id.display_row_edit)
+ void openPopup(View view) {
+ if (dialog == null) {
+ buildDialog();
}
+ dialog.show();
+ }
- @Override
- public void readFromTaskOnInitialize() {
- controlSet.setModel(model);
- controlSet.setTimeDuration(model.getValue(property));
- }
+ protected Dialog buildDialog() {
+ AlertDialog.Builder builder = dialogBuilder.newDialog()
+ .setView(dialogView)
+ .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ refreshDisplayView();
+ }
+ })
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ refreshDisplayView();
+ }
+ });
+ dialog = builder.show();
+ return dialog;
+ }
- @Override
- protected void afterInflate() {
- // Nothing
+ @OnClick(R.id.timer_container)
+ void timerClicked(View view) {
+ if (timerActive()) {
+ Task task = callback.stopTimer();
+ elapsed.setTimeDuration(task.getElapsedSeconds());
+ timerStarted = 0;
+ for (TimerActionListener listener : listeners) {
+ listener.timerStopped(task);
+ }
+ chronometer.stop();
+ refreshDisplayView();
+ } else {
+ Task task = callback.startTimer();
+ timerStarted = task.getTimerStart();
+ chronometer.start();
+ for (TimerActionListener listener : listeners) {
+ listener.timerStarted(task);
+ }
}
+ updateChronometer();
+ }
- @Override
- protected void writeToModelAfterInitialized(Task task) {
- task.setValue(property, controlSet.getTimeDurationInSeconds());
- }
+ @Override
+ protected int getLayout() {
+ return R.layout.control_set_timers;
+ }
- public String getDisplayString() {
- int seconds = controlSet.getTimeDurationInSeconds();
- if (seconds > 0) {
- return DateUtils.formatElapsedTime(controlSet.getTimeDurationInSeconds());
- }
- return null;
- }
+ @Override
+ public int getIcon() {
+ return R.drawable.ic_timer_24dp;
+ }
- @Override
- public int getIcon() {
- return -1;
- }
+ @Override
+ public void initialize(boolean isNewTask, Task task) {
+ timerStarted = task.getTimerStart();
+ elapsedSeconds = task.getElapsedSeconds();
+ estimatedSeconds = task.getEstimatedSeconds();
}
@Override
- protected void refreshDisplayView() {
- String est = estimated.getDisplayString();
- if (!TextUtils.isEmpty(est)) {
- est = activity.getString(R.string.TEA_timer_est, est);
+ public void apply(Task task) {
+ task.setElapsedSeconds(elapsed.getTimeDurationInSeconds());
+ task.setEstimatedSeconds(estimated.getTimeDurationInSeconds());
+ }
+
+ public void setEditNotes(EditNoteActivity editNotes) {
+ removeListener(editNotes);
+ addListener(editNotes);
+ }
+
+ private void refresh() {
+ refreshDisplayView();
+ updateChronometer();
+ }
+
+ private void refreshDisplayView() {
+ String est = null;
+ int estimatedSeconds = estimated.getTimeDurationInSeconds();
+ if (estimatedSeconds > 0) {
+ est = getString(R.string.TEA_timer_est, DateUtils.formatElapsedTime(estimatedSeconds));
}
- String elap = elapsed.getDisplayString();
- if (!TextUtils.isEmpty(elap)) {
- elap = activity.getString(R.string.TEA_timer_elap, elap);
+ String elap = null;
+ int elapsedSeconds = elapsed.getTimeDurationInSeconds();
+ if (elapsedSeconds > 0) {
+ elap = getString(R.string.TEA_timer_elap, DateUtils.formatElapsedTime(elapsedSeconds));
}
String toDisplay;
@@ -142,20 +220,51 @@ public class TimerControlSet extends PopupControlSet implements TimerActionListe
if (!TextUtils.isEmpty(toDisplay)) {
displayEdit.setText(toDisplay);
- displayEdit.setTextColor(themeColor);
+ displayEdit.setAlpha(1.0f);
} else {
displayEdit.setText(R.string.TEA_timer_controls);
- displayEdit.setTextColor(unsetColor);
+ displayEdit.setAlpha(0.5f);
}
}
- @Override
- public void timerStopped(Task task) {
- elapsed.readFromTask(task);
+ private void updateChronometer() {
+ timerButton.setImageResource(timerActive()
+ ? R.drawable.ic_pause_24dp
+ : R.drawable.ic_play_arrow_24dp);
+
+ long elapsed = this.elapsed.getTimeDurationInSeconds() * 1000L;
+ if (timerActive()) {
+ chronometer.setVisibility(View.VISIBLE);
+ elapsed += DateUtilities.now() - timerStarted;
+ chronometer.setBase(SystemClock.elapsedRealtime() - elapsed);
+ if (elapsed > DateUtilities.ONE_DAY) {
+ chronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
+ @Override
+ public void onChronometerTick(Chronometer cArg) {
+ long t = SystemClock.elapsedRealtime() - cArg.getBase();
+ cArg.setText(DateFormat.format("d'd' h:mm", t)); //$NON-NLS-1$
+ }
+ });
+
+ }
+ chronometer.start();
+ } else {
+ chronometer.setVisibility(View.GONE);
+ chronometer.stop();
+ }
}
- @Override
- public void timerStarted(Task task) {
+ public void addListener(TimerActionListener listener) {
+ this.listeners.add(listener);
+ }
+
+ public void removeListener(TimerActionListener listener) {
+ if (listeners.contains(listener)) {
+ listeners.remove(listener);
+ }
}
+ private boolean timerActive() {
+ return timerStarted > 0;
+ }
}
diff --git a/src/main/java/com/todoroo/astrid/timers/TimerPlugin.java b/src/main/java/com/todoroo/astrid/timers/TimerPlugin.java
index c5df3935d..759c4b196 100644
--- a/src/main/java/com/todoroo/astrid/timers/TimerPlugin.java
+++ b/src/main/java/com/todoroo/astrid/timers/TimerPlugin.java
@@ -61,8 +61,7 @@ public class TimerPlugin {
if(task.getTimerStart() > 0) {
int newElapsed = (int)((DateUtilities.now() - task.getTimerStart()) / 1000L);
task.setTimerStart(0L);
- task.setELAPSED_SECONDS(
- task.getElapsedSeconds() + newElapsed);
+ task.setElapsedSeconds(task.getElapsedSeconds() + newElapsed);
}
}
taskService.save(task);
diff --git a/src/main/java/com/todoroo/astrid/ui/DeadlineNumberPicker.java b/src/main/java/com/todoroo/astrid/ui/DeadlineNumberPicker.java
deleted file mode 100644
index 69c3f5afd..000000000
--- a/src/main/java/com/todoroo/astrid/ui/DeadlineNumberPicker.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * Copyright (c) 2012 Todoroo Inc
- *
- * See the file "LICENSE" for the full license governing this code.
- */
-package com.todoroo.astrid.ui;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-import org.tasks.R;
-
-public class DeadlineNumberPicker extends NumberPicker {
-
- public DeadlineNumberPicker(Context context) {
- super(context);
- }
-
- public DeadlineNumberPicker(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected int getLayout() {
- return R.layout.deadline_number_picker;
- }
-
- @Override
- protected int getMaxDigits() {
- return 2;
- }
-}
diff --git a/src/main/java/com/todoroo/astrid/ui/DescriptionControlSet.java b/src/main/java/com/todoroo/astrid/ui/DescriptionControlSet.java
deleted file mode 100644
index 524556281..000000000
--- a/src/main/java/com/todoroo/astrid/ui/DescriptionControlSet.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * Copyright (c) 2012 Todoroo Inc
- *
- * See the file "LICENSE" for the full license governing this code.
- */
-package com.todoroo.astrid.ui;
-
-import android.app.Activity;
-import android.widget.EditText;
-
-import com.todoroo.astrid.data.Task;
-import com.todoroo.astrid.helper.TaskEditControlSetBase;
-
-import org.tasks.R;
-
-public class DescriptionControlSet extends TaskEditControlSetBase {
-
- protected EditText editText;
-
- public DescriptionControlSet(Activity activity) {
- super(activity, R.layout.control_set_description);
- }
-
- @Override
- protected void afterInflate() {
- editText = (EditText) getView().findViewById(R.id.notes);
- }
-
- @Override
- protected void readFromTaskOnInitialize() {
- editText.setTextKeepState(model.getNotes());
- }
-
- @Override
- protected void writeToModelAfterInitialized(Task task) {
- task.setNotes(editText.getText().toString().trim());
- }
-
- @Override
- public int getIcon() {
- return R.drawable.ic_event_note_24dp;
- }
-}
diff --git a/src/main/java/com/todoroo/astrid/ui/EditTitleControlSet.java b/src/main/java/com/todoroo/astrid/ui/EditTitleControlSet.java
index 8ecf138b1..61c635a41 100644
--- a/src/main/java/com/todoroo/astrid/ui/EditTitleControlSet.java
+++ b/src/main/java/com/todoroo/astrid/ui/EditTitleControlSet.java
@@ -7,53 +7,85 @@ package com.todoroo.astrid.ui;
import android.app.Activity;
import android.graphics.Paint;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.KeyEvent;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
+import android.view.ViewGroup;
+import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.astrid.data.Task;
-import com.todoroo.astrid.helper.TaskEditControlSet;
-import com.todoroo.astrid.repeats.RepeatControlSet.RepeatChangedListener;
import com.todoroo.astrid.service.TaskService;
+import org.tasks.R;
import org.tasks.ui.CheckBoxes;
-import org.tasks.ui.PriorityControlSet.ImportanceChangedListener;
+import org.tasks.ui.TaskEditControlFragment;
+
+import javax.inject.Inject;
+
+import butterknife.Bind;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
/**
* Control set for mapping a Property to an EditText
* @author Tim Su
*
*/
-public class EditTitleControlSet implements TaskEditControlSet, ImportanceChangedListener, RepeatChangedListener {
+public class EditTitleControlSet extends TaskEditControlFragment {
+
+ private static final String EXTRA_COMPLETE = "extra_complete";
+ private static final String EXTRA_TITLE = "extra_title";
+ private static final String EXTRA_REPEATING = "extra_repeating";
+ private static final String EXTRA_PRIORITY = "extra_priority";
- private final EditText editText;
- private CheckableImageView completeBox;
+ @Inject TaskService taskService;
- private final CheckBoxes checkBoxes;
+ @Bind(R.id.title) EditText editText;
+ @Bind(R.id.completeBox) CheckableImageView completeBox;
+
+ private CheckBoxes checkBoxes;
+ private boolean isComplete;
private boolean isRepeating;
private int importanceValue;
- private Task model;
- private final TaskService taskService;
+ private boolean isNewTask;
+ private String title;
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
- public EditTitleControlSet(TaskService taskService, final Activity activity, final EditText editText, CheckableImageView completeBox) {
- this.checkBoxes = new CheckBoxes(activity);
- this.editText = editText;
- this.completeBox = completeBox;
- this.taskService = taskService;
+ checkBoxes = new CheckBoxes(activity);
+ }
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(getLayout(), null);
+ ButterKnife.bind(this, view);
+ if (savedInstanceState != null) {
+ isComplete = savedInstanceState.getBoolean(EXTRA_COMPLETE);
+ title = savedInstanceState.getString(EXTRA_TITLE);
+ isRepeating = savedInstanceState.getBoolean(EXTRA_REPEATING);
+ importanceValue = savedInstanceState.getInt(EXTRA_PRIORITY);
+ }
+ completeBox.setChecked(isComplete);
+ editText.setTextKeepState(title);
editText.setHorizontallyScrolling(false);
editText.setMaxLines(Integer.MAX_VALUE);
editText.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
- AndroidUtilities.hideSoftInputForViews(activity, editText);
+ AndroidUtilities.hideSoftInputForViews(getActivity(), editText);
return true;
}
return false;
@@ -74,39 +106,46 @@ public class EditTitleControlSet implements TaskEditControlSet, ImportanceChange
return false;
}
});
+ updateCompleteBox();
+ return view;
}
- protected void readFromTaskOnInitialize() {
- editText.setTextKeepState(model.getTitle());
- completeBox.setChecked(model.isCompleted());
- completeBox.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // set check box to actual action item state
- updateCompleteBox();
- }
- });
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putBoolean(EXTRA_COMPLETE, completeBox.isChecked());
+ outState.putString(EXTRA_TITLE, getTitle());
+ outState.putBoolean(EXTRA_REPEATING, isRepeating);
+ outState.putInt(EXTRA_PRIORITY, importanceValue);
}
- @Override
- public void importanceChanged(int i) {
- importanceValue = i;
+ @OnClick(R.id.completeBox)
+ void toggleComplete(View view) {
updateCompleteBox();
}
-
@Override
- public void repeatChanged(boolean repeat) {
- isRepeating = repeat;
+ public void onStart() {
+ super.onStart();
+
+ if (isNewTask) {
+ editText.requestFocus();
+ editText.setCursorVisible(true);
+ getActivity().getWindow()
+ .setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
+ | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
+ }
+ }
+
+ public void setPriority(int priority) {
+ importanceValue = priority;
updateCompleteBox();
}
- @Override
- public void readFromTask(Task task) {
- this.model = task;
- readFromTaskOnInitialize();
- isRepeating = !TextUtils.isEmpty(task.getRecurrence());
- importanceValue = model.getImportance();
+ public void repeatChanged(boolean repeat) {
+ isRepeating = repeat;
+ updateCompleteBox();
}
private void updateCompleteBox() {
@@ -128,12 +167,8 @@ public class EditTitleControlSet implements TaskEditControlSet, ImportanceChange
}
@Override
- public void writeToModel(Task task) {
- task.setTitle(editText.getText().toString());
- boolean newState = completeBox.isChecked();
- if (newState != task.isCompleted()) {
- taskService.setComplete(task, newState);
- }
+ protected int getLayout() {
+ return R.layout.control_set_title;
}
@Override
@@ -142,7 +177,30 @@ public class EditTitleControlSet implements TaskEditControlSet, ImportanceChange
}
@Override
- public View getView() {
- throw new RuntimeException();
+ public void initialize(boolean isNewTask, Task task) {
+ this.isNewTask = isNewTask;
+
+ isComplete = task.isCompleted();
+ title = task.getTitle();
+ isRepeating = !TextUtils.isEmpty(task.getRecurrence());
+ importanceValue = task.getImportance();
+ }
+
+ @Override
+ public void apply(Task task) {
+ task.setTitle(getTitle());
+ boolean newState = completeBox.isChecked();
+ if (newState != task.isCompleted()) {
+ taskService.setComplete(task, newState);
+ }
+ }
+
+ public String getTitle() {
+ return editText.getText().toString();
+ }
+
+ public void hideKeyboard() {
+ AndroidUtilities.hideSoftInputForViews(getActivity(), editText);
+ editText.setCursorVisible(false);
}
}
diff --git a/src/main/java/com/todoroo/astrid/ui/HideUntilControlSet.java b/src/main/java/com/todoroo/astrid/ui/HideUntilControlSet.java
index 771da5fa8..08bb4dfb6 100644
--- a/src/main/java/com/todoroo/astrid/ui/HideUntilControlSet.java
+++ b/src/main/java/com/todoroo/astrid/ui/HideUntilControlSet.java
@@ -5,9 +5,14 @@
*/
package com.todoroo.astrid.ui;
+import android.app.Activity;
+import android.content.Context;
import android.content.Intent;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
import android.view.View;
-import android.view.View.OnClickListener;
+import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
@@ -16,18 +21,24 @@ import android.widget.Spinner;
import android.widget.TextView;
import com.todoroo.andlib.utility.DateUtilities;
-import com.todoroo.astrid.activity.TaskEditFragment;
import com.todoroo.astrid.data.Task;
-import com.todoroo.astrid.helper.TaskEditControlSetBase;
import org.tasks.R;
import org.tasks.activities.DateAndTimePickerActivity;
+import org.tasks.activities.TimePickerActivity;
+import org.tasks.injection.ForActivity;
import org.tasks.time.DateTime;
import org.tasks.ui.HiddenTopArrayAdapter;
+import org.tasks.ui.TaskEditControlFragment;
import java.util.ArrayList;
import java.util.List;
+import javax.inject.Inject;
+
+import butterknife.Bind;
+import butterknife.OnClick;
+
import static java.util.Arrays.asList;
import static org.tasks.date.DateTimeUtils.newDateTime;
@@ -37,29 +48,145 @@ import static org.tasks.date.DateTimeUtils.newDateTime;
* @author Tim Su
*
*/
-public class HideUntilControlSet extends TaskEditControlSetBase implements OnItemSelectedListener {
+public class HideUntilControlSet extends TaskEditControlFragment implements OnItemSelectedListener {
+
+ private static String EXTRA_CUSTOM = "extra_custom";
+ private static String EXTRA_SELECTION = "extra_selection";
private static final int SPECIFIC_DATE = -1;
private static final int EXISTING_TIME_UNSET = -2;
- public static final int REQUEST_HIDE_UNTIL = 11011;
+ private static final int REQUEST_HIDE_UNTIL = 11011;
+
+ @Inject @ForActivity Context context;
//private final CheckBox enabled;
- private Spinner spinner;
+ @Bind(R.id.hideUntil) Spinner spinner;
+ @Bind(R.id.clear) ImageView clearButton;
+
+ private ArrayAdapter adapter;
+ private long initialHideUntil;
+
private int previousSetting = Task.HIDE_UNTIL_NONE;
private int selection;
-
private long existingDate = EXISTING_TIME_UNSET;
- private TaskEditFragment taskEditFragment;
- private TextView textDisplay;
- private ImageView clearButton;
private final List spinnerItems = new ArrayList<>();
- public HideUntilControlSet(TaskEditFragment taskEditFragment) {
- super(taskEditFragment.getActivity(), R.layout.control_set_hide);
- this.taskEditFragment = taskEditFragment;
+ @OnClick(R.id.clear)
+ void clearHideUntil(View view) {
+ updateSpinnerOptions(0);
+ selection = 0;
+ spinner.setSelection(selection);
+ refreshDisplayView();
}
- private ArrayAdapter adapter;
+ @Nullable
+ @Override
+ public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = super.onCreateView(inflater, container, savedInstanceState);
+ adapter = new HiddenTopArrayAdapter(context, android.R.layout.simple_spinner_item, spinnerItems) {
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ int selectedItemPosition = position;
+ if (parent instanceof AdapterView) {
+ selectedItemPosition = ((AdapterView) parent).getSelectedItemPosition();
+ }
+ TextView tv = (TextView) inflater.inflate(android.R.layout.simple_spinner_item, parent, false);
+ HideUntilValue value = getItem(selectedItemPosition);
+ if (value.setting == Task.HIDE_UNTIL_NONE) {
+ clearButton.setVisibility(View.GONE);
+ tv.setText(value.label);
+ } else {
+ String display = value.label;
+ if (value.setting != Task.HIDE_UNTIL_SPECIFIC_DAY && value.setting != Task.HIDE_UNTIL_SPECIFIC_DAY_TIME) {
+ display = display.toLowerCase();
+ }
+ tv.setText(getString(R.string.TEA_hideUntil_display, display));
+ }
+ return tv;
+ }
+ };
+ if (savedInstanceState == null) {
+ updateSpinnerOptions(initialHideUntil);
+ } else {
+ updateSpinnerOptions(savedInstanceState.getLong(EXTRA_CUSTOM));
+ selection = savedInstanceState.getInt(EXTRA_SELECTION);
+ }
+ spinner.setAdapter(adapter);
+ spinner.setSelection(selection);
+ spinner.setOnItemSelectedListener(this);
+ refreshDisplayView();
+ return view;
+ }
+
+ @Override
+ protected int getLayout() {
+ return R.layout.control_set_hide;
+ }
+
+ @Override
+ protected int getIcon() {
+ return R.drawable.ic_visibility_off_24dp;
+ }
+
+ @Override
+ public void initialize(boolean isNewTask, Task task) {
+ long dueDate = task.getDueDate();
+ long hideUntil = task.getHideUntil();
+
+ DateTime dueDay = newDateTime(dueDate)
+ .withHourOfDay(0)
+ .withMinuteOfHour(0)
+ .withSecondOfMinute(0)
+ .withMillisOfSecond(0);
+
+ // For the hide until due case, we need the time component
+ long dueTime = dueDate/1000L*1000L;
+
+ if(hideUntil == 0) {
+ selection = 0;
+ hideUntil = 0;
+ } else if(hideUntil == dueDay.getMillis()) {
+ selection = 1;
+ hideUntil = 0;
+ } else if (hideUntil == dueTime){
+ selection = 2;
+ hideUntil = 0;
+ } else if(hideUntil + DateUtilities.ONE_DAY == dueDay.getMillis()) {
+ selection = 3;
+ hideUntil = 0;
+ } else if(hideUntil + DateUtilities.ONE_WEEK == dueDay.getMillis()) {
+ selection = 4;
+ hideUntil = 0;
+ }
+
+ initialHideUntil = hideUntil;
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_HIDE_UNTIL) {
+ if (resultCode == Activity.RESULT_OK) {
+ setCustomDate(data.getLongExtra(TimePickerActivity.EXTRA_TIMESTAMP, 0L));
+ }
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+
+ @Override
+ public void apply(Task task) {
+ HideUntilValue selectedItem = (HideUntilValue) spinner.getSelectedItem();
+ long hideUntil = task.createHideUntil(selectedItem.setting, selectedItem.date);
+ task.setHideUntil(hideUntil);
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putLong(EXTRA_CUSTOM, existingDate);
+ outState.putInt(EXTRA_SELECTION, selection);
+ }
/**
* Container class for urgencies
@@ -91,7 +218,7 @@ public class HideUntilControlSet extends TaskEditControlSetBase implements OnIte
private void updateSpinnerOptions(long specificDate) {
spinnerItems.clear();
// set up base values
- String[] labels = activity.getResources().getStringArray(R.array.TEA_hideUntil);
+ String[] labels = getResources().getStringArray(R.array.TEA_hideUntil);
spinnerItems.addAll(new ArrayList<>(asList(
new HideUntilValue(labels[0], Task.HIDE_UNTIL_DUE),
new HideUntilValue(labels[1], Task.HIDE_UNTIL_DUE_TIME),
@@ -100,22 +227,26 @@ public class HideUntilControlSet extends TaskEditControlSetBase implements OnIte
new HideUntilValue(labels[4], Task.HIDE_UNTIL_SPECIFIC_DAY, -1))));
if(specificDate > 0) {
- DateTime hideUntilAsDate = newDateTime(specificDate);
- if(hideUntilAsDate.getHourOfDay() == 0 && hideUntilAsDate.getMinuteOfHour() == 0 && hideUntilAsDate.getSecondOfMinute() == 0) {
- spinnerItems.add(0, new HideUntilValue(DateUtilities.getDateString(newDateTime(specificDate)),
- Task.HIDE_UNTIL_SPECIFIC_DAY, specificDate));
- } else {
- spinnerItems.add(0, new HideUntilValue(DateUtilities.getDateStringWithTime(activity, specificDate),
- Task.HIDE_UNTIL_SPECIFIC_DAY_TIME, specificDate));
- }
+ spinnerItems.add(0, getHideUntilValue(specificDate));
existingDate = specificDate;
} else {
- spinnerItems.add(0, new HideUntilValue("", Task.HIDE_UNTIL_NONE));
+ spinnerItems.add(0, new HideUntilValue(getString(R.string.TEA_hideUntil_label), Task.HIDE_UNTIL_NONE));
existingDate = EXISTING_TIME_UNSET;
}
adapter.notifyDataSetChanged();
}
+ private HideUntilValue getHideUntilValue(long timestamp) {
+ DateTime hideUntilAsDate = newDateTime(timestamp);
+ if(hideUntilAsDate.getHourOfDay() == 0 && hideUntilAsDate.getMinuteOfHour() == 0 && hideUntilAsDate.getSecondOfMinute() == 0) {
+ return new HideUntilValue(DateUtilities.getDateString(newDateTime(timestamp)),
+ Task.HIDE_UNTIL_SPECIFIC_DAY, timestamp);
+ } else {
+ return new HideUntilValue(DateUtilities.getDateStringWithTime(context, timestamp),
+ Task.HIDE_UNTIL_SPECIFIC_DAY_TIME, timestamp);
+ }
+ }
+
// --- listening for events
@Override
@@ -124,11 +255,12 @@ public class HideUntilControlSet extends TaskEditControlSetBase implements OnIte
// ... at conclusion of dialog, update our list
HideUntilValue item = adapter.getItem(position);
if(item.date == SPECIFIC_DATE) {
- customDate =
+ final DateTime customDate =
newDateTime(existingDate == EXISTING_TIME_UNSET ? DateUtilities.now() : existingDate)
.withSecondOfMinute(0);
- taskEditFragment.startActivityForResult(new Intent(taskEditFragment.getActivity(), DateAndTimePickerActivity.class) {{
+ final Activity activity = getActivity();
+ startActivityForResult(new Intent(activity, DateAndTimePickerActivity.class) {{
putExtra(DateAndTimePickerActivity.EXTRA_TIMESTAMP, customDate.getMillis());
}}, REQUEST_HIDE_UNTIL);
spinner.setSelection(previousSetting);
@@ -140,8 +272,9 @@ public class HideUntilControlSet extends TaskEditControlSetBase implements OnIte
}
public void setCustomDate(long timestamp) {
- customDate = new DateTime(timestamp);
- customDateFinished();
+ updateSpinnerOptions(timestamp);
+ spinner.setSelection(0);
+ refreshDisplayView();
}
@Override
@@ -149,121 +282,16 @@ public class HideUntilControlSet extends TaskEditControlSetBase implements OnIte
// ignore
}
- DateTime customDate;
-
- private void customDateFinished() {
- updateSpinnerOptions(customDate.getMillis());
- spinner.setSelection(0);
- refreshDisplayView();
- }
-
// --- setting up values
private void refreshDisplayView() {
HideUntilValue value = adapter.getItem(selection);
if (value.setting == Task.HIDE_UNTIL_NONE) {
- textDisplay.setText(R.string.TEA_hideUntil_label);
- textDisplay.setTextColor(unsetColor);
+ spinner.setAlpha(0.5f);
clearButton.setVisibility(View.GONE);
} else {
- String display = value.toString();
- if (value.setting != Task.HIDE_UNTIL_SPECIFIC_DAY && value.setting != Task.HIDE_UNTIL_SPECIFIC_DAY_TIME) {
- display = display.toLowerCase();
- }
-
- textDisplay.setText(activity.getString(R.string.TEA_hideUntil_display, display));
- textDisplay.setTextColor(themeColor);
+ spinner.setAlpha(1.0f);
clearButton.setVisibility(View.VISIBLE);
}
}
-
- @Override
- protected void afterInflate() {
- textDisplay = (TextView) getView().findViewById(R.id.display_row_edit);
- clearButton = (ImageView) getView().findViewById(R.id.clear);
- clearButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- updateSpinnerOptions(0);
- selection = 0;
- spinner.setSelection(selection);
- refreshDisplayView();
- }
- });
- textDisplay.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (spinner == null) {
- getView();
- }
- spinner.performClick();
- }
- });
- this.spinner = (Spinner) getView().findViewById(R.id.hideUntil);
- adapter = new HiddenTopArrayAdapter<>(activity, android.R.layout.simple_spinner_item, spinnerItems);
- spinner.setAdapter(adapter);
- this.spinner.setOnItemSelectedListener(this);
- }
-
- @Override
- public void readFromTask(Task task) {
- long date = task.getHideUntil();
-
- DateTime dueDay = newDateTime(task.getDueDate())
- .withHourOfDay(0)
- .withMinuteOfHour(0)
- .withSecondOfMinute(0)
- .withMillisOfSecond(0);
-
- // For the hide until due case, we need the time component
- long dueTime = task.getDueDate()/1000L*1000L;
-
- if(date == 0) {
- selection = 0;
- date = 0;
- } else if(date == dueDay.getMillis()) {
- selection = 1;
- date = 0;
- } else if (date == dueTime){
- selection = 2;
- date = 0;
- } else if(date + DateUtilities.ONE_DAY == dueDay.getMillis()) {
- selection = 3;
- date = 0;
- } else if(date + DateUtilities.ONE_WEEK == dueDay.getMillis()) {
- selection = 4;
- date = 0;
- }
-
- updateSpinnerOptions(date);
-
- super.readFromTask(task);
- }
-
- @Override
- public int getIcon() {
- return R.drawable.ic_visibility_off_24dp;
- }
-
- @Override
- protected void readFromTaskOnInitialize() {
- adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- spinner.setAdapter(adapter);
-
- spinner.setSelection(selection);
- refreshDisplayView();
- }
-
- @Override
- protected void writeToModelAfterInitialized(Task task) {
- if(adapter == null || spinner == null) {
- return;
- }
- HideUntilValue item = adapter.getItem(spinner.getSelectedItemPosition());
- if(item == null) {
- return;
- }
- long value = task.createHideUntil(item.setting, item.date);
- task.setHideUntil(value);
- }
}
diff --git a/src/main/java/com/todoroo/astrid/ui/PopupControlSet.java b/src/main/java/com/todoroo/astrid/ui/PopupControlSet.java
deleted file mode 100644
index d82211493..000000000
--- a/src/main/java/com/todoroo/astrid/ui/PopupControlSet.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/**
- * Copyright (c) 2012 Todoroo Inc
- *
- * See the file "LICENSE" for the full license governing this code.
- */
-package com.todoroo.astrid.ui;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.DialogInterface;
-import android.support.v7.app.AlertDialog;
-import android.view.View;
-import android.view.View.OnClickListener;
-
-import com.todoroo.astrid.data.Task;
-import com.todoroo.astrid.helper.TaskEditControlSetBase;
-
-import org.tasks.dialogs.DialogBuilder;
-import org.tasks.preferences.ActivityPreferences;
-
-public abstract class PopupControlSet extends TaskEditControlSetBase {
-
- protected final View displayView;
- protected final ActivityPreferences preferences;
- private DialogBuilder dialogBuilder;
- protected AlertDialog dialog;
- private final String titleString;
-
- public interface PopupDialogClickListener {
- boolean onClick(DialogInterface d, int which);
- }
-
- final PopupDialogClickListener okListener = new PopupDialogClickListener() {
- @Override
- public boolean onClick(DialogInterface d, int which) {
- onOkClick();
- return true;
- }
- };
-
- final DialogInterface.OnCancelListener cancelListener = new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface d) {
- onCancelClick();
- }
- };
-
- public PopupControlSet(ActivityPreferences preferences, Activity activity, int viewLayout,
- int taskEditViewLayout, final int title, DialogBuilder dialogBuilder) {
- super(activity, viewLayout, false);
- this.preferences = preferences;
- this.dialogBuilder = dialogBuilder;
- if (taskEditViewLayout != -1) {
- this.displayView = inflateWithTemplate(taskEditViewLayout);
- } else {
- this.displayView = null;
- }
-
- titleString = (title > 0) ? activity.getString(title) : ""; //$NON-NLS-1$
-
- if (displayView != null) {
- displayView.setOnClickListener(getDisplayClickListener());
- }
- }
-
- @Override
- public View getView() {
- return displayView;
- }
-
- protected View getDialogView() {
- return super.getView();
- }
-
- protected Dialog buildDialog(String title, final PopupDialogClickListener okClickListener, DialogInterface.OnCancelListener cancelClickListener) {
- AlertDialog.Builder builder = dialogBuilder.newDialog()
- .setView(getDialogView())
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (okClickListener.onClick(dialog, 0)) {
- dialog.dismiss();
- }
- }
- })
- .setOnCancelListener(cancelClickListener);
- dialog = builder.show();
- return dialog;
- }
-
- protected OnClickListener getDisplayClickListener() {
- return new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (dialog == null) {
- buildDialog(titleString, okListener, cancelListener);
- }
- dialog.show();
- }
- };
- }
-
- protected void onOkClick() {
- refreshDisplayView();
- }
-
- protected void onCancelClick() {
- refreshDisplayView();
- }
-
- public Dialog getDialog() {
- return dialog;
- }
-
- @Override
- public void writeToModel(Task task) {
- if (initialized && dialog != null) {
- dialog.dismiss();
- }
- super.writeToModel(task);
- }
-
- @Override
- public void readFromTask(Task task) {
- super.readFromTask(task);
- refreshDisplayView();
- }
-
- protected abstract void refreshDisplayView();
-}
diff --git a/src/main/java/com/todoroo/astrid/ui/RandomReminderControlSet.java b/src/main/java/com/todoroo/astrid/ui/RandomReminderControlSet.java
index b9b577cfb..d6efad2ef 100644
--- a/src/main/java/com/todoroo/astrid/ui/RandomReminderControlSet.java
+++ b/src/main/java/com/todoroo/astrid/ui/RandomReminderControlSet.java
@@ -5,13 +5,12 @@
*/
package com.todoroo.astrid.ui;
-import android.app.Activity;
+import android.content.Context;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import com.todoroo.andlib.utility.DateUtilities;
-import com.todoroo.astrid.data.Task;
import org.tasks.R;
@@ -27,35 +26,26 @@ public class RandomReminderControlSet {
private final int[] hours;
- public RandomReminderControlSet(Activity activity, View parentView) {
+ public RandomReminderControlSet(Context context, View parentView, long reminderPeriod) {
periodSpinner = (Spinner) parentView.findViewById(R.id.reminder_random_interval);
periodSpinner.setVisibility(View.VISIBLE);
// create adapter
ArrayAdapter adapter = new ArrayAdapter<>(
- activity, android.R.layout.simple_spinner_item,
- activity.getResources().getStringArray(R.array.TEA_reminder_random));
+ context, android.R.layout.simple_spinner_item,
+ context.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);
+ String[] hourStrings = context.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]);
}
- }
-
- public void readFromTaskOnInitialize(Task model) {
- long time = model.getReminderPeriod();
-
- if(time <= 0) {
- /* default interval for spinner if date is unselected */
- time = DateUtilities.ONE_WEEK * 2;
- }
int i;
for(i = 0; i < hours.length - 1; i++) {
- if (hours[i] * DateUtilities.ONE_HOUR >= time) {
+ if (hours[i] * DateUtilities.ONE_HOUR >= reminderPeriod) {
break;
}
}
diff --git a/src/main/java/com/todoroo/astrid/ui/ReminderControlSet.java b/src/main/java/com/todoroo/astrid/ui/ReminderControlSet.java
index ad2396c0d..6049b7237 100644
--- a/src/main/java/com/todoroo/astrid/ui/ReminderControlSet.java
+++ b/src/main/java/com/todoroo/astrid/ui/ReminderControlSet.java
@@ -5,41 +5,55 @@
*/
package com.todoroo.astrid.ui;
+import android.app.Activity;
+import android.content.Context;
import android.content.Intent;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
-import android.widget.AdapterView;
+import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
+import com.google.common.primitives.Longs;
import com.todoroo.andlib.data.Callback;
import com.todoroo.andlib.utility.DateUtilities;
-import com.todoroo.astrid.activity.TaskEditFragment;
import com.todoroo.astrid.alarms.AlarmFields;
import com.todoroo.astrid.alarms.AlarmService;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task;
-import com.todoroo.astrid.helper.TaskEditControlSetBase;
import org.tasks.R;
import org.tasks.activities.DateAndTimePickerActivity;
+import org.tasks.activities.TimePickerActivity;
+import org.tasks.injection.ForActivity;
import org.tasks.location.Geofence;
import org.tasks.location.GeofenceService;
import org.tasks.location.PlacePicker;
import org.tasks.preferences.Device;
import org.tasks.preferences.PermissionRequestor;
+import org.tasks.preferences.Preferences;
import org.tasks.ui.HiddenTopArrayAdapter;
+import org.tasks.ui.TaskEditControlFragment;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
-import timber.log.Timber;
+import javax.inject.Inject;
+import butterknife.Bind;
+import butterknife.OnClick;
+import butterknife.OnItemSelected;
+
+import static com.google.common.collect.Lists.newArrayList;
import static com.todoroo.andlib.utility.DateUtilities.getLongDateStringWithTime;
import static org.tasks.date.DateTimeUtils.newDateTime;
@@ -49,40 +63,227 @@ import static org.tasks.date.DateTimeUtils.newDateTime;
* @author Tim Su
*
*/
-public class ReminderControlSet extends TaskEditControlSetBase implements AdapterView.OnItemSelectedListener {
+public class ReminderControlSet extends TaskEditControlFragment {
+
+ private static final int REQUEST_NEW_ALARM = 12152;
+ private static final int REQUEST_LOCATION_REMINDER = 12153;
+
+ private static final String EXTRA_TASK_ID = "extra_task_id";
+ private static final String EXTRA_FLAGS = "extra_flags";
+ private static final String EXTRA_RANDOM_REMINDER = "extra_random_reminder";
+ private static final String EXTRA_ALARMS = "extra_alarms";
+ private static final String EXTRA_GEOFENCES = "extra_geofences";
+
+ @Inject AlarmService alarmService;
+ @Inject GeofenceService geofenceService;
+ @Inject PermissionRequestor permissionRequestor;
+ @Inject Device device;
+ @Inject Preferences preferences;
+ @Inject @ForActivity Context context;
- public static final int REQUEST_NEW_ALARM = 12152;
- public static final int REQUEST_LOCATION_REMINDER = 12153;
+ @Bind(R.id.alert_container) LinearLayout alertContainer;
+ @Bind(R.id.reminder_alarm) Spinner mode;
+ @Bind(R.id.alarms_add_spinner) Spinner addSpinner;
- private Spinner mode;
- private Spinner addSpinner;
- private TextView modeDisplay;
+ private long taskId;
+ private int flags;
+ private long randomReminder;
private RandomReminderControlSet randomControlSet;
- private LinearLayout alertContainer;
private boolean whenDue;
private boolean whenOverdue;
- private AlarmService alarmService;
- private GeofenceService geofenceService;
- private TaskEditFragment taskEditFragment;
- private PermissionRequestor permissionRequestor;
- private Device device;
private List spinnerOptions = new ArrayList<>();
private ArrayAdapter remindAdapter;
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = super.onCreateView(inflater, container, savedInstanceState);
+
+ remindAdapter = new HiddenTopArrayAdapter(context, android.R.layout.simple_spinner_item, spinnerOptions);
+ String[] modes = getResources().getStringArray(R.array.reminder_ring_modes);
+ ArrayAdapter modeAdapter = new ArrayAdapter<>(context, android.R.layout.simple_spinner_item, modes);
+ modeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mode.setAdapter(modeAdapter);
+
+ if (savedInstanceState != null) {
+ taskId = savedInstanceState.getLong(EXTRA_TASK_ID);
+ flags = savedInstanceState.getInt(EXTRA_FLAGS);
+ randomReminder = savedInstanceState.getLong(EXTRA_RANDOM_REMINDER);
+ List geofences = new ArrayList<>();
+ List geofenceArray = savedInstanceState.getParcelableArrayList(EXTRA_GEOFENCES);
+ for (Parcelable geofence : geofenceArray) {
+ geofences.add((Geofence) geofence);
+ }
+ setup(Longs.asList(savedInstanceState.getLongArray(EXTRA_ALARMS)), geofences);
+ } else {
+ final List alarms = new ArrayList<>();
+ alarmService.getAlarms(taskId, new Callback() {
+ @Override
+ public void apply(Metadata entry) {
+ alarms.add(entry.getValue(AlarmFields.TIME));
+ }
+ });
+ setup(alarms, geofenceService.getGeofences(taskId));
+ }
+
+ addSpinner.setAdapter(remindAdapter);
+
+ return view;
+ }
+
+ @OnItemSelected(R.id.alarms_add_spinner)
+ void addAlarm(int position) {
+ String selected = spinnerOptions.get(position);
+ if (selected.equals(getString(R.string.when_due))) {
+ addDue();
+ } else if(selected.equals(getString(R.string.when_overdue))) {
+ addOverdue();
+ } else if (selected.equals(getString(R.string.randomly))) {
+ addRandomReminder(TimeUnit.DAYS.toMillis(14));
+ } else if (selected.equals(getString(R.string.pick_a_date_and_time))) {
+ addNewAlarm();
+ } else if (selected.equals(getString(R.string.pick_a_location))) {
+ if (permissionRequestor.requestFineLocation()) {
+ pickLocation();
+ }
+ }
+ if (position != 0) {
+ updateSpinner();
+ }
+ }
+
+ @OnClick(R.id.alarms_add)
+ void addAlarm(View view) {
+ if (spinnerOptions.size() == 2) {
+ addNewAlarm();
+ } else {
+ addSpinner.performClick();
+ }
+ }
+
+ @Override
+ protected int getLayout() {
+ return R.layout.control_set_reminders;
+ }
+
+ @Override
+ public int getIcon() {
+ return R.drawable.ic_notifications_24dp;
+ }
+
+ @Override
+ public void initialize(boolean isNewTask, Task task) {
+ taskId = task.getId();
+ flags = task.getReminderFlags();
+ randomReminder = task.getReminderPeriod();
+ }
+
+ private void setup(List alarms, List geofences) {
+ setValue(flags);
+
+ alertContainer.removeAllViews();
+ if (whenDue) {
+ addDue();
+ }
+ if (whenOverdue) {
+ addOverdue();
+ }
+ if (randomReminder > 0) {
+ addRandomReminder(randomReminder);
+ }
+ for (long timestamp : alarms) {
+ addAlarmRow(timestamp);
+ }
+ for (Geofence geofence : geofences) {
+ addGeolocationReminder(geofence);
+ }
+ updateSpinner();
+ }
+
+ @Override
+ public void apply(Task task) {
+ task.setReminderFlags(getValue());
+
+ task.setReminderPeriod(getRandomReminderPeriod());
+
+ if(alarmService.synchronizeAlarms(task.getId(), getAlarms())) {
+ task.setModificationDate(DateUtilities.now());
+ }
+ if (geofenceService.synchronizeGeofences(task.getId(), getGeofences())) {
+ task.setModificationDate(DateUtilities.now());
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putLong(EXTRA_TASK_ID, taskId);
+ outState.putInt(EXTRA_FLAGS, getValue());
+ outState.putLong(EXTRA_RANDOM_REMINDER, getRandomReminderPeriod());
+ outState.putLongArray(EXTRA_ALARMS, Longs.toArray(getAlarms()));
+ outState.putParcelableArrayList(EXTRA_GEOFENCES, newArrayList(getGeofences()));
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_NEW_ALARM) {
+ if (resultCode == Activity.RESULT_OK) {
+ addAlarmRow(data.getLongExtra(TimePickerActivity.EXTRA_TIMESTAMP, 0L));
+ }
+ } else if (requestCode == REQUEST_LOCATION_REMINDER) {
+ if (resultCode == Activity.RESULT_OK) {
+ addGeolocationReminder(PlacePicker.getPlace(context, data, preferences));
+ }
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+
+ private Set getAlarms() {
+ Set alarms = new LinkedHashSet<>();
+ for (int i = 0 ; i < alertContainer.getChildCount() ; i++) {
+ Object tag = alertContainer.getChildAt(i).getTag();
+ if (tag instanceof Long) {
+ alarms.add((Long) tag);
+ }
+ }
+ return alarms;
+ }
+
+ private Set getGeofences() {
+ Set geofences = new LinkedHashSet<>();
+ for (int i = 0 ; i < alertContainer.getChildCount() ; i++) {
+ Object tag = alertContainer.getChildAt(i).getTag();
+ if (tag instanceof Geofence) {
+ geofences.add((Geofence) tag);
+ }
+ }
+ return geofences;
+ }
- public ReminderControlSet(AlarmService alarmService, GeofenceService geofenceService,
- TaskEditFragment taskEditFragment, PermissionRequestor permissionRequestor,
- Device device) {
- super(taskEditFragment.getActivity(), R.layout.control_set_reminders);
- this.alarmService = alarmService;
- this.geofenceService = geofenceService;
- this.taskEditFragment = taskEditFragment;
- this.permissionRequestor = permissionRequestor;
- this.device = device;
+ public void addAlarmRow(final Long timestamp) {
+ addAlarmRow(getLongDateStringWithTime(context, timestamp), timestamp, null);
+ }
+
+ public void pickLocation() {
+ Intent intent = PlacePicker.getIntent(getActivity());
+ if (intent != null) {
+ startActivityForResult(intent, REQUEST_LOCATION_REMINDER);
+ }
+ }
+
+ public void addGeolocationReminder(final Geofence geofence) {
+ View alertItem = addAlarmRow(geofence.getName(), null, new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ }
+ });
+ alertItem.setTag(geofence);
}
- public int getValue() {
+ private int getValue() {
int value = 0;
if(whenDue) {
value |= Task.NOTIFY_AT_DEADLINE;
@@ -101,40 +302,18 @@ public class ReminderControlSet extends TaskEditControlSetBase implements Adapte
return value;
}
+ private long getRandomReminderPeriod() {
+ return randomControlSet == null ? 0L : randomControlSet.getReminderPeriod();
+ }
+
private void addNewAlarm() {
- taskEditFragment.startActivityForResult(new Intent(taskEditFragment.getActivity(), DateAndTimePickerActivity.class) {{
+ startActivityForResult(new Intent(getActivity(), DateAndTimePickerActivity.class) {{
putExtra(DateAndTimePickerActivity.EXTRA_TIMESTAMP, newDateTime().startOfDay().getMillis());
}}, REQUEST_NEW_ALARM);
}
- public void addAlarmRow(final Long timestamp) {
- final View alertItem = addAlarmRow(getLongDateStringWithTime(activity, timestamp), timestamp, null);
- TextView display = (TextView) alertItem.findViewById(R.id.alarm_string);
- display.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
-// pickNewAlarm(newDateTime(timestamp), new DateAndTimePickerDialog.OnDateTimePicked() {
-// @Override
-// public void onDateTimePicked(DateTime dateTime) {
-// long millis = dateTime.getMillis();
-// addAlarmRow(alertItem, getDisplayString(millis), millis, null);
-// }
-// });
- }
- });
- }
-
- public void addGeolocationReminder(final Geofence geofence) {
- View alertItem = addAlarmRow(geofence.getName(), null, new OnClickListener() {
- @Override
- public void onClick(View v) {
- }
- });
- alertItem.setTag(geofence);
- }
-
private View addAlarmRow(String text, Long timestamp, final OnClickListener onRemove) {
- final View alertItem = LayoutInflater.from(activity).inflate(R.layout.alarm_edit_row, null);
+ final View alertItem = getActivity().getLayoutInflater().inflate(R.layout.alarm_edit_row, null);
alertContainer.addView(alertItem);
addAlarmRow(alertItem, text, timestamp, onRemove);
return alertItem;
@@ -162,106 +341,24 @@ public class ReminderControlSet extends TaskEditControlSetBase implements Adapte
spinnerOptions.clear();
spinnerOptions.add("");
if (!whenDue) {
- spinnerOptions.add(taskEditFragment.getString(R.string.when_due));
+ spinnerOptions.add(getString(R.string.when_due));
}
if (!whenOverdue) {
- spinnerOptions.add(taskEditFragment.getString(R.string.when_overdue));
+ spinnerOptions.add(getString(R.string.when_overdue));
}
if (randomControlSet == null) {
- spinnerOptions.add(taskEditFragment.getString(R.string.randomly));
+ spinnerOptions.add(getString(R.string.randomly));
}
if (device.supportsLocationServices()) {
- spinnerOptions.add(taskEditFragment.getString(R.string.pick_a_location));
+ spinnerOptions.add(getString(R.string.pick_a_location));
}
- spinnerOptions.add(taskEditFragment.getString(R.string.pick_a_date_and_time));
+ spinnerOptions.add(getString(R.string.pick_a_date_and_time));
remindAdapter.notifyDataSetChanged();
}
- @Override
- protected void afterInflate() {
- alertContainer = (LinearLayout) getView().findViewById(R.id.alert_container);
- getView().findViewById(R.id.alarms_add).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- if (spinnerOptions.size() == 2) {
- addNewAlarm();
- } else {
- addSpinner.performClick();
- }
- }
- });
- addSpinner = (Spinner) getView().findViewById(R.id.alarms_add_spinner);
- addSpinner.setOnItemSelectedListener(ReminderControlSet.this);
- remindAdapter = new HiddenTopArrayAdapter(activity, android.R.layout.simple_spinner_item, spinnerOptions);
- addSpinner.setAdapter(remindAdapter);
- modeDisplay = (TextView) getView().findViewById(R.id.reminder_alarm_display);
- mode = (Spinner) getView().findViewById(R.id.reminder_alarm);
- modeDisplay.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mode.performClick();
- }
- });
-
- String[] list = new String[] {
- activity.getString(R.string.ring_once),
- activity.getString(R.string.ring_five_times),
- activity.getString(R.string.ring_nonstop),
- };
- final ArrayAdapter modeAdapter = new ArrayAdapter<>(
- activity, android.R.layout.simple_spinner_item, list);
- modeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- mode.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
-
- @Override
- public void onItemSelected(AdapterView> parent, View view,
- int position, long id) {
- modeDisplay.setText(modeAdapter.getItem(position));
- }
-
- @Override
- public void onNothingSelected(AdapterView> parent) {
-// TODO Auto-generated method stub
-
- }
- });
- activity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- mode.setAdapter(modeAdapter);
- }
- });
- }
-
- @Override
- protected void readFromTaskOnInitialize() {
- setValue(model.getReminderFlags());
-
- alertContainer.removeAllViews();
- if (whenDue) {
- addDue();
- }
- if (whenOverdue) {
- addOverdue();
- }
- if (model.hasRandomReminder()) {
- addRandomReminder();
- }
- alarmService.getAlarms(model.getId(), new Callback() {
- @Override
- public void apply(Metadata entry) {
- addAlarmRow(entry.getValue(AlarmFields.TIME));
- }
- });
- for (Geofence geofence : geofenceService.getGeofences(model.getId())) {
- addGeolocationReminder(geofence);
- }
- updateSpinner();
- }
-
private void addDue() {
whenDue = true;
- addAlarmRow(taskEditFragment.getString(R.string.when_due), null, new OnClickListener() {
+ addAlarmRow(getString(R.string.when_due), null, new OnClickListener() {
@Override
public void onClick(View v) {
whenDue = false;
@@ -271,7 +368,7 @@ public class ReminderControlSet extends TaskEditControlSetBase implements Adapte
private void addOverdue() {
whenOverdue = true;
- addAlarmRow(taskEditFragment.getString(R.string.when_overdue), null, new OnClickListener() {
+ addAlarmRow(getString(R.string.when_overdue), null, new OnClickListener() {
@Override
public void onClick(View v) {
whenOverdue = false;
@@ -279,15 +376,14 @@ public class ReminderControlSet extends TaskEditControlSetBase implements Adapte
});
}
- private void addRandomReminder() {
- View alarmRow = addAlarmRow(taskEditFragment.getString(R.string.randomly_once), null, new OnClickListener() {
+ private void addRandomReminder(long reminderPeriod) {
+ View alarmRow = addAlarmRow(getString(R.string.randomly_once), null, new OnClickListener() {
@Override
public void onClick(View v) {
randomControlSet = null;
}
});
- randomControlSet = new RandomReminderControlSet(activity, alarmRow);
- randomControlSet.readFromTaskOnInitialize(model);
+ randomControlSet = new RandomReminderControlSet(context, alarmRow, reminderPeriod);
}
private void setValue(int flags) {
@@ -302,72 +398,4 @@ public class ReminderControlSet extends TaskEditControlSetBase implements Adapte
mode.setSelection(0);
}
}
-
- @Override
- protected void writeToModelAfterInitialized(Task task) {
- task.setReminderFlags(getValue());
-
- task.setReminderPeriod(randomControlSet == null ? 0L : randomControlSet.getReminderPeriod());
-
- Set alarms = new LinkedHashSet<>();
- Set geofences = new LinkedHashSet<>();
-
- for(int i = 0; i < alertContainer.getChildCount(); i++) {
- Object tag = alertContainer.getChildAt(i).getTag();
- //noinspection StatementWithEmptyBody
- if (tag == null) {
- } else if (tag instanceof Long) {
- alarms.add((Long) tag);
- } else if (tag instanceof Geofence) {
- geofences.add((Geofence) tag);
- } else {
- Timber.e("Unexpected tag: %s", tag);
- }
- }
-
- if(alarmService.synchronizeAlarms(task.getId(), alarms)) {
- task.setModificationDate(DateUtilities.now());
- }
- if (geofenceService.synchronizeGeofences(task.getId(), geofences)) {
- task.setModificationDate(DateUtilities.now());
- }
- }
-
- @Override
- public void onItemSelected(AdapterView> parent, View view, int position, long id) {
- Timber.i("onItemSelected(%s, %s, %s, %s)", parent, view, position, id);
- String selected = spinnerOptions.get(position);
- if (selected.equals(taskEditFragment.getString(R.string.when_due))) {
- addDue();
- } else if(selected.equals(taskEditFragment.getString(R.string.when_overdue))) {
- addOverdue();
- } else if (selected.equals(taskEditFragment.getString(R.string.randomly))) {
- addRandomReminder();
- } else if (selected.equals(taskEditFragment.getString(R.string.pick_a_date_and_time))) {
- addNewAlarm();
- } else if (selected.equals(taskEditFragment.getString(R.string.pick_a_location))) {
- if (permissionRequestor.requestFineLocation()) {
- pickLocation();
- }
- }
- if (position != 0) {
- updateSpinner();
- }
- }
-
- public void pickLocation() {
- Intent intent = PlacePicker.getIntent(taskEditFragment.getActivity());
- if (intent != null) {
- taskEditFragment.startActivityForResult(intent, REQUEST_LOCATION_REMINDER);
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView> parent) {
- }
-
- @Override
- public int getIcon() {
- return R.drawable.ic_notifications_24dp;
- }
}
diff --git a/src/main/java/com/todoroo/astrid/ui/TimeDurationControlSet.java b/src/main/java/com/todoroo/astrid/ui/TimeDurationControlSet.java
index 19666f4af..321795d43 100644
--- a/src/main/java/com/todoroo/astrid/ui/TimeDurationControlSet.java
+++ b/src/main/java/com/todoroo/astrid/ui/TimeDurationControlSet.java
@@ -5,7 +5,7 @@
*/
package com.todoroo.astrid.ui;
-import android.app.Activity;
+import android.content.Context;
import android.content.res.Resources;
import android.text.format.DateUtils;
import android.view.View;
@@ -20,29 +20,22 @@ import org.tasks.preferences.ActivityPreferences;
public class TimeDurationControlSet implements OnNNumberPickedListener, View.OnClickListener {
- private final Activity activity;
+ private final Context context;
private final TextView timeButton;
private int timeDuration;
private int[] initialValues = null;
private NNumberPickerDialog dialog = null;
- private Task model;
- private final IntegerProperty property;
private ActivityPreferences activityPreferences;
- public TimeDurationControlSet(Activity activity, View view, IntegerProperty property,
+ public TimeDurationControlSet(Context context, View view,
int timeButtonId, ActivityPreferences activityPreferences) {
- this.activity = activity;
- this.property = property;
+ this.context = context;
this.activityPreferences = activityPreferences;
timeButton = (TextView)view.findViewById(timeButtonId);
((View) timeButton.getParent()).setOnClickListener(this);
}
- public void setModel(Task model) {
- this.model = model;
- }
-
public int getTimeDurationInSeconds() {
return timeDuration;
}
@@ -54,7 +47,7 @@ public class TimeDurationControlSet implements OnNNumberPickedListener, View.OnC
timeDuration = timeDurationInSeconds;
- Resources r = activity.getResources();
+ Resources r = context.getResources();
if(timeDurationInSeconds == 0) {
timeButton.setText(r.getString(R.string.WID_dateButtonUnset));
return;
@@ -65,10 +58,6 @@ public class TimeDurationControlSet implements OnNNumberPickedListener, View.OnC
int hours = timeDuration / 3600;
int minutes = timeDuration / 60 - 60 * hours;
initialValues = new int[] { hours, minutes };
-
- if (model != null) {
- model.setValue(property, timeDuration);
- }
}
/** Called when NumberPicker activity is completed */
@@ -81,8 +70,8 @@ public class TimeDurationControlSet implements OnNNumberPickedListener, View.OnC
@Override
public void onClick(View v) {
if(dialog == null) {
- dialog = new NNumberPickerDialog(activity, activityPreferences.getDialogTheme(), this,
- activity.getResources().getString(R.string.DLG_hour_minutes),
+ dialog = new NNumberPickerDialog(context, activityPreferences.getDialogTheme(), this,
+ context.getResources().getString(R.string.DLG_hour_minutes),
new int[] {0, 0}, new int[] {1, 5}, new int[] {0, 0},
new int[] {999, 59}, new String[] {":", null});
final NumberPicker hourPicker = dialog.getPicker(0);
diff --git a/src/main/java/org/tasks/activities/CalendarSelectionActivity.java b/src/main/java/org/tasks/activities/CalendarSelectionActivity.java
index dcba4bf67..bc6f3af32 100644
--- a/src/main/java/org/tasks/activities/CalendarSelectionActivity.java
+++ b/src/main/java/org/tasks/activities/CalendarSelectionActivity.java
@@ -2,11 +2,16 @@ package org.tasks.activities;
import android.app.FragmentManager;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.os.Bundle;
import com.todoroo.astrid.gcal.AndroidCalendar;
import org.tasks.injection.InjectingAppCompatActivity;
+import org.tasks.preferences.ActivityPreferences;
+import org.tasks.preferences.PermissionRequestor;
+
+import javax.inject.Inject;
public class CalendarSelectionActivity extends InjectingAppCompatActivity implements CalendarSelectionDialog.CalendarSelectionHandler {
@@ -14,19 +19,20 @@ public class CalendarSelectionActivity extends InjectingAppCompatActivity implem
public static final String EXTRA_CALENDAR_ID = "extra_calendar_id";
public static final String EXTRA_CALENDAR_NAME = "extra_calendar_name";
+ public static final String EXTRA_SHOW_NONE = "extra_show_none";
+
+ @Inject PermissionRequestor permissionRequestor;
+ @Inject ActivityPreferences preferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- FragmentManager fragmentManager = getFragmentManager();
- CalendarSelectionDialog fragmentByTag = (CalendarSelectionDialog) fragmentManager.findFragmentByTag(FRAG_TAG_CALENDAR_PREFERENCE_SELECTION);
- if (fragmentByTag == null) {
- fragmentByTag = new CalendarSelectionDialog();
- fragmentByTag.enableNone();
- fragmentByTag.show(fragmentManager, FRAG_TAG_CALENDAR_PREFERENCE_SELECTION);
+ preferences.applyTheme();
+
+ if (permissionRequestor.requestCalendarPermissions()) {
+ showDialog();
}
- fragmentByTag.setCalendarSelectionHandler(this);
}
@Override
@@ -41,4 +47,30 @@ public class CalendarSelectionActivity extends InjectingAppCompatActivity implem
public void dismiss() {
finish();
}
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
+ if (requestCode == PermissionRequestor.REQUEST_CALENDAR) {
+ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ showDialog();
+ } else {
+ finish();
+ }
+ } else {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ }
+ }
+
+ private void showDialog() {
+ FragmentManager fragmentManager = getFragmentManager();
+ CalendarSelectionDialog fragmentByTag = (CalendarSelectionDialog) fragmentManager.findFragmentByTag(FRAG_TAG_CALENDAR_PREFERENCE_SELECTION);
+ if (fragmentByTag == null) {
+ fragmentByTag = new CalendarSelectionDialog();
+ if (getIntent().getBooleanExtra(EXTRA_SHOW_NONE, false)) {
+ fragmentByTag.enableNone();
+ }
+ fragmentByTag.show(fragmentManager, FRAG_TAG_CALENDAR_PREFERENCE_SELECTION);
+ }
+ fragmentByTag.setCalendarSelectionHandler(this);
+ }
}
diff --git a/src/main/java/org/tasks/activities/DatePickerActivity.java b/src/main/java/org/tasks/activities/DatePickerActivity.java
new file mode 100644
index 000000000..b9573e852
--- /dev/null
+++ b/src/main/java/org/tasks/activities/DatePickerActivity.java
@@ -0,0 +1,70 @@
+package org.tasks.activities;
+
+import android.app.FragmentManager;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
+
+import org.tasks.R;
+import org.tasks.dialogs.MyDatePickerDialog;
+import org.tasks.injection.InjectingAppCompatActivity;
+import org.tasks.preferences.ActivityPreferences;
+import org.tasks.time.DateTime;
+
+import javax.inject.Inject;
+
+import static org.tasks.time.DateTimeUtils.currentTimeMillis;
+
+public class DatePickerActivity extends InjectingAppCompatActivity
+ implements DatePickerDialog.OnDateSetListener, DialogInterface.OnDismissListener {
+
+ private static final String FRAG_TAG_DATE_PICKER = "frag_tag_date_picker";
+
+ public static final String EXTRA_TIMESTAMP = "extra_timestamp";
+
+ @Inject ActivityPreferences preferences;
+
+ private DateTime initial;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ preferences.applyTheme();
+
+ long timestamp = getIntent().getLongExtra(EXTRA_TIMESTAMP, currentTimeMillis());
+ initial = timestamp > 0 ? new DateTime(timestamp) : new DateTime().startOfDay();
+
+ FragmentManager fragmentManager = getFragmentManager();
+ MyDatePickerDialog dialog = (MyDatePickerDialog) fragmentManager.findFragmentByTag(FRAG_TAG_DATE_PICKER);
+ if (dialog == null) {
+ dialog = new MyDatePickerDialog();
+ dialog.initialize(null, initial.getYear(), initial.getMonthOfYear() - 1, initial.getDayOfMonth());
+ if (preferences.isDarkTheme()) {
+ dialog.setAccentColor(getResources().getColor(R.color.black_text_hint));
+ }
+ dialog.show(fragmentManager, FRAG_TAG_DATE_PICKER);
+ }
+ dialog.setOnDismissListener(this);
+ dialog.setOnDateSetListener(this);
+ }
+
+
+ @Override
+ public void onDateSet(DatePickerDialog view, final int year, final int monthOfYear, final int dayOfMonth) {
+ setResult(RESULT_OK, new Intent() {{
+ putExtra(EXTRA_TIMESTAMP, initial
+ .withYear(year)
+ .withMonthOfYear(monthOfYear + 1)
+ .withDayOfMonth(dayOfMonth)
+ .getMillis());
+ }});
+ }
+
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ finish();
+ }
+}
diff --git a/src/main/java/org/tasks/injection/ActivityModule.java b/src/main/java/org/tasks/injection/ActivityModule.java
index 201b5c2b3..1cab16bb6 100644
--- a/src/main/java/org/tasks/injection/ActivityModule.java
+++ b/src/main/java/org/tasks/injection/ActivityModule.java
@@ -29,6 +29,7 @@ import org.tasks.activities.CameraActivity;
import org.tasks.activities.ClearAllDataActivity;
import org.tasks.activities.ClearGtaskDataActivity;
import org.tasks.activities.DateAndTimePickerActivity;
+import org.tasks.activities.DatePickerActivity;
import org.tasks.activities.DeleteAllCalendarEventsActivity;
import org.tasks.activities.DeleteCompletedActivity;
import org.tasks.activities.DeleteCompletedEventsActivity;
@@ -103,6 +104,7 @@ import dagger.Provides;
AddAttachmentActivity.class,
ShortcutActivity.class,
CameraActivity.class,
+ DatePickerActivity.class,
TimePickerActivity.class,
DateAndTimePickerActivity.class
})
diff --git a/src/main/java/org/tasks/injection/FragmentModule.java b/src/main/java/org/tasks/injection/FragmentModule.java
index 0ec7ec8af..e572efc9b 100644
--- a/src/main/java/org/tasks/injection/FragmentModule.java
+++ b/src/main/java/org/tasks/injection/FragmentModule.java
@@ -7,12 +7,23 @@ import android.content.Context;
import com.todoroo.astrid.actfm.TagViewFragment;
import com.todoroo.astrid.activity.TaskEditFragment;
import com.todoroo.astrid.activity.TaskListFragment;
+import com.todoroo.astrid.files.FilesControlSet;
import com.todoroo.astrid.gtasks.GtasksListFragment;
+import com.todoroo.astrid.repeats.RepeatControlSet;
import com.todoroo.astrid.subtasks.SubtasksListFragment;
import com.todoroo.astrid.subtasks.SubtasksTagListFragment;
+import com.todoroo.astrid.tags.TagsControlSet;
+import com.todoroo.astrid.timers.TimerControlSet;
+import com.todoroo.astrid.ui.EditTitleControlSet;
+import com.todoroo.astrid.ui.HideUntilControlSet;
import com.todoroo.astrid.ui.QuickAddBar;
+import com.todoroo.astrid.ui.ReminderControlSet;
+import org.tasks.ui.CalendarControlSet;
+import org.tasks.ui.DeadlineControlSet;
+import org.tasks.ui.DescriptionControlSet;
import org.tasks.ui.NavigationDrawerFragment;
+import org.tasks.ui.PriorityControlSet;
import javax.inject.Singleton;
@@ -28,7 +39,18 @@ import dagger.Provides;
TagViewFragment.class,
TaskEditFragment.class,
NavigationDrawerFragment.class,
- QuickAddBar.class
+ QuickAddBar.class,
+ CalendarControlSet.class,
+ DeadlineControlSet.class,
+ PriorityControlSet.class,
+ DescriptionControlSet.class,
+ HideUntilControlSet.class,
+ ReminderControlSet.class,
+ FilesControlSet.class,
+ EditTitleControlSet.class,
+ TimerControlSet.class,
+ TagsControlSet.class,
+ RepeatControlSet.class
})
public class FragmentModule {
diff --git a/src/main/java/org/tasks/location/Geofence.java b/src/main/java/org/tasks/location/Geofence.java
index 5d12a6029..db705a562 100644
--- a/src/main/java/org/tasks/location/Geofence.java
+++ b/src/main/java/org/tasks/location/Geofence.java
@@ -1,10 +1,13 @@
package org.tasks.location;
+import android.os.Parcel;
+import android.os.Parcelable;
+
import com.todoroo.astrid.data.Metadata;
import java.io.Serializable;
-public class Geofence implements Serializable {
+public class Geofence implements Serializable, Parcelable {
private final String name;
private final double latitude;
private final double longitude;
@@ -63,4 +66,31 @@ public class Geofence implements Serializable {
", metadataId=" + metadataId +
'}';
}
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(name);
+ out.writeDouble(latitude);
+ out.writeDouble(longitude);
+ out.writeInt(radius);
+ }
+
+ public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
+ @Override
+ public Geofence createFromParcel(Parcel source) {
+ String name = source.readString();
+ double latitude = source.readDouble();
+ double longitude = source.readDouble();
+ int radius = source.readInt();
+ return new Geofence(name, latitude, longitude, radius);
+ }
+
+ @Override
+ public Geofence[] newArray(int size) {
+ return new Geofence[size];
+ }
+ };
}
\ No newline at end of file
diff --git a/src/main/java/org/tasks/preferences/ResourceResolver.java b/src/main/java/org/tasks/preferences/ResourceResolver.java
index 2f05bcc2c..aaf330588 100644
--- a/src/main/java/org/tasks/preferences/ResourceResolver.java
+++ b/src/main/java/org/tasks/preferences/ResourceResolver.java
@@ -1,6 +1,7 @@
package org.tasks.preferences;
import android.app.Activity;
+import android.content.Context;
import android.util.TypedValue;
import javax.inject.Inject;
@@ -21,19 +22,9 @@ public class ResourceResolver {
return getData(activity, attr);
}
- public int getResource(int attr) {
- return getResource(activity, attr);
- }
-
- public static int getResource(Activity activity, int attr) {
- TypedValue typedValue = new TypedValue();
- activity.getTheme().resolveAttribute(attr, typedValue, true);
- return typedValue.resourceId;
- }
-
- public static int getData(Activity activity, int attr) {
+ public static int getData(Context context, int attr) {
TypedValue typedValue = new TypedValue();
- activity.getTheme().resolveAttribute(attr, typedValue, true);
+ context.getTheme().resolveAttribute(attr, typedValue, true);
return typedValue.data;
}
}
diff --git a/src/main/java/org/tasks/ui/CalendarControlSet.java b/src/main/java/org/tasks/ui/CalendarControlSet.java
new file mode 100644
index 000000000..9bedf0e5a
--- /dev/null
+++ b/src/main/java/org/tasks/ui/CalendarControlSet.java
@@ -0,0 +1,246 @@
+package org.tasks.ui;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.google.common.base.Strings;
+import com.todoroo.astrid.data.Task;
+import com.todoroo.astrid.gcal.AndroidCalendar;
+import com.todoroo.astrid.gcal.GCalHelper;
+
+import org.tasks.R;
+import org.tasks.activities.CalendarSelectionActivity;
+import org.tasks.injection.ForActivity;
+import org.tasks.preferences.Preferences;
+
+import javax.inject.Inject;
+
+import butterknife.Bind;
+import butterknife.OnClick;
+import timber.log.Timber;
+
+import static com.google.common.base.Strings.isNullOrEmpty;
+
+public class CalendarControlSet extends TaskEditControlFragment {
+
+ private static final int REQUEST_CODE_CALENDAR = 70;
+ private static final String EXTRA_URI = "extra_uri";
+ private static final String EXTRA_ID = "extra_id";
+ private static final String EXTRA_NAME = "extra_name";
+
+ @Bind(R.id.clear) View cancelButton;
+ @Bind(R.id.calendar_display_which) TextView calendar;
+
+ @Inject GCalHelper gcalHelper;
+ @Inject Preferences preferences;
+ @Inject @ForActivity Context context;
+
+ private String calendarId;
+ private String calendarName;
+ private String eventUri;
+ private boolean isNewTask;
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = super.onCreateView(inflater, container, savedInstanceState);
+ if (savedInstanceState != null) {
+ eventUri = savedInstanceState.getString(EXTRA_URI);
+ calendarName = savedInstanceState.getString(EXTRA_NAME);
+ calendarId = savedInstanceState.getString(EXTRA_ID);
+ } else if (isNewTask) {
+ calendarId = preferences.getDefaultCalendar();
+ if (!Strings.isNullOrEmpty(calendarId)) {
+ AndroidCalendar defaultCalendar = gcalHelper.getCalendar(calendarId);
+ if (defaultCalendar == null) {
+ calendarId = null;
+ } else {
+ calendarName = defaultCalendar.getName();
+ }
+ }
+ }
+ if (!calendarEntryExists(eventUri)) {
+ eventUri = null;
+ }
+ refreshDisplayView();
+ return view;
+ }
+
+ @Override
+ protected int getLayout() {
+ return R.layout.control_set_gcal_display;
+ }
+
+ @Override
+ protected int getIcon() {
+ return R.drawable.ic_event_24dp;
+ }
+
+ @Override
+ public void initialize(boolean isNewTask, Task task) {
+ this.isNewTask = isNewTask;
+ eventUri = task.getCalendarURI();
+ }
+
+ @Override
+ public void apply(Task task) {
+ if (!task.hasDueDate()) {
+ return;
+ }
+
+ if (calendarEntryExists(task.getCalendarURI())) {
+ ContentResolver cr = context.getContentResolver();
+ try {
+ ContentValues updateValues = new ContentValues();
+
+ // check if we need to update the item
+ ContentValues setValues = task.getSetValues();
+ if(setValues.containsKey(Task.TITLE.name)) {
+ updateValues.put("title", task.getTitle());
+ }
+ if(setValues.containsKey(Task.NOTES.name)) {
+ updateValues.put("description", task.getNotes());
+ }
+ if(setValues.containsKey(Task.DUE_DATE.name) || setValues.containsKey(Task.ESTIMATED_SECONDS.name)) {
+ gcalHelper.createStartAndEndDate(task, updateValues);
+ }
+
+ cr.update(Uri.parse(task.getCalendarURI()), updateValues, null, null);
+ } catch (Exception e) {
+ Timber.e(e, "unable-to-update-calendar: %s", task.getCalendarURI());
+ }
+
+ return;
+ }
+
+ if (!isNullOrEmpty(calendarId)) {
+ ContentResolver cr = context.getContentResolver();
+ try{
+ ContentValues values = new ContentValues();
+ values.put("calendar_id", calendarId);
+ Uri uri = gcalHelper.createTaskEvent(task, cr, values);
+ if(uri != null) {
+ task.setCalendarUri(uri.toString());
+ // pop up the new event
+ Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ intent.putExtra("beginTime", values.getAsLong("dtstart"));
+ intent.putExtra("endTime", values.getAsLong("dtend"));
+ startActivity(intent);
+ }
+ } catch (Exception e) {
+ Timber.e(e, e.getMessage());
+ }
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putString(EXTRA_URI, eventUri);
+ outState.putString(EXTRA_NAME, calendarName);
+ outState.putString(EXTRA_ID, calendarId);
+ }
+
+ @OnClick(R.id.clear)
+ void clearCalendar(View view) {
+ calendarName = null;
+ calendarId = null;
+ eventUri = null;
+ refreshDisplayView();
+ }
+
+ @OnClick(R.id.calendar_display_which)
+ void clickCalendar(View view) {
+ if (Strings.isNullOrEmpty(eventUri)) {
+ startActivityForResult(new Intent(context, CalendarSelectionActivity.class), REQUEST_CODE_CALENDAR);
+ } else {
+ ContentResolver cr = getActivity().getContentResolver();
+ Uri uri = Uri.parse(eventUri);
+ Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ Cursor cursor = cr.query(uri, new String[] { "dtstart", "dtend" }, null, null, null);
+ try {
+ if(cursor.getCount() == 0) {
+ // event no longer exists
+ eventUri = null;
+ refreshDisplayView();
+ return;
+ }
+ cursor.moveToFirst();
+ intent.putExtra("beginTime", cursor.getLong(0));
+ intent.putExtra("endTime", cursor.getLong(1));
+ } catch (Exception e) {
+ Timber.e(e, e.getMessage());
+ Toast.makeText(getActivity(), R.string.gcal_TEA_error, Toast.LENGTH_LONG).show();
+ } finally {
+ cursor.close();
+ }
+
+ startActivity(intent);
+ }
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_CODE_CALENDAR) {
+ if (resultCode == Activity.RESULT_OK) {
+ calendarId = data.getStringExtra(CalendarSelectionActivity.EXTRA_CALENDAR_ID);
+ calendarName = data.getStringExtra(CalendarSelectionActivity.EXTRA_CALENDAR_NAME);
+ refreshDisplayView();
+ }
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+
+ private void refreshDisplayView() {
+ if (!Strings.isNullOrEmpty(eventUri)) {
+ calendar.setAlpha(1.0f);
+ calendar.setText(R.string.gcal_TEA_showCalendar_label);
+ cancelButton.setVisibility(View.GONE);
+ } else if (calendarName != null) {
+ calendar.setAlpha(1.0f);
+ calendar.setText(calendarName);
+ cancelButton.setVisibility(View.VISIBLE);
+ } else {
+ calendar.setAlpha(0.5f);
+ calendar.setText(R.string.gcal_TEA_addToCalendar_label);
+ cancelButton.setVisibility(View.GONE);
+ }
+ }
+
+ private boolean calendarEntryExists(String eventUri) {
+ if (isNullOrEmpty(eventUri)) {
+ return false;
+ }
+
+ try {
+ Uri uri = Uri.parse(eventUri);
+ ContentResolver contentResolver = context.getContentResolver();
+ Cursor cursor = contentResolver.query(uri, new String[]{"dtstart"}, null, null, null);
+ try {
+ if (cursor.getCount() != 0) {
+ return true;
+ }
+ } finally {
+ cursor.close();
+ }
+ } catch(Exception e) {
+ Timber.e(e, "%s: %s", eventUri, e.getMessage());
+ }
+
+ return false;
+ }
+}
diff --git a/src/main/java/org/tasks/ui/CheckBoxes.java b/src/main/java/org/tasks/ui/CheckBoxes.java
index 1f048b64c..60f839200 100644
--- a/src/main/java/org/tasks/ui/CheckBoxes.java
+++ b/src/main/java/org/tasks/ui/CheckBoxes.java
@@ -5,6 +5,8 @@ import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.support.v4.graphics.drawable.DrawableCompat;
+import com.google.common.collect.ImmutableList;
+
import org.tasks.R;
import org.tasks.injection.ForApplication;
@@ -14,8 +16,6 @@ import javax.inject.Inject;
import timber.log.Timber;
-import static java.util.Arrays.asList;
-
public class CheckBoxes {
private static final int MAX_IMPORTANCE_INDEX = 3;
@@ -24,6 +24,7 @@ public class CheckBoxes {
private static List checkboxes;
private static List repeatingCheckboxes;
private static List completedCheckboxes;
+ private static List priorityColors;
@Inject
public CheckBoxes(@ForApplication Context context) {
@@ -32,10 +33,19 @@ public class CheckBoxes {
checkboxes = wrapDrawable(context, R.drawable.ic_check_box_outline_blank_24dp);
repeatingCheckboxes = wrapDrawable(context, R.drawable.ic_repeat_24dp);
completedCheckboxes = wrapDrawable(context, R.drawable.ic_check_box_24dp);
+ priorityColors = ImmutableList.of(
+ context.getResources().getColor(R.color.importance_1),
+ context.getResources().getColor(R.color.importance_2),
+ context.getResources().getColor(R.color.importance_3),
+ context.getResources().getColor(R.color.importance_4));
initialized = true;
}
}
+ public List getPriorityColors() {
+ return priorityColors;
+ }
+
List getCheckBoxes() {
return checkboxes;
}
@@ -49,7 +59,7 @@ public class CheckBoxes {
}
private static List wrapDrawable(Context context, int resId) {
- return asList(
+ return ImmutableList.of(
getDrawable(context, resId, 0),
getDrawable(context, resId, 1),
getDrawable(context, resId, 2),
diff --git a/src/main/java/org/tasks/ui/DeadlineControlSet.java b/src/main/java/org/tasks/ui/DeadlineControlSet.java
index 4ba979a5c..a076310d1 100644
--- a/src/main/java/org/tasks/ui/DeadlineControlSet.java
+++ b/src/main/java/org/tasks/ui/DeadlineControlSet.java
@@ -1,10 +1,12 @@
package org.tasks.ui;
import android.app.Activity;
-import android.content.DialogInterface;
+import android.content.Context;
+import android.content.Intent;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
import android.support.v4.graphics.drawable.DrawableCompat;
-import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -15,58 +17,65 @@ import android.widget.TextView;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.data.Task;
-import com.todoroo.astrid.helper.TaskEditControlSetBase;
-import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
-import com.wdullaer.materialdatetimepicker.time.RadialPickerLayout;
-import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
import org.tasks.R;
-import org.tasks.dialogs.MyDatePickerDialog;
-import org.tasks.dialogs.MyTimePickerDialog;
+import org.tasks.activities.DatePickerActivity;
+import org.tasks.activities.TimePickerActivity;
+import org.tasks.injection.ForActivity;
import org.tasks.preferences.ActivityPreferences;
import org.tasks.time.DateTime;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+
+import butterknife.Bind;
+import butterknife.OnClick;
+import butterknife.OnItemSelected;
import static java.util.Arrays.asList;
import static org.tasks.date.DateTimeUtils.newDateTime;
+import static org.tasks.preferences.ResourceResolver.getData;
-public class DeadlineControlSet extends TaskEditControlSetBase {
+public class DeadlineControlSet extends TaskEditControlFragment {
- private static final String FRAG_TAG_PICK_A_DATE = "frag_tag_pick_a_date";
- private static final String FRAG_TAG_PICK_A_TIME = "frag_tag_pick_a_time";
+ private static final int REQUEST_DATE = 504;
+ private static final int REQUEST_TIME = 505;
+ private static final String EXTRA_DATE = "extra_date";
+ private static final String EXTRA_TIME = "extra_time";
private final List dueDateOptions = new ArrayList<>();
private final List dueTimeOptions = new ArrayList<>();
- private final List dueTimeHint;
- private final int dateShortcutMorning;
- private final int dateShortcutAfternoon;
- private final int dateShortcutEvening;
- private final int dateShortcutNight;
- private final String nightString;
- private final String eveningString;
- private final String afternoonString;
- private final String morningString;
- private final String noTimeString;
- private final String todayString;
- private final String tomorrowString;
-
- private Activity activity;
- private ActivityPreferences preferences;
- private Spinner dueDateSpinner;
- private Spinner dueTimeSpinner;
- private View clearButton;
+ private List dueTimeHint = new ArrayList<>();
+ private int dateShortcutMorning;
+ private int dateShortcutAfternoon;
+ private int dateShortcutEvening;
+ private int dateShortcutNight;
+ private String nightString;
+ private String eveningString;
+ private String afternoonString;
+ private String morningString;
+ private String noTimeString;
+ private String todayString;
+ private String tomorrowString;
+
+ @Inject ActivityPreferences preferences;
+ @Inject @ForActivity Context context;
+
+ @Bind(R.id.due_date) Spinner dueDateSpinner;
+ @Bind(R.id.due_time) Spinner dueTimeSpinner;
+ @Bind(R.id.clear) View clearButton;
+
private ArrayAdapter dueDateAdapter;
private ArrayAdapter dueTimeAdapter;
private long date = 0;
private int time = -1;
- public DeadlineControlSet(Activity activity, ActivityPreferences preferences) {
- super(activity, R.layout.control_set_deadline);
- this.activity = activity;
- this.preferences = preferences;
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+
dateShortcutMorning = preferences.getDateShortcutMorning();
dateShortcutAfternoon = preferences.getDateShortcutAfternoon();
dateShortcutEvening = preferences.getDateShortcutEvening();
@@ -101,95 +110,35 @@ public class DeadlineControlSet extends TaskEditControlSetBase {
activity.getString(R.string.pick_a_time)));
}
- private String getTimeHint(int millisOfDay) {
- DateTime dateTime = newDateTime().withMillisOfDay(millisOfDay);
- return DateUtilities.getTimeString(activity, dateTime);
- }
-
- private void refreshDisplayView() {
- updateDueDateOptions();
- updateDueTimeOptions();
- clearButton.setVisibility(date > 0 ? View.VISIBLE : View.GONE);
- }
-
- private void updateDueDateOptions() {
- DateTime today = newDateTime().startOfDay();
- String nextWeekString = activity.getString(R.string.next, today.plusWeeks(1).toString("EEEE"));
- if (date == 0) {
- dueDateOptions.set(0, activity.getString(R.string.TEA_no_date));
- } else {
- if (date == today.getMillis()) {
- dueDateOptions.set(0, todayString);
- } else if (date == today.plusDays(1).getMillis()) {
- dueDateOptions.set(0, tomorrowString);
- } else if (date == today.plusWeeks(1).getMillis()) {
- dueDateOptions.set(0, nextWeekString);
- } else {
- dueDateOptions.set(0, DateUtilities.getLongDateString(newDateTime(date)));
- }
- }
- dueDateOptions.set(3, nextWeekString);
- dueDateAdapter.notifyDataSetChanged();
- dueDateSpinner.setSelection(0);
- }
-
- private void updateDueTimeOptions() {
- if (time == -1) {
- dueTimeOptions.set(0, noTimeString);
- } else {
- int compareTime = newDateTime()
- .withMillisOfDay(time)
- .withSecondOfMinute(0)
- .withMillisOfSecond(0)
- .getMillisOfDay();
- if (compareTime == dateShortcutMorning) {
- dueTimeOptions.set(0, morningString);
- } else if (compareTime == dateShortcutAfternoon) {
- dueTimeOptions.set(0, afternoonString);
- } else if (compareTime == dateShortcutEvening) {
- dueTimeOptions.set(0, eveningString);
- } else if (compareTime == dateShortcutNight) {
- dueTimeOptions.set(0, nightString);
- } else {
- dueTimeOptions.set(0, DateUtilities.getTimeString(activity, newDateTime().withMillisOfDay(time)));
- }
- }
- dueTimeAdapter.notifyDataSetChanged();
- dueTimeSpinner.setSelection(0);
- }
-
+ @Nullable
@Override
- protected void afterInflate() {
- View view = getView();
- clearButton = view.findViewById(R.id.clear);
- clearButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- date = 0;
- time = -1;
- refreshDisplayView();
- }
- });
- dueDateSpinner = (Spinner) view.findViewById(R.id.due_date);
- dueDateAdapter = new HiddenTopArrayAdapter(activity, android.R.layout.simple_spinner_item, dueDateOptions) {
+ public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = super.onCreateView(inflater, container, savedInstanceState);
+ if (savedInstanceState != null) {
+ date = savedInstanceState.getLong(EXTRA_DATE);
+ time = savedInstanceState.getInt(EXTRA_TIME);
+ }
+ final int themeColor = getData(context, R.attr.asTextColor);
+ final int overdueColor = context.getResources().getColor(R.color.overdue);
+ dueDateAdapter = new HiddenTopArrayAdapter(context, android.R.layout.simple_spinner_item, dueDateOptions) {
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
int selectedItemPosition = position;
if (parent instanceof AdapterView) {
selectedItemPosition = ((AdapterView) parent).getSelectedItemPosition();
}
- TextView tv = (TextView) LayoutInflater.from(activity).inflate(android.R.layout.simple_spinner_item, parent, false);
+ TextView tv = (TextView) inflater.inflate(android.R.layout.simple_spinner_item, parent, false);
tv.setText(dueDateOptions.get(selectedItemPosition));
if (date == 0) {
dueDateSpinner.setAlpha(0.5f);
- dueDateSpinner.setBackgroundDrawable(getThemedUnderline());
+ dueDateSpinner.setBackgroundDrawable(getUnderline(themeColor));
} else {
dueDateSpinner.setAlpha(1.0f);
if (date < newDateTime().startOfDay().getMillis()) {
- dueDateSpinner.setBackgroundDrawable(getRedUnderline());
- tv.setTextColor(activity.getResources().getColor(R.color.overdue));
+ dueDateSpinner.setBackgroundDrawable(getUnderline(overdueColor));
+ tv.setTextColor(overdueColor);
} else {
- dueDateSpinner.setBackgroundDrawable(getThemedUnderline());
+ dueDateSpinner.setBackgroundDrawable(getUnderline(themeColor));
tv.setTextColor(themeColor);
}
}
@@ -198,26 +147,25 @@ public class DeadlineControlSet extends TaskEditControlSetBase {
};
dueDateSpinner.setAdapter(dueDateAdapter);
- dueTimeSpinner = (Spinner) view.findViewById(R.id.due_time);
- dueTimeAdapter = new HiddenTopArrayAdapter(activity, android.R.layout.simple_spinner_item, dueTimeOptions, dueTimeHint) {
+ dueTimeAdapter = new HiddenTopArrayAdapter(context, android.R.layout.simple_spinner_item, dueTimeOptions, dueTimeHint) {
@Override
public View getView(final int position, final View convertView, final ViewGroup parent) {
int selectedItemPosition = position;
if (parent instanceof AdapterView) {
selectedItemPosition = ((AdapterView) parent).getSelectedItemPosition();
}
- TextView tv = (TextView) LayoutInflater.from(activity).inflate(android.R.layout.simple_spinner_item, parent, false);
+ TextView tv = (TextView) inflater.inflate(android.R.layout.simple_spinner_item, parent, false);
tv.setText(dueTimeOptions.get(selectedItemPosition));
if (time == -1) {
dueTimeSpinner.setAlpha(0.5f);
- dueTimeSpinner.setBackgroundDrawable(getThemedUnderline());
+ dueTimeSpinner.setBackgroundDrawable(getUnderline(themeColor));
} else {
dueTimeSpinner.setAlpha(1.0f);
if (newDateTime(date).withMillisOfDay(time).isBeforeNow()) {
- dueTimeSpinner.setBackgroundDrawable(getRedUnderline());
- tv.setTextColor(activity.getResources().getColor(R.color.overdue));
+ dueTimeSpinner.setBackgroundDrawable(getUnderline(overdueColor));
+ tv.setTextColor(overdueColor);
} else {
- dueTimeSpinner.setBackgroundDrawable(getThemedUnderline());
+ dueTimeSpinner.setBackgroundDrawable(getUnderline(themeColor));
tv.setTextColor(themeColor);
}
}
@@ -226,119 +174,197 @@ public class DeadlineControlSet extends TaskEditControlSetBase {
};
dueTimeSpinner.setAdapter(dueTimeAdapter);
- dueDateSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView> parent, View view, int position, long id) {
- DateTime today = newDateTime().startOfDay();
- switch (position) {
- case 0:
- return;
- case 1:
- setDate(today.getMillis());
- break;
- case 2:
- setDate(today.plusDays(1).getMillis());
- break;
- case 3:
- setDate(today.plusWeeks(1).getMillis());
- break;
- case 4:
- MyDatePickerDialog dialog = new MyDatePickerDialog();
- DateTime initial = date > 0 ? newDateTime(date) : today;
- dialog.initialize(new DatePickerDialog.OnDateSetListener() {
- @Override
- public void onDateSet(DatePickerDialog datePickerDialog, int year, int month, int day) {
- setDate(new DateTime(year, month + 1, day, 0, 0, 0, 0).getMillis());
- }
- }, initial.getYear(), initial.getMonthOfYear() - 1, initial.getDayOfMonth());
- dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- refreshDisplayView();
- }
- });
- if (preferences.isDarkTheme()) {
- dialog.setAccentColor(activity.getResources().getColor(R.color.black_text_hint));
- }
- dialog.show(activity.getFragmentManager(), FRAG_TAG_PICK_A_DATE);
- break;
- }
- }
+ refreshDisplayView();
- @Override
- public void onNothingSelected(AdapterView> parent) {
+ return view;
+ }
- }
- });
+ @OnClick(R.id.clear)
+ void clearTime(View view) {
+ date = 0;
+ time = -1;
+ refreshDisplayView();
+ }
- dueTimeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
- @Override
- public void onItemSelected(AdapterView> parent, View view, int position, long id) {
- switch (position) {
- case 0:
- return;
- case 1:
- setTime(-1);
- break;
- case 2:
- setTime(dateShortcutMorning);
- break;
- case 3:
- setTime(dateShortcutAfternoon);
- break;
- case 4:
- setTime(dateShortcutEvening);
- break;
- case 5:
- setTime(dateShortcutNight);
- break;
- case 6:
- MyTimePickerDialog dialog = new MyTimePickerDialog();
- int initialHours = 0;
- int initialMinutes = 0;
- if (time >= 0) {
- DateTime initial = newDateTime(date).withMillisOfDay(time);
- initialHours = initial.getHourOfDay();
- initialMinutes = initial.getMinuteOfHour();
- }
- dialog.initialize(new TimePickerDialog.OnTimeSetListener() {
- @Override
- public void onTimeSet(RadialPickerLayout radialPickerLayout, int hour, int minute, int seconds) {
- setTime((int) TimeUnit.HOURS.toMillis(hour) + (int) TimeUnit.MINUTES.toMillis(minute));
- }
- }, initialHours, initialMinutes, 0, DateFormat.is24HourFormat(activity));
- dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- refreshDisplayView();
- }
- });
- if (preferences.isDarkTheme()) {
- dialog.setAccentColor(activity.getResources().getColor(R.color.black_text_hint));
- }
- dialog.show(activity.getFragmentManager(), FRAG_TAG_PICK_A_TIME);
- break;
- }
+ @OnItemSelected(R.id.due_date)
+ void onDateSelected(int position) {
+ DateTime today = newDateTime().startOfDay();
+ switch (position) {
+ case 0:
+ return;
+ case 1:
+ setDate(today.getMillis());
+ break;
+ case 2:
+ setDate(today.plusDays(1).getMillis());
+ break;
+ case 3:
+ setDate(today.plusWeeks(1).getMillis());
+ break;
+ case 4:
+ startActivityForResult(new Intent(context, DatePickerActivity.class) {{
+ putExtra(DatePickerActivity.EXTRA_TIMESTAMP, getDueDate());
+ }}, REQUEST_DATE);
+ break;
+ }
+ }
+
+ @OnItemSelected(R.id.due_time)
+ void onTimeSelected(int position) {
+ switch (position) {
+ case 0:
+ return;
+ case 1:
+ setTime(-1);
+ break;
+ case 2:
+ setTime(dateShortcutMorning);
+ break;
+ case 3:
+ setTime(dateShortcutAfternoon);
+ break;
+ case 4:
+ setTime(dateShortcutEvening);
+ break;
+ case 5:
+ setTime(dateShortcutNight);
+ break;
+ case 6:
+ startActivityForResult(new Intent(context, TimePickerActivity.class) {{
+ putExtra(TimePickerActivity.EXTRA_TIMESTAMP, getDueDate());
+ }}, REQUEST_TIME);
+ break;
+ }
+ }
+
+ @Override
+ protected int getLayout() {
+ return R.layout.control_set_deadline;
+ }
+
+ @Override
+ protected int getIcon() {
+ return R.drawable.ic_schedule_24dp;
+ }
+
+ @Override
+ public void initialize(boolean isNewTask, Task task) {
+ if (task.hasDueDate()) {
+ DateTime dateTime = newDateTime(task.getDueDate());
+ date = dateTime.startOfDay().getMillis();
+ time = task.hasDueTime() ? dateTime.getMillisOfDay() : -1;
+ } else {
+ date = 0;
+ time = -1;
+ }
+ }
+
+ @Override
+ public void apply(Task task) {
+ long dueDate = getDueDate();
+ if (dueDate != task.getDueDate()) {
+ task.setReminderSnooze(0L);
+ }
+ task.setDueDate(dueDate);
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_DATE) {
+ if (resultCode == Activity.RESULT_OK) {
+ long timestamp = data.getLongExtra(DatePickerActivity.EXTRA_TIMESTAMP, 0L);
+ DateTime dateTime = new DateTime(timestamp);
+ setDate(dateTime.getMillis());
+ } else {
+ refreshDisplayView();
+ }
+ } else if (requestCode == REQUEST_TIME) {
+ if (resultCode == Activity.RESULT_OK) {
+ long timestamp = data.getLongExtra(TimePickerActivity.EXTRA_TIMESTAMP, 0L);
+ DateTime dateTime = new DateTime(timestamp);
+ setTime(dateTime.getMillisOfDay());
+ } else {
+ refreshDisplayView();
}
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
- @Override
- public void onNothingSelected(AdapterView> parent) {
+ private long getDueDate() {
+ return time >= 0
+ ? Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, newDateTime(date).withMillisOfDay(time).getMillis())
+ : Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, date);
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putLong(EXTRA_DATE, date);
+ outState.putInt(EXTRA_TIME, time);
+ }
+
+ private String getTimeHint(int millisOfDay) {
+ DateTime dateTime = newDateTime().withMillisOfDay(millisOfDay);
+ return DateUtilities.getTimeString(context, dateTime);
+ }
+
+ private void refreshDisplayView() {
+ updateDueDateOptions();
+ updateDueTimeOptions();
+ clearButton.setVisibility(date > 0 ? View.VISIBLE : View.GONE);
+ }
+
+ private void updateDueDateOptions() {
+ DateTime today = newDateTime().startOfDay();
+ String nextWeekString = getString(R.string.next, today.plusWeeks(1).toString("EEEE"));
+ if (date == 0) {
+ dueDateOptions.set(0, getString(R.string.TEA_no_date));
+ } else {
+ if (date == today.getMillis()) {
+ dueDateOptions.set(0, todayString);
+ } else if (date == today.plusDays(1).getMillis()) {
+ dueDateOptions.set(0, tomorrowString);
+ } else if (date == today.plusWeeks(1).getMillis()) {
+ dueDateOptions.set(0, nextWeekString);
+ } else {
+ dueDateOptions.set(0, DateUtilities.getLongDateString(newDateTime(date)));
}
- });
+ }
+ dueDateOptions.set(3, nextWeekString);
+ dueDateAdapter.notifyDataSetChanged();
+ dueDateSpinner.setSelection(0);
}
- private Drawable getThemedUnderline() {
- Drawable drawable = DrawableCompat.wrap(activity.getResources().getDrawable(R.drawable.textfield_underline_black));
- DrawableCompat.setTint(drawable, activity.getResources().getColor(preferences.isDarkTheme()
- ? android.R.color.white
- : android.R.color.black));
- return drawable;
+ private void updateDueTimeOptions() {
+ if (time == -1) {
+ dueTimeOptions.set(0, noTimeString);
+ } else {
+ int compareTime = newDateTime()
+ .withMillisOfDay(time)
+ .withSecondOfMinute(0)
+ .withMillisOfSecond(0)
+ .getMillisOfDay();
+ if (compareTime == dateShortcutMorning) {
+ dueTimeOptions.set(0, morningString);
+ } else if (compareTime == dateShortcutAfternoon) {
+ dueTimeOptions.set(0, afternoonString);
+ } else if (compareTime == dateShortcutEvening) {
+ dueTimeOptions.set(0, eveningString);
+ } else if (compareTime == dateShortcutNight) {
+ dueTimeOptions.set(0, nightString);
+ } else {
+ dueTimeOptions.set(0, DateUtilities.getTimeString(context, newDateTime().withMillisOfDay(time)));
+ }
+ }
+ dueTimeAdapter.notifyDataSetChanged();
+ dueTimeSpinner.setSelection(0);
}
- private Drawable getRedUnderline() {
- Drawable drawable = DrawableCompat.wrap(activity.getResources().getDrawable(R.drawable.textfield_underline_black));
- DrawableCompat.setTint(drawable, activity.getResources().getColor(R.color.overdue));
+ private Drawable getUnderline(int color) {
+ Drawable drawable = DrawableCompat.wrap(context.getResources().getDrawable(R.drawable.textfield_underline_black));
+ DrawableCompat.setTint(drawable, color);
return drawable;
}
@@ -363,38 +389,4 @@ public class DeadlineControlSet extends TaskEditControlSetBase {
refreshDisplayView();
}
-
- @Override
- protected void readFromTaskOnInitialize() {
- Long dueDate = model.getDueDate();
- if (dueDate > 0) {
- DateTime dateTime = newDateTime(dueDate);
- date = dateTime.startOfDay().getMillis();
- if (Task.hasDueTime(dateTime.getMillis())) {
- setTime(dateTime.getMillisOfDay());
- } else {
- time = -1;
- }
- } else {
- date = 0;
- time = -1;
- }
- refreshDisplayView();
- }
-
- @Override
- protected void writeToModelAfterInitialized(Task task) {
- long dueDate = time >= 0
- ? Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, newDateTime(date).withMillisOfDay(time).getMillis())
- : Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, date);
- if (dueDate != task.getDueDate()) {
- task.setReminderSnooze(0L);
- }
- task.setDueDate(dueDate);
- }
-
- @Override
- public int getIcon() {
- return R.drawable.ic_schedule_24dp;
- }
}
diff --git a/src/main/java/org/tasks/ui/DescriptionControlSet.java b/src/main/java/org/tasks/ui/DescriptionControlSet.java
new file mode 100644
index 000000000..a40c48b2d
--- /dev/null
+++ b/src/main/java/org/tasks/ui/DescriptionControlSet.java
@@ -0,0 +1,70 @@
+package org.tasks.ui;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+
+import com.google.common.base.Strings;
+import com.todoroo.astrid.data.Task;
+
+import org.tasks.R;
+
+import butterknife.Bind;
+import butterknife.OnTextChanged;
+
+public class DescriptionControlSet extends TaskEditControlFragment {
+
+ private static final String EXTRA_DESCRIPTION = "extra_description";
+
+ @Bind(R.id.notes) EditText editText;
+
+ private String description;
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = super.onCreateView(inflater, container, savedInstanceState);
+ if (savedInstanceState != null) {
+ description = savedInstanceState.getString(EXTRA_DESCRIPTION);
+ }
+ if (!Strings.isNullOrEmpty(description)) {
+ editText.setTextKeepState(description);
+ }
+ return view;
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putString(EXTRA_DESCRIPTION, description);
+ }
+
+ @Override
+ protected int getLayout() {
+ return R.layout.control_set_description;
+ }
+
+ @Override
+ protected int getIcon() {
+ return R.drawable.ic_event_note_24dp;
+ }
+
+ @OnTextChanged(R.id.notes)
+ void textChanged(CharSequence text) {
+ description = text.toString().trim();
+ }
+
+ @Override
+ public void initialize(boolean isNewTask, Task task) {
+ description = task.getNotes();
+ }
+
+ @Override
+ public void apply(Task task) {
+ task.setNotes(description);
+ }
+}
diff --git a/src/main/java/org/tasks/ui/PriorityControlSet.java b/src/main/java/org/tasks/ui/PriorityControlSet.java
index 080fb9013..5dc04a37a 100644
--- a/src/main/java/org/tasks/ui/PriorityControlSet.java
+++ b/src/main/java/org/tasks/ui/PriorityControlSet.java
@@ -1,104 +1,115 @@
package org.tasks.ui;
import android.app.Activity;
+import android.content.Context;
import android.content.res.ColorStateList;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatRadioButton;
+import android.view.LayoutInflater;
import android.view.View;
-import android.widget.RadioGroup;
+import android.view.ViewGroup;
+import android.widget.CompoundButton;
-import com.google.common.primitives.Ints;
import com.todoroo.astrid.data.Task;
-import com.todoroo.astrid.helper.TaskEditControlSetBase;
import org.tasks.R;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
+import javax.inject.Inject;
-public class PriorityControlSet extends TaskEditControlSetBase {
+import butterknife.Bind;
+import butterknife.OnClick;
- private final List colors;
- private final List listeners = new LinkedList<>();
- private RadioGroup radioGroup;
+public class PriorityControlSet extends TaskEditControlFragment {
- public interface ImportanceChangedListener {
- void importanceChanged(int i);
+ public interface OnPriorityChanged {
+ void onPriorityChange(int priority);
}
- public PriorityControlSet(Activity activity) {
- super(activity, R.layout.control_set_priority);
- colors = Ints.asList(Task.getImportanceColors(activity.getResources()));
- Collections.reverse(colors);
- }
+ private static final String EXTRA_PRIORITY = "extra_priority";
- public void notifyImportanceChange(Integer i) {
- for (ImportanceChangedListener l : listeners) {
- l.importanceChanged(i);
- }
- }
+ @Inject CheckBoxes checkBoxes;
- private Integer getImportance(int checkedId) {
- return getImportance(getView().findViewById(checkedId));
- }
+ @Bind(R.id.priority_high) AppCompatRadioButton priorityHigh;
+ @Bind(R.id.priority_medium) AppCompatRadioButton priorityMedium;
+ @Bind(R.id.priority_low) AppCompatRadioButton priorityLow;
+ @Bind(R.id.priority_none) AppCompatRadioButton priorityNone;
- private Integer getImportance(View view) {
- return Integer.parseInt((String) view.getTag());
+ private OnPriorityChanged callback;
+ private int priority;
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+
+ callback = (OnPriorityChanged) activity;
}
- public void addListener(ImportanceChangedListener listener) {
- listeners.add(listener);
+ @OnClick({R.id.priority_high, R.id.priority_medium, R.id.priority_low, R.id.priority_none})
+ void onImportanceChanged(CompoundButton button) {
+ callback.onPriorityChange(getPriority());
}
+ @Nullable
@Override
- protected void afterInflate() {
- final View view = getView();
- radioGroup = (RadioGroup) view.findViewById(R.id.importance_group);
- radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(RadioGroup group, int checkedId) {
- notifyImportanceChange(getImportance(checkedId));
- }
- });
- for (int i = 0; i < radioGroup.getChildCount(); i++) {
- AppCompatRadioButton radioButton = (AppCompatRadioButton) radioGroup.getChildAt(i);
- radioButton.setSupportButtonTintList(new ColorStateList(new int[][]{
- new int[]{-android.R.attr.state_checked}, new int[]{android.R.attr.state_checked}},
- new int[]{colors.get(i), colors.get(i)}));
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ final View view = super.onCreateView(inflater, container, savedInstanceState);
+ if (savedInstanceState != null) {
+ priority = savedInstanceState.getInt(EXTRA_PRIORITY);
+ }
+ if (priority == 0) {
+ priorityHigh.setChecked(true);
+ } else if(priority == 1) {
+ priorityMedium.setChecked(true);
+ } else if(priority == 2) {
+ priorityLow.setChecked(true);
+ } else {
+ priorityNone.setChecked(true);
}
+ tintRadioButton(priorityHigh, 0);
+ tintRadioButton(priorityMedium, 1);
+ tintRadioButton(priorityLow, 2);
+ tintRadioButton(priorityNone, 3);
+ return view;
}
@Override
- public void readFromTask(Task task) {
- super.readFromTask(task);
- setSelected(model.getImportance());
+ protected int getLayout() {
+ return R.layout.control_set_priority;
}
@Override
- public int getIcon() {
+ protected int getIcon() {
return R.drawable.ic_flag_24dp;
}
@Override
- protected void readFromTaskOnInitialize() {
- setSelected(model.getImportance());
+ public void initialize(boolean isNewTask, Task task) {
+ priority = task.getImportance();
}
- private void setSelected(int importance) {
- if (radioGroup == null) {
- return;
- }
+ @Override
+ public void apply(Task task) {
+ task.setImportance(getPriority());
+ }
- for (int i = 0; i < radioGroup.getChildCount(); i++) {
- AppCompatRadioButton radioButton = (AppCompatRadioButton) radioGroup.getChildAt(i);
- if (importance == getImportance(radioButton)) {
- radioButton.setChecked(true);
- }
- }
+ private void tintRadioButton(AppCompatRadioButton radioButton, int priority) {
+ int color = checkBoxes.getPriorityColors().get(priority);
+ radioButton.setSupportButtonTintList(new ColorStateList(new int[][]{
+ new int[]{-android.R.attr.state_checked}, new int[]{android.R.attr.state_checked}},
+ new int[]{color, color}));
}
- @Override
- protected void writeToModelAfterInitialized(Task task) {
- task.setImportance(getImportance(radioGroup.getCheckedRadioButtonId()));
+ private int getPriority() {
+ if (priorityHigh.isChecked()) {
+ return 0;
+ }
+ if (priorityMedium.isChecked()) {
+ return 1;
+ }
+ if (priorityLow.isChecked()) {
+ return 2;
+ }
+ return 3;
}
}
diff --git a/src/main/java/org/tasks/ui/TaskEditControlFragment.java b/src/main/java/org/tasks/ui/TaskEditControlFragment.java
new file mode 100644
index 000000000..8bf8bf223
--- /dev/null
+++ b/src/main/java/org/tasks/ui/TaskEditControlFragment.java
@@ -0,0 +1,39 @@
+package org.tasks.ui;
+
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+import com.todoroo.astrid.data.Task;
+
+import org.tasks.R;
+import org.tasks.injection.InjectingFragment;
+
+import butterknife.ButterKnife;
+
+public abstract class TaskEditControlFragment extends InjectingFragment {
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ final View view = inflater.inflate(R.layout.control_set_template, null);
+ LinearLayout content = (LinearLayout) view.findViewById(R.id.content);
+ content.addView(inflater.inflate(getLayout(), null));
+ ImageView icon = (ImageView) view.findViewById(R.id.icon);
+ icon.setImageResource(getIcon());
+ ButterKnife.bind(this, view);
+ return view;
+ }
+
+ protected abstract int getLayout();
+
+ protected abstract int getIcon();
+
+ public abstract void initialize(boolean isNewTask, Task task);
+
+ public abstract void apply(Task task);
+}
diff --git a/src/main/res/drawable/btn_check.xml b/src/main/res/drawable/btn_check.xml
deleted file mode 100644
index 80906df34..000000000
--- a/src/main/res/drawable/btn_check.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/src/main/res/drawable/btn_check_small.xml b/src/main/res/drawable/btn_check_small.xml
deleted file mode 100644
index 3ff6790be..000000000
--- a/src/main/res/drawable/btn_check_small.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/res/drawable/icn_arrow_down.png b/src/main/res/drawable/icn_arrow_down.png
deleted file mode 100644
index 3ffbaac88..000000000
Binary files a/src/main/res/drawable/icn_arrow_down.png and /dev/null differ
diff --git a/src/main/res/drawable/icn_arrow_up.png b/src/main/res/drawable/icn_arrow_up.png
deleted file mode 100644
index 56ae0016a..000000000
Binary files a/src/main/res/drawable/icn_arrow_up.png and /dev/null differ
diff --git a/src/main/res/drawable/icn_check_off.png b/src/main/res/drawable/icn_check_off.png
deleted file mode 100644
index 12bfa5215..000000000
Binary files a/src/main/res/drawable/icn_check_off.png and /dev/null differ
diff --git a/src/main/res/drawable/icn_check_on.png b/src/main/res/drawable/icn_check_on.png
deleted file mode 100644
index a316022ff..000000000
Binary files a/src/main/res/drawable/icn_check_on.png and /dev/null differ
diff --git a/src/main/res/layout/control_set_gcal_display.xml b/src/main/res/layout/control_set_gcal_display.xml
index 557a79049..e8b222be7 100644
--- a/src/main/res/layout/control_set_gcal_display.xml
+++ b/src/main/res/layout/control_set_gcal_display.xml
@@ -20,7 +20,7 @@
android:layout_height="wrap_content"
android:layout_gravity="top"
android:gravity="start"
- android:textColor="?attr/asThemeTextColor"
+ android:textColor="?attr/asTextColor"
android:textSize="@dimen/task_edit_text_size" />
diff --git a/src/main/res/layout/control_set_hide.xml b/src/main/res/layout/control_set_hide.xml
index 259391d58..0645611ed 100644
--- a/src/main/res/layout/control_set_hide.xml
+++ b/src/main/res/layout/control_set_hide.xml
@@ -1,32 +1,20 @@
-
+
-
-
+ android:layout_weight="100"
+ android:orientation="horizontal">
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:background="@null"/>
diff --git a/src/main/res/layout/control_set_priority.xml b/src/main/res/layout/control_set_priority.xml
index a3a688d01..68e7a6f0d 100644
--- a/src/main/res/layout/control_set_priority.xml
+++ b/src/main/res/layout/control_set_priority.xml
@@ -17,7 +17,6 @@
android:textSize="@dimen/task_edit_text_size" />
+ android:id="@+id/priority_none"
+ style="@style/priority_button"/>
+ android:id="@+id/priority_low"
+ style="@style/priority_button"/>
+ android:id="@+id/priority_medium"
+ style="@style/priority_button"/>
+ android:id="@+id/priority_high"
+ style="@style/priority_button"/>
diff --git a/src/main/res/layout/control_set_reminders.xml b/src/main/res/layout/control_set_reminders.xml
index a3bd07a88..608685d55 100644
--- a/src/main/res/layout/control_set_reminders.xml
+++ b/src/main/res/layout/control_set_reminders.xml
@@ -50,19 +50,14 @@
android:gravity="end"
android:layout_weight="50">
-
-
+ android:background="@null"
+ android:gravity="end"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="10dp"
+ android:paddingEnd="10dp"/>
diff --git a/src/main/res/layout/control_set_repeat.xml b/src/main/res/layout/control_set_repeat.xml
index 51e431fe5..28cb6fa35 100644
--- a/src/main/res/layout/control_set_repeat.xml
+++ b/src/main/res/layout/control_set_repeat.xml
@@ -28,14 +28,16 @@
android:id="@+id/repeatValue"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_weight="1" />
+ android:layout_weight="1"
+ android:textColor="?attr/asTextColor"/>
+ android:prompt="@string/repeat_interval_prompt"
+ android:textColor="?attr/asTextColor" />
@@ -44,7 +46,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
- android:paddingTop="5dp" />
+ android:paddingTop="5dp"
+ android:textColor="?attr/asTextColor" />
+ android:paddingTop="5dp">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:paddingTop="5dp"
+ android:textColor="?attr/asTextColor" />
diff --git a/src/main/res/layout/control_set_repeat_display.xml b/src/main/res/layout/control_set_repeat_display.xml
index 6d253dc47..a97bfd9ae 100644
--- a/src/main/res/layout/control_set_repeat_display.xml
+++ b/src/main/res/layout/control_set_repeat_display.xml
@@ -20,7 +20,7 @@
android:layout_height="wrap_content"
android:layout_gravity="top"
android:gravity="start"
- android:textColor="?attr/asThemeTextColor"
+ android:textColor="?attr/asTextColor"
android:textSize="@dimen/task_edit_text_size" />
diff --git a/src/main/res/layout/control_set_tag_list.xml b/src/main/res/layout/control_set_tag_list.xml
index 197408cc0..b0dddbcc2 100644
--- a/src/main/res/layout/control_set_tag_list.xml
+++ b/src/main/res/layout/control_set_tag_list.xml
@@ -32,6 +32,7 @@
android:layout_height="fill_parent"
android:layout_marginLeft="3dip"
android:layout_marginRight="3dip"
- android:layout_weight="100"/>
+ android:layout_weight="100"
+ android:choiceMode="multipleChoice"/>
diff --git a/src/main/res/layout/control_set_tags.xml b/src/main/res/layout/control_set_tags.xml
index 43f7d576a..620e0b995 100644
--- a/src/main/res/layout/control_set_tags.xml
+++ b/src/main/res/layout/control_set_tags.xml
@@ -8,5 +8,5 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
- android:textColor="?attr/asThemeTextColor"
+ android:textColor="?attr/asTextColor"
android:textSize="@dimen/task_edit_text_size" />
diff --git a/src/main/res/layout/control_set_timers.xml b/src/main/res/layout/control_set_timers.xml
index 292b45354..33438ceaf 100644
--- a/src/main/res/layout/control_set_timers.xml
+++ b/src/main/res/layout/control_set_timers.xml
@@ -3,9 +3,61 @@
**
** See the file "LICENSE" for the full license governing this code.
-->
-
+ android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/res/layout/control_set_timers_dialog.xml b/src/main/res/layout/control_set_timers_dialog.xml
index 61a8e700a..bf124c337 100644
--- a/src/main/res/layout/control_set_timers_dialog.xml
+++ b/src/main/res/layout/control_set_timers_dialog.xml
@@ -32,7 +32,7 @@
android:layout_weight="1"
android:gravity="right"
android:paddingLeft="10dip"
- android:textColor="?attr/asThemeTextColor" />
+ android:textColor="?attr/asTextColor" />
+ android:textColor="?attr/asTextColor" />
diff --git a/src/main/res/layout/control_set_title.xml b/src/main/res/layout/control_set_title.xml
index 1e403971d..0a0bd3ecf 100644
--- a/src/main/res/layout/control_set_title.xml
+++ b/src/main/res/layout/control_set_title.xml
@@ -1,5 +1,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/res/layout/task_edit_activity.xml b/src/main/res/layout/task_edit_activity.xml
index 3c72ec89c..f367c2285 100644
--- a/src/main/res/layout/task_edit_activity.xml
+++ b/src/main/res/layout/task_edit_activity.xml
@@ -24,13 +24,6 @@
android:orientation="vertical"
android:gravity="center_horizontal" >
-
-
-
-
-
-
-
-
-
-
-
-
+ android:orientation="vertical"
+ android:layout_gravity="center">
+
+
+
+
+
+
+
diff --git a/src/main/res/values-ar/strings.xml b/src/main/res/values-ar/strings.xml
index 5c13a33c0..fcaf15d77 100644
--- a/src/main/res/values-ar/strings.xml
+++ b/src/main/res/values-ar/strings.xml
@@ -65,7 +65,6 @@
أنشئت القائمة
ظهور
تعديل خيارات الشاشه
- إظهار إختصار المنبه
الإعادة إلى الإفتراضي
إظهار عنوان المهمه
خيارات قائمة المهام
@@ -159,7 +158,6 @@
- من تاريخ الموعد
- من تاريخ الاتمام
- أضف للقائمة
أدخل اسم للقائمة أولاً
غير مصنف
مؤقت
diff --git a/src/main/res/values-bg-rBG/strings.xml b/src/main/res/values-bg-rBG/strings.xml
index 0e89a5ba2..f9955a9a8 100644
--- a/src/main/res/values-bg-rBG/strings.xml
+++ b/src/main/res/values-bg-rBG/strings.xml
@@ -116,7 +116,6 @@
Изглед
Филтри за показване
Редактиране на опциите екрана
- Покажи прекия път към таймера
Настройване изгледа на екрана за редактиране на задача
Възстанови по подразбиране
Настройване изгледа на екрана за редактиране на задача чрез изтегляне на елементите във всеки ред
@@ -255,7 +254,6 @@
- месечно
- на два месеца
- Повторения
Всеки %d
Интервал на повторение
Без повторение
@@ -276,7 +274,6 @@
Повтаряй завинаги
Повтаряй до %s
%1$s е насрочено за %2$s
- Добави към списъци
Нов таг
Моля, първо въведете име за този списък!
Без категория
diff --git a/src/main/res/values-ca/strings.xml b/src/main/res/values-ca/strings.xml
index f0553441e..d7b6b380b 100644
--- a/src/main/res/values-ca/strings.xml
+++ b/src/main/res/values-ca/strings.xml
@@ -125,7 +125,6 @@
Inici de Silenci
Final de Silenci
Notificacions al Atzar
- Repeticions
Cada %d
Interval de Repecitiò
Sense repetir
diff --git a/src/main/res/values-cs/strings.xml b/src/main/res/values-cs/strings.xml
index daf0b9014..401983999 100644
--- a/src/main/res/values-cs/strings.xml
+++ b/src/main/res/values-cs/strings.xml
@@ -220,7 +220,6 @@
- měsíčně
- každý druhý měsíc
- Opakování
Každý %d
Opakovací interval
Bez opakování
@@ -240,7 +239,6 @@
Každý %1$s\n až do %2$s
Opakovat stále
Opakovat až do %s
- Přidat na seznam
Prosím zadejte jméno pro první seznam
Nezařazené
Aktivní časovače pro %s!
diff --git a/src/main/res/values-da/strings.xml b/src/main/res/values-da/strings.xml
index 9ed16bc98..1199cae09 100644
--- a/src/main/res/values-da/strings.xml
+++ b/src/main/res/values-da/strings.xml
@@ -120,7 +120,6 @@
Stille timer start
Stille timer slut
Tilfældige påmindelser
- Gentagelser
Hver %d
Interval for gentagelse
Gentages ikke
diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml
index 0f48c8eda..42fe33d88 100644
--- a/src/main/res/values-de/strings.xml
+++ b/src/main/res/values-de/strings.xml
@@ -109,7 +109,6 @@
Erscheinungsbild
Angezeigte Filter
Bildschirmeinstellungen bearbeiten
- Verknüpfung zu Timer anzeigen
Erscheinungsbild Aufgabenseite anpassen
Auf Standardeinstellungen zurücksetzen
Du kannst die Eingabeseite für Aufgaben mit den Schiebereglern links anpassen
@@ -235,7 +234,6 @@
- monatlich
- alle zwei Monate
- Wiederholungen
Jeden %d
Wiederholungsintervall
Nicht wiederholen
@@ -256,7 +254,6 @@
Endlos wiederholen
Wiederhole bis %s
%1$s verschoben um %2$s
- Zur Liste hinzufügen
Neues Schlagwort
Bitte gib zuerst einen Namen für die Liste ein!
Nicht kategorisiert
diff --git a/src/main/res/values-el/strings.xml b/src/main/res/values-el/strings.xml
index 94f9b310f..3f6d9e90a 100644
--- a/src/main/res/values-el/strings.xml
+++ b/src/main/res/values-el/strings.xml
@@ -103,7 +103,6 @@
Εμφάνιση
Φίλτρα για εμφάνιση
Επεξεργασία επιλογών εμφάνισης
- Εμφάνιση συντόμευσης χρονομέτρου
Προσαρμόστε τη διάταξη της οθόνης επεξεργασίας της εργασίας
Επαναφορά προεπιλογών
Προσαρμόστε τη διάταξη της οθόνης επεξεργασίας της εργασίας τραβώντας την αριστερή λαβή σε κάθε σειρά
@@ -223,7 +222,6 @@
- μηνιαία
- διμηνιαία
- Επαναλήψεις
Κάθε %d
Διάστημα επανάληψης
Μή επαναλαμβανόμενα
@@ -243,7 +241,6 @@
Κάθε %1$s\nμέχρι %2$s
Επανάληψη επ\'αορίστου
Επανάληψη μέχρι %s
- Προσθήκη στις λίστες
Παρακαλώ εισάγετε ενα όνομα για την λίστα πρώτα!
Μη κατηγοριοποιημένο
Χρονοδιακόπτες ενεργοί για %s!
diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml
index 58b5f6927..ad54dc261 100644
--- a/src/main/res/values-es/strings.xml
+++ b/src/main/res/values-es/strings.xml
@@ -113,7 +113,6 @@
Apariencia
Filtros a mostrar
Editar opciones de pantalla
- Mostrar atajo del temporizador
Personalizar la disposición de la pantalla de edición de tareas
Restablecer valores predeterminados
Personalice su pantalla de edición de tareas arrastrando el asa izquierda en cada fila
@@ -245,7 +244,6 @@
- mensualmente
- bimensualmente
- Repeticiones
Cada %d
Intervalo de repetición
Sin repetir
@@ -266,7 +264,6 @@
Repetir por siempre
Repetir hasta %s
%1$s He reprogramado esta tarea recurrente para %2$s
- Añadir a listas
Nueva Etiqueta
Por favor, ¡introduce un nombre para la primera lista!
Sin Categoría
diff --git a/src/main/res/values-fa/strings.xml b/src/main/res/values-fa/strings.xml
index 345c6c1b2..3fdf5792d 100644
--- a/src/main/res/values-fa/strings.xml
+++ b/src/main/res/values-fa/strings.xml
@@ -80,7 +80,6 @@
ظاهر
فیلترها برای نمایش
ویرایش تنظیمات صفحه
- نمایش میانبر تایمر
شخصی سازی قالب صفحه ویرایش وظیفه
برگرداندن به پیش فرض
نمایش عنوان کامل وظیفه
@@ -178,7 +177,6 @@
- هر ماه
- یک ماه درمیان
- تکرارها
دوره تکرار
بدون تکرار
@@ -194,7 +192,6 @@
- از تاریخ اتمام
تکرار بینهایت
- اضافه به لیست
تگ جدید
لطفا ابتدا یک نام برای لیست انتخاب نمایید
دسته بندی نشده
diff --git a/src/main/res/values-fi/strings.xml b/src/main/res/values-fi/strings.xml
index 92c249f43..59c1431d4 100644
--- a/src/main/res/values-fi/strings.xml
+++ b/src/main/res/values-fi/strings.xml
@@ -54,7 +54,6 @@
Valitettavasti meillä on yhteysongelmia Google palvelimiin. Ole hyvä ja yritä myöhemmin uudestaa.
Google tehtävät
Satunnainen muistutus
- Ei toistoa
Toista %d
Toistoväli
Ei toistuva
@@ -62,7 +61,6 @@
Joka %1$s\nkunnes %2$s
Toista loputtomiin
Toista kunnes %s
- Lisää listaan
Ole hyvä syötä ensin nimi tälle listalle!
Poista tehtävä
Lähdekoodi
diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml
index 16a4155d2..4f9ea5fc1 100644
--- a/src/main/res/values-fr/strings.xml
+++ b/src/main/res/values-fr/strings.xml
@@ -112,7 +112,6 @@
Apparence
Filtres à afficher
Edition des options d\'affichage
- Afficher le raccourci de minuterie
Personnaliser la disposition de l\'écran d\'édition de tâche
Rétablir les valeurs par défaut
Personnalisez votre écran d\'ajout de tâche en faisant glisser chaque ligne vers la gauche
@@ -247,7 +246,6 @@
- mensuel
- bi-mensuel
- Répétitions
Tous les %d
Interval de répétition
Une fois seulement
@@ -268,7 +266,6 @@
Répéter indéfiniment
Répéter jusqu\'à %s
%1$s replanifiée à %2$s
- Ajouter à la liste
Nouveau tag
Veuillez d\'abord entrer un nom pour cette liste.
Non classé
diff --git a/src/main/res/values-hu/strings.xml b/src/main/res/values-hu/strings.xml
index f8182e45a..ecb6b4a35 100644
--- a/src/main/res/values-hu/strings.xml
+++ b/src/main/res/values-hu/strings.xml
@@ -100,7 +100,6 @@
Befejezve
Szundi
Véletlenszerű emlékeztetők
- Ismétlések
Minden %d
Ismétlési időköz
Nem ismétlődő
@@ -108,7 +107,6 @@
Minden %1$s\neddig: %2$s
Ismétlés örökké
Ismétlés eddig: %s
- Hozzáadás listákhoz
Kérlek, először add meg a lista nevét!
Feladat törlése
diff --git a/src/main/res/values-it/strings.xml b/src/main/res/values-it/strings.xml
index bc676df96..fc7aa86ce 100644
--- a/src/main/res/values-it/strings.xml
+++ b/src/main/res/values-it/strings.xml
@@ -114,7 +114,6 @@
Aspetto
Filtri da visualizzare
Modifica opzioni schermo
- Mostra scorciatoia timer
Personalizza il layout della schermata di modifica attività
Ripristina predefiniti
Personalizza la schermata di modifica attività trascinando l’indicatore a sinistra di ogni riga
@@ -248,7 +247,6 @@ Se visualizzi questo errore più volte, ti consigliamo di cancellare tutti i dat
- mensilmente
- bi-mensilmente
- Ripetizioni
Ogni %d
Intervallo di ripetizione
Non ricorrente
@@ -269,7 +267,6 @@ Se visualizzi questo errore più volte, ti consigliamo di cancellare tutti i dat
Ripeti all\'infinito
Ripeti fino %s
%1$s ripianificata per %2$s
- Aggiungi alle liste
Nuova etichetta
Per cortesia, prima inserisci un nome per questa lista
Non classificato
diff --git a/src/main/res/values-iw/strings.xml b/src/main/res/values-iw/strings.xml
index 21e31dff5..b26241583 100644
--- a/src/main/res/values-iw/strings.xml
+++ b/src/main/res/values-iw/strings.xml
@@ -223,7 +223,6 @@
- חודשי
- דו חודשי
- חזרה
כל %d
אינטרוול חזרות
@@ -242,7 +241,6 @@
כל %1$s\nעד %2$s
חזור לנצח
חזרה עד %s
- הוסף לרשימות
אנא הכנס שם לרשימה זו
קוצב זמן הופעל עבור %s משימות
משימות עם הערכת זמן
diff --git a/src/main/res/values-ja/strings.xml b/src/main/res/values-ja/strings.xml
index fc359ed48..9c09d3ed3 100644
--- a/src/main/res/values-ja/strings.xml
+++ b/src/main/res/values-ja/strings.xml
@@ -114,7 +114,6 @@
外観
表示のフィルター
編集画面オプション
- タイマーのショートカットを表示
タスク編集画面のレイアウトをカスタマイズ
デフォルトにリセット
各行の左側をドラッグしてタスク編集画面をカスタマイズしてください
@@ -254,7 +253,6 @@
- 毎月
- 一ヶ月おき
- 繰り返し
%d 毎
繰り返し間隔
繰り返しなし
@@ -275,7 +273,6 @@
永久に繰り返す
%s まで繰り返す
%1$s を %2$s にスケジュール変更しました
- リストに追加
新しいタグ
まずリスト名を記入してください!
未分類
diff --git a/src/main/res/values-ko/strings.xml b/src/main/res/values-ko/strings.xml
index c64a9d97b..60924fe0f 100644
--- a/src/main/res/values-ko/strings.xml
+++ b/src/main/res/values-ko/strings.xml
@@ -117,7 +117,6 @@
보기 설정
표시할 필터
화면 설정 편집하기
- 타이머 바로가기 보기
일정 편집화면 레이아웃 설정하기
기본값으로 초기화하기
각 줄의 왼쪽 손잡이를 끌어서 일정 편집 화면을 사용자 정의하기
@@ -255,7 +254,6 @@ Tasks의 백업에서 당신의 일정을 복구하시기 바랍니다.
- 매달
- 격월로
- 반복 설정
매 %d
반복 주기
반복하지 않기
@@ -276,7 +274,6 @@ Tasks의 백업에서 당신의 일정을 복구하시기 바랍니다.
영원히 반복하기
%s 까지 반복
%1$s 이 %2$s 로 변경되었습니다
- 목록에 추가하기
새 태그
이 목록의 이름을 먼저 입력하세요!
미분류 일정
diff --git a/src/main/res/values-nb/strings.xml b/src/main/res/values-nb/strings.xml
index 4634a1c4b..d70773ebe 100644
--- a/src/main/res/values-nb/strings.xml
+++ b/src/main/res/values-nb/strings.xml
@@ -110,7 +110,6 @@
Stilletimer start
Stilletimer slutt
Tilfeldige påminnelser
- Gjentakelser
Hver %d
Gjentakelsesintervall
Hver %s
diff --git a/src/main/res/values-nl/strings.xml b/src/main/res/values-nl/strings.xml
index 62ee9a757..18cfd1dec 100644
--- a/src/main/res/values-nl/strings.xml
+++ b/src/main/res/values-nl/strings.xml
@@ -114,7 +114,6 @@
Uiterlijk
Te tonen filters
Scherm opties bewerken
- Toon timer snelkoppeling
Pas de layout van het Taak Wijzigingsscherm aan
Standaardinstellingen herstellen
Pas uw taak bewerken scherm aan door de linker handle van elke rij te verslepen
@@ -251,7 +250,6 @@
- maandelijks
- tweemaandelijks
- Herhalingen
Elke %d
Herhaal interval
Niet herhalend
@@ -272,7 +270,6 @@
Altijd herhalen
Herhalen tot %s
%1$s opnieuw ingepland op %2$s
- Voeg toe aan lijsten
Nieuwe Label
Voer a.u.b. eerst een naam in voor deze lijst!
Niet gecategoriseerd
diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml
index 25b0f2978..6bfab901b 100644
--- a/src/main/res/values-pl/strings.xml
+++ b/src/main/res/values-pl/strings.xml
@@ -102,7 +102,6 @@
Wygląd
Pokazywane filtry
Edytuj ustawienia ekranu
- Pokaż skrót minutnika
Dostosuj układ strony edycji zadania
Przywróć domyślne
Dostosuj swój ekran edycji zadania przez przeciąganie za uchwyt po prawej w każdym wierszu
@@ -226,7 +225,6 @@ i odzyskanie zadań z kopi zapasowej (Settings->Sync and backup->Backup-&g
- raz w miesiącu
- raz na dwa miesiące
- Powtarza się
Co %d
Odstęp powtarzania
Jednorazowo
@@ -246,7 +244,6 @@ i odzyskanie zadań z kopi zapasowej (Settings->Sync and backup->Backup-&g
Co %1$s\ndo %2$s
Powtarzaj bez końca
Powtarzaj do %s
- Dodaj do list
Wpisz nazwę dla tej listy najpierw!
Na żadnej liście
Minutnkiki aktywne przez %s!
diff --git a/src/main/res/values-pt-rBR/strings.xml b/src/main/res/values-pt-rBR/strings.xml
index 88439c360..60ffbd215 100644
--- a/src/main/res/values-pt-rBR/strings.xml
+++ b/src/main/res/values-pt-rBR/strings.xml
@@ -102,7 +102,6 @@
Aparência
Filtros a mostrar
Editar opções da tela
- Exibir atalho para temporizador
Personalize o layout da tela de edição
Restaurar valores padrão
Personalize suas tarefas na tela de edição arrastando-as para a esquerda
@@ -223,7 +222,6 @@
- mensalmente
- a cada dois meses
- Repetir
A cada %d
Intervalo de repetição
Não repetir
@@ -243,7 +241,6 @@
Todo %1$s\naté %2$s
Repetir para sempre
Repetir até %s
- Adicionar às listas
Entre com o nome da lista primeiro!
Sem categoria
Temporizador ativado para %s!
diff --git a/src/main/res/values-pt/strings.xml b/src/main/res/values-pt/strings.xml
index 996e72238..adab75a22 100644
--- a/src/main/res/values-pt/strings.xml
+++ b/src/main/res/values-pt/strings.xml
@@ -113,7 +113,6 @@
Aspeto
Filtros a mostrar
Opções do ecrã de edição
- Mostrar atalho do temporizador
Personalizar o esquema do ecrã de edição de tarefas
Restaurar definições originas
Personalize o ecrã de edição de tarefas arrastando a guia em cada linha
@@ -246,7 +245,6 @@ das tarefas através de um backup em Definições->Sincronização e backup-&
- mensal
- bimensal
- Repete
Cada %d
Intervalo de repetição
Não repete
@@ -267,7 +265,6 @@ das tarefas através de um backup em Definições->Sincronização e backup-&
Repetir eternamente
Repetir até %s
%1$s agendada para %2$s
- Adicionar às listas
Nova etiqueta
Introduza o nome para esta lista!
Sem categoria
diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml
index 8128599a0..dc15003ca 100644
--- a/src/main/res/values-ru/strings.xml
+++ b/src/main/res/values-ru/strings.xml
@@ -114,7 +114,6 @@
Интерфейс
Показать фильтры
Редактировать настройки экрана
- Показать вкладку таймера
Настроить внешний вид экрана правки задачи
Настройки по умолчанию
Настройте экран редактирования задачи, перетаскивая элементы
@@ -253,7 +252,6 @@
- ежемесячно
- каждые два месяца
- Повторения
С интервалом в %d
Интервал повтора
Без повторений
@@ -274,7 +272,6 @@
Повторять всегда
Повторять до %s
«%1$s» перенесено на %2$s
- Добавить в список
Новый тег
Пожалуйста, для начала введите название списка!
Без тега
diff --git a/src/main/res/values-sk/strings.xml b/src/main/res/values-sk/strings.xml
index 3b6a28d09..ab95167bf 100644
--- a/src/main/res/values-sk/strings.xml
+++ b/src/main/res/values-sk/strings.xml
@@ -111,7 +111,6 @@
Vzhľad
Filtre pre zobrazenie
Možnosti úprav zobrazenia
- Zobraziť skratku časovača
Prispôsobiť rozvrhnutie zobrazenia úpravy úloh
Obnoviť na predvolené
Prispôsob si rozvrhnutie zobrazenia úpravy úloh potiahnutím ľavej rukoväte na každom riadku
@@ -239,7 +238,6 @@
- mesačne
- každý druhý mesiac
- Opakovanie
Každý %d
Interval opakovania
Neopakovať
@@ -260,7 +258,6 @@
Opakovať donekonečna
Opakovať do %s
%1$s preplánované na %2$s
- Pridať do zoznamov
Nasledujúci tag
Prosím, uveďte najprv názov pre tento zoznam!
Nezaradené
diff --git a/src/main/res/values-sl-rSI/strings.xml b/src/main/res/values-sl-rSI/strings.xml
index ddd0a75bb..3e929d6d0 100644
--- a/src/main/res/values-sl-rSI/strings.xml
+++ b/src/main/res/values-sl-rSI/strings.xml
@@ -106,7 +106,6 @@
Izgled
Filtri za prikaz
Uredi možnosti zaslona
- Prikaži bližnjico za štoparico
Po meri postavi stran za urejevanje opravkov
Povrni privzeto nastavitev
Stran za urejanje opravkov se postavi po meri s potegom leve ročke posamezne vrstice
@@ -227,7 +226,6 @@
- mesečno
- vsake dva meseca
- Ponovitve
Vsakih %d
Pogostost ponovitev
Brez ponovitev
@@ -247,7 +245,6 @@
Vsak %1$s\n do %2$s
Ponavljaj do preklica
Ponavljaj do %s
- Dodaj na sezname
Prosimo, vnesite naziv tega seznama najprej!
Nerazvrščen
Merilniki časa aktivni za %s!
diff --git a/src/main/res/values-sv/strings.xml b/src/main/res/values-sv/strings.xml
index 3c3fa54c4..9d9ba7cdb 100644
--- a/src/main/res/values-sv/strings.xml
+++ b/src/main/res/values-sv/strings.xml
@@ -218,7 +218,6 @@ och återställer dina aktuella uppgifter från en backup
- varje månad
- varannan månad
- Upprepningar
Varje %d
Upprepningsintervall
Inte upprepande
@@ -238,7 +237,6 @@ och återställer dina aktuella uppgifter från en backup
Varje %1$s\ntill %2$s
Repetera oändligt
Repetera till %s
- Lägg till på listor
Ange först ett namn på listan!
Ingen kategori
Tidtagarur aktivt för %s!
diff --git a/src/main/res/values-th/strings.xml b/src/main/res/values-th/strings.xml
index 53a90330f..c27647aa2 100644
--- a/src/main/res/values-th/strings.xml
+++ b/src/main/res/values-th/strings.xml
@@ -65,7 +65,6 @@
%s (เสร็จสิ้นแล้ว)
เสร็จเรียบร้อยแล้ว!
หลับ..
- การเกิดซ้ำ
วันนี้
พรุ่งนี้
เมื่อวาน
diff --git a/src/main/res/values-tr/strings.xml b/src/main/res/values-tr/strings.xml
index 0c3f6b496..40869bf39 100644
--- a/src/main/res/values-tr/strings.xml
+++ b/src/main/res/values-tr/strings.xml
@@ -198,7 +198,6 @@
- ayda bir
- ayda 2 kez
- Tekrarlar
Her %d
Yineleme Aralığı
diff --git a/src/main/res/values-uk/strings.xml b/src/main/res/values-uk/strings.xml
index 0b8e1f9e5..9aa32f668 100644
--- a/src/main/res/values-uk/strings.xml
+++ b/src/main/res/values-uk/strings.xml
@@ -109,7 +109,6 @@
Інтерфейс
Показати фільтри
Редагувати налаштування екрану
- Показати ярлик таймера
Налаштувати зовнішній вигляд екрану редагування завдань
Налаштування за замовчуванням
Налаштуйте Ваш екран редагування нотатки перетягуванням лівої частини рядків
@@ -239,7 +238,6 @@
- щомісяця
- два рази на місяць
- Повторення
З інтервалом в %d
Інтервал повторення
Не повторювати
@@ -247,7 +245,6 @@
Кожні %1$s\nпоки %2$s
Повторювати завжди
Повторювати до %s
- Додати до списку
Введіть назву списку спочатку!
Без категорії
Для %s діють таймери!
diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml
index efce8bd7b..cd5e4f99b 100644
--- a/src/main/res/values-zh-rCN/strings.xml
+++ b/src/main/res/values-zh-rCN/strings.xml
@@ -177,7 +177,6 @@
- 每月
- 每两个月
- 重复
每 %d
重复间隔
diff --git a/src/main/res/values-zh-rTW/strings.xml b/src/main/res/values-zh-rTW/strings.xml
index 608ad9603..6af1dc898 100644
--- a/src/main/res/values-zh-rTW/strings.xml
+++ b/src/main/res/values-zh-rTW/strings.xml
@@ -208,7 +208,6 @@
- 每月
- 每2個月
- 重複
每 %d
重複間隔
@@ -227,7 +226,6 @@
每隔 %1$s\n直到 %2$s
永遠重複
重複到 %s
- 加入至列表
請先為此列表鍵入一個名稱!
未分類
秒錶啟動了 %s!
diff --git a/src/main/res/values/arrays.xml b/src/main/res/values/arrays.xml
index 00504bb9b..34a3d2954 100644
--- a/src/main/res/values/arrays.xml
+++ b/src/main/res/values/arrays.xml
@@ -62,4 +62,10 @@
- @string/none
+
+ - @string/ring_once
+ - @string/ring_five_times
+ - @string/ring_nonstop
+
+
\ No newline at end of file
diff --git a/src/main/res/values/keys.xml b/src/main/res/values/keys.xml
index b3a6cdd6d..9e9850a8e 100644
--- a/src/main/res/values/keys.xml
+++ b/src/main/res/values/keys.xml
@@ -112,8 +112,6 @@
fullTaskTitle
- p_show_timer_shortcut
-
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index b49d7b4c8..bec189d04 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -344,8 +344,6 @@ File %1$s contained %2$s.\n\n
Edit screen options
- Show timer shortcut
-
Customize the layout of the task edit screen
@@ -696,9 +694,6 @@ File %1$s contained %2$s.\n\n
-
- Repeats
-
Every %d
@@ -739,13 +734,7 @@ File %1$s contained %2$s.\n\n
%1$s rescheduled for %2$s
-
-
-
-
- Add to lists
-
-
+
New Tag
diff --git a/src/main/res/xml/preferences_appearance.xml b/src/main/res/xml/preferences_appearance.xml
index 2abf69861..e3d501f1b 100644
--- a/src/main/res/xml/preferences_appearance.xml
+++ b/src/main/res/xml/preferences_appearance.xml
@@ -34,10 +34,6 @@
android:key="@string/p_show_task_edit_comments"
android:title="@string/EPr_show_task_edit_comments" />
-