Add multi-select copy and delete

pull/493/head
Alex Baker 8 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,30 +485,20 @@ 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); public void onTaskCreated(String uuid) {
menu.add(id, CONTEXT_MENU_DELETE_TASK_ID, Menu.NONE, R.string.TAd_contextDeleteTask);
} }
/** Show a dialog box and delete the task specified */ public void onTaskDelete(List<Task> tasks) {
private void deleteTask(final Task task) { for (Task task : tasks) {
dialogBuilder.newMessageDialog(R.string.delete_tag_confirmation, task.getTitle())
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
onTaskDelete(task); onTaskDelete(task);
taskDeleter.delete(task);
loadTaskListContent();
})
.setNegativeButton(android.R.string.cancel, null)
.show();
} }
public void onTaskCreated(String uuid) {
} }
protected void onTaskDelete(Task task) { protected void onTaskDelete(Task task) {
@ -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);
} }
} }
private int markDeleted(List<Task> tasks) { public int delete(List<Task> tasks) {
return markDeleted(tasks);
}
public void undelete(List<Task> tasks) {
for (Task task : tasks) {
Task template = new Task(); Task template = new Task();
template.setDeletionDate(DateUtilities.now()); template.setId(task.getId());
int count = taskDao.update(Task.ID.in(transform(tasks, Task::getId)), template); template.setDeletionDate(0L);
if (count > 0) { taskDao.save(template);
broadcaster.refresh(); }
}
private int markDeleted(List<Task> tasks) {
for (Task task : tasks) {
delete(task);
} }
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) {
List<Task> result = new ArrayList<>();
for (Task task : tasks) {
result.add(clone(taskDao.fetch(task.getId(), Task.PROPERTIES), true));
}
broadcaster.refresh();
return result;
} }
/** private Task clone(Task original, boolean suppressRefresh) {
* Create an uncompleted copy of this task and edit it
* @return cloned item id
*/
public long duplicateTask(long itemId) {
Task original = taskDao.fetch(itemId, Task.PROPERTIES);
Timber.d("Cloning %s", original);
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);
if(GtasksMetadata.METADATA_KEY.equals(oldMetadata.getKey())) {
Metadata gtaskMetadata = GtasksMetadata.createEmptyMetadataWithoutList(clone.getId());
gtaskMetadata.setValue(GtasksMetadata.LIST_ID, oldMetadata.getValue(GtasksMetadata.LIST_ID));
metadataDao.createNew(gtaskMetadata);
} else if (TaskToTagMetadata.KEY.equals(oldMetadata.getKey())) {
Metadata metadata = new Metadata(oldMetadata); Metadata metadata = new Metadata(oldMetadata);
if(GtasksMetadata.METADATA_KEY.equals(metadata.getKey())) {
metadata.setValue(GtasksMetadata.ID, ""); //$NON-NLS-1$
} else if (TaskToTagMetadata.KEY.equals(metadata.getKey())) {
metadata.setValue(TaskToTagMetadata.TASK_UUID, clone.getUuid()); metadata.setValue(TaskToTagMetadata.TASK_UUID, clone.getUuid());
}
metadata.setTask(clone.getId()); metadata.setTask(clone.getId());
metadata.clearValue(Metadata.ID); metadata.clearValue(Metadata.ID);
metadataDao.createNew(metadata); 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,25 +64,15 @@ 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)) {
TagData newTagData = tagDataDao.fetch(uuid, TagData.PROPERTIES);
if (newTagData != null) {
Filter filter = TagFilterExposer.filterFromTag(newTagData);
activity.onFilterItemClicked(filter);
}
}
} else if (TagSettingsActivity.ACTION_TAG_DELETED.equals(action)) {
String activeUuid = tagData.getUuid();
if (activeUuid.equals(uuid)) {
activity.onFilterItemClicked(null); activity.onFilterItemClicked(null);
} else if (TagSettingsActivity.ACTION_RELOAD.equals(action)) {
activity.getIntent().putExtra(TaskListActivity.OPEN_FILTER,
(Filter) data.getParcelableExtra(TaskListActivity.OPEN_FILTER));
activity.recreate();
} }
} }
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) {
if (viewHolder.isMoving()) {
return;
}
if (multiSelector.tapSelection(viewHolder)) {
afterSelect();
} else {
Task task = viewHolder.task; Task task = viewHolder.task;
if (!task.isDeleted()) {
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,8 +249,15 @@ 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);
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); Flags.set(Flags.TLFP_NO_INTERCEPT_TOUCH);
} }
}
}
@Override @Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) { public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
@ -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 (vh.isMoving()) {
if (from == -1) {
select(vh);
} else {
if (from >= 0 && from != to) { if (from >= 0 && from != to) {
if (from < to) { if (from < to) {
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;
private boolean selected;
private boolean moving;
public ViewHolder(Context context, ViewGroup view, boolean showFullTaskTitle, int fontSize, ViewHolder(Context context, ViewGroup view, boolean showFullTaskTitle, int fontSize,
CheckBoxes checkBoxes, TagFormatter tagFormatter, CheckBoxes checkBoxes, TagFormatter tagFormatter,
int textColorOverdue, int textColorSecondary, int textColorHint, TaskDao taskDao, int textColorOverdue, int textColorSecondary, int textColorHint, TaskDao taskDao,
DialogBuilder dialogBuilder, ViewHolderCallbacks callback, int minRowHeight, DialogBuilder dialogBuilder, ViewHolderCallbacks callback, int minRowHeight,
DisplayMetrics metrics) { DisplayMetrics metrics, int background, int selectedColor, MultiSelector multiSelector) {
super(view); 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>

@ -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