From f1f45bfd280eb3759ad536702832ec5d604e473e Mon Sep 17 00:00:00 2001 From: proninyaroslav Date: Wed, 10 Feb 2016 19:23:10 +0300 Subject: [PATCH 1/2] Option to cancel the removal of tags/notes --- .idea/compiler.xml | 2 +- .idea/misc.xml | 45 ++++++ .idea/scopes/scope_settings.xml | 5 - .idea/vcs.xml | 2 +- app/app.iml | 5 +- app/build.gradle | 1 + .../android/adapter/NoteAdapter.java | 5 + .../android/adapter/TagAdapter.java | 5 + .../android/fragment/OverviewFragment.java | 131 +++++++++++++----- .../android/fragment/TagListFragment.java | 75 +++++++--- app/src/main/res/layout/fragment_overview.xml | 9 +- app/src/main/res/layout/fragment_tag_list.xml | 6 +- app/src/main/res/values-ru/strings.xml | 4 +- app/src/main/res/values/strings.xml | 4 +- 14 files changed, 227 insertions(+), 72 deletions(-) delete mode 100644 .idea/scopes/scope_settings.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 96cc43e..9a8b7e5 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,6 +1,7 @@ + + + + + + + + + + + + Abstraction issues + + + + + + + + + + + + + + + + + + + + + + 1.8 + + + + + + + \ No newline at end of file diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml deleted file mode 100644 index 922003b..0000000 --- a/.idea/scopes/scope_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 35eb1dd..6564d52 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/app/app.iml b/app/app.iml index 3060132..e5d6fa6 100644 --- a/app/app.iml +++ b/app/app.iml @@ -76,6 +76,7 @@ + @@ -84,7 +85,6 @@ - @@ -100,13 +100,14 @@ - + + diff --git a/app/build.gradle b/app/build.gradle index e3ed6fa..9ddbb5f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -40,6 +40,7 @@ dependencies { compile 'com.android.support:recyclerview-v7:23.1.1' compile 'com.android.support:cardview-v7:23.1.1' compile 'jp.wasabeef:richeditor-android:1.0.0' + compile 'com.android.support:design:23.1.1' // Add dependency for UI test androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1' diff --git a/app/src/main/java/org/kore/kolabnotes/android/adapter/NoteAdapter.java b/app/src/main/java/org/kore/kolabnotes/android/adapter/NoteAdapter.java index 6d1c48c..d507086 100755 --- a/app/src/main/java/org/kore/kolabnotes/android/adapter/NoteAdapter.java +++ b/app/src/main/java/org/kore/kolabnotes/android/adapter/NoteAdapter.java @@ -58,6 +58,11 @@ public void clearNotes() { } } + public void deleteNotes(List notes) { + this.notes.removeAll(notes); + this.notifyDataSetChanged(); + } + public void addNotes(List notes) { this.notes.addAll(notes); Collections.sort(this.notes, new NoteSortingComparator(Utils.getNoteSorting(context))); diff --git a/app/src/main/java/org/kore/kolabnotes/android/adapter/TagAdapter.java b/app/src/main/java/org/kore/kolabnotes/android/adapter/TagAdapter.java index ed607f3..cccdf69 100644 --- a/app/src/main/java/org/kore/kolabnotes/android/adapter/TagAdapter.java +++ b/app/src/main/java/org/kore/kolabnotes/android/adapter/TagAdapter.java @@ -91,6 +91,11 @@ public void clearTags() { } } + public void deleteTags(List tags) { + this.tags.removeAll(tags); + this.notifyDataSetChanged(); + } + public void addTags(List tags) { this.tags.addAll(tags); Collections.sort(this.tags); diff --git a/app/src/main/java/org/kore/kolabnotes/android/fragment/OverviewFragment.java b/app/src/main/java/org/kore/kolabnotes/android/fragment/OverviewFragment.java index 5c91c25..e74fe82 100644 --- a/app/src/main/java/org/kore/kolabnotes/android/fragment/OverviewFragment.java +++ b/app/src/main/java/org/kore/kolabnotes/android/fragment/OverviewFragment.java @@ -17,6 +17,8 @@ import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.design.widget.FloatingActionButton; +import android.support.design.widget.Snackbar; import android.support.v4.content.ContextCompat; import android.support.v4.view.MenuItemCompat; import android.support.v4.widget.SwipeRefreshLayout; @@ -68,6 +70,7 @@ import org.kore.kolabnotes.android.content.ActiveAccount; import org.kore.kolabnotes.android.content.ActiveAccountRepository; import org.kore.kolabnotes.android.content.NoteRepository; +import org.kore.kolabnotes.android.content.NoteSorting; import org.kore.kolabnotes.android.content.NoteTagRepository; import org.kore.kolabnotes.android.content.NotebookRepository; import org.kore.kolabnotes.android.content.TagRepository; @@ -104,12 +107,13 @@ public class OverviewFragment extends Fragment implements /*NoteAdapter.NoteSele private NoteAdapter mAdapter; - private ImageButton mFabButton; + private FloatingActionButton mFabButton; private RecyclerView mRecyclerView; private TextView mEmptyView; private SwipeRefreshLayout mSwipeRefreshLayout; private SearchView mSearchView; private String mSearchKeyWord; + private Snackbar mSnackbarDelete; private ActionMode mActionMode; private ActionModeCallback mActionModeCallback = new ActionModeCallback(); @@ -232,7 +236,7 @@ public void onActivityCreated(Bundle savedInstanceState) { mAccountManager = AccountManager.get(activity); // Fab Button - mFabButton = (ImageButton) getActivity().findViewById(R.id.fab_button); + mFabButton = (FloatingActionButton) getActivity().findViewById(R.id.fab_button); //mFabButton.setImageDrawable(new IconicsDrawable(this, FontAwesome.Icon.faw_upload).color(Color.WHITE).actionBarSize()); Utils.configureFab(mFabButton); mFabButton.setOnClickListener(new CreateButtonListener()); @@ -306,6 +310,15 @@ public void run() { setListState(); } + @Override + public void onPause() { + super.onPause(); + + if (mSnackbarDelete != null) { + mSnackbarDelete.dismiss(); + } + } + @Override public void onSaveInstanceState(Bundle outState) { outState.putIntegerArrayList(TAG_SELECTABLE_ADAPTER, mAdapter.getSelectedItems()); @@ -463,40 +476,92 @@ void deleteNotes(final List items) { final String account = activeAccountRepository.getActiveAccount().getAccount(); final String rootFolder = activeAccountRepository.getActiveAccount().getRootFolder(); - AlertDialog.Builder builder = new AlertDialog.Builder(activity); +// AlertDialog.Builder builder = new AlertDialog.Builder(activity); +// +// builder.setTitle(R.string.dialog_delete_notes); +// builder.setMessage(R.string.dialog_question_delete_notes); +// builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { +// @Override +// public void onClick(DialogInterface dialog, int which) { +// for (int position : items) { +// final String uid = mSelectedNotes.get(position); +// final Note note = notesRepository.getByUID(account, rootFolder, uid); +// +// if (note != null) { +// Notebook book = checkModificationPermissionInCurrentBook(account, rootFolder, uid); +// if (book == null) continue; +// notesRepository.delete(account, rootFolder, note); +// } +// } +// mSelectedNotes.clear(); +// Utils.setSelectedTagName(activity,null); +// Utils.setSelectedNotebookName(activity, null); +// reloadData(); +// if (tabletMode) { +// displayBlankFragment(); +// } +// } +// }); +// +// builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { +// @Override +// public void onClick(DialogInterface dialog, int which) { +// //nothing +// } +// }); +// builder.show(); + + final ArrayList notes = new ArrayList(); + for (int position : items) { + final String uid = mSelectedNotes.get(position); + final Note note = notesRepository.getByUID(account, rootFolder, uid); + notes.add(note); + } + mAdapter.deleteNotes(notes); + setListState(); + mSelectedNotes.clear(); - builder.setTitle(R.string.dialog_delete_notes); - builder.setMessage(R.string.dialog_question_delete_notes); - builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - for (int position : items) { - final String uid = mSelectedNotes.get(position); - final Note note = notesRepository.getByUID(account, rootFolder, uid); - - if (note != null) { - Notebook book = checkModificationPermissionInCurrentBook(account, rootFolder, uid); - if (book == null) continue; - notesRepository.delete(account, rootFolder, note); + if (mSnackbarDelete != null) { + mSnackbarDelete.dismiss(); + } + + mSnackbarDelete = Snackbar.make(activity.findViewById(R.id.coordinator_overview), R.string.snackbar_delete_message, Snackbar.LENGTH_LONG) + .setCallback(new Snackbar.Callback() { + @Override + public void onDismissed(Snackbar snackbar, int event) { + switch(event) { + /* If undo button pressed */ + case Snackbar.Callback.DISMISS_EVENT_ACTION: + mAdapter.clearNotes(); + mAdapter.addNotes(notesRepository.getAll(account, rootFolder, Utils.getNoteSorting(getActivity()))); + setListState(); + break; + default: + for (Note note : notes) { + if (note != null) { + Notebook book = checkModificationPermissionInCurrentBook(account, rootFolder, + note.getIdentification().getUid()); + if (book == null) continue; + notesRepository.delete(account, rootFolder, note); + } + } + reloadData(); + Utils.setSelectedTagName(activity,null); + Utils.setSelectedNotebookName(activity, null); + if (tabletMode) { + displayBlankFragment(); + } + break; + } } - } - mSelectedNotes.clear(); - Utils.setSelectedTagName(activity,null); - Utils.setSelectedNotebookName(activity, null); - reloadData(); - if (tabletMode) { - displayBlankFragment(); - } - } - }); + }).setAction(R.string.snackbar_undo_delete, new View.OnClickListener() { + @Override + public void onClick(View v) { + /* Nothing */ + } + }); - builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - //nothing - } - }); - builder.show(); + mSnackbarDelete.show(); } } diff --git a/app/src/main/java/org/kore/kolabnotes/android/fragment/TagListFragment.java b/app/src/main/java/org/kore/kolabnotes/android/fragment/TagListFragment.java index bf7c024..f119775 100644 --- a/app/src/main/java/org/kore/kolabnotes/android/fragment/TagListFragment.java +++ b/app/src/main/java/org/kore/kolabnotes/android/fragment/TagListFragment.java @@ -8,6 +8,8 @@ import android.graphics.Color; import android.os.Build; import android.os.Bundle; +import android.support.design.widget.FloatingActionButton; +import android.support.design.widget.Snackbar; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; @@ -21,7 +23,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.EditText; -import android.widget.ImageButton; import android.widget.TextView; import org.kore.kolab.notes.Colors; @@ -42,6 +43,11 @@ /** * Created by yaroslav on 09.01.16. */ + +/** + * Fragment which displays, edits and deletes tags + */ + public class TagListFragment extends Fragment implements TagAdapter.ViewHolder.ClickListener{ private static final String TAG_ACTION_MODE = "ActionMode"; @@ -52,7 +58,8 @@ public class TagListFragment extends Fragment implements TagAdapter.ViewHolder.C private Toolbar toolbar; private RecyclerView mRecyclerView; private TextView mEmptyView; - private ImageButton mAddTagButton; + private FloatingActionButton mAddTagButton; + private Snackbar mSnackbarDelete; private TagRepository tagRepository; private ActiveAccountRepository activeAccountRepository; @@ -101,7 +108,7 @@ public void onActivityCreated(Bundle savedInstanceState) { } setHasOptionsMenu(true); - mAddTagButton = (ImageButton) getActivity().findViewById(R.id.addTagButton); + mAddTagButton = (FloatingActionButton) getActivity().findViewById(R.id.addTagButton); mAddTagButton.setOnClickListener(new CreateButtonListener()); mRecyclerView = (RecyclerView) activity.findViewById(R.id.listTag); @@ -127,6 +134,15 @@ public void onActivityCreated(Bundle savedInstanceState) { } } + @Override + public void onPause() { + super.onPause(); + + if (mSnackbarDelete != null) { + mSnackbarDelete.dismiss(); + } + } + @Override public void onSaveInstanceState(Bundle outState) { outState.putIntegerArrayList(TAG_SELECTABLE_ADAPTER, mAdapter.getSelectedItems()); @@ -282,32 +298,49 @@ void deleteTags(final List items) { final String account = activeAccountRepository.getActiveAccount().getAccount(); final String rootFolder = activeAccountRepository.getActiveAccount().getRootFolder(); - AlertDialog.Builder builder = new AlertDialog.Builder(activity); + final ArrayList tags = new ArrayList(); + for (int position : items) { + final String uid = mSelectedTags.get(position); + final Tag tag = tagRepository.getTagWithUID(account, rootFolder, uid); + tags.add(tag); + } + mAdapter.deleteTags(tags); + setListState(); + mSelectedTags.clear(); + + if (mSnackbarDelete != null) { + mSnackbarDelete.dismiss(); + } - builder.setTitle(R.string.dialog_delete_tags); - builder.setMessage(R.string.dialog_question_delete_tags); - builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { + mSnackbarDelete = Snackbar.make(activity.findViewById(R.id.tag_list_fragment), R.string.snackbar_delete_message, Snackbar.LENGTH_LONG) + .setCallback(new Snackbar.Callback() { @Override - public void onClick(DialogInterface dialog, int which) { - for (int position : items) { - final String uid = mSelectedTags.get(position); - final Tag tag = tagRepository.getTagWithUID(account, rootFolder, uid); - if (tag != null) { - tagRepository.delete(account, rootFolder, tag); - } + public void onDismissed(Snackbar snackbar, int event) { + switch(event) { + /* If undo button pressed */ + case Snackbar.Callback.DISMISS_EVENT_ACTION: + mAdapter.clearTags(); + mAdapter.addTags(tagRepository.getAll(account, rootFolder)); + setListState(); + break; + default: + for (Tag tag : tags) { + if (tag != null) { + tagRepository.delete(account, rootFolder, tag); + } + } + reloadData(); + break; } - mSelectedTags.clear(); - reloadData(); } - }); - - builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { + }).setAction(R.string.snackbar_undo_delete, new View.OnClickListener() { @Override - public void onClick(DialogInterface dialog, int which) { + public void onClick(View v) { /* Nothing */ } }); - builder.show(); + + mSnackbarDelete.show(); } } diff --git a/app/src/main/res/layout/fragment_overview.xml b/app/src/main/res/layout/fragment_overview.xml index e4de47d..fa80a97 100644 --- a/app/src/main/res/layout/fragment_overview.xml +++ b/app/src/main/res/layout/fragment_overview.xml @@ -10,9 +10,10 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - + android:layout_height="match_parent" + android:id="@+id/coordinator_overview"> - - + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_tag_list.xml b/app/src/main/res/layout/fragment_tag_list.xml index c3c6619..faeb66a 100644 --- a/app/src/main/res/layout/fragment_tag_list.xml +++ b/app/src/main/res/layout/fragment_tag_list.xml @@ -1,4 +1,4 @@ - @@ -17,7 +17,7 @@ android:gravity="center" android:visibility="gone" android:text="@string/no_tags" /> - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 5a426f5..9d5f511 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -140,6 +140,8 @@ Нет прав на запись в выбранном блокноте Нет прав редактировать в выбранном блокноте Нет прав для создания в выбранном блокноте + Удалено + Отменить Последняя измененная заметка @@ -159,10 +161,10 @@ Удалить метки Вы действительно хотите удалить выбранные метки?\n\nПредупреждение: удаление метки может влиять на другие объекты групповой работы. Предупреждение: изменение метки может влиять на другие объекты групповой работы. + Изменить метку Нет меток Нет заметок - Изменить тэг diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fd91654..9476c0a 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -126,6 +126,8 @@ Attach link No permission for folder Settings + Deleted + Undo Move @@ -175,10 +177,10 @@ Delete Tags Do you really want to delete selected tags?\n\nWarning: deleting a tag will maybe affect other groupware objects. Warning: changing a tag will maybe affect other groupware objects + Change tagname No tags No notes - Change tagname From 3aa3c8ac787e41733b64d26662050c9b8c380dc2 Mon Sep 17 00:00:00 2001 From: proninyaroslav Date: Wed, 10 Feb 2016 19:25:41 +0300 Subject: [PATCH 2/2] Option to cancel the removal of tags/notes --- .../android/fragment/OverviewFragment.java | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/app/src/main/java/org/kore/kolabnotes/android/fragment/OverviewFragment.java b/app/src/main/java/org/kore/kolabnotes/android/fragment/OverviewFragment.java index e74fe82..be180b8 100644 --- a/app/src/main/java/org/kore/kolabnotes/android/fragment/OverviewFragment.java +++ b/app/src/main/java/org/kore/kolabnotes/android/fragment/OverviewFragment.java @@ -476,41 +476,6 @@ void deleteNotes(final List items) { final String account = activeAccountRepository.getActiveAccount().getAccount(); final String rootFolder = activeAccountRepository.getActiveAccount().getRootFolder(); -// AlertDialog.Builder builder = new AlertDialog.Builder(activity); -// -// builder.setTitle(R.string.dialog_delete_notes); -// builder.setMessage(R.string.dialog_question_delete_notes); -// builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { -// @Override -// public void onClick(DialogInterface dialog, int which) { -// for (int position : items) { -// final String uid = mSelectedNotes.get(position); -// final Note note = notesRepository.getByUID(account, rootFolder, uid); -// -// if (note != null) { -// Notebook book = checkModificationPermissionInCurrentBook(account, rootFolder, uid); -// if (book == null) continue; -// notesRepository.delete(account, rootFolder, note); -// } -// } -// mSelectedNotes.clear(); -// Utils.setSelectedTagName(activity,null); -// Utils.setSelectedNotebookName(activity, null); -// reloadData(); -// if (tabletMode) { -// displayBlankFragment(); -// } -// } -// }); -// -// builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { -// @Override -// public void onClick(DialogInterface dialog, int which) { -// //nothing -// } -// }); -// builder.show(); - final ArrayList notes = new ArrayList(); for (int position : items) { final String uid = mSelectedNotes.get(position);