Add multi-select copy and delete

pull/493/head
Alex Baker 9 years ago
parent 1d8411915a
commit 385900cad3

@ -129,6 +129,7 @@ dependencies {
compile 'com.jakewharton:process-phoenix:1.1.0' compile 'com.jakewharton:process-phoenix:1.1.0'
compile 'com.google.android.apps.dashclock:dashclock-api:2.0.0' compile 'com.google.android.apps.dashclock:dashclock-api:2.0.0'
compile 'com.twofortyfouram:android-plugin-api-for-locale:1.0.2' compile 'com.twofortyfouram:android-plugin-api-for-locale:1.0.2'
compile 'com.bignerdranch.android:recyclerview-multiselect:0.2'
compile ('com.rubiconproject.oss:jchronic:0.2.6') { compile ('com.rubiconproject.oss:jchronic:0.2.6') {
transitive = false transitive = false
} }

@ -58,8 +58,7 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
public static final String EXTRA_STORE_DATA = "extra_store_data"; public static final String EXTRA_STORE_DATA = "extra_store_data";
public static final String ACTION_DELETED = "action_deleted"; public static final String ACTION_DELETED = "action_deleted";
public static final String ACTION_RENAMED = "action_renamed"; public static final String ACTION_RELOAD = "action_reload";
public static final String ACTION_THEME_CHANGED = "action_theme_changed";
private boolean isNewList; private boolean isNewList;
private GtasksList gtasksList; private GtasksList gtasksList;
@ -174,7 +173,7 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
if (colorChanged()) { if (colorChanged()) {
gtasksList.setColor(selectedTheme); gtasksList.setColor(selectedTheme);
storeObjectDao.persist(gtasksList); storeObjectDao.persist(gtasksList);
setResult(RESULT_OK, new Intent(ACTION_THEME_CHANGED).putExtra(TaskListActivity.OPEN_FILTER, new GtasksFilter(gtasksList))); setResult(RESULT_OK, new Intent(ACTION_RELOAD).putExtra(TaskListActivity.OPEN_FILTER, new GtasksFilter(gtasksList)));
} }
finish(); finish();
} }
@ -269,7 +268,7 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
gtasksList.setName(taskList.getTitle()); gtasksList.setName(taskList.getTitle());
gtasksList.setColor(selectedTheme); gtasksList.setColor(selectedTheme);
storeObjectDao.persist(gtasksList); storeObjectDao.persist(gtasksList);
setResult(RESULT_OK, new Intent(ACTION_RENAMED).putExtra(TaskListActivity.OPEN_FILTER, new GtasksFilter(gtasksList))); setResult(RESULT_OK, new Intent(ACTION_RELOAD).putExtra(TaskListActivity.OPEN_FILTER, new GtasksFilter(gtasksList)));
finish(); finish();
} }
@ -302,6 +301,6 @@ public class GoogleTaskListSettingsActivity extends ThemedInjectingAppCompatActi
color.setText(themeColor.getName()); color.setText(themeColor.getName());
} }
themeColor.apply(toolbar); themeColor.apply(toolbar);
themeColor.applyStatusBarColor(this); themeColor.applyToStatusBar(this);
} }
} }

@ -7,6 +7,7 @@ import android.view.MenuItem;
import com.todoroo.astrid.activity.TaskListActivity; import com.todoroo.astrid.activity.TaskListActivity;
import com.todoroo.astrid.activity.TaskListFragment; import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.GtasksFilter; import com.todoroo.astrid.api.GtasksFilter;
import com.todoroo.astrid.data.StoreObject; import com.todoroo.astrid.data.StoreObject;
import com.todoroo.astrid.gtasks.GtasksList; import com.todoroo.astrid.gtasks.GtasksList;
@ -75,9 +76,10 @@ public class GtasksListFragment extends TaskListFragment {
String action = data.getAction(); String action = data.getAction();
if (GoogleTaskListSettingsActivity.ACTION_DELETED.equals(action)) { if (GoogleTaskListSettingsActivity.ACTION_DELETED.equals(action)) {
activity.onFilterItemClicked(null); activity.onFilterItemClicked(null);
} else if (GoogleTaskListSettingsActivity.ACTION_RENAMED.equals(action) || } else if (GoogleTaskListSettingsActivity.ACTION_RELOAD.equals(action)) {
GoogleTaskListSettingsActivity.ACTION_THEME_CHANGED.equals(action)) { activity.getIntent().putExtra(TaskListActivity.OPEN_FILTER,
activity.onFilterItemClicked(data.getParcelableExtra(TaskListActivity.OPEN_FILTER)); (Filter) data.getParcelableExtra(TaskListActivity.OPEN_FILTER));
activity.recreate();
} }
} }
} else { } else {

@ -11,9 +11,11 @@ import android.content.IntentFilter;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings; import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.widget.DrawerLayout; import android.support.v4.widget.DrawerLayout;
import android.support.v7.view.ActionMode;
import android.view.View; import android.view.View;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
@ -68,7 +70,9 @@ import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import timber.log.Timber; import timber.log.Timber;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastLollipop;
import static com.todoroo.astrid.activity.TaskEditFragment.newTaskEditFragment; import static com.todoroo.astrid.activity.TaskEditFragment.newTaskEditFragment;
import static org.tasks.tasklist.ActionUtils.applySupportActionModeColor;
import static org.tasks.ui.NavigationDrawerFragment.OnFilterItemClickedListener; import static org.tasks.ui.NavigationDrawerFragment.OnFilterItemClickedListener;
public class TaskListActivity extends InjectingAppCompatActivity implements public class TaskListActivity extends InjectingAppCompatActivity implements
@ -110,6 +114,7 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
private int currentNightMode; private int currentNightMode;
private Filter filter; private Filter filter;
private ActionMode actionMode = null;
/** /**
* @see android.app.Activity#onCreate(Bundle) * @see android.app.Activity#onCreate(Bundle)
@ -180,13 +185,15 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
} }
private void loadTaskListFragment(TaskListFragment taskListFragment) { private void loadTaskListFragment(TaskListFragment taskListFragment) {
finishActionMode();
filter = taskListFragment.filter; filter = taskListFragment.filter;
ThemeColor themeColor = filter.tint >= 0 ThemeColor filterColor = getFilterColor();
? themeCache.getThemeColor(filter.tint)
: theme.getThemeColor(); filterColor.applyToStatusBar(drawerLayout);
themeColor.applyStatusBarColor(drawerLayout);
themeColor.applyTaskDescription(this, filter.listingTitle); filterColor.applyTaskDescription(this, filter.listingTitle);
theme.withColor(themeColor).applyToContext(this); filterColor.applyStyle(getTheme());
FragmentManager fragmentManager = getSupportFragmentManager(); FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
@ -196,7 +203,15 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
.commit(); .commit();
} }
private ThemeColor getFilterColor() {
return filter != null && filter.tint >= 0
? themeCache.getThemeColor(filter.tint)
: theme.getThemeColor();
}
private void loadTaskEditFragment(TaskEditFragment taskEditFragment) { private void loadTaskEditFragment(TaskEditFragment taskEditFragment) {
finishActionMode();
getSupportFragmentManager() getSupportFragmentManager()
.beginTransaction() .beginTransaction()
.replace(isDoublePaneLayout() ? R.id.detail_dual : R.id.single_pane, taskEditFragment, TaskEditFragment.TAG_TASKEDIT_FRAGMENT) .replace(isDoublePaneLayout() ? R.id.detail_dual : R.id.single_pane, taskEditFragment, TaskEditFragment.TAG_TASKEDIT_FRAGMENT)
@ -447,6 +462,7 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
@Override @Override
public void taskEditFinished() { public void taskEditFinished() {
getSupportFragmentManager().popBackStackImmediate(TaskEditFragment.TAG_TASKEDIT_FRAGMENT, FragmentManager.POP_BACK_STACK_INCLUSIVE); getSupportFragmentManager().popBackStackImmediate(TaskEditFragment.TAG_TASKEDIT_FRAGMENT, FragmentManager.POP_BACK_STACK_INCLUSIVE);
getTaskListFragment().clearSelections();
hideKeyboard(); hideKeyboard();
} }
@ -484,4 +500,33 @@ public class TaskListActivity extends InjectingAppCompatActivity implements
public void selectedList(GtasksList list) { public void selectedList(GtasksList list) {
getTaskEditFragment().onGoogleTaskListChanged(list); getTaskEditFragment().onGoogleTaskListChanged(list);
} }
@Override
public void onSupportActionModeStarted(@NonNull ActionMode mode) {
super.onSupportActionModeStarted(mode);
actionMode = mode;
ThemeColor filterColor = getFilterColor();
applySupportActionModeColor(filterColor, mode);
filterColor.setStatusBarColor(this);
}
@Override
public void onSupportActionModeFinished(@NonNull ActionMode mode) {
super.onSupportActionModeFinished(mode);
if (atLeastLollipop()) {
getWindow().setStatusBarColor(0);
}
}
private void finishActionMode() {
if (actionMode != null) {
actionMode.finish();
actionMode = null;
}
}
} }

@ -12,6 +12,7 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.database.Cursor; import android.database.Cursor;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.v4.view.MenuItemCompat; import android.support.v4.view.MenuItemCompat;
@ -20,14 +21,11 @@ import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView; import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView.AdapterContextMenuInfo;
import com.todoroo.andlib.data.Callback; import com.todoroo.andlib.data.Callback;
import com.todoroo.andlib.data.Property; import com.todoroo.andlib.data.Property;
@ -40,7 +38,6 @@ import com.todoroo.astrid.api.AstridApiConstants;
import com.todoroo.astrid.api.CustomFilter; import com.todoroo.astrid.api.CustomFilter;
import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.core.BuiltInFilterExposer; import com.todoroo.astrid.core.BuiltInFilterExposer;
import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gtasks.GtasksPreferenceService; import com.todoroo.astrid.gtasks.GtasksPreferenceService;
import com.todoroo.astrid.service.TaskCreator; import com.todoroo.astrid.service.TaskCreator;
@ -63,12 +60,13 @@ import org.tasks.injection.FragmentComponent;
import org.tasks.injection.InjectingFragment; import org.tasks.injection.InjectingFragment;
import org.tasks.preferences.Preferences; import org.tasks.preferences.Preferences;
import org.tasks.tasklist.TaskListRecyclerAdapter; import org.tasks.tasklist.TaskListRecyclerAdapter;
import org.tasks.tasklist.ViewHolder;
import org.tasks.tasklist.ViewHolderFactory; import org.tasks.tasklist.ViewHolderFactory;
import org.tasks.ui.CheckBoxes; import org.tasks.ui.CheckBoxes;
import org.tasks.ui.MenuColorizer; import org.tasks.ui.MenuColorizer;
import org.tasks.ui.ProgressDialogAsyncTask; import org.tasks.ui.ProgressDialogAsyncTask;
import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import butterknife.BindView; import butterknife.BindView;
@ -100,11 +98,6 @@ public class TaskListFragment extends InjectingFragment implements
public static final int VOICE_RECOGNITION_REQUEST_CODE = 1234; public static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;
private static final int REQUEST_EDIT_FILTER = 11544; private static final int REQUEST_EDIT_FILTER = 11544;
// --- menu codes
private static final int CONTEXT_MENU_COPY_TASK_ID = R.string.TAd_contextCopyTask;
private static final int CONTEXT_MENU_DELETE_TASK_ID = R.string.TAd_contextDeleteTask;
// --- instance variables // --- instance variables
@Inject SyncAdapterHelper syncAdapterHelper; @Inject SyncAdapterHelper syncAdapterHelper;
@ -120,7 +113,6 @@ public class TaskListFragment extends InjectingFragment implements
@Inject Broadcaster broadcaster; @Inject Broadcaster broadcaster;
@Inject protected TaskListDataProvider taskListDataProvider; @Inject protected TaskListDataProvider taskListDataProvider;
@Inject TimerPlugin timerPlugin; @Inject TimerPlugin timerPlugin;
@Inject TaskDao taskDao;
@Inject ViewHolderFactory viewHolderFactory; @Inject ViewHolderFactory viewHolderFactory;
@Inject protected Tracker tracker; @Inject protected Tracker tracker;
@ -160,6 +152,15 @@ public class TaskListFragment extends InjectingFragment implements
} }
} }
@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
if (savedInstanceState != null) {
recyclerAdapter.restoreSaveState(savedInstanceState);
}
}
/** /**
* Container Activity must implement this interface and we ensure that it * Container Activity must implement this interface and we ensure that it
* does during the onAttach() callback * does during the onAttach() callback
@ -203,6 +204,7 @@ public class TaskListFragment extends InjectingFragment implements
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
outState.putParcelable(EXTRA_FILTER, filter); outState.putParcelable(EXTRA_FILTER, filter);
outState.putAll(recyclerAdapter.getSaveState());
} }
@Override @Override
@ -320,7 +322,7 @@ public class TaskListFragment extends InjectingFragment implements
@Override @Override
protected int getResultResource() { protected int getResultResource() {
return R.string.EPr_manage_delete_completed_status; return R.string.delete_multiple_tasks_confirmation;
} }
}.execute(); }.execute();
} }
@ -343,8 +345,6 @@ public class TaskListFragment extends InjectingFragment implements
@Override @Override
public void onActivityCreated(Bundle savedInstanceState) { public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState);
// We have a menu item to show in action bar.
// registerForContextMenu(recyclerView);
filter.setFilterQueryOverride(null); filter.setFilterQueryOverride(null);
@ -352,12 +352,6 @@ public class TaskListFragment extends InjectingFragment implements
recyclerView.setLayoutManager(new LinearLayoutManager(context)); recyclerView.setLayoutManager(new LinearLayoutManager(context));
loadTaskListContent(); loadTaskListContent();
if (getResources().getBoolean(R.bool.two_pane_layout)) {
// In dual-pane mode, the list view highlights the selected item.
// listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
// listView.setItemsCanFocus(false);
}
} }
@Override @Override
@ -465,7 +459,8 @@ public class TaskListFragment extends InjectingFragment implements
// set up list adapters // set up list adapters
taskAdapter = createTaskAdapter(currentCursor); taskAdapter = createTaskAdapter(currentCursor);
recyclerAdapter = new TaskListRecyclerAdapter(context, taskAdapter, viewHolderFactory, this); recyclerAdapter = new TaskListRecyclerAdapter(getActivity(), taskAdapter, viewHolderFactory,
this, taskDeleter, taskDuplicator, tracker);
} }
public Property<?>[] taskProperties() { public Property<?>[] taskProperties() {
@ -490,32 +485,22 @@ public class TaskListFragment extends InjectingFragment implements
* ====================================================================== * ======================================================================
*/ */
@Override public void onTaskCreated(List<Task> tasks) {
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { for (Task task : tasks) {
AdapterContextMenuInfo adapterInfo = (AdapterContextMenuInfo) menuInfo; onTaskCreated(task.getUuid());
Task task = ((ViewHolder) adapterInfo.targetView.getTag()).task; }
int id = (int) task.getId(); syncAdapterHelper.requestSynchronization();
menu.setHeaderTitle(task.getTitle());
menu.add(id, CONTEXT_MENU_COPY_TASK_ID, Menu.NONE, R.string.TAd_contextCopyTask);
menu.add(id, CONTEXT_MENU_DELETE_TASK_ID, Menu.NONE, R.string.TAd_contextDeleteTask);
}
/** Show a dialog box and delete the task specified */
private void deleteTask(final Task task) {
dialogBuilder.newMessageDialog(R.string.delete_tag_confirmation, task.getTitle())
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
onTaskDelete(task);
taskDeleter.delete(task);
loadTaskListContent();
})
.setNegativeButton(android.R.string.cancel, null)
.show();
} }
public void onTaskCreated(String uuid) { public void onTaskCreated(String uuid) {
} }
public void onTaskDelete(List<Task> tasks) {
for (Task task : tasks) {
onTaskDelete(task);
}
}
protected void onTaskDelete(Task task) { protected void onTaskDelete(Task task) {
TaskListActivity activity = (TaskListActivity) getActivity(); TaskListActivity activity = (TaskListActivity) getActivity();
TaskEditFragment tef = activity.getTaskEditFragment(); TaskEditFragment tef = activity.getTaskEditFragment();
@ -527,14 +512,6 @@ public class TaskListFragment extends InjectingFragment implements
timerPlugin.stopTimer(task); timerPlugin.stopTimer(task);
} }
// @Override
// public void onListItemClick(ListView l, View v, int position, long id) {
// super.onListItemClick(l, v, position, id);
// if (getResources().getBoolean(R.bool.two_pane_layout)) {
// setSelection(position);
// }
// }
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == VOICE_RECOGNITION_REQUEST_CODE) { if (requestCode == VOICE_RECOGNITION_REQUEST_CODE) {
@ -551,14 +528,14 @@ public class TaskListFragment extends InjectingFragment implements
} else if (requestCode == REQUEST_EDIT_FILTER) { } else if (requestCode == REQUEST_EDIT_FILTER) {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
String action = data.getAction(); String action = data.getAction();
if (FilterSettingsActivity.ACTION_FILTER_RENAMED.equals(action)) { TaskListActivity activity = (TaskListActivity) getActivity();
CustomFilter customFilter = data.getParcelableExtra(FilterSettingsActivity.TOKEN_FILTER); if (FilterSettingsActivity.ACTION_FILTER_DELETED.equals(action)) {
((TaskListActivity) getActivity()).onFilterItemClicked(customFilter); activity.onFilterItemClicked(null);
} else if(FilterSettingsActivity.ACTION_FILTER_DELETED.equals(action)) { } else if(FilterSettingsActivity.ACTION_FILTER_RENAMED.equals(action)) {
((TaskListActivity) getActivity()).onFilterItemClicked(null); activity.getIntent().putExtra(TaskListActivity.OPEN_FILTER,
(Filter) data.getParcelableExtra(FilterSettingsActivity.TOKEN_FILTER));
activity.recreate();
} }
broadcaster.refresh();
} }
} else { } else {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);
@ -569,33 +546,6 @@ public class TaskListFragment extends InjectingFragment implements
public boolean onContextItemSelected(android.view.MenuItem item) { public boolean onContextItemSelected(android.view.MenuItem item) {
return onOptionsItemSelected(item); return onOptionsItemSelected(item);
} }
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
long itemId;
switch (item.getItemId()) {
case CONTEXT_MENU_COPY_TASK_ID:
itemId = item.getGroupId();
duplicateTask(itemId);
return true;
case CONTEXT_MENU_DELETE_TASK_ID:
itemId = item.getGroupId();
Task task = taskDao.fetch(itemId, Task.ID, Task.TITLE, Task.UUID);
if (task != null) {
deleteTask(task);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void duplicateTask(long itemId) {
long cloneId = taskDuplicator.duplicateTask(itemId);
onTaskListItemClicked(cloneId);
}
public void onTaskListItemClicked(long taskId) { public void onTaskListItemClicked(long taskId) {
callbacks.onTaskListItemClicked(taskId); callbacks.onTaskListItemClicked(taskId);
} }
@ -603,4 +553,8 @@ public class TaskListFragment extends InjectingFragment implements
protected boolean hasDraggableOption() { protected boolean hasDraggableOption() {
return BuiltInFilterExposer.isInbox(context, filter) || BuiltInFilterExposer.isTodayFilter(context, filter); return BuiltInFilterExposer.isInbox(context, filter) || BuiltInFilterExposer.isTodayFilter(context, filter);
} }
public void clearSelections() {
recyclerAdapter.clearSelections();
}
} }

@ -6,15 +6,11 @@ import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.TaskDao;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import org.tasks.Broadcaster;
import org.tasks.calendars.CalendarEventProvider;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import static com.google.common.collect.Iterables.transform;
import static com.todoroo.andlib.sql.Criterion.all; import static com.todoroo.andlib.sql.Criterion.all;
import static com.todoroo.astrid.dao.TaskDao.TaskCriteria.isVisible; import static com.todoroo.astrid.dao.TaskDao.TaskCriteria.isVisible;
import static com.todoroo.astrid.dao.TaskDao.TaskCriteria.notCompleted; import static com.todoroo.astrid.dao.TaskDao.TaskCriteria.notCompleted;
@ -22,14 +18,10 @@ import static com.todoroo.astrid.dao.TaskDao.TaskCriteria.notCompleted;
public class TaskDeleter { public class TaskDeleter {
private final TaskDao taskDao; private final TaskDao taskDao;
private final CalendarEventProvider calendarEventProvider;
private final Broadcaster broadcaster;
@Inject @Inject
public TaskDeleter(TaskDao taskDao, CalendarEventProvider calendarEventProvider, Broadcaster broadcaster) { public TaskDeleter(TaskDao taskDao) {
this.taskDao = taskDao; this.taskDao = taskDao;
this.calendarEventProvider = calendarEventProvider;
this.broadcaster = broadcaster;
} }
/** /**
@ -54,22 +46,31 @@ public class TaskDeleter {
taskDao.delete(item.getId()); taskDao.delete(item.getId());
item.setId(Task.NO_ID); item.setId(Task.NO_ID);
} else { } else {
long id = item.getId(); Task template = new Task();
item.clear(); template.setId(item.getId());
item.setId(id); template.setDeletionDate(DateUtilities.now());
item.setDeletionDate(DateUtilities.now()); taskDao.save(template);
taskDao.save(item); }
}
public int delete(List<Task> tasks) {
return markDeleted(tasks);
}
public void undelete(List<Task> tasks) {
for (Task task : tasks) {
Task template = new Task();
template.setId(task.getId());
template.setDeletionDate(0L);
taskDao.save(template);
} }
} }
private int markDeleted(List<Task> tasks) { private int markDeleted(List<Task> tasks) {
Task template = new Task(); for (Task task : tasks) {
template.setDeletionDate(DateUtilities.now()); delete(task);
int count = taskDao.update(Task.ID.in(transform(tasks, Task::getId)), template);
if (count > 0) {
broadcaster.refresh();
} }
return count; return tasks.size();
} }
public int clearCompleted(Filter filter) { public int clearCompleted(Filter filter) {

@ -10,6 +10,9 @@ import com.todoroo.astrid.gcal.GCalHelper;
import com.todoroo.astrid.gtasks.GtasksMetadata; import com.todoroo.astrid.gtasks.GtasksMetadata;
import com.todoroo.astrid.tags.TaskToTagMetadata; import com.todoroo.astrid.tags.TaskToTagMetadata;
import org.tasks.Broadcaster;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
@ -21,21 +24,27 @@ public class TaskDuplicator {
private final GCalHelper gcalHelper; private final GCalHelper gcalHelper;
private final MetadataDao metadataDao; private final MetadataDao metadataDao;
private final TaskDao taskDao; private final TaskDao taskDao;
private final Broadcaster broadcaster;
@Inject @Inject
public TaskDuplicator(GCalHelper gcalHelper, MetadataDao metadataDao, TaskDao taskDao) { public TaskDuplicator(GCalHelper gcalHelper, MetadataDao metadataDao, TaskDao taskDao,
Broadcaster broadcaster) {
this.gcalHelper = gcalHelper; this.gcalHelper = gcalHelper;
this.metadataDao = metadataDao; this.metadataDao = metadataDao;
this.taskDao = taskDao; this.taskDao = taskDao;
this.broadcaster = broadcaster;
} }
/** public List<Task> duplicate(List<Task> tasks) {
* Create an uncompleted copy of this task and edit it List<Task> result = new ArrayList<>();
* @return cloned item id for (Task task : tasks) {
*/ result.add(clone(taskDao.fetch(task.getId(), Task.PROPERTIES), true));
public long duplicateTask(long itemId) { }
Task original = taskDao.fetch(itemId, Task.PROPERTIES); broadcaster.refresh();
Timber.d("Cloning %s", original); return result;
}
private Task clone(Task original, boolean suppressRefresh) {
Task clone = new Task(original); Task clone = new Task(original);
clone.setCreationDate(DateUtilities.now()); clone.setCreationDate(DateUtilities.now());
clone.setCompletionDate(0L); clone.setCompletionDate(0L);
@ -44,10 +53,13 @@ public class TaskDuplicator {
clone.clearValue(Task.ID); clone.clearValue(Task.ID);
clone.clearValue(Task.UUID); clone.clearValue(Task.UUID);
List<Metadata> metadataList = metadataDao.byTask(itemId); List<Metadata> metadataList = metadataDao.byTask(original.getId());
if (!metadataList.isEmpty()) { if (!metadataList.isEmpty()) {
clone.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true); clone.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true);
} }
if (suppressRefresh) {
clone.putTransitory(TaskDao.TRANS_SUPPRESS_REFRESH, true);
}
taskDao.save(clone); taskDao.save(clone);
@ -56,19 +68,21 @@ public class TaskDuplicator {
continue; continue;
} }
Timber.d("Cloning %s", oldMetadata); Timber.d("Cloning %s", oldMetadata);
Metadata metadata = new Metadata(oldMetadata); if(GtasksMetadata.METADATA_KEY.equals(oldMetadata.getKey())) {
if(GtasksMetadata.METADATA_KEY.equals(metadata.getKey())) { Metadata gtaskMetadata = GtasksMetadata.createEmptyMetadataWithoutList(clone.getId());
metadata.setValue(GtasksMetadata.ID, ""); //$NON-NLS-1$ gtaskMetadata.setValue(GtasksMetadata.LIST_ID, oldMetadata.getValue(GtasksMetadata.LIST_ID));
} else if (TaskToTagMetadata.KEY.equals(metadata.getKey())) { metadataDao.createNew(gtaskMetadata);
} else if (TaskToTagMetadata.KEY.equals(oldMetadata.getKey())) {
Metadata metadata = new Metadata(oldMetadata);
metadata.setValue(TaskToTagMetadata.TASK_UUID, clone.getUuid()); metadata.setValue(TaskToTagMetadata.TASK_UUID, clone.getUuid());
metadata.setTask(clone.getId());
metadata.clearValue(Metadata.ID);
metadataDao.createNew(metadata);
} }
metadata.setTask(clone.getId());
metadata.clearValue(Metadata.ID);
metadataDao.createNew(metadata);
} }
gcalHelper.createTaskEventIfEnabled(clone); gcalHelper.createTaskEventIfEnabled(clone);
return clone.getId(); return clone;
} }
} }

@ -44,7 +44,7 @@ public class TagFilterExposer {
} }
/** Create filter from new tag object */ /** Create filter from new tag object */
public static TagFilter filterFromTag(TagData tag) { private static TagFilter filterFromTag(TagData tag) {
if (tag == null || Strings.isNullOrEmpty(tag.getName())) { if (tag == null || Strings.isNullOrEmpty(tag.getName())) {
return null; return null;
} }

@ -18,12 +18,12 @@ import android.view.inputmethod.InputMethodManager;
import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Criterion;
import com.todoroo.astrid.activity.TaskListActivity; import com.todoroo.astrid.activity.TaskListActivity;
import com.todoroo.astrid.api.TagFilter;
import com.todoroo.astrid.dao.MetadataDao; import com.todoroo.astrid.dao.MetadataDao;
import com.todoroo.astrid.dao.TagDataDao; import com.todoroo.astrid.dao.TagDataDao;
import com.todoroo.astrid.data.Metadata; import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.helper.UUIDHelper; import com.todoroo.astrid.helper.UUIDHelper;
import com.todoroo.astrid.tags.TagFilterExposer;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagService;
import com.todoroo.astrid.tags.TaskToTagMetadata; import com.todoroo.astrid.tags.TaskToTagMetadata;
@ -58,8 +58,8 @@ public class TagSettingsActivity extends ThemedInjectingAppCompatActivity implem
public static final String EXTRA_TAG_DATA = "tagData"; //$NON-NLS-1$ public static final String EXTRA_TAG_DATA = "tagData"; //$NON-NLS-1$
public static final String EXTRA_TAG_UUID = "uuid"; //$NON-NLS-1$ public static final String EXTRA_TAG_UUID = "uuid"; //$NON-NLS-1$
public static final String ACTION_TAG_RENAMED = "tagRenamed"; public static final String ACTION_RELOAD = "tagRenamed";
public static final String ACTION_TAG_DELETED = "tagDeleted"; public static final String ACTION_DELETED = "tagDeleted";
private boolean isNewTag; private boolean isNewTag;
private TagData tagData; private TagData tagData;
@ -190,7 +190,7 @@ public class TagSettingsActivity extends ThemedInjectingAppCompatActivity implem
tagData.setName(newName); tagData.setName(newName);
tagData.setColor(selectedTheme); tagData.setColor(selectedTheme);
tagDataDao.persist(tagData); tagDataDao.persist(tagData);
setResult(RESULT_OK, new Intent().putExtra(TaskListActivity.OPEN_FILTER, TagFilterExposer.filterFromTag(tagData))); setResult(RESULT_OK, new Intent().putExtra(TaskListActivity.OPEN_FILTER, new TagFilter(tagData)));
} else if (hasChanges()) { } else if (hasChanges()) {
tagData.setName(newName); tagData.setName(newName);
tagData.setColor(selectedTheme); tagData.setColor(selectedTheme);
@ -201,7 +201,7 @@ public class TagSettingsActivity extends ThemedInjectingAppCompatActivity implem
metadataDao.update(Criterion.and( metadataDao.update(Criterion.and(
MetadataDao.MetadataCriteria.withKey(TaskToTagMetadata.KEY), MetadataDao.MetadataCriteria.withKey(TaskToTagMetadata.KEY),
TaskToTagMetadata.TAG_UUID.eq(tagData.getUUID())), m); TaskToTagMetadata.TAG_UUID.eq(tagData.getUUID())), m);
setResult(RESULT_OK, new Intent(ACTION_TAG_RENAMED).putExtra(EXTRA_TAG_UUID, tagData.getUuid())); setResult(RESULT_OK, new Intent(ACTION_RELOAD).putExtra(TaskListActivity.OPEN_FILTER, new TagFilter(tagData)));
} }
finish(); finish();
@ -251,7 +251,7 @@ public class TagSettingsActivity extends ThemedInjectingAppCompatActivity implem
String uuid = tagData.getUuid(); String uuid = tagData.getUuid();
metadataDao.deleteWhere(Criterion.and(MetadataDao.MetadataCriteria.withKey(TaskToTagMetadata.KEY), TaskToTagMetadata.TAG_UUID.eq(uuid))); metadataDao.deleteWhere(Criterion.and(MetadataDao.MetadataCriteria.withKey(TaskToTagMetadata.KEY), TaskToTagMetadata.TAG_UUID.eq(uuid)));
tagDataDao.delete(tagData.getId()); tagDataDao.delete(tagData.getId());
setResult(RESULT_OK, new Intent(ACTION_TAG_DELETED).putExtra(EXTRA_TAG_UUID, uuid)); setResult(RESULT_OK, new Intent(ACTION_DELETED).putExtra(EXTRA_TAG_UUID, uuid));
} }
finish(); finish();
}) })
@ -280,7 +280,7 @@ public class TagSettingsActivity extends ThemedInjectingAppCompatActivity implem
color.setText(themeColor.getName()); color.setText(themeColor.getName());
} }
themeColor.apply(toolbar); themeColor.apply(toolbar);
themeColor.applyStatusBarColor(this); themeColor.applyToStatusBar(this);
} }
@Override @Override

@ -22,6 +22,8 @@ public class Tracking {
GTASK_DELETE_LIST(R.string.tracking_category_google_tasks, R.string.tracking_action_delete_list), GTASK_DELETE_LIST(R.string.tracking_category_google_tasks, R.string.tracking_action_delete_list),
GTASK_SET_COLOR(R.string.tracking_category_google_tasks, R.string.p_theme_color), GTASK_SET_COLOR(R.string.tracking_category_google_tasks, R.string.p_theme_color),
GTASK_CLEAR_COMPLETED(R.string.tracking_category_google_tasks, R.string.tracking_action_clear_completed), GTASK_CLEAR_COMPLETED(R.string.tracking_category_google_tasks, R.string.tracking_action_clear_completed),
MULTISELECT_DELETE(R.string.tracking_category_event, R.string.tracking_event_multiselect_delete),
MULTISELECT_CLONE(R.string.tracking_category_event, R.string.tracking_event_multiselect_clone),
CLEAR_COMPLETED(R.string.tracking_category_event, R.string.tracking_action_clear_completed), CLEAR_COMPLETED(R.string.tracking_category_event, R.string.tracking_action_clear_completed),
UPGRADE(R.string.tracking_category_event, R.string.tracking_event_upgrade), UPGRADE(R.string.tracking_category_event, R.string.tracking_event_upgrade),
LEGACY_TASKER_TRIGGER(R.string.tracking_category_event, R.string.tracking_event_legacy_tasker_trigger), LEGACY_TASKER_TRIGGER(R.string.tracking_category_event, R.string.tracking_event_legacy_tasker_trigger),

@ -10,4 +10,10 @@ public class ResourceResolver {
context.getTheme().resolveAttribute(attr, typedValue, true); context.getTheme().resolveAttribute(attr, typedValue, true);
return typedValue.data; return typedValue.data;
} }
@Deprecated public static int getResourceId(Context context, int attr) {
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(attr, typedValue, true);
return typedValue.resourceId;
}
} }

@ -0,0 +1,71 @@
package org.tasks.tasklist;
import android.support.v7.app.WindowDecorActionBar;
import android.support.v7.view.StandaloneActionMode;
import android.support.v7.widget.ActionBarContextView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import org.tasks.R;
import org.tasks.themes.ThemeColor;
import java.lang.reflect.Field;
public class ActionUtils {
// cribbed from Twittnuker
public static void applySupportActionModeColor(ThemeColor themeColor, final android.support.v7.view.ActionMode modeCompat) {
// Very dirty implementation
// This call ensures TitleView created
modeCompat.setTitle(modeCompat.getTitle());
View contextView = null;
if (modeCompat instanceof WindowDecorActionBar.ActionModeImpl) {
WindowDecorActionBar actionBar = (WindowDecorActionBar) findFieldOfTypes(modeCompat,
WindowDecorActionBar.ActionModeImpl.class, WindowDecorActionBar.class);
if (actionBar == null) {
return;
}
contextView = (View) findFieldOfTypes(actionBar, WindowDecorActionBar.class, ActionBarContextView.class);
} else if (modeCompat instanceof StandaloneActionMode) {
contextView = (View) findFieldOfTypes(modeCompat, StandaloneActionMode.class, ActionBarContextView.class);
}
if (!(contextView instanceof ActionBarContextView)) {
return;
}
contextView.setBackgroundColor(themeColor.getPrimaryColor());
TextView title = (TextView) contextView.findViewById(R.id.action_bar_title);
if (title != null) {
title.setTextColor(themeColor.getActionBarTint());
}
ImageView closeButton = (ImageView) contextView.findViewById(R.id.action_mode_close_button);
if (closeButton != null) {
closeButton.setColorFilter(themeColor.getActionBarTint());
}
}
private static <T> Object findFieldOfTypes(T obj, Class<? extends T> cls, Class<?>... checkTypes) {
labelField:
for (Field field : cls.getDeclaredFields()) {
field.setAccessible(true);
final Object fieldObj;
try {
fieldObj = field.get(obj);
} catch (Exception ignore) {
continue;
}
if (fieldObj != null) {
final Class<?> type = fieldObj.getClass();
for (Class<?> checkType : checkTypes) {
if (!checkType.isAssignableFrom(type)) {
continue labelField;
}
}
return fieldObj;
}
}
return null;
}
}

@ -10,17 +10,12 @@ import com.todoroo.astrid.activity.TaskListActivity;
import com.todoroo.astrid.activity.TaskListFragment; import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.TagFilter; import com.todoroo.astrid.api.TagFilter;
import com.todoroo.astrid.dao.TagDataDao;
import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.tags.TagFilterExposer;
import org.tasks.Broadcaster;
import org.tasks.R; import org.tasks.R;
import org.tasks.activities.TagSettingsActivity; import org.tasks.activities.TagSettingsActivity;
import org.tasks.injection.FragmentComponent; import org.tasks.injection.FragmentComponent;
import javax.inject.Inject;
public class TagListFragment extends TaskListFragment { public class TagListFragment extends TaskListFragment {
private static final int REQUEST_EDIT_TAG = 11543; private static final int REQUEST_EDIT_TAG = 11543;
@ -34,9 +29,6 @@ public class TagListFragment extends TaskListFragment {
private static final String EXTRA_TAG_DATA = "extra_tag_data"; private static final String EXTRA_TAG_DATA = "extra_tag_data";
@Inject TagDataDao tagDataDao;
@Inject Broadcaster broadcaster;
protected TagData tagData; protected TagData tagData;
@Override @Override
@ -72,24 +64,14 @@ public class TagListFragment extends TaskListFragment {
if (requestCode == REQUEST_EDIT_TAG) { if (requestCode == REQUEST_EDIT_TAG) {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
String action = data.getAction(); String action = data.getAction();
String uuid = data.getStringExtra(TagSettingsActivity.EXTRA_TAG_UUID);
TaskListActivity activity = (TaskListActivity) getActivity(); TaskListActivity activity = (TaskListActivity) getActivity();
if (TagSettingsActivity.ACTION_TAG_RENAMED.equals(action)) { if (TagSettingsActivity.ACTION_DELETED.equals(action)) {
if (tagData.getUuid().equals(uuid)) { activity.onFilterItemClicked(null);
TagData newTagData = tagDataDao.fetch(uuid, TagData.PROPERTIES); } else if (TagSettingsActivity.ACTION_RELOAD.equals(action)) {
if (newTagData != null) { activity.getIntent().putExtra(TaskListActivity.OPEN_FILTER,
Filter filter = TagFilterExposer.filterFromTag(newTagData); (Filter) data.getParcelableExtra(TaskListActivity.OPEN_FILTER));
activity.onFilterItemClicked(filter); activity.recreate();
}
}
} else if (TagSettingsActivity.ACTION_TAG_DELETED.equals(action)) {
String activeUuid = tagData.getUuid();
if (activeUuid.equals(uuid)) {
activity.onFilterItemClicked(null);
}
} }
broadcaster.refresh();
} }
} else { } else {
super.onActivityResult(requestCode, resultCode, data); super.onActivityResult(requestCode, resultCode, data);

@ -1,35 +1,66 @@
package org.tasks.tasklist; package org.tasks.tasklist;
import android.content.Context; import android.app.Activity;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.os.Bundle;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper; import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback;
import com.bignerdranch.android.multiselector.MultiSelector;
import com.google.common.collect.Ordering;
import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.astrid.activity.TaskListActivity;
import com.todoroo.astrid.activity.TaskListFragment; import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.adapter.TaskAdapter; import com.todoroo.astrid.adapter.TaskAdapter;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.TaskDeleter;
import com.todoroo.astrid.service.TaskDuplicator;
import com.todoroo.astrid.utility.Flags; import com.todoroo.astrid.utility.Flags;
import org.tasks.R; import org.tasks.R;
import org.tasks.analytics.Tracker;
import org.tasks.analytics.Tracking;
import org.tasks.ui.MenuColorizer;
import java.util.List;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Lists.newArrayList;
public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder> implements ViewHolder.ViewHolderCallbacks { public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder> implements ViewHolder.ViewHolderCallbacks {
private final Context context; private final MultiSelector multiSelector = new MultiSelector();
private final Activity activity;
private final TaskAdapter adapter; private final TaskAdapter adapter;
private final ViewHolderFactory viewHolderFactory; private final ViewHolderFactory viewHolderFactory;
private final TaskListFragment taskList; private final TaskListFragment taskList;
private final TaskDeleter taskDeleter;
private final TaskDuplicator taskDuplicator;
private final Tracker tracker;
private final ItemTouchHelper itemTouchHelper; private final ItemTouchHelper itemTouchHelper;
public TaskListRecyclerAdapter(Context context, TaskAdapter adapter, private ActionMode mode = null;
ViewHolderFactory viewHolderFactory, TaskListFragment taskList) {
this.context = context; public TaskListRecyclerAdapter(Activity activity, TaskAdapter adapter,
ViewHolderFactory viewHolderFactory,
TaskListFragment taskList, TaskDeleter taskDeleter,
TaskDuplicator taskDuplicator, Tracker tracker) {
this.activity = activity;
this.adapter = adapter; this.adapter = adapter;
this.viewHolderFactory = viewHolderFactory; this.viewHolderFactory = viewHolderFactory;
this.taskList = taskList; this.taskList = taskList;
this.taskDeleter = taskDeleter;
this.taskDuplicator = taskDuplicator;
this.tracker = tracker;
itemTouchHelper = new ItemTouchHelper(new ItemTouchHelperCallback()); itemTouchHelper = new ItemTouchHelper(new ItemTouchHelperCallback());
} }
@ -38,11 +69,23 @@ public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder> im
itemTouchHelper.attachToRecyclerView(recyclerView); itemTouchHelper.attachToRecyclerView(recyclerView);
} }
public Bundle getSaveState() {
return multiSelector.saveSelectionStates();
}
public void restoreSaveState(Bundle savedState) {
multiSelector.restoreSelectionStates(savedState);
if (multiSelector.getSelectedPositions().size() > 0) {
mode = ((TaskListActivity) activity).startSupportActionMode(actionModeCallback);
updateModeTitle();
}
}
@Override @Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewGroup view = (ViewGroup) LayoutInflater.from(context) ViewGroup view = (ViewGroup) LayoutInflater.from(activity)
.inflate(R.layout.task_adapter_row_simple, parent, false); .inflate(R.layout.task_adapter_row_simple, parent, false);
return viewHolderFactory.newViewHolder(view, this); return viewHolderFactory.newViewHolder(view, this, multiSelector);
} }
@Override @Override
@ -65,12 +108,121 @@ public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder> im
@Override @Override
public void onClick(ViewHolder viewHolder) { public void onClick(ViewHolder viewHolder) {
Task task = viewHolder.task; if (viewHolder.isMoving()) {
if (!task.isDeleted()) { return;
}
if (multiSelector.tapSelection(viewHolder)) {
afterSelect();
} else {
Task task = viewHolder.task;
taskList.onTaskListItemClicked(task.getId()); taskList.onTaskListItemClicked(task.getId());
} }
} }
@Override
public boolean onLongPress(ViewHolder viewHolder) {
if (adapter.isManuallySorted()) {
return false;
}
select(viewHolder);
return true;
}
private void select(ViewHolder viewHolder) {
if (!multiSelector.isSelectable()) {
multiSelector.setSelectable(true);
mode = ((TaskListActivity) activity).startSupportActionMode(actionModeCallback);
}
if (multiSelector.tapSelection(viewHolder)) {
afterSelect();
}
}
private void afterSelect() {
if (multiSelector.getSelectedPositions().isEmpty()) {
if (mode != null) {
mode.finish();
}
} else {
updateModeTitle();
}
}
private List<Task> getTasks() {
return newArrayList(transform(multiSelector.getSelectedPositions(), adapter::getTask));
}
private void deleteSelectedItems() {
tracker.reportEvent(Tracking.Events.MULTISELECT_DELETE);
List<Task> tasks = getTasks();
int result = taskDeleter.delete(tasks);
taskList.onTaskDelete(tasks);
for (int position : Ordering.natural().reverse().sortedCopy(multiSelector.getSelectedPositions())) {
notifyItemRemoved(position);
}
taskList.makeSnackbar(activity.getString(R.string.delete_multiple_tasks_confirmation, Integer.toString(result)))
.setAction(R.string.DLG_undo, v -> {
taskDeleter.undelete(tasks);
taskList.loadTaskListContent();
})
.show();
}
private void copySelectedItems() {
tracker.reportEvent(Tracking.Events.MULTISELECT_CLONE);
List<Task> duplicates = taskDuplicator.duplicate(getTasks());
taskList.onTaskCreated(duplicates);
taskList.makeSnackbar(activity.getString(R.string.copy_multiple_tasks_confirmation, Integer.toString(duplicates.size())))
.setAction(R.string.DLG_undo, v -> {
taskDeleter.delete(duplicates);
taskList.onTaskDelete(duplicates);
})
.show();
}
public void clearSelections() {
multiSelector.clearSelections();
}
private void updateModeTitle() {
if (mode != null) {
mode.setTitle(Integer.toString(multiSelector.getSelectedPositions().size()));
}
}
private ModalMultiSelectorCallback actionModeCallback = new ModalMultiSelectorCallback(multiSelector) {
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
MenuInflater inflater = actionMode.getMenuInflater();
inflater.inflate(R.menu.menu_multi_select, menu);
MenuColorizer.colorMenu(activity, menu);
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.delete:
deleteSelectedItems();
mode.finish();
return true;
case R.id.copy_tasks:
copySelectedItems();
mode.finish();
return true;
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode actionMode) {
super.onDestroyActionMode(actionMode);
multiSelector.clearSelections();
TaskListRecyclerAdapter.this.mode = null;
}
};
private class ItemTouchHelperCallback extends ItemTouchHelper.Callback { private class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
private int from = -1; private int from = -1;
@ -78,7 +230,7 @@ public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder> im
@Override @Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if (!adapter.isManuallySorted()) { if (!adapter.isManuallySorted() || mode != null) {
return makeMovementFlags(0, 0); return makeMovementFlags(0, 0);
} }
@ -97,7 +249,14 @@ public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder> im
@Override @Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
super.onSelectedChanged(viewHolder, actionState); super.onSelectedChanged(viewHolder, actionState);
Flags.set(Flags.TLFP_NO_INTERCEPT_TOUCH); if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
if (viewHolder != null) {
ViewHolder vh = (ViewHolder) viewHolder;
vh.setMoving(true);
vh.updateBackground();
Flags.set(Flags.TLFP_NO_INTERCEPT_TOUCH);
}
}
} }
@Override @Override
@ -129,16 +288,24 @@ public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder> im
@Override @Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
super.clearView(recyclerView, viewHolder); super.clearView(recyclerView, viewHolder);
ViewHolder vh = (ViewHolder) viewHolder;
if (from >= 0 && from != to) { if (vh.isMoving()) {
if (from < to) { if (from == -1) {
to++; select(vh);
} else {
if (from >= 0 && from != to) {
if (from < to) {
to++;
}
adapter.moved(from, to);
}
} }
adapter.moved(from, to);
} }
from = -1; from = -1;
to = -1; to = -1;
Flags.checkAndClear(Flags.TLFP_NO_INTERCEPT_TOUCH); Flags.checkAndClear(Flags.TLFP_NO_INTERCEPT_TOUCH);
vh.setMoving(false);
vh.updateBackground();
} }
@Override @Override

@ -5,7 +5,6 @@ import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.graphics.Paint; import android.graphics.Paint;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.widget.RecyclerView;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
@ -16,6 +15,8 @@ import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.bignerdranch.android.multiselector.MultiSelector;
import com.bignerdranch.android.multiselector.MultiSelectorBindingHolder;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.utility.DateUtilities; import com.todoroo.andlib.utility.DateUtilities;
@ -47,12 +48,55 @@ import static com.todoroo.andlib.utility.AndroidUtilities.atLeastLollipop;
* *
* @author Tim Su <tim@todoroo.com> * @author Tim Su <tim@todoroo.com>
*/ */
public class ViewHolder extends RecyclerView.ViewHolder { class ViewHolder extends MultiSelectorBindingHolder {
public interface ViewHolderCallbacks { @Override
public void setSelectable(boolean selectable) {
this.selectable = selectable;
updateBackground();
}
@Override
public boolean isSelectable() {
return selectable;
}
@Override
public void setActivated(boolean selected) {
this.selected = selected;
updateBackground();
}
void setMoving(boolean moving) {
this.moving = moving;
}
boolean isMoving() {
return moving;
}
void updateBackground() {
if (selected || moving) {
rowBody.setBackgroundColor(selectedColor);
} else if (selectable) {
rowBody.setBackgroundColor(0);
} else {
rowBody.setBackgroundResource(background);
rowBody.getBackground().jumpToCurrentState();
}
}
@Override
public boolean isActivated() {
return selected;
}
interface ViewHolderCallbacks {
void onCompletedTask(Task task, boolean newState); void onCompletedTask(Task task, boolean newState);
void onClick(ViewHolder viewHolder); void onClick(ViewHolder viewHolder);
boolean onLongPress(ViewHolder viewHolder);
} }
@BindView(R.id.row) public ViewGroup row; @BindView(R.id.row) public ViewGroup row;
@ -79,16 +123,21 @@ public class ViewHolder extends RecyclerView.ViewHolder {
private final DialogBuilder dialogBuilder; private final DialogBuilder dialogBuilder;
private final ViewHolderCallbacks callback; private final ViewHolderCallbacks callback;
private final DisplayMetrics metrics; private final DisplayMetrics metrics;
private final int background;
private final int selectedColor;
private final int textColorOverdue; private final int textColorOverdue;
private Pair<Float, Float> lastTouchYRawY = new Pair<>(0f, 0f); private Pair<Float, Float> lastTouchYRawY = new Pair<>(0f, 0f);
private int indent; private int indent;
private boolean selectable = false;
public ViewHolder(Context context, ViewGroup view, boolean showFullTaskTitle, int fontSize, private boolean selected;
CheckBoxes checkBoxes, TagFormatter tagFormatter, private boolean moving;
int textColorOverdue, int textColorSecondary, int textColorHint, TaskDao taskDao,
DialogBuilder dialogBuilder, ViewHolderCallbacks callback, int minRowHeight, ViewHolder(Context context, ViewGroup view, boolean showFullTaskTitle, int fontSize,
DisplayMetrics metrics) { CheckBoxes checkBoxes, TagFormatter tagFormatter,
super(view); int textColorOverdue, int textColorSecondary, int textColorHint, TaskDao taskDao,
DialogBuilder dialogBuilder, ViewHolderCallbacks callback, int minRowHeight,
DisplayMetrics metrics, int background, int selectedColor, MultiSelector multiSelector) {
super(view, multiSelector);
this.context = context; this.context = context;
this.fontSize = fontSize; this.fontSize = fontSize;
this.checkBoxes = checkBoxes; this.checkBoxes = checkBoxes;
@ -100,6 +149,8 @@ public class ViewHolder extends RecyclerView.ViewHolder {
this.dialogBuilder = dialogBuilder; this.dialogBuilder = dialogBuilder;
this.callback = callback; this.callback = callback;
this.metrics = metrics; this.metrics = metrics;
this.background = background;
this.selectedColor = selectedColor;
ButterKnife.bind(this, view); ButterKnife.bind(this, view);
task = new Task(); task = new Task();
@ -293,6 +344,8 @@ public class ViewHolder extends RecyclerView.ViewHolder {
rowBody.setOnClickListener(view -> callback.onClick(this)); rowBody.setOnClickListener(view -> callback.onClick(this));
rowBody.setOnLongClickListener(view -> callback.onLongPress(this));
if (taskActionContainer != null) { if (taskActionContainer != null) {
taskActionContainer.setOnClickListener(v -> { taskActionContainer.setOnClickListener(v -> {
TaskAction action = (TaskAction) taskActionIcon.getTag(); TaskAction action = (TaskAction) taskActionIcon.getTag();

@ -4,6 +4,7 @@ import android.content.Context;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.bignerdranch.android.multiselector.MultiSelector;
import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.TaskDao;
import org.tasks.R; import org.tasks.R;
@ -16,6 +17,7 @@ import javax.inject.Inject;
import static android.support.v4.content.ContextCompat.getColor; import static android.support.v4.content.ContextCompat.getColor;
import static org.tasks.preferences.ResourceResolver.getData; import static org.tasks.preferences.ResourceResolver.getData;
import static org.tasks.preferences.ResourceResolver.getResourceId;
public class ViewHolderFactory { public class ViewHolderFactory {
@ -31,6 +33,8 @@ public class ViewHolderFactory {
private final DialogBuilder dialogBuilder; private final DialogBuilder dialogBuilder;
private final int minRowHeight; private final int minRowHeight;
private final DisplayMetrics metrics; private final DisplayMetrics metrics;
private final int background;
private final int selectedColor;
@Inject @Inject
public ViewHolderFactory(@ForActivity Context context, Preferences preferences, public ViewHolderFactory(@ForActivity Context context, Preferences preferences,
@ -44,15 +48,17 @@ public class ViewHolderFactory {
textColorSecondary = getData(context, android.R.attr.textColorSecondary); textColorSecondary = getData(context, android.R.attr.textColorSecondary);
textColorHint = getData(context, android.R.attr.textColorTertiary); textColorHint = getData(context, android.R.attr.textColorTertiary);
textColorOverdue = getColor(context, R.color.overdue); textColorOverdue = getColor(context, R.color.overdue);
background = getResourceId(context, R.attr.selectableItemBackground);
selectedColor = getData(context, R.attr.colorControlHighlight);
showFullTaskTitle = preferences.getBoolean(R.string.p_fullTaskTitle, false); showFullTaskTitle = preferences.getBoolean(R.string.p_fullTaskTitle, false);
fontSize = preferences.getIntegerFromString(R.string.p_fontSize, 18); fontSize = preferences.getIntegerFromString(R.string.p_fontSize, 18);
metrics = context.getResources().getDisplayMetrics(); metrics = context.getResources().getDisplayMetrics();
minRowHeight = (int) (metrics.density * 40); minRowHeight = (int) (metrics.density * 40);
} }
ViewHolder newViewHolder(ViewGroup viewGroup, ViewHolder.ViewHolderCallbacks callbacks) { ViewHolder newViewHolder(ViewGroup viewGroup, ViewHolder.ViewHolderCallbacks callbacks, MultiSelector multiSelector) {
return new ViewHolder(context, viewGroup, showFullTaskTitle, fontSize, checkBoxes, return new ViewHolder(context, viewGroup, showFullTaskTitle, fontSize, checkBoxes,
tagFormatter, textColorOverdue, textColorSecondary, textColorHint, taskDao, tagFormatter, textColorOverdue, textColorSecondary, textColorHint, taskDao,
dialogBuilder, callbacks, minRowHeight, metrics); dialogBuilder, callbacks, minRowHeight, metrics, background, selectedColor, multiSelector);
} }
} }

@ -51,7 +51,7 @@ public class Theme {
} }
public void applyStatusBarColor(Activity activity) { public void applyStatusBarColor(Activity activity) {
themeColor.applyStatusBarColor(activity); themeColor.applyToStatusBar(activity);
themeColor.applyTaskDescription(activity, activity.getString(R.string.app_name)); themeColor.applyTaskDescription(activity, activity.getString(R.string.app_name));
} }
@ -72,8 +72,4 @@ public class Theme {
applyToContext(wrapper); applyToContext(wrapper);
return wrapper; return wrapper;
} }
public Theme withColor(ThemeColor themeColor) {
return new Theme(themeBase, themeColor, themeAccent);
}
} }

@ -11,11 +11,11 @@ import org.tasks.R;
public class ThemeBase { public class ThemeBase {
private static final int[] THEMES = new int[]{ private static final int[] THEMES = new int[]{
R.style.TasksOverride, R.style.Tasks,
R.style.ThemeBlack, R.style.ThemeBlack,
R.style.TasksOverride, R.style.Tasks,
R.style.Wallpaper, R.style.Wallpaper,
R.style.TasksOverride R.style.Tasks
}; };
private final String name; private final String name;

@ -18,7 +18,7 @@ import static com.todoroo.andlib.utility.AndroidUtilities.atLeastMarshmallow;
public class ThemeColor { public class ThemeColor {
public static final int[] COLORS = new int[] { static final int[] COLORS = new int[] {
R.style.BlueGrey, R.style.BlueGrey,
R.style.DarkGrey, R.style.DarkGrey,
R.style.Red, R.style.Red,
@ -58,10 +58,9 @@ public class ThemeColor {
} }
@SuppressLint("NewApi") @SuppressLint("NewApi")
public void applyStatusBarColor(Activity activity) { public void applyToStatusBar(Activity activity) {
if (atLeastLollipop()) { setStatusBarColor(activity);
activity.getWindow().setStatusBarColor(getColorPrimaryDark());
}
if (atLeastMarshmallow()) { if (atLeastMarshmallow()) {
View decorView = activity.getWindow().getDecorView(); View decorView = activity.getWindow().getDecorView();
int systemUiVisibility = applyLightStatusBarFlag(decorView.getSystemUiVisibility()); int systemUiVisibility = applyLightStatusBarFlag(decorView.getSystemUiVisibility());
@ -69,8 +68,14 @@ public class ThemeColor {
} }
} }
public void setStatusBarColor(Activity activity) {
if (atLeastLollipop()) {
activity.getWindow().setStatusBarColor(getColorPrimaryDark());
}
}
@SuppressLint("NewApi") @SuppressLint("NewApi")
public void applyStatusBarColor(DrawerLayout drawerLayout) { public void applyToStatusBar(DrawerLayout drawerLayout) {
if (atLeastLollipop()) { if (atLeastLollipop()) {
drawerLayout.setStatusBarBackgroundColor(getColorPrimaryDark()); drawerLayout.setStatusBarBackgroundColor(getColorPrimaryDark());
} }
@ -110,7 +115,7 @@ public class ThemeColor {
return actionBarTint; return actionBarTint;
} }
private int getColorPrimaryDark() { public int getColorPrimaryDark() {
return colorPrimaryDark; return colorPrimaryDark;
} }

@ -63,6 +63,12 @@ public class MenuColorizer {
colorMenu(toolbar.getMenu(), color); colorMenu(toolbar.getMenu(), color);
} }
public static void colorMenu(Context context, Menu menu) {
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(R.attr.actionBarPrimaryText, typedValue, true);
colorMenu(menu, typedValue.data);
}
/** Sets a color filter on all menu icons, including the overflow button (if it exists) */ /** Sets a color filter on all menu icons, including the overflow button (if it exists) */
private static void colorMenu(final Menu menu, final int color) { private static void colorMenu(final Menu menu, final int color) {
for (int i = 0, size = menu.size(); i < size; i++) { for (int i = 0, size = menu.size(); i < size; i++) {

@ -0,0 +1,5 @@
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z"/>
</vector>

@ -3,6 +3,7 @@
android:id="@+id/row" android:id="@+id/row"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/asContentBackground"
android:orientation="vertical"> android:orientation="vertical">
<include layout="@layout/task_adapter_row_body" /> <include layout="@layout/task_adapter_row_body" />

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/copy_tasks"
android:title="@string/TAd_contextCopyTask"
android:icon="@drawable/ic_content_copy_black_24dp"
app:showAsAction="ifRoom" />
<item
android:id="@+id/delete"
android:title="@string/delete"
android:icon="@drawable/ic_delete_24dp"
app:showAsAction="ifRoom" />
</menu>

@ -107,7 +107,6 @@
<string name="EPr_cal_end_at_due_time">Приключване на събития в календара на крайния срок</string> <string name="EPr_cal_end_at_due_time">Приключване на събития в календара на крайния срок</string>
<string name="EPr_cal_start_at_due_time">Започване на събития в календара на крайния срок</string> <string name="EPr_cal_start_at_due_time">Започване на събития в календара на крайния срок</string>
<string name="EPr_manage_header">Управление на стари задачи</string> <string name="EPr_manage_header">Управление на стари задачи</string>
<string name="EPr_manage_delete_completed_status">Изтрити %d задачи!</string>
<string name="EPr_manage_purge_deleted">Изчистване на изтритите задачи</string> <string name="EPr_manage_purge_deleted">Изчистване на изтритите задачи</string>
<string name="EPr_manage_purge_deleted_message">Наистина ли искате да изчистите всичките си приключени задачи?\n\nТези задачи ще изчезнат завинаги!</string> <string name="EPr_manage_purge_deleted_message">Наистина ли искате да изчистите всичките си приключени задачи?\n\nТези задачи ще изчезнат завинаги!</string>
<string name="EPr_manage_purge_deleted_status">Изчистени %d задачи!</string> <string name="EPr_manage_purge_deleted_status">Изчистени %d задачи!</string>

@ -64,7 +64,6 @@
<string name="EPr_appearance_header">Aparença</string> <string name="EPr_appearance_header">Aparença</string>
<string name="EPr_beastMode_reset">Restableix els valors predeterminats</string> <string name="EPr_beastMode_reset">Restableix els valors predeterminats</string>
<string name="EPr_fullTask_title">Mostra el títol sencer de la tasca</string> <string name="EPr_fullTask_title">Mostra el títol sencer de la tasca</string>
<string name="EPr_manage_delete_completed_status">S\'han suprimit %d tasques</string>
<string name="EPr_manage_delete_completed_gcal_message">Segur que voleu suprimir els esdeveniments de calendari de les tasques completades?</string> <string name="EPr_manage_delete_completed_gcal_message">Segur que voleu suprimir els esdeveniments de calendari de les tasques completades?</string>
<string name="day_after_tomorrow">Demà passat</string> <string name="day_after_tomorrow">Demà passat</string>
<string name="next_week">La setmana que ve</string> <string name="next_week">La setmana que ve</string>

@ -98,7 +98,6 @@
<string name="EPr_cal_end_at_due_time">Událost v kalendáři končí splněním úkolu</string> <string name="EPr_cal_end_at_due_time">Událost v kalendáři končí splněním úkolu</string>
<string name="EPr_cal_start_at_due_time">Událost v kalendáři začíná splněním úkolu</string> <string name="EPr_cal_start_at_due_time">Událost v kalendáři začíná splněním úkolu</string>
<string name="EPr_manage_header">Spravovat staré úkoly</string> <string name="EPr_manage_header">Spravovat staré úkoly</string>
<string name="EPr_manage_delete_completed_status">Odstraněno %d úkolů!</string>
<string name="EPr_manage_purge_deleted">Vymazat smazané úkoly</string> <string name="EPr_manage_purge_deleted">Vymazat smazané úkoly</string>
<string name="EPr_manage_purge_deleted_message">Opravdu chcete vymazat vaše smazané úkoly?\n\nTyto úkoly budou vymazány navždy!</string> <string name="EPr_manage_purge_deleted_message">Opravdu chcete vymazat vaše smazané úkoly?\n\nTyto úkoly budou vymazány navždy!</string>
<string name="EPr_manage_purge_deleted_status">Vymyzáno %d úkolů!</string> <string name="EPr_manage_purge_deleted_status">Vymyzáno %d úkolů!</string>

@ -102,7 +102,6 @@
<string name="EPr_cal_end_at_due_time">Kalendereintrag endet zur Fälligkeits-Uhrzeit</string> <string name="EPr_cal_end_at_due_time">Kalendereintrag endet zur Fälligkeits-Uhrzeit</string>
<string name="EPr_cal_start_at_due_time">Kalendereintrag Startet zur Fälligkeits-Uhrzeit</string> <string name="EPr_cal_start_at_due_time">Kalendereintrag Startet zur Fälligkeits-Uhrzeit</string>
<string name="EPr_manage_header">Alte Aufgaben verwalten</string> <string name="EPr_manage_header">Alte Aufgaben verwalten</string>
<string name="EPr_manage_delete_completed_status">%d Aufgaben gelöscht</string>
<string name="EPr_manage_purge_deleted">Gelöschte Aufgaben endgültig löschen</string> <string name="EPr_manage_purge_deleted">Gelöschte Aufgaben endgültig löschen</string>
<string name="EPr_manage_purge_deleted_message">Willst du wirklich alle gelöschten Aufgaben bereinigen?\n\nDiese Aufgaben werden für immer gelöscht bleiben!</string> <string name="EPr_manage_purge_deleted_message">Willst du wirklich alle gelöschten Aufgaben bereinigen?\n\nDiese Aufgaben werden für immer gelöscht bleiben!</string>
<string name="EPr_manage_purge_deleted_status">%d Aufgaben bereinigt!</string> <string name="EPr_manage_purge_deleted_status">%d Aufgaben bereinigt!</string>

@ -89,7 +89,6 @@
<string name="EPr_cal_end_at_due_time">Τερματισμός γεγονότων ημερολογίου στην ώρα λήξης τους</string> <string name="EPr_cal_end_at_due_time">Τερματισμός γεγονότων ημερολογίου στην ώρα λήξης τους</string>
<string name="EPr_cal_start_at_due_time">Εκκίνηση γεγονότων ημερολογίου στην ώρα λήξης τους</string> <string name="EPr_cal_start_at_due_time">Εκκίνηση γεγονότων ημερολογίου στην ώρα λήξης τους</string>
<string name="EPr_manage_header">Διαχείριση παλιών εργασιών</string> <string name="EPr_manage_header">Διαχείριση παλιών εργασιών</string>
<string name="EPr_manage_delete_completed_status">Διαγράφηκαν %d εργασίες!</string>
<string name="EPr_manage_purge_deleted">Εκκαθάριση διεγραμμένων εργασιών</string> <string name="EPr_manage_purge_deleted">Εκκαθάριση διεγραμμένων εργασιών</string>
<string name="EPr_manage_purge_deleted_message">Θέλετε πραγματικά να καθαρίσετε όλες τις διαγραμμένες εργασίες;\n\nΑυτές οι εργασίες θα χαθούν για πάντα!</string> <string name="EPr_manage_purge_deleted_message">Θέλετε πραγματικά να καθαρίσετε όλες τις διαγραμμένες εργασίες;\n\nΑυτές οι εργασίες θα χαθούν για πάντα!</string>
<string name="EPr_manage_purge_deleted_status">Εκκαθαρίστηκαν %d εργασίες!</string> <string name="EPr_manage_purge_deleted_status">Εκκαθαρίστηκαν %d εργασίες!</string>

@ -103,7 +103,6 @@
<string name="EPr_cal_end_at_due_time">Finalizar eventos del calendario al vencimiento</string> <string name="EPr_cal_end_at_due_time">Finalizar eventos del calendario al vencimiento</string>
<string name="EPr_cal_start_at_due_time">Iniciar eventos del calendario al vencimiento</string> <string name="EPr_cal_start_at_due_time">Iniciar eventos del calendario al vencimiento</string>
<string name="EPr_manage_header">Administrar tareas antiguas</string> <string name="EPr_manage_header">Administrar tareas antiguas</string>
<string name="EPr_manage_delete_completed_status">¡%d tareas borradas!</string>
<string name="EPr_manage_purge_deleted">Limpiar tareas eliminadas</string> <string name="EPr_manage_purge_deleted">Limpiar tareas eliminadas</string>
<string name="EPr_manage_purge_deleted_message">¿Seguro que desea limpiar todas las tareas eliminadas?\n\n¡Estas tareas se perderán por siempre!</string> <string name="EPr_manage_purge_deleted_message">¿Seguro que desea limpiar todas las tareas eliminadas?\n\n¡Estas tareas se perderán por siempre!</string>
<string name="EPr_manage_purge_deleted_status">¡%d tareas purgadas!</string> <string name="EPr_manage_purge_deleted_status">¡%d tareas purgadas!</string>

@ -107,7 +107,6 @@
<string name="EPr_cal_end_at_due_time">Lopeta kalenteritapahtuma määräaikana</string> <string name="EPr_cal_end_at_due_time">Lopeta kalenteritapahtuma määräaikana</string>
<string name="EPr_cal_start_at_due_time">Aloita kalenteritapahtumat määräaikana</string> <string name="EPr_cal_start_at_due_time">Aloita kalenteritapahtumat määräaikana</string>
<string name="EPr_manage_header">Hallinnoi vanhoja tehtäviä</string> <string name="EPr_manage_header">Hallinnoi vanhoja tehtäviä</string>
<string name="EPr_manage_delete_completed_status">Poistettu %d tehtävää</string>
<string name="EPr_manage_purge_deleted">Tyjennä poistetut tehtävät</string> <string name="EPr_manage_purge_deleted">Tyjennä poistetut tehtävät</string>
<string name="EPr_manage_purge_deleted_message">Haluatko todella tyhjentää kaikki poistetut tehtävät?\n\n Nämä tehtävät häviävät lopullisesti!</string> <string name="EPr_manage_purge_deleted_message">Haluatko todella tyhjentää kaikki poistetut tehtävät?\n\n Nämä tehtävät häviävät lopullisesti!</string>
<string name="EPr_manage_purge_deleted_status">Tyhjennettu %d tehtävää!</string> <string name="EPr_manage_purge_deleted_status">Tyhjennettu %d tehtävää!</string>

@ -102,7 +102,6 @@
<string name="EPr_cal_end_at_due_time">Terminer les événements dans le calendrier à l\'échéance</string> <string name="EPr_cal_end_at_due_time">Terminer les événements dans le calendrier à l\'échéance</string>
<string name="EPr_cal_start_at_due_time">Commencer les événements dans le calendrier à l\'échéance</string> <string name="EPr_cal_start_at_due_time">Commencer les événements dans le calendrier à l\'échéance</string>
<string name="EPr_manage_header">Gérer les anciennes tâches</string> <string name="EPr_manage_header">Gérer les anciennes tâches</string>
<string name="EPr_manage_delete_completed_status">%d tâches supprimées !</string>
<string name="EPr_manage_purge_deleted">Supprimer définitivement les tâches supprimées</string> <string name="EPr_manage_purge_deleted">Supprimer définitivement les tâches supprimées</string>
<string name="EPr_manage_purge_deleted_message">Voulez vous vraiment supprimer définitivement toutes les tâches supprimées ?\n\nCes tâches seront perdues à jamais !</string> <string name="EPr_manage_purge_deleted_message">Voulez vous vraiment supprimer définitivement toutes les tâches supprimées ?\n\nCes tâches seront perdues à jamais !</string>
<string name="EPr_manage_purge_deleted_status">%d tâches supprimées définitivement !</string> <string name="EPr_manage_purge_deleted_status">%d tâches supprimées définitivement !</string>

@ -107,7 +107,6 @@
<string name="EPr_cal_end_at_due_time">Naptáresemények befejezése határidőkor</string> <string name="EPr_cal_end_at_due_time">Naptáresemények befejezése határidőkor</string>
<string name="EPr_cal_start_at_due_time">Naptáresemények kezdése határidőkor</string> <string name="EPr_cal_start_at_due_time">Naptáresemények kezdése határidőkor</string>
<string name="EPr_manage_header">Régi feladatok kezelése</string> <string name="EPr_manage_header">Régi feladatok kezelése</string>
<string name="EPr_manage_delete_completed_status">%d feladat törölve!</string>
<string name="EPr_manage_purge_deleted">Törölt feladatok elvetése</string> <string name="EPr_manage_purge_deleted">Törölt feladatok elvetése</string>
<string name="EPr_manage_purge_deleted_message">Biztosan el akarja vetni az összes törölt feladatot?\n\nEzek a feladatok többé nem lesznek visszaállíthatóak!</string> <string name="EPr_manage_purge_deleted_message">Biztosan el akarja vetni az összes törölt feladatot?\n\nEzek a feladatok többé nem lesznek visszaállíthatóak!</string>
<string name="EPr_manage_purge_deleted_status">%d feladat elvetve</string> <string name="EPr_manage_purge_deleted_status">%d feladat elvetve</string>

@ -104,7 +104,6 @@
<string name="EPr_cal_end_at_due_time">Calendario eventi fino alla scadenza</string> <string name="EPr_cal_end_at_due_time">Calendario eventi fino alla scadenza</string>
<string name="EPr_cal_start_at_due_time">Calendario eventi dalla scadenza</string> <string name="EPr_cal_start_at_due_time">Calendario eventi dalla scadenza</string>
<string name="EPr_manage_header">Gestisci compiti vecchi</string> <string name="EPr_manage_header">Gestisci compiti vecchi</string>
<string name="EPr_manage_delete_completed_status">Eliminate %d attività!</string>
<string name="EPr_manage_purge_deleted">Elimina definitivamente i compiti eliminati</string> <string name="EPr_manage_purge_deleted">Elimina definitivamente i compiti eliminati</string>
<string name="EPr_manage_purge_deleted_message">Vuoi davvero eliminare definitivamente i compiti eliminati?\n\nQuesti compiti saranno persi per sempre!</string> <string name="EPr_manage_purge_deleted_message">Vuoi davvero eliminare definitivamente i compiti eliminati?\n\nQuesti compiti saranno persi per sempre!</string>
<string name="EPr_manage_purge_deleted_status">Rimosse %d attività!</string> <string name="EPr_manage_purge_deleted_status">Rimosse %d attività!</string>
@ -413,4 +412,4 @@
<string name="creating_new_list">Crea nuova lista</string> <string name="creating_new_list">Crea nuova lista</string>
<string name="deleting_list">Cancella lista</string> <string name="deleting_list">Cancella lista</string>
<string name="renaming_list">RInomina lista</string> <string name="renaming_list">RInomina lista</string>
</resources> </resources>

@ -104,7 +104,6 @@
<string name="EPr_cal_end_at_due_time">סיים את אירועי היומן במועד היעד?</string> <string name="EPr_cal_end_at_due_time">סיים את אירועי היומן במועד היעד?</string>
<string name="EPr_cal_start_at_due_time">התחל את מאורעות היומן במועד היעד</string> <string name="EPr_cal_start_at_due_time">התחל את מאורעות היומן במועד היעד</string>
<string name="EPr_manage_header">נהל משימות ישנות</string> <string name="EPr_manage_header">נהל משימות ישנות</string>
<string name="EPr_manage_delete_completed_status">%d משימות נמחקו!</string>
<string name="EPr_manage_purge_deleted">מחק לצמיתות משימות שנמחקו</string> <string name="EPr_manage_purge_deleted">מחק לצמיתות משימות שנמחקו</string>
<string name="EPr_manage_purge_deleted_message">האם אתה בטוח שברצונך למחוק לצמיתות את כל המשימות שנמחקו?</string> <string name="EPr_manage_purge_deleted_message">האם אתה בטוח שברצונך למחוק לצמיתות את כל המשימות שנמחקו?</string>
<string name="EPr_manage_purge_deleted_status">%d משימות אֻיְּנוּ!</string> <string name="EPr_manage_purge_deleted_status">%d משימות אֻיְּנוּ!</string>

@ -104,7 +104,6 @@
<string name="EPr_cal_end_at_due_time">カレンダーイベント終了時間</string> <string name="EPr_cal_end_at_due_time">カレンダーイベント終了時間</string>
<string name="EPr_cal_start_at_due_time">カレンダーイベント開始時間</string> <string name="EPr_cal_start_at_due_time">カレンダーイベント開始時間</string>
<string name="EPr_manage_header">古いタスクを管理</string> <string name="EPr_manage_header">古いタスクを管理</string>
<string name="EPr_manage_delete_completed_status">%d タスクが削除されました!</string>
<string name="EPr_manage_purge_deleted">削除済のタスクを消去</string> <string name="EPr_manage_purge_deleted">削除済のタスクを消去</string>
<string name="EPr_manage_purge_deleted_message">削除済のタスクをすべて消去してもよろしいですか?\n\nこれらのタスクは永久になくなります!</string> <string name="EPr_manage_purge_deleted_message">削除済のタスクをすべて消去してもよろしいですか?\n\nこれらのタスクは永久になくなります!</string>
<string name="EPr_manage_purge_deleted_status">%d タスクを消去しました!</string> <string name="EPr_manage_purge_deleted_status">%d タスクを消去しました!</string>

@ -106,7 +106,6 @@
<string name="EPr_cal_end_at_due_time">설정한 시간에 달력 이벤트 종료</string> <string name="EPr_cal_end_at_due_time">설정한 시간에 달력 이벤트 종료</string>
<string name="EPr_cal_start_at_due_time">설정한 시간에 달력 이벤트 시작</string> <string name="EPr_cal_start_at_due_time">설정한 시간에 달력 이벤트 시작</string>
<string name="EPr_manage_header">오래된 일정 관리하기</string> <string name="EPr_manage_header">오래된 일정 관리하기</string>
<string name="EPr_manage_delete_completed_status">%d 일정을 삭제했습니다!</string>
<string name="EPr_manage_purge_deleted">삭제한 일정을 비우기</string> <string name="EPr_manage_purge_deleted">삭제한 일정을 비우기</string>
<string name="EPr_manage_purge_deleted_message">삭제한 일정을 모두 비울까요?\n\n비운 일정은 다시 살릴 수 없습니다!</string> <string name="EPr_manage_purge_deleted_message">삭제한 일정을 모두 비울까요?\n\n비운 일정은 다시 살릴 수 없습니다!</string>
<string name="EPr_manage_purge_deleted_status">%d 일정을 비웠습니다!</string> <string name="EPr_manage_purge_deleted_status">%d 일정을 비웠습니다!</string>

@ -9,4 +9,5 @@
<color name="text_secondary">@color/white_70</color> <color name="text_secondary">@color/white_70</color>
<color name="text_tertiary">@color/white_50</color> <color name="text_tertiary">@color/white_50</color>
<color name="divider">@color/white_12</color> <color name="divider">@color/white_12</color>
<color name="action_mode_background">@color/grey_900</color>
</resources> </resources>

@ -103,7 +103,6 @@
<string name="EPr_cal_end_at_due_time">Agenda item op tijd afronden</string> <string name="EPr_cal_end_at_due_time">Agenda item op tijd afronden</string>
<string name="EPr_cal_start_at_due_time">Agenda item op tijd starten</string> <string name="EPr_cal_start_at_due_time">Agenda item op tijd starten</string>
<string name="EPr_manage_header">Oude taken beheren</string> <string name="EPr_manage_header">Oude taken beheren</string>
<string name="EPr_manage_delete_completed_status">%d taken verwijderd!</string>
<string name="EPr_manage_purge_deleted">Verwijderde taken opruimen</string> <string name="EPr_manage_purge_deleted">Verwijderde taken opruimen</string>
<string name="EPr_manage_purge_deleted_message">Alle verwijderde taken werkelijk opschonen?\n\nDeze taken zijn dan definitief verwijderd!</string> <string name="EPr_manage_purge_deleted_message">Alle verwijderde taken werkelijk opschonen?\n\nDeze taken zijn dan definitief verwijderd!</string>
<string name="EPr_manage_purge_deleted_status">%d verwijderde taken opgeruimd!</string> <string name="EPr_manage_purge_deleted_status">%d verwijderde taken opgeruimd!</string>

@ -9,4 +9,5 @@
<color name="text_secondary">@color/black_54</color> <color name="text_secondary">@color/black_54</color>
<color name="text_tertiary">@color/black_38</color> <color name="text_tertiary">@color/black_38</color>
<color name="divider">@color/black_12</color> <color name="divider">@color/black_12</color>
<color name="action_mode_background">@color/grey_100</color>
</resources> </resources>

@ -104,7 +104,6 @@
<string name="EPr_cal_end_at_due_time">Zakończ zadania kalendarza w ustalonym czasie</string> <string name="EPr_cal_end_at_due_time">Zakończ zadania kalendarza w ustalonym czasie</string>
<string name="EPr_cal_start_at_due_time">Rozpocznij zadania kalendarza w ustalonym czasie</string> <string name="EPr_cal_start_at_due_time">Rozpocznij zadania kalendarza w ustalonym czasie</string>
<string name="EPr_manage_header">Zarządzaj starymi zadaniami</string> <string name="EPr_manage_header">Zarządzaj starymi zadaniami</string>
<string name="EPr_manage_delete_completed_status">Usunięto %d zadań!</string>
<string name="EPr_manage_purge_deleted">Skasuj usunięte zadania</string> <string name="EPr_manage_purge_deleted">Skasuj usunięte zadania</string>
<string name="EPr_manage_purge_deleted_message">Czy na pewno chcesz, aby oczyścić wszystkie usunięte zadania?\n\n Te zadania znikną na zawsze!</string> <string name="EPr_manage_purge_deleted_message">Czy na pewno chcesz, aby oczyścić wszystkie usunięte zadania?\n\n Te zadania znikną na zawsze!</string>
<string name="EPr_manage_purge_deleted_status">Oczyszczone %d zadań!</string> <string name="EPr_manage_purge_deleted_status">Oczyszczone %d zadań!</string>

@ -94,7 +94,6 @@
<string name="EPr_cal_end_at_due_time">Eventos da agenda terminou no devido tempo</string> <string name="EPr_cal_end_at_due_time">Eventos da agenda terminou no devido tempo</string>
<string name="EPr_cal_start_at_due_time">Eventos da agenda iniciaram no devido tempo</string> <string name="EPr_cal_start_at_due_time">Eventos da agenda iniciaram no devido tempo</string>
<string name="EPr_manage_header">Gerenciar tarefas antigas</string> <string name="EPr_manage_header">Gerenciar tarefas antigas</string>
<string name="EPr_manage_delete_completed_status">%d tarefas excluídas!</string>
<string name="EPr_manage_purge_deleted">Limpar tarefas excluídas</string> <string name="EPr_manage_purge_deleted">Limpar tarefas excluídas</string>
<string name="EPr_manage_purge_deleted_message">Você realmente deseja limpar todas as suas tarefas excluídas?\n\nEstas tarefas irão desaparecer para sempre!</string> <string name="EPr_manage_purge_deleted_message">Você realmente deseja limpar todas as suas tarefas excluídas?\n\nEstas tarefas irão desaparecer para sempre!</string>
<string name="EPr_manage_purge_deleted_status">%d tarefas removidas!</string> <string name="EPr_manage_purge_deleted_status">%d tarefas removidas!</string>

@ -98,7 +98,6 @@
<string name="EPr_cal_end_at_due_time">Terminar evento do calendário na hora limite</string> <string name="EPr_cal_end_at_due_time">Terminar evento do calendário na hora limite</string>
<string name="EPr_cal_start_at_due_time">Iniciar eventos de calendário na hora limite</string> <string name="EPr_cal_start_at_due_time">Iniciar eventos de calendário na hora limite</string>
<string name="EPr_manage_header">Gerir tarefas antigas</string> <string name="EPr_manage_header">Gerir tarefas antigas</string>
<string name="EPr_manage_delete_completed_status">%d tarefas eliminadas!</string>
<string name="EPr_manage_purge_deleted">Remover tarefas eliminadas</string> <string name="EPr_manage_purge_deleted">Remover tarefas eliminadas</string>
<string name="EPr_manage_purge_deleted_message">Quer mesmo remover todas as tarefas eliminadas?\n\nNunca mais as conseguirá recuperar!</string> <string name="EPr_manage_purge_deleted_message">Quer mesmo remover todas as tarefas eliminadas?\n\nNunca mais as conseguirá recuperar!</string>
<string name="EPr_manage_purge_deleted_status">%d tarefas removidas!</string> <string name="EPr_manage_purge_deleted_status">%d tarefas removidas!</string>

@ -104,7 +104,6 @@
<string name="EPr_cal_end_at_due_time">Завершать события в календаре при наступлении срока</string> <string name="EPr_cal_end_at_due_time">Завершать события в календаре при наступлении срока</string>
<string name="EPr_cal_start_at_due_time">Создавать события в календаре при наступлении срока</string> <string name="EPr_cal_start_at_due_time">Создавать события в календаре при наступлении срока</string>
<string name="EPr_manage_header">Управление старыми задачами</string> <string name="EPr_manage_header">Управление старыми задачами</string>
<string name="EPr_manage_delete_completed_status">Удалено %d задач!</string>
<string name="EPr_manage_purge_deleted">Очистить удаленные задачи?</string> <string name="EPr_manage_purge_deleted">Очистить удаленные задачи?</string>
<string name="EPr_manage_purge_deleted_message">Действительно хотите убрать все удалённые задачи?\n\nЭта операция необратима!</string> <string name="EPr_manage_purge_deleted_message">Действительно хотите убрать все удалённые задачи?\n\nЭта операция необратима!</string>
<string name="EPr_manage_purge_deleted_status">Убрано %d задач!</string> <string name="EPr_manage_purge_deleted_status">Убрано %d задач!</string>

@ -96,7 +96,6 @@
<string name="EPr_cal_end_at_due_time">Ukončiť udalosť kalendára v danom čase</string> <string name="EPr_cal_end_at_due_time">Ukončiť udalosť kalendára v danom čase</string>
<string name="EPr_cal_start_at_due_time">Začať kalendárne udalosti v danom čase</string> <string name="EPr_cal_start_at_due_time">Začať kalendárne udalosti v danom čase</string>
<string name="EPr_manage_header">Spravovať staré úlohy</string> <string name="EPr_manage_header">Spravovať staré úlohy</string>
<string name="EPr_manage_delete_completed_status">Vymazané %d úlohy</string>
<string name="EPr_manage_purge_deleted">Zbaviť sa vymazaných úloh</string> <string name="EPr_manage_purge_deleted">Zbaviť sa vymazaných úloh</string>
<string name="EPr_manage_purge_deleted_message">Naozaj chceš vyhodiť všetky tvoje vymazané úlohy?\n\nTieto budú vymazané navždy!</string> <string name="EPr_manage_purge_deleted_message">Naozaj chceš vyhodiť všetky tvoje vymazané úlohy?\n\nTieto budú vymazané navždy!</string>
<string name="EPr_manage_purge_deleted_status">Vyčistené %d úlohy</string> <string name="EPr_manage_purge_deleted_status">Vyčistené %d úlohy</string>

@ -91,7 +91,6 @@
<string name="EPr_cal_end_at_due_time">Končaj dogodke na koledarju ob dospelosti</string> <string name="EPr_cal_end_at_due_time">Končaj dogodke na koledarju ob dospelosti</string>
<string name="EPr_cal_start_at_due_time">Začni dogodke na koledarju ob dospelosti</string> <string name="EPr_cal_start_at_due_time">Začni dogodke na koledarju ob dospelosti</string>
<string name="EPr_manage_header">Upravljanje s preteklimi opravki</string> <string name="EPr_manage_header">Upravljanje s preteklimi opravki</string>
<string name="EPr_manage_delete_completed_status">Število zbrisanih opravkov: %d </string>
<string name="EPr_manage_purge_deleted">Popolnoma odstrani zbrisane opravke</string> <string name="EPr_manage_purge_deleted">Popolnoma odstrani zbrisane opravke</string>
<string name="EPr_manage_purge_deleted_message">Ste prepričani, da želite popolnoma odstraniti vse zbrisane opravke?\n\nTega ukaza ne bo mogoče razveljaviti! </string> <string name="EPr_manage_purge_deleted_message">Ste prepričani, da želite popolnoma odstraniti vse zbrisane opravke?\n\nTega ukaza ne bo mogoče razveljaviti! </string>
<string name="EPr_manage_purge_deleted_status">Število popolnoma odstranjenih opravkov: %d </string> <string name="EPr_manage_purge_deleted_status">Število popolnoma odstranjenih opravkov: %d </string>

@ -104,7 +104,6 @@
<string name="EPr_cal_end_at_due_time">Avsluta kalenderhändelser vid förfallotid</string> <string name="EPr_cal_end_at_due_time">Avsluta kalenderhändelser vid förfallotid</string>
<string name="EPr_cal_start_at_due_time">Påbörja kalenderhändelser vid förfallotid</string> <string name="EPr_cal_start_at_due_time">Påbörja kalenderhändelser vid förfallotid</string>
<string name="EPr_manage_header">Hantera gamla uppgifter</string> <string name="EPr_manage_header">Hantera gamla uppgifter</string>
<string name="EPr_manage_delete_completed_status">%d uppgifter raderade!</string>
<string name="EPr_manage_purge_deleted">Rensa bort raderade uppgifter</string> <string name="EPr_manage_purge_deleted">Rensa bort raderade uppgifter</string>
<string name="EPr_manage_purge_deleted_message">Vill du verkligen rensa bort alla dina raderade uppgifter?\n\nDe här uppgifterna kommer att tas bort för alltid!</string> <string name="EPr_manage_purge_deleted_message">Vill du verkligen rensa bort alla dina raderade uppgifter?\n\nDe här uppgifterna kommer att tas bort för alltid!</string>
<string name="EPr_manage_purge_deleted_status">%d uppgifter bortrensade!</string> <string name="EPr_manage_purge_deleted_status">%d uppgifter bortrensade!</string>

@ -66,7 +66,6 @@
<string name="EPr_beastMode_reset">Varsayılanlara sıfırla</string> <string name="EPr_beastMode_reset">Varsayılanlara sıfırla</string>
<string name="EPr_fullTask_title">Tüm görev başlığını göster</string> <string name="EPr_fullTask_title">Tüm görev başlığını göster</string>
<string name="EPr_manage_header">Eski Görevleri Yönet</string> <string name="EPr_manage_header">Eski Görevleri Yönet</string>
<string name="EPr_manage_delete_completed_status">%d görev silindi!</string>
<string name="EPr_manage_purge_deleted">Silinen Görevleri Temizle</string> <string name="EPr_manage_purge_deleted">Silinen Görevleri Temizle</string>
<string name="EPr_manage_purge_deleted_message">Tüm silinen görevleri temizlemek istediğine emin misin?\n\nBu görevler tamamen silinecek!</string> <string name="EPr_manage_purge_deleted_message">Tüm silinen görevleri temizlemek istediğine emin misin?\n\nBu görevler tamamen silinecek!</string>
<string name="EPr_manage_purge_deleted_status">%d görev temizlendi!</string> <string name="EPr_manage_purge_deleted_status">%d görev temizlendi!</string>

@ -107,7 +107,6 @@
<string name="EPr_cal_end_at_due_time">Завершення календарної події при настанні терміну</string> <string name="EPr_cal_end_at_due_time">Завершення календарної події при настанні терміну</string>
<string name="EPr_cal_start_at_due_time">Початок календарної події при настанні терміну</string> <string name="EPr_cal_start_at_due_time">Початок календарної події при настанні терміну</string>
<string name="EPr_manage_header">Управління старими завданнями</string> <string name="EPr_manage_header">Управління старими завданнями</string>
<string name="EPr_manage_delete_completed_status">Видалено %d завдань!</string>
<string name="EPr_manage_purge_deleted">Очистити видалені завдання</string> <string name="EPr_manage_purge_deleted">Очистити видалені завдання</string>
<string name="EPr_manage_purge_deleted_message">Ви дійсно хочете очистити всі видалені завдання?\n\nЦя операція незворотна!</string> <string name="EPr_manage_purge_deleted_message">Ви дійсно хочете очистити всі видалені завдання?\n\nЦя операція незворотна!</string>
<string name="EPr_manage_purge_deleted_status">Очищено %d завдань!</string> <string name="EPr_manage_purge_deleted_status">Очищено %d завдань!</string>

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<style name="TasksOverride" parent="Tasks"> <style name="Tasks" parent="TasksBase">
<item name="android:windowDrawsSystemBarBackgrounds">true</item> <item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item> <item name="android:statusBarColor">@android:color/transparent</item>
</style> </style>

@ -78,7 +78,6 @@
<string name="EPr_fullTask_title">显示完整的任务标题</string> <string name="EPr_fullTask_title">显示完整的任务标题</string>
<string name="task_list_options">任务列表选项</string> <string name="task_list_options">任务列表选项</string>
<string name="EPr_manage_header">管理旧任务</string> <string name="EPr_manage_header">管理旧任务</string>
<string name="EPr_manage_delete_completed_status">删除了 %d 个任务!</string>
<string name="EPr_manage_purge_deleted">清除已删除任务</string> <string name="EPr_manage_purge_deleted">清除已删除任务</string>
<string name="EPr_manage_purge_deleted_message">您真的要清楚所有已删除任务吗? \n\n 这些任务将会被彻底永久删除!</string> <string name="EPr_manage_purge_deleted_message">您真的要清楚所有已删除任务吗? \n\n 这些任务将会被彻底永久删除!</string>
<string name="EPr_manage_purge_deleted_status">清除了 %d 个任务!</string> <string name="EPr_manage_purge_deleted_status">清除了 %d 个任务!</string>

@ -77,7 +77,6 @@
<string name="EPr_beastMode_reset">恢復默認值</string> <string name="EPr_beastMode_reset">恢復默認值</string>
<string name="EPr_fullTask_title">顯示完整的任務工作標題</string> <string name="EPr_fullTask_title">顯示完整的任務工作標題</string>
<string name="EPr_manage_header">管理舊任務工作</string> <string name="EPr_manage_header">管理舊任務工作</string>
<string name="EPr_manage_delete_completed_status">刪除了 %d 個任務工作!</string>
<string name="EPr_manage_purge_deleted">清除已刪除任務工作</string> <string name="EPr_manage_purge_deleted">清除已刪除任務工作</string>
<string name="EPr_manage_purge_deleted_message">您真的要清楚所有已刪除任務工作嗎? \n\n 這些任務工作將會被徹底永久刪除!</string> <string name="EPr_manage_purge_deleted_message">您真的要清楚所有已刪除任務工作嗎? \n\n 這些任務工作將會被徹底永久刪除!</string>
<string name="EPr_manage_purge_deleted_status">清除了 %d 個任務工作!</string> <string name="EPr_manage_purge_deleted_status">清除了 %d 個任務工作!</string>

@ -74,6 +74,7 @@
<color name="brown_700">#5d4037</color> <color name="brown_700">#5d4037</color>
<color name="grey_50">#fafafa</color> <color name="grey_50">#fafafa</color>
<color name="grey_100">#f5f5f5</color>
<color name="grey_500">#9e9e9e</color> <color name="grey_500">#9e9e9e</color>
<color name="grey_700">#616161</color> <color name="grey_700">#616161</color>
<color name="grey_800">#424242</color> <color name="grey_800">#424242</color>

@ -297,6 +297,8 @@
<string name="tracking_event_play_services_error">Play Services Error</string> <string name="tracking_event_play_services_error">Play Services Error</string>
<string name="tracking_event_upgrade">Upgrade</string> <string name="tracking_event_upgrade">Upgrade</string>
<string name="tracking_event_legacy_tasker_trigger">Legacy Tasker</string> <string name="tracking_event_legacy_tasker_trigger">Legacy Tasker</string>
<string name="tracking_event_multiselect_delete">Multiselect delete</string>
<string name="tracking_event_multiselect_clone">Multiselect clone</string>
<string name="p_tesla_unread_enabled">tesla_unread_enabled</string> <string name="p_tesla_unread_enabled">tesla_unread_enabled</string>
<string name="p_purchased_tesla_unread">purchased_tesla_unread</string> <string name="p_purchased_tesla_unread">purchased_tesla_unread</string>
<string name="p_purchased_tasker">purchased_tasker</string> <string name="p_purchased_tasker">purchased_tasker</string>

@ -291,7 +291,6 @@ File %1$s contained %2$s.\n\n
<!-- slide 33a/47c: Preference Screen Header: Old Task Management --> <!-- slide 33a/47c: Preference Screen Header: Old Task Management -->
<string name="EPr_manage_header">Manage old tasks</string> <string name="EPr_manage_header">Manage old tasks</string>
<string name="EPr_manage_delete_completed_status">Deleted %d tasks!</string>
<string name="EPr_manage_purge_deleted">Purge deleted tasks</string> <string name="EPr_manage_purge_deleted">Purge deleted tasks</string>
<string name="EPr_manage_purge_deleted_message">Do you really want to purge all your deleted tasks?\n\nThese tasks will be gone forever!</string> <string name="EPr_manage_purge_deleted_message">Do you really want to purge all your deleted tasks?\n\nThese tasks will be gone forever!</string>
<string name="EPr_manage_purge_deleted_status">Purged %d tasks!</string> <string name="EPr_manage_purge_deleted_status">Purged %d tasks!</string>
@ -821,5 +820,7 @@ File %1$s contained %2$s.\n\n
<string name="deleting_list">Deleting list</string> <string name="deleting_list">Deleting list</string>
<string name="renaming_list">Renaming list</string> <string name="renaming_list">Renaming list</string>
<string name="clear_completed_tasks_confirmation">Clear completed tasks?</string> <string name="clear_completed_tasks_confirmation">Clear completed tasks?</string>
<string name="copy_multiple_tasks_confirmation">%s copied</string>
<string name="delete_multiple_tasks_confirmation">%s deleted</string>
</resources> </resources>

@ -55,12 +55,10 @@
</style> </style>
<style name="WhiteToolbarOverlay" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <style name="WhiteToolbarOverlay" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<!--<item name="android:textColorPrimary">@color/white_100</item>-->
<item name="colorControlNormal">@color/white_100</item> <item name="colorControlNormal">@color/white_100</item>
</style> </style>
<style name="BlackToolbarOverlay" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> <style name="BlackToolbarOverlay" parent="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<!--<item name="android:textColorPrimary">@color/black_87</item>-->
<item name="colorControlNormal">@color/black_87</item> <item name="colorControlNormal">@color/black_87</item>
</style> </style>

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<style name="Tasks" parent="Theme.AppCompat.DayNight.NoActionBar"> <style name="TasksBase" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowBackground">@null</item> <item name="android:windowBackground">@null</item>
<item name="windowActionModeOverlay">true</item> <item name="windowActionModeOverlay">true</item>
<item name="asWindowBackground">@color/window_background</item> <item name="asWindowBackground">@color/window_background</item>
@ -10,7 +10,6 @@
<item name="asTextColorHint">@color/text_tertiary</item> <item name="asTextColorHint">@color/text_tertiary</item>
<item name="icon_tint">@color/icon_tint</item> <item name="icon_tint">@color/icon_tint</item>
<item name="android:spinnerItemStyle">@style/SpinnerNoPadding</item> <item name="android:spinnerItemStyle">@style/SpinnerNoPadding</item>
<item name="android:actionModeBackground">?attr/colorPrimary</item>
<item name="dialogTheme">@style/TasksDialog</item> <item name="dialogTheme">@style/TasksDialog</item>
<item name="android:dialogTheme">@style/TasksDialog</item> <item name="android:dialogTheme">@style/TasksDialog</item>
<item name="alertDialogTheme">@style/TasksDialogAlert</item> <item name="alertDialogTheme">@style/TasksDialogAlert</item>
@ -26,8 +25,7 @@
<item name="card_elevation">2dp</item> <item name="card_elevation">2dp</item>
</style> </style>
<style name="TasksOverride" parent="Tasks"> <style name="Tasks" parent="TasksBase" />
</style>
<style name="TasksDialogAlert" parent="@style/Theme.AppCompat.DayNight.Dialog.Alert"> <style name="TasksDialogAlert" parent="@style/Theme.AppCompat.DayNight.Dialog.Alert">
<item name="android:windowBackground">@color/dialog_background</item> <item name="android:windowBackground">@color/dialog_background</item>
@ -43,12 +41,12 @@
<item name="icon_tint">@color/icon_tint</item> <item name="icon_tint">@color/icon_tint</item>
</style> </style>
<style name="ThemeBlack" parent="TasksOverride"> <style name="ThemeBlack" parent="Tasks">
<item name="asWindowBackground">@color/grey_900</item> <item name="asWindowBackground">@color/grey_900</item>
<item name="asContentBackground">@android:color/black</item> <item name="asContentBackground">@android:color/black</item>
</style> </style>
<style name="Wallpaper" parent="TasksOverride"> <style name="Wallpaper" parent="Tasks">
<item name="asWindowBackground">@color/black_38</item> <item name="asWindowBackground">@color/black_38</item>
<item name="asContentBackground">@color/black_54</item> <item name="asContentBackground">@color/black_54</item>
<item name="android:windowShowWallpaper">true</item> <item name="android:windowShowWallpaper">true</item>

Loading…
Cancel
Save