aboutsummaryrefslogtreecommitdiffstats
path: root/app/src/main/java/com/zeapo/pwdstore/utils
diff options
context:
space:
mode:
authorDaniël van den Berg <danielvandenberg95@gmail.com>2016-09-09 11:47:49 +0200
committerMohamed Zenadi <zeapo@users.noreply.github.com>2016-09-09 11:47:49 +0200
commita6da17417eed1412dfbd9c06d03d85f100d35608 (patch)
treedfa093c2c2b0df651be55420bf6b0a903b605ece /app/src/main/java/com/zeapo/pwdstore/utils
parent86083f03f5a60074cddb7496bff157b31ce8c2a3 (diff)
downloadHardenedPass-a6da17417eed1412dfbd9c06d03d85f100d35608.tar.gz
HardenedPass-a6da17417eed1412dfbd9c06d03d85f100d35608.zip
Added the ability to move passwords around. (#210)
* Added the ability to move passwords around. * Generified the PasswordRecyclerAdapter and the FolderRecyclerAdapter into EntryRecyclerAdapter
Diffstat (limited to 'app/src/main/java/com/zeapo/pwdstore/utils')
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/utils/EntryRecyclerAdapter.java162
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/utils/FolderRecyclerAdapter.java31
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/utils/PasswordRecyclerAdapter.java184
3 files changed, 228 insertions, 149 deletions
diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/EntryRecyclerAdapter.java b/app/src/main/java/com/zeapo/pwdstore/utils/EntryRecyclerAdapter.java
new file mode 100644
index 00000000..78b81928
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/utils/EntryRecyclerAdapter.java
@@ -0,0 +1,162 @@
+package com.zeapo.pwdstore.utils;
+
+import android.app.Activity;
+import android.graphics.Color;
+import android.support.annotation.NonNull;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.zeapo.pwdstore.R;
+
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.TreeSet;
+
+public abstract class EntryRecyclerAdapter extends RecyclerView.Adapter<EntryRecyclerAdapter.ViewHolder> {
+ private final Activity activity;
+ protected final ArrayList<PasswordItem> values;
+ protected final Set<Integer> selectedItems = new TreeSet<>();
+
+ public EntryRecyclerAdapter(Activity activity, ArrayList<PasswordItem> values) {
+ this.activity = activity;
+ this.values = values;
+ }
+
+ // Return the size of your dataset (invoked by the layout manager)
+ @Override
+ public int getItemCount() {
+ return values.size();
+ }
+
+ public ArrayList<PasswordItem> getValues() {
+ return this.values;
+ }
+
+ public void clear() {
+ this.values.clear();
+ this.notifyDataSetChanged();
+ }
+
+ public void addAll(ArrayList<PasswordItem> list) {
+ this.values.addAll(list);
+ this.notifyDataSetChanged();
+ }
+
+ public void add(PasswordItem item) {
+ this.values.add(item);
+ this.notifyItemInserted(getItemCount());
+ }
+
+ public void toggleSelection(int position) {
+ if (!selectedItems.remove(position)) {
+ selectedItems.add(position);
+ }
+ }
+
+ // use this after an item is removed to update the positions of items in set
+ // that followed the removed position
+ public void updateSelectedItems(int position, Set<Integer> selectedItems) {
+ Set<Integer> temp = new TreeSet<>();
+ for (int selected : selectedItems) {
+ if (selected > position) {
+ temp.add(selected - 1);
+ } else {
+ temp.add(selected);
+ }
+ }
+ selectedItems.clear();
+ selectedItems.addAll(temp);
+ }
+
+ public void remove(int position) {
+ this.values.remove(position);
+ this.notifyItemRemoved(position);
+
+ // keep selectedItems updated so we know what to notifyItemChanged
+ // (instead of just using notifyDataSetChanged)
+ updateSelectedItems(position, selectedItems);
+ }
+
+ @NonNull
+ protected View.OnLongClickListener getOnLongClickListener(ViewHolder holder, PasswordItem pass) {
+ return new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ return false;
+ }
+ };
+ }
+
+ // Replace the contents of a view (invoked by the layout manager)
+ @Override
+ public void onBindViewHolder(final ViewHolder holder, int position) {
+ final PasswordItem pass = getValues().get(position);
+ holder.name.setText(pass.toString());
+ if (pass.getType() == PasswordItem.TYPE_CATEGORY) {
+ holder.typeImage.setImageResource(R.drawable.ic_folder_grey600_24dp);
+ holder.name.setText(pass.toString() + "/");
+ } else {
+ holder.typeImage.setImageResource(R.drawable.ic_action_secure);
+ holder.name.setText(pass.toString());
+ }
+
+ holder.type.setText(pass.getFullPathName());
+ if (pass.getType() == PasswordItem.TYPE_CATEGORY) {
+// holder.card.setCardBackgroundColor(activity.getResources().getColor(R.color.blue_grey_200));
+ } else {
+// holder.card.setCardBackgroundColor(activity.getResources().getColor(R.color.blue_grey_50));
+ }
+
+ holder.view.setOnClickListener(getOnClickListener(holder, pass));
+
+ holder.view.setOnLongClickListener(getOnLongClickListener(holder, pass));
+
+ // after removal, everything is rebound for some reason; views are shuffled?
+ boolean selected = selectedItems.contains(position);
+ holder.view.setSelected(selected);
+ if (selected) {
+ holder.itemView.setBackgroundResource(R.color.deep_orange_200);
+ holder.type.setTextColor(Color.BLACK);
+ } else {
+ holder.itemView.setBackgroundResource(Color.alpha(1));
+ holder.type.setTextColor(ContextCompat.getColor(activity, R.color.grey_500));
+ }
+ }
+
+ @NonNull
+ protected abstract View.OnClickListener getOnClickListener(ViewHolder holder, PasswordItem pass);
+
+ // Provide a reference to the views for each data item
+ // Complex data items may need more than one view per item, and
+ // you provide access to all the views for a data item in a view holder
+ public static class ViewHolder extends RecyclerView.ViewHolder {
+ // each data item is just a string in this case
+ public View view;
+ public TextView name;
+ public TextView type;
+ public ImageView typeImage;
+
+ public ViewHolder(View v) {
+ super(v);
+ view = v;
+ name = (TextView) view.findViewById(R.id.label);
+ type = (TextView) view.findViewById(R.id.type);
+ typeImage = (ImageView) view.findViewById(R.id.type_image);
+ }
+ }
+
+ // Create new views (invoked by the layout manager)
+ @Override
+ public PasswordRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
+ int viewType) {
+ // create a new view
+ View v = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.password_row_layout, parent, false);
+ return new ViewHolder(v);
+ }
+}
diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/FolderRecyclerAdapter.java b/app/src/main/java/com/zeapo/pwdstore/utils/FolderRecyclerAdapter.java
new file mode 100644
index 00000000..04b243e1
--- /dev/null
+++ b/app/src/main/java/com/zeapo/pwdstore/utils/FolderRecyclerAdapter.java
@@ -0,0 +1,31 @@
+package com.zeapo.pwdstore.utils;
+
+import android.support.annotation.NonNull;
+import android.view.View;
+
+import com.zeapo.pwdstore.SelectFolderFragment;
+import com.zeapo.pwdstore.crypto.PgpHandler;
+
+import java.util.ArrayList;
+
+public class FolderRecyclerAdapter extends EntryRecyclerAdapter {
+ private final SelectFolderFragment.OnFragmentInteractionListener listener;
+
+ // Provide a suitable constructor (depends on the kind of dataset)
+ public FolderRecyclerAdapter(PgpHandler activity, SelectFolderFragment.OnFragmentInteractionListener listener, ArrayList<PasswordItem> values) {
+ super(activity, values);
+ this.listener = listener;
+ }
+
+ @NonNull
+ protected View.OnClickListener getOnClickListener(final ViewHolder holder, final PasswordItem pass) {
+ return new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ listener.onFragmentInteraction(pass);
+ notifyItemChanged(holder.getAdapterPosition());
+ }
+ };
+ }
+
+}
diff --git a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRecyclerAdapter.java b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRecyclerAdapter.java
index 0835425a..a4446198 100644
--- a/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRecyclerAdapter.java
+++ b/app/src/main/java/com/zeapo/pwdstore/utils/PasswordRecyclerAdapter.java
@@ -1,17 +1,10 @@
package com.zeapo.pwdstore.utils;
-import android.graphics.Color;
-import android.os.Build;
-import android.support.v4.content.ContextCompat;
+import android.support.annotation.NonNull;
import android.support.v7.view.ActionMode;
-import android.support.v7.widget.RecyclerView;
-import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
import com.zeapo.pwdstore.PasswordFragment;
import com.zeapo.pwdstore.PasswordStore;
@@ -19,76 +12,46 @@ import com.zeapo.pwdstore.R;
import java.util.ArrayList;
import java.util.Iterator;
-import java.util.Set;
import java.util.TreeSet;
-public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecyclerAdapter.ViewHolder> {
+public class PasswordRecyclerAdapter extends EntryRecyclerAdapter {
private final PasswordStore activity;
- private final ArrayList<PasswordItem> values;
private final PasswordFragment.OnFragmentInteractionListener listener;
- private final Set<Integer> selectedItems;
private ActionMode mActionMode;
private Boolean canEdit;
- // Provide a reference to the views for each data item
- // Complex data items may need more than one view per item, and
- // you provide access to all the views for a data item in a view holder
- public static class ViewHolder extends RecyclerView.ViewHolder {
- // each data item is just a string in this case
- public View view;
- public TextView name;
- public TextView type;
- public ImageView typeImage;
-
- public ViewHolder(View v) {
- super(v);
- view = v;
- name = (TextView) view.findViewById(R.id.label);
- type = (TextView) view.findViewById(R.id.type);
- typeImage = (ImageView) view.findViewById(R.id.type_image);
- }
- }
-
// Provide a suitable constructor (depends on the kind of dataset)
public PasswordRecyclerAdapter(PasswordStore activity, PasswordFragment.OnFragmentInteractionListener listener, ArrayList<PasswordItem> values) {
- this.values = values;
+ super(activity, values);
this.activity = activity;
this.listener = listener;
- selectedItems = new TreeSet<>();
}
- // Create new views (invoked by the layout manager)
@Override
- public PasswordRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
- int viewType) {
- // create a new view
- View v = LayoutInflater.from(parent.getContext())
- .inflate(R.layout.password_row_layout, parent, false);
- return new ViewHolder(v);
+ @NonNull
+ protected View.OnLongClickListener getOnLongClickListener(final ViewHolder holder, final PasswordItem pass) {
+ return new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ if (mActionMode != null) {
+ return false;
+ }
+ toggleSelection(holder.getAdapterPosition());
+ canEdit = pass.getType() == PasswordItem.TYPE_PASSWORD;
+ // Start the CAB using the ActionMode.Callback
+ mActionMode = activity.startSupportActionMode(mActionModeCallback);
+ mActionMode.setTitle("" + selectedItems.size());
+ mActionMode.invalidate();
+ notifyItemChanged(holder.getAdapterPosition());
+ return true;
+ }
+ };
}
- // Replace the contents of a view (invoked by the layout manager)
@Override
- public void onBindViewHolder(final ViewHolder holder, int position) {
- final PasswordItem pass = values.get(position);
- holder.name.setText(pass.toString());
- if (pass.getType() == PasswordItem.TYPE_CATEGORY) {
- holder.typeImage.setImageResource(R.drawable.ic_folder_grey600_24dp);
- holder.name.setText(pass.toString() + "/");
- } else {
- holder.typeImage.setImageResource(R.drawable.ic_action_secure);
- holder.name.setText(pass.toString());
- }
- int sdk = Build.VERSION.SDK_INT;
-
- holder.type.setText(pass.getFullPathName());
- if (pass.getType() == PasswordItem.TYPE_CATEGORY) {
-// holder.card.setCardBackgroundColor(activity.getResources().getColor(R.color.blue_grey_200));
- } else {
-// holder.card.setCardBackgroundColor(activity.getResources().getColor(R.color.blue_grey_50));
- }
-
- holder.view.setOnClickListener(new View.OnClickListener() {
+ @NonNull
+ protected View.OnClickListener getOnClickListener(final ViewHolder holder, final PasswordItem pass) {
+ return new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mActionMode != null) {
@@ -97,7 +60,7 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
if (selectedItems.isEmpty()) {
mActionMode.finish();
} else if (selectedItems.size() == 1 && !canEdit) {
- if (values.get(selectedItems.iterator().next()).getType() == PasswordItem.TYPE_PASSWORD) {
+ if (getValues().get(selectedItems.iterator().next()).getType() == PasswordItem.TYPE_PASSWORD) {
canEdit = true;
mActionMode.invalidate();
}
@@ -110,35 +73,7 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
}
notifyItemChanged(holder.getAdapterPosition());
}
- });
-
- holder.view.setOnLongClickListener(new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(View v) {
- if (mActionMode != null) {
- return false;
- }
- toggleSelection(holder.getAdapterPosition());
- canEdit = pass.getType() == PasswordItem.TYPE_PASSWORD;
- // Start the CAB using the ActionMode.Callback
- mActionMode = activity.startSupportActionMode(mActionModeCallback);
- mActionMode.setTitle("" + selectedItems.size());
- mActionMode.invalidate();
- notifyItemChanged(holder.getAdapterPosition());
- return true;
- }
- });
-
- // after removal, everything is rebound for some reason; views are shuffled?
- boolean selected = selectedItems.contains(position);
- holder.view.setSelected(selected);
- if (selected) {
- holder.itemView.setBackgroundResource(R.color.deep_orange_200);
- holder.type.setTextColor(Color.BLACK);
- } else {
- holder.itemView.setBackgroundResource(Color.alpha(1));
- holder.type.setTextColor(ContextCompat.getColor(activity, R.color.grey_500));
- }
+ };
}
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
@@ -172,9 +107,15 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
mode.finish(); // Action picked, so close the CAB
return true;
case R.id.menu_edit_password:
- activity.editPassword(values.get(selectedItems.iterator().next()));
+ activity.editPassword(getValues().get(selectedItems.iterator().next()));
mode.finish();
return true;
+ case R.id.menu_move_password:
+ ArrayList<PasswordItem> selectedPasswords = new ArrayList<>();
+ for (Integer id : selectedItems) {
+ selectedPasswords.add(getValues().get(id));
+ }
+ activity.movePasswords(selectedPasswords);
default:
return false;
}
@@ -183,67 +124,12 @@ public class PasswordRecyclerAdapter extends RecyclerView.Adapter<PasswordRecycl
// Called when the user exits the action mode
@Override
public void onDestroyActionMode(ActionMode mode) {
- for (Iterator it = selectedItems.iterator(); it.hasNext();) {
+ for (Iterator<Integer> it = selectedItems.iterator(); it.hasNext(); ) {
// need the setSelected line in onBind
- notifyItemChanged((Integer) it.next());
+ notifyItemChanged(it.next());
it.remove();
}
mActionMode = null;
}
};
-
- // Return the size of your dataset (invoked by the layout manager)
- @Override
- public int getItemCount() {
- return values.size();
- }
-
- public ArrayList<PasswordItem> getValues() {
- return this.values;
- }
-
- public void clear() {
- this.values.clear();
- this.notifyDataSetChanged();
- }
-
- public void addAll(ArrayList<PasswordItem> list) {
- this.values.addAll(list);
- this.notifyDataSetChanged();
- }
-
- public void add(PasswordItem item) {
- this.values.add(item);
- this.notifyItemInserted(values.size());
- }
-
- public void remove(int position) {
- this.values.remove(position);
- this.notifyItemRemoved(position);
-
- // keep selectedItems updated so we know what to notifyItemChanged
- // (instead of just using notifyDataSetChanged)
- updateSelectedItems(position, selectedItems);
- }
-
- public void toggleSelection(int position) {
- if (!selectedItems.remove(position)) {
- selectedItems.add(position);
- }
- }
-
- // use this after an item is removed to update the positions of items in set
- // that followed the removed position
- public void updateSelectedItems(int position, Set<Integer> selectedItems) {
- Set<Integer> temp = new TreeSet<>();
- for (int selected : selectedItems) {
- if (selected > position) {
- temp.add(selected - 1);
- } else {
- temp.add(selected);
- }
- }
- selectedItems.clear();
- selectedItems.addAll(temp);
- }
}