Add ascending sort

This commit is contained in:
J-Jamet
2018-02-24 21:10:12 +01:00
parent 0ddd08bf6d
commit 0650a6f7db
11 changed files with 133 additions and 25 deletions

View File

@@ -147,17 +147,16 @@ public abstract class ListNodesActivity extends LockCloseListActivity
} }
@Override @Override
public void onSortSelected(SortNodeEnum sortNodeEnum, boolean groupsBefore) { public void onSortSelected(SortNodeEnum sortNodeEnum, boolean ascending, boolean groupsBefore) {
// Toggle setting // Toggle setting
String sortKey = getString(R.string.sort_node_key);
String groupsBeforeKey = getString(R.string.sort_group_before_key);
Editor editor = prefs.edit(); Editor editor = prefs.edit();
editor.putString(sortKey, sortNodeEnum.name()); editor.putString(getString(R.string.sort_node_key), sortNodeEnum.name());
editor.putBoolean(groupsBeforeKey, groupsBefore); editor.putBoolean(getString(R.string.sort_ascending_key), ascending);
editor.putBoolean(getString(R.string.sort_group_before_key), groupsBefore);
EditorCompat.apply(editor); EditorCompat.apply(editor);
// Tell the adapter to refresh it's list // Tell the adapter to refresh it's list
mAdapter.notifyChangeSort(sortNodeEnum, groupsBefore); mAdapter.notifyChangeSort(sortNodeEnum, ascending, groupsBefore);
mAdapter.rebuildList(mCurrentGroup); mAdapter.rebuildList(mCurrentGroup);
} }
@@ -169,6 +168,7 @@ public abstract class ListNodesActivity extends LockCloseListActivity
SortDialogFragment sortDialogFragment = SortDialogFragment sortDialogFragment =
SortDialogFragment.getInstance( SortDialogFragment.getInstance(
PrefsUtil.getListSort(this), PrefsUtil.getListSort(this),
PrefsUtil.getAscendingSort(this),
PrefsUtil.getGroupsBeforeSort(this)); PrefsUtil.getGroupsBeforeSort(this));
sortDialogFragment.show(getSupportFragmentManager(), "sortDialog"); sortDialogFragment.show(getSupportFragmentManager(), "sortDialog");
return true; return true;

View File

@@ -48,6 +48,7 @@ public class NodeAdapter extends RecyclerView.Adapter<BasicViewHolder> {
private float textSize; private float textSize;
private SortNodeEnum listSort; private SortNodeEnum listSort;
private boolean groupsBeforeSort; private boolean groupsBeforeSort;
private boolean ascendingSort;
private OnNodeClickCallback onNodeClickCallback; private OnNodeClickCallback onNodeClickCallback;
private int nodePositionToUpdate; private int nodePositionToUpdate;
@@ -75,12 +76,13 @@ public class NodeAdapter extends RecyclerView.Adapter<BasicViewHolder> {
this.textSize = PrefsUtil.getListTextSize(context); this.textSize = PrefsUtil.getListTextSize(context);
this.listSort = PrefsUtil.getListSort(context); this.listSort = PrefsUtil.getListSort(context);
this.groupsBeforeSort = PrefsUtil.getGroupsBeforeSort(context); this.groupsBeforeSort = PrefsUtil.getGroupsBeforeSort(context);
this.ascendingSort = PrefsUtil.getAscendingSort(context);
this.activateContextMenu = activateContextMenu; this.activateContextMenu = activateContextMenu;
this.nodePositionToUpdate = -1; this.nodePositionToUpdate = -1;
this.nodeSortedList = new SortedList<>(PwNode.class, new SortedListAdapterCallback<PwNode>(this) { this.nodeSortedList = new SortedList<>(PwNode.class, new SortedListAdapterCallback<PwNode>(this) {
@Override public int compare(PwNode item1, PwNode item2) { @Override public int compare(PwNode item1, PwNode item2) {
return listSort.getNodeComparator(groupsBeforeSort).compare(item1, item2); return listSort.getNodeComparator(ascendingSort, groupsBeforeSort).compare(item1, item2);
} }
@Override public boolean areContentsTheSame(PwNode oldItem, PwNode newItem) { @Override public boolean areContentsTheSame(PwNode oldItem, PwNode newItem) {
@@ -151,8 +153,9 @@ public class NodeAdapter extends RecyclerView.Adapter<BasicViewHolder> {
/** /**
* Notify a change sort of the list * Notify a change sort of the list
*/ */
public void notifyChangeSort(SortNodeEnum sortNodeEnum, boolean groupsBefore) { public void notifyChangeSort(SortNodeEnum sortNodeEnum, boolean ascending, boolean groupsBefore) {
this.listSort = sortNodeEnum; this.listSort = sortNodeEnum;
this.ascendingSort = ascending;
this.groupsBeforeSort = groupsBefore; this.groupsBeforeSort = groupsBefore;
} }

View File

@@ -227,6 +227,17 @@ public abstract class PwEntry extends PwNode implements Cloneable {
* Comparator of Entry by Name * Comparator of Entry by Name
*/ */
public static class EntryNameComparator implements Comparator<PwEntry> { public static class EntryNameComparator implements Comparator<PwEntry> {
private boolean ascending;
public EntryNameComparator() {
this(true);
}
public EntryNameComparator(boolean ascending) {
this.ascending = ascending;
}
public int compare(PwEntry object1, PwEntry object2) { public int compare(PwEntry object1, PwEntry object2) {
if (object1.equals(object2)) if (object1.equals(object2))
return 0; return 0;
@@ -236,6 +247,10 @@ public abstract class PwEntry extends PwNode implements Cloneable {
if (entryTitleComp == 0) { if (entryTitleComp == 0) {
return object1.hashCode() - object2.hashCode(); return object1.hashCode() - object2.hashCode();
} }
// If descending
if (!ascending)
entryTitleComp = -entryTitleComp;
return entryTitleComp; return entryTitleComp;
} }
} }
@@ -244,6 +259,17 @@ public abstract class PwEntry extends PwNode implements Cloneable {
* Comparator of Entry by Creation * Comparator of Entry by Creation
*/ */
public static class EntryCreationComparator implements Comparator<PwEntry> { public static class EntryCreationComparator implements Comparator<PwEntry> {
private boolean ascending;
public EntryCreationComparator() {
this(true);
}
public EntryCreationComparator(boolean ascending) {
this.ascending = ascending;
}
public int compare(PwEntry object1, PwEntry object2) { public int compare(PwEntry object1, PwEntry object2) {
if (object1.equals(object2)) if (object1.equals(object2))
return 0; return 0;
@@ -253,6 +279,10 @@ public abstract class PwEntry extends PwNode implements Cloneable {
if (entryCreationComp == 0) { if (entryCreationComp == 0) {
return object1.hashCode() - object2.hashCode(); return object1.hashCode() - object2.hashCode();
} }
// If descending
if (!ascending)
entryCreationComp = -entryCreationComp;
return entryCreationComp; return entryCreationComp;
} }
} }

View File

@@ -252,6 +252,17 @@ public abstract class PwGroup extends PwNode {
* Group comparator by name * Group comparator by name
*/ */
public static class GroupNameComparator implements Comparator<PwGroup> { public static class GroupNameComparator implements Comparator<PwGroup> {
private boolean ascending;
public GroupNameComparator() {
this(true);
}
public GroupNameComparator(boolean ascending) {
this.ascending = ascending;
}
public int compare(PwGroup object1, PwGroup object2) { public int compare(PwGroup object1, PwGroup object2) {
if (object1.equals(object2)) if (object1.equals(object2))
return 0; return 0;
@@ -261,6 +272,10 @@ public abstract class PwGroup extends PwNode {
if (groupNameComp == 0) { if (groupNameComp == 0) {
return object1.hashCode() - object2.hashCode(); return object1.hashCode() - object2.hashCode();
} }
// If descending
if (!ascending)
groupNameComp = -groupNameComp;
return groupNameComp; return groupNameComp;
} }
} }
@@ -269,6 +284,17 @@ public abstract class PwGroup extends PwNode {
* Group comparator by name * Group comparator by name
*/ */
public static class GroupCreationComparator implements Comparator<PwGroup> { public static class GroupCreationComparator implements Comparator<PwGroup> {
private boolean ascending;
public GroupCreationComparator() {
this(true);
}
public GroupCreationComparator(boolean ascending) {
this.ascending = ascending;
}
public int compare(PwGroup object1, PwGroup object2) { public int compare(PwGroup object1, PwGroup object2) {
if (object1.equals(object2)) if (object1.equals(object2))
return 0; return 0;
@@ -278,6 +304,10 @@ public abstract class PwGroup extends PwNode {
if (groupCreationComp == 0) { if (groupCreationComp == 0) {
return object1.hashCode() - object2.hashCode(); return object1.hashCode() - object2.hashCode();
} }
// If descending
if (!ascending)
groupCreationComp = -groupCreationComp;
return groupCreationComp; return groupCreationComp;
} }
} }

View File

@@ -25,32 +25,38 @@ import java.util.Comparator;
public enum SortNodeEnum { public enum SortNodeEnum {
DB, TITLE, USERNAME, CREATION_TIME, LAST_MODIFY_TIME, LAST_ACCESS_TIME; DB, TITLE, USERNAME, CREATION_TIME, LAST_MODIFY_TIME, LAST_ACCESS_TIME;
public Comparator<PwNode> getNodeComparator(boolean groupsBefore) { public Comparator<PwNode> getNodeComparator(boolean ascending, boolean groupsBefore) {
switch (this) { switch (this) {
case DB: case DB:
return new NodeCreationComparator(groupsBefore); // TODO Sort return new NodeCreationComparator(ascending, groupsBefore); // TODO Sort
default: default:
case TITLE: case TITLE:
return new NodeTitleComparator(groupsBefore); return new NodeTitleComparator(ascending, groupsBefore);
case USERNAME: case USERNAME:
return new NodeCreationComparator(groupsBefore); // TODO Sort return new NodeCreationComparator(ascending, groupsBefore); // TODO Sort
case CREATION_TIME: case CREATION_TIME:
return new NodeCreationComparator(groupsBefore); return new NodeCreationComparator(ascending, groupsBefore);
case LAST_MODIFY_TIME: case LAST_MODIFY_TIME:
return new NodeCreationComparator(groupsBefore); // TODO Sort return new NodeCreationComparator(ascending, groupsBefore); // TODO Sort
case LAST_ACCESS_TIME: case LAST_ACCESS_TIME:
return new NodeCreationComparator(groupsBefore); // TODO Sort return new NodeCreationComparator(ascending, groupsBefore); // TODO Sort
} }
} }
private static abstract class NodeComparator implements Comparator<PwNode> { private static abstract class NodeComparator implements Comparator<PwNode> {
boolean ascending;
boolean groupsBefore; boolean groupsBefore;
NodeComparator() { NodeComparator() {
this.groupsBefore = true; this(true, true);
} }
NodeComparator(boolean groupsBefore) { NodeComparator(boolean groupsBefore) {
this(true, groupsBefore);
}
NodeComparator(boolean ascending, boolean groupsBefore) {
this.ascending = ascending;
this.groupsBefore = groupsBefore; this.groupsBefore = groupsBefore;
} }
} }
@@ -68,13 +74,17 @@ public enum SortNodeEnum {
super(groupsBefore); super(groupsBefore);
} }
public NodeTitleComparator(boolean ascending, boolean groupsBefore) {
super(ascending, groupsBefore);
}
public int compare(PwNode object1, PwNode object2) { public int compare(PwNode object1, PwNode object2) {
if (object1.equals(object2)) if (object1.equals(object2))
return 0; return 0;
if (object1 instanceof PwGroup) { if (object1 instanceof PwGroup) {
if (object2 instanceof PwGroup) { if (object2 instanceof PwGroup) {
return new PwGroup.GroupNameComparator() return new PwGroup.GroupNameComparator(ascending)
.compare((PwGroup) object1, (PwGroup) object2); .compare((PwGroup) object1, (PwGroup) object2);
} else if (object2 instanceof PwEntry) { } else if (object2 instanceof PwEntry) {
if(groupsBefore) if(groupsBefore)
@@ -86,7 +96,7 @@ public enum SortNodeEnum {
} }
} else if (object1 instanceof PwEntry) { } else if (object1 instanceof PwEntry) {
if(object2 instanceof PwEntry) { if(object2 instanceof PwEntry) {
return new PwEntry.EntryNameComparator() return new PwEntry.EntryNameComparator(ascending)
.compare((PwEntry) object1, (PwEntry) object2); .compare((PwEntry) object1, (PwEntry) object2);
} else if (object2 instanceof PwGroup) { } else if (object2 instanceof PwGroup) {
if(groupsBefore) if(groupsBefore)
@@ -119,6 +129,11 @@ public enum SortNodeEnum {
super(groupsBefore); super(groupsBefore);
} }
public NodeCreationComparator(boolean ascending, boolean groupsBefore) {
super(ascending, groupsBefore);
}
@Override @Override
public int compare(PwNode object1, PwNode object2) { public int compare(PwNode object1, PwNode object2) {
if (object1.equals(object2)) if (object1.equals(object2))
@@ -126,7 +141,7 @@ public enum SortNodeEnum {
if (object1 instanceof PwGroup) { if (object1 instanceof PwGroup) {
if (object2 instanceof PwGroup) { if (object2 instanceof PwGroup) {
return new PwGroup.GroupCreationComparator() return new PwGroup.GroupCreationComparator(ascending)
.compare((PwGroup) object1, (PwGroup) object2); .compare((PwGroup) object1, (PwGroup) object2);
} else if (object2 instanceof PwEntry) { } else if (object2 instanceof PwEntry) {
if(groupsBefore) if(groupsBefore)
@@ -138,7 +153,7 @@ public enum SortNodeEnum {
} }
} else if (object1 instanceof PwEntry) { } else if (object1 instanceof PwEntry) {
if(object2 instanceof PwEntry) { if(object2 instanceof PwEntry) {
return new PwEntry.EntryCreationComparator() return new PwEntry.EntryCreationComparator(ascending)
.compare((PwEntry) object1, (PwEntry) object2); .compare((PwEntry) object1, (PwEntry) object2);
} else if (object2 instanceof PwGroup) { } else if (object2 instanceof PwGroup) {
if(groupsBefore) if(groupsBefore)

View File

@@ -38,6 +38,7 @@ import com.kunzisoft.keepass.R;
public class SortDialogFragment extends DialogFragment { public class SortDialogFragment extends DialogFragment {
private static final String SORT_NODE_ENUM_BUNDLE_KEY = "SORT_NODE_ENUM_BUNDLE_KEY"; private static final String SORT_NODE_ENUM_BUNDLE_KEY = "SORT_NODE_ENUM_BUNDLE_KEY";
private static final String SORT_ASCENDING_BUNDLE_KEY = "SORT_ASCENDING_BUNDLE_KEY";
private static final String SORT_GROUPS_BEFORE_BUNDLE_KEY = "SORT_GROUPS_BEFORE_BUNDLE_KEY"; private static final String SORT_GROUPS_BEFORE_BUNDLE_KEY = "SORT_GROUPS_BEFORE_BUNDLE_KEY";
private SortSelectionListener mListener; private SortSelectionListener mListener;
@@ -46,10 +47,12 @@ public class SortDialogFragment extends DialogFragment {
private @IdRes private @IdRes
int mCheckedId; int mCheckedId;
private boolean mGroupsBefore; private boolean mGroupsBefore;
private boolean mAscending;
public static SortDialogFragment getInstance(SortNodeEnum sortNodeEnum, boolean groupsBefore) { public static SortDialogFragment getInstance(SortNodeEnum sortNodeEnum, boolean ascending, boolean groupsBefore) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putString(SORT_NODE_ENUM_BUNDLE_KEY, sortNodeEnum.name()); bundle.putString(SORT_NODE_ENUM_BUNDLE_KEY, sortNodeEnum.name());
bundle.putBoolean(SORT_ASCENDING_BUNDLE_KEY, ascending);
bundle.putBoolean(SORT_GROUPS_BEFORE_BUNDLE_KEY, groupsBefore); bundle.putBoolean(SORT_GROUPS_BEFORE_BUNDLE_KEY, groupsBefore);
SortDialogFragment fragment = new SortDialogFragment(); SortDialogFragment fragment = new SortDialogFragment();
fragment.setArguments(bundle); fragment.setArguments(bundle);
@@ -74,12 +77,15 @@ public class SortDialogFragment extends DialogFragment {
LayoutInflater inflater = getActivity().getLayoutInflater(); LayoutInflater inflater = getActivity().getLayoutInflater();
sortNodeEnum = SortNodeEnum.TITLE; sortNodeEnum = SortNodeEnum.TITLE;
mAscending = true;
mGroupsBefore = true; mGroupsBefore = true;
if (getArguments() != null if (getArguments() != null
&& getArguments().containsKey(SORT_NODE_ENUM_BUNDLE_KEY) && getArguments().containsKey(SORT_NODE_ENUM_BUNDLE_KEY)
&& getArguments().containsKey(SORT_ASCENDING_BUNDLE_KEY)
&& getArguments().containsKey(SORT_GROUPS_BEFORE_BUNDLE_KEY)) { && getArguments().containsKey(SORT_GROUPS_BEFORE_BUNDLE_KEY)) {
sortNodeEnum = SortNodeEnum.valueOf(getArguments().getString(SORT_NODE_ENUM_BUNDLE_KEY)); sortNodeEnum = SortNodeEnum.valueOf(getArguments().getString(SORT_NODE_ENUM_BUNDLE_KEY));
mAscending = getArguments().getBoolean(SORT_ASCENDING_BUNDLE_KEY);
mGroupsBefore = getArguments().getBoolean(SORT_GROUPS_BEFORE_BUNDLE_KEY); mGroupsBefore = getArguments().getBoolean(SORT_GROUPS_BEFORE_BUNDLE_KEY);
} }
@@ -92,13 +98,23 @@ public class SortDialogFragment extends DialogFragment {
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
mListener.onSortSelected(sortNodeEnum, mGroupsBefore); mListener.onSortSelected(sortNodeEnum, mAscending, mGroupsBefore);
} }
}) })
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {} public void onClick(DialogInterface dialog, int id) {}
}); });
CompoundButton ascendingView = (CompoundButton) rootView.findViewById(R.id.sort_selection_ascending);
// Check if is ascending or descending
ascendingView.setChecked(mAscending);
ascendingView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mAscending = isChecked;
}
});
CompoundButton groupsBeforeView = (CompoundButton) rootView.findViewById(R.id.sort_selection_groups_before); CompoundButton groupsBeforeView = (CompoundButton) rootView.findViewById(R.id.sort_selection_groups_before);
// Check if groups before // Check if groups before
groupsBeforeView.setChecked(mGroupsBefore); groupsBeforeView.setChecked(mGroupsBefore);
@@ -169,6 +185,6 @@ public class SortDialogFragment extends DialogFragment {
} }
public interface SortSelectionListener { public interface SortSelectionListener {
void onSortSelected(SortNodeEnum sortNodeEnum, boolean groupsBefore); void onSortSelected(SortNodeEnum sortNodeEnum, boolean ascending, boolean groupsBefore);
} }
} }

View File

@@ -102,6 +102,12 @@ public class PrefsUtil {
ctx.getResources().getBoolean(R.bool.sort_group_before_default)); ctx.getResources().getBoolean(R.bool.sort_group_before_default));
} }
public static boolean getAscendingSort(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.sort_ascending_key),
ctx.getResources().getBoolean(R.bool.sort_ascending_default));
}
public static boolean isPasswordMask(Context ctx) { public static boolean isPasswordMask(Context ctx) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
return prefs.getBoolean(ctx.getString(R.string.maskpass_key), return prefs.getBoolean(ctx.getString(R.string.maskpass_key),

View File

@@ -38,9 +38,13 @@
android:text="@string/sort_last_access_time" android:text="@string/sort_last_access_time"
android:visibility="gone"/> android:visibility="gone"/>
</RadioGroup> </RadioGroup>
<CheckBox android:id="@+id/sort_selection_groups_before" <CheckBox android:id="@+id/sort_selection_ascending"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:text="@string/sort_ascending"/>
<CheckBox android:id="@+id/sort_selection_groups_before"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sort_groups_before"/> android:text="@string/sort_groups_before"/>
</LinearLayout> </LinearLayout>

View File

@@ -182,6 +182,7 @@
<string name="show_password">Afficher le mot de passe</string> <string name="show_password">Afficher le mot de passe</string>
<string name="sort_menu">Trier</string> <string name="sort_menu">Trier</string>
<string name="sort_groups_before">Groupes avant</string> <string name="sort_groups_before">Groupes avant</string>
<string name="sort_ascending">Ascendant</string>
<string name="sort_db">Tri par défaut (base de données)</string> <string name="sort_db">Tri par défaut (base de données)</string>
<string name="sort_title">Tri par Titre</string> <string name="sort_title">Tri par Titre</string>
<string name="sort_name">Tri par nom</string> <string name="sort_name">Tri par nom</string>

View File

@@ -50,6 +50,7 @@
<string name="show_read_only_warning" translatable="false">show_read_only_warning</string> <string name="show_read_only_warning" translatable="false">show_read_only_warning</string>
<string name="sort_node_key" translatable="false">sort_node_key</string> <string name="sort_node_key" translatable="false">sort_node_key</string>
<string name="sort_group_before_key" translatable="false">sort_group_before_key</string> <string name="sort_group_before_key" translatable="false">sort_group_before_key</string>
<string name="sort_ascending_key" translatable="false">sort_ascending_key</string>
<string name="timeout_key" translatable="false">timeout_key</string> <string name="timeout_key" translatable="false">timeout_key</string>
<string name="saf_key" translatable="false">storage_access_framework_key</string> <string name="saf_key" translatable="false">storage_access_framework_key</string>
<integer name="roundsFix_default" translatable="false">100000</integer> <integer name="roundsFix_default" translatable="false">100000</integer>
@@ -71,6 +72,7 @@
<bool name="fingerprint_enable_default" translatable="true">false</bool> <bool name="fingerprint_enable_default" translatable="true">false</bool>
<bool name="full_file_path_enable_default" translatable="true">false</bool> <bool name="full_file_path_enable_default" translatable="true">false</bool>
<bool name="sort_group_before_default" translatable="true">true</bool> <bool name="sort_group_before_default" translatable="true">true</bool>
<bool name="sort_ascending_default" translatable="true">true</bool>
<string name="clipboard_timeout_default" translatable="false">300000</string> <string name="clipboard_timeout_default" translatable="false">300000</string>
<string-array name="clipboard_timeout_values"> <string-array name="clipboard_timeout_values">

View File

@@ -182,6 +182,7 @@
<string name="show_password">Show password</string> <string name="show_password">Show password</string>
<string name="sort_menu">Sort</string> <string name="sort_menu">Sort</string>
<string name="sort_groups_before">Groups before</string> <string name="sort_groups_before">Groups before</string>
<string name="sort_ascending">Ascending</string>
<string name="sort_db">DB sort order</string> <string name="sort_db">DB sort order</string>
<string name="sort_title">Sort by Title</string> <string name="sort_title">Sort by Title</string>
<string name="sort_name">Sort by Name</string> <string name="sort_name">Sort by Name</string>