mirror of
https://github.com/moparisthebest/keepass2android
synced 2024-11-16 06:25:05 -05:00
allow differnt sorting options
"touch" groups after editing to get correct sort order "modification date"
This commit is contained in:
parent
b61904c01c
commit
fa7365323c
@ -53,6 +53,7 @@ namespace keepass2android
|
|||||||
Group.Name = _name;
|
Group.Name = _name;
|
||||||
Group.IconId = _iconId;
|
Group.IconId = _iconId;
|
||||||
Group.CustomIconUuid = _customIconId;
|
Group.CustomIconUuid = _customIconId;
|
||||||
|
Group.Touch(true);
|
||||||
|
|
||||||
// Commit to disk
|
// Commit to disk
|
||||||
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun);
|
SaveDb save = new SaveDb(_ctx, _app, OnFinishToRun);
|
||||||
|
@ -53,23 +53,15 @@ namespace keepass2android
|
|||||||
|
|
||||||
public override void Run() {
|
public override void Run() {
|
||||||
if ( Success ) {
|
if ( Success ) {
|
||||||
// Mark group dirty if title, icon or Expiry stuff changes
|
// Mark parent group dirty. Even only the last modification date changed, this might affect sort order
|
||||||
if ( ! _backup.Strings.ReadSafe (PwDefs.TitleField).Equals(_updatedEntry.Strings.ReadSafe (PwDefs.TitleField))
|
PwGroup parent = _updatedEntry.ParentGroup;
|
||||||
|| ! _backup.IconId.Equals(_updatedEntry.IconId)
|
if ( parent != null ) {
|
||||||
|| !_backup.CustomIconUuid.Equals(_updatedEntry.CustomIconUuid)
|
|
||||||
|| _backup.Expires != _updatedEntry.Expires
|
|
||||||
|| (_backup.Expires && (! _backup.ExpiryTime.Equals(_updatedEntry.ExpiryTime)))
|
|
||||||
)
|
|
||||||
|
|
||||||
{
|
// Mark parent group dirty
|
||||||
PwGroup parent = _updatedEntry.ParentGroup;
|
_app.GetDb().Dirty.Add(parent);
|
||||||
if ( parent != null ) {
|
|
||||||
|
|
||||||
// Mark parent group dirty
|
|
||||||
_app.GetDb().Dirty.Add(parent);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
StatusLogger.UpdateMessage(UiStringKey.UndoingChanges);
|
StatusLogger.UpdateMessage(UiStringKey.UndoingChanges);
|
||||||
// If we fail to save, back out changes to global structure
|
// If we fail to save, back out changes to global structure
|
||||||
|
@ -16,6 +16,8 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
@ -331,19 +333,7 @@ namespace keepass2android
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetSortMenuText(IMenu menu) {
|
|
||||||
bool sortByName = _prefs.GetBoolean(GetString(Resource.String.sort_key), Resources.GetBoolean(Resource.Boolean.sort_default));
|
|
||||||
|
|
||||||
int resId;
|
|
||||||
if ( sortByName ) {
|
|
||||||
resId = Resource.String.sort_db;
|
|
||||||
} else {
|
|
||||||
resId = Resource.String.sort_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
menu.FindItem(Resource.Id.menu_sort).SetTitle(resId);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnPrepareOptionsMenu(IMenu menu) {
|
public override bool OnPrepareOptionsMenu(IMenu menu) {
|
||||||
if ( ! base.OnPrepareOptionsMenu(menu) ) {
|
if ( ! base.OnPrepareOptionsMenu(menu) ) {
|
||||||
@ -351,7 +341,7 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
Util.PrepareDonateOptionMenu(menu, this);
|
Util.PrepareDonateOptionMenu(menu, this);
|
||||||
SetSortMenuText(menu);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -378,7 +368,7 @@ namespace keepass2android
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case Resource.Id.menu_sort:
|
case Resource.Id.menu_sort:
|
||||||
ToggleSort();
|
ChangeSort();
|
||||||
return true;
|
return true;
|
||||||
case Android.Resource.Id.Home:
|
case Android.Resource.Id.Home:
|
||||||
//Currently the action bar only displays the home button when we come from a previous activity.
|
//Currently the action bar only displays the home button when we come from a previous activity.
|
||||||
@ -471,26 +461,41 @@ namespace keepass2android
|
|||||||
base.OnBackPressed();
|
base.OnBackPressed();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ToggleSort() {
|
private void ChangeSort()
|
||||||
// Toggle setting
|
{
|
||||||
String sortKey = GetString(Resource.String.sort_key);
|
var sortOrderManager = new GroupViewSortOrderManager(this);
|
||||||
bool sortByName = _prefs.GetBoolean(sortKey, Resources.GetBoolean(Resource.Boolean.sort_default));
|
IEnumerable<string> sortOptions = sortOrderManager.SortOrders.Select(
|
||||||
ISharedPreferencesEditor editor = _prefs.Edit();
|
o => GetString(o.ResourceId)
|
||||||
editor.PutBoolean(sortKey, ! sortByName);
|
);
|
||||||
EditorCompat.Apply(editor);
|
|
||||||
|
int selectedBefore = sortOrderManager.GetCurrentSortOrderIndex();
|
||||||
|
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.SetSingleChoiceItems(sortOptions.ToArray(), selectedBefore, (sender, args) =>
|
||||||
|
{
|
||||||
|
int selectedAfter = args.Which;
|
||||||
|
|
||||||
|
sortOrderManager.SetNewSortOrder(selectedAfter);
|
||||||
|
// Refresh menu titles
|
||||||
|
ActivityCompat.InvalidateOptionsMenu(this);
|
||||||
|
|
||||||
|
// Mark all groups as dirty now to refresh them on load
|
||||||
|
Database db = App.Kp2a.GetDb();
|
||||||
|
db.MarkAllGroupsAsDirty();
|
||||||
|
// We'll manually refresh this group so we can remove it
|
||||||
|
db.Dirty.Remove(Group);
|
||||||
|
|
||||||
|
// Tell the adapter to refresh it's list
|
||||||
|
BaseAdapter adapter = (BaseAdapter)ListAdapter;
|
||||||
|
adapter.NotifyDataSetChanged();
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
.SetPositiveButton(Android.Resource.String.Ok, (sender, args) => ((Dialog)sender).Dismiss())
|
||||||
|
.Show();
|
||||||
|
|
||||||
// Refresh menu titles
|
|
||||||
ActivityCompat.InvalidateOptionsMenu(this);
|
|
||||||
|
|
||||||
// Mark all groups as dirty now to refresh them on load
|
|
||||||
Database db = App.Kp2a.GetDb();
|
|
||||||
db.MarkAllGroupsAsDirty();
|
|
||||||
// We'll manually refresh this group so we can remove it
|
|
||||||
db.Dirty.Remove(Group);
|
|
||||||
|
|
||||||
// Tell the adapter to refresh it's list
|
|
||||||
BaseAdapter adapter = (BaseAdapter) ListAdapter;
|
|
||||||
adapter.NotifyDataSetChanged();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,182 @@ using keepass2android.view;
|
|||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
public interface IGroupViewSortOrder
|
||||||
|
{
|
||||||
|
int ResourceId { get; }
|
||||||
|
bool RequiresSort { get; }
|
||||||
|
int CompareEntries(PwEntry a, PwEntry b);
|
||||||
|
int CompareGroups(PwGroup a, PwGroup b);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ModDateSortOrder : IGroupViewSortOrder
|
||||||
|
{
|
||||||
|
public int ResourceId
|
||||||
|
{
|
||||||
|
get { return Resource.String.sort_moddate; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RequiresSort
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CompareEntries(PwEntry a, PwEntry b)
|
||||||
|
{
|
||||||
|
return a.LastModificationTime.CompareTo(b.LastModificationTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CompareGroups(PwGroup a, PwGroup b)
|
||||||
|
{
|
||||||
|
return a.LastModificationTime.CompareTo(b.LastModificationTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class CreationDateSortOrder : IGroupViewSortOrder
|
||||||
|
{
|
||||||
|
public int ResourceId
|
||||||
|
{
|
||||||
|
get { return Resource.String.sort_db; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RequiresSort
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CompareEntries(PwEntry a, PwEntry b)
|
||||||
|
{
|
||||||
|
return a.CreationTime.CompareTo(b.CreationTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CompareGroups(PwGroup a, PwGroup b)
|
||||||
|
{
|
||||||
|
return a.CreationTime.CompareTo(b.CreationTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DefaultSortOrder: IGroupViewSortOrder
|
||||||
|
{
|
||||||
|
public int ResourceId
|
||||||
|
{
|
||||||
|
get { return Resource.String.sort_default; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RequiresSort
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CompareEntries(PwEntry a, PwEntry b)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CompareGroups(PwGroup a, PwGroup b)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class NameSortOrder: IGroupViewSortOrder
|
||||||
|
{
|
||||||
|
public int ResourceId
|
||||||
|
{
|
||||||
|
get { return Resource.String.sort_name; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RequiresSort
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CompareEntries(PwEntry x, PwEntry y)
|
||||||
|
{
|
||||||
|
String nameX = x.Strings.ReadSafe(PwDefs.TitleField);
|
||||||
|
String nameY = y.Strings.ReadSafe(PwDefs.TitleField);
|
||||||
|
if (nameX.ToLower() != nameY.ToLower())
|
||||||
|
return String.Compare(nameX, nameY, StringComparison.OrdinalIgnoreCase);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (PwDefs.IsTanEntry(x) && PwDefs.IsTanEntry(y))
|
||||||
|
{
|
||||||
|
//compare the user name fields (=TAN index)
|
||||||
|
String userX = x.Strings.ReadSafe(PwDefs.UserNameField);
|
||||||
|
String userY = y.Strings.ReadSafe(PwDefs.UserNameField);
|
||||||
|
if (userX != userY)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return int.Parse(userX).CompareTo(int.Parse(userY));
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
//ignore
|
||||||
|
}
|
||||||
|
return String.Compare(userX, userY, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//use creation time for non-tan entries:
|
||||||
|
|
||||||
|
return x.CreationTime.CompareTo(y.CreationTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CompareGroups(PwGroup a, PwGroup b)
|
||||||
|
{
|
||||||
|
return String.CompareOrdinal(a.Name, b.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GroupViewSortOrderManager
|
||||||
|
{
|
||||||
|
private readonly Context _context;
|
||||||
|
private readonly IGroupViewSortOrder[] _orders = new IGroupViewSortOrder[] { new DefaultSortOrder(), new NameSortOrder(), new ModDateSortOrder(), new CreationDateSortOrder()};
|
||||||
|
private readonly ISharedPreferences _prefs;
|
||||||
|
|
||||||
|
public GroupViewSortOrderManager(Context context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_prefs = PreferenceManager.GetDefaultSharedPreferences(_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IGroupViewSortOrder[] SortOrders
|
||||||
|
{
|
||||||
|
get { return _orders; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SortGroups
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
//_prefs.GetBoolean(_context.GetString(Resource.String.sortgroups_key), false); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IGroupViewSortOrder GetCurrentSortOrder()
|
||||||
|
{
|
||||||
|
return SortOrders[GetCurrentSortOrderIndex()];
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetCurrentSortOrderIndex()
|
||||||
|
{
|
||||||
|
String sortKeyOld = _context.GetString(Resource.String.sort_key_old);
|
||||||
|
String sortKey = _context.GetString(Resource.String.sort_key);
|
||||||
|
|
||||||
|
int sortId = _prefs.GetInt(sortKey, -1);
|
||||||
|
if (sortId == -1)
|
||||||
|
{
|
||||||
|
sortId = _prefs.GetBoolean(sortKeyOld, true) ? 1 : 0;
|
||||||
|
}
|
||||||
|
return sortId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetNewSortOrder(int selectedAfter)
|
||||||
|
{
|
||||||
|
String sortKey = _context.GetString(Resource.String.sort_key);
|
||||||
|
ISharedPreferencesEditor editor = _prefs.Edit();
|
||||||
|
editor.PutInt(sortKey, selectedAfter);
|
||||||
|
//editor.PutBoolean(_context.GetString(Resource.String.sortgroups_key), false);
|
||||||
|
EditorCompat.Apply(editor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class PwGroupListAdapter : BaseAdapter
|
public class PwGroupListAdapter : BaseAdapter
|
||||||
{
|
{
|
||||||
@ -36,12 +212,12 @@ namespace keepass2android
|
|||||||
private List<PwGroup> _groupsForViewing;
|
private List<PwGroup> _groupsForViewing;
|
||||||
private List<PwEntry> _entriesForViewing;
|
private List<PwEntry> _entriesForViewing;
|
||||||
|
|
||||||
private readonly ISharedPreferences _prefs;
|
|
||||||
|
|
||||||
public PwGroupListAdapter(GroupBaseActivity act, PwGroup group) {
|
public PwGroupListAdapter(GroupBaseActivity act, PwGroup group) {
|
||||||
_act = act;
|
_act = act;
|
||||||
_group = group;
|
_group = group;
|
||||||
_prefs = PreferenceManager.GetDefaultSharedPreferences(act);
|
|
||||||
|
|
||||||
FilterAndSort();
|
FilterAndSort();
|
||||||
|
|
||||||
@ -68,45 +244,21 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
_entriesForViewing.Add(entry);
|
_entriesForViewing.Add(entry);
|
||||||
}
|
}
|
||||||
|
GroupViewSortOrderManager sortOrderManager = new GroupViewSortOrderManager(_act);
|
||||||
|
var sortOrder = sortOrderManager.GetCurrentSortOrder();
|
||||||
|
|
||||||
bool sortLists = _prefs.GetBoolean(_act.GetString(Resource.String.sort_key), _act.Resources.GetBoolean(Resource.Boolean.sort_default));
|
if ( sortOrder.RequiresSort )
|
||||||
if ( sortLists )
|
|
||||||
{
|
{
|
||||||
|
var sortGroups = sortOrderManager.SortGroups;
|
||||||
_groupsForViewing = new List<PwGroup>(_group.Groups);
|
_groupsForViewing = new List<PwGroup>(_group.Groups);
|
||||||
_groupsForViewing.Sort( (x, y) => { return String.Compare (x.Name, y.Name, true); });
|
_groupsForViewing.Sort( (x, y) =>
|
||||||
_entriesForViewing.Sort( (x, y) =>
|
{
|
||||||
{
|
if (sortGroups)
|
||||||
String nameX = x.Strings.ReadSafe(PwDefs.TitleField);
|
return sortOrder.CompareGroups(x, y);
|
||||||
String nameY = y.Strings.ReadSafe(PwDefs.TitleField);
|
else
|
||||||
if (nameX.ToLower() != nameY.ToLower())
|
return String.Compare (x.Name, y.Name, true);
|
||||||
return String.Compare(nameX, nameY, StringComparison.OrdinalIgnoreCase);
|
});
|
||||||
else
|
_entriesForViewing.Sort(sortOrder.CompareEntries);
|
||||||
{
|
|
||||||
if (PwDefs.IsTanEntry(x) && PwDefs.IsTanEntry(y))
|
|
||||||
{
|
|
||||||
//compare the user name fields (=TAN index)
|
|
||||||
String userX = x.Strings.ReadSafe(PwDefs.UserNameField);
|
|
||||||
String userY = y.Strings.ReadSafe(PwDefs.UserNameField);
|
|
||||||
if (userX != userY)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return int.Parse(userX).CompareTo(int.Parse(userY));
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
//ignore
|
|
||||||
}
|
|
||||||
return String.Compare(userX, userY, StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//use creation time for non-tan entries:
|
|
||||||
|
|
||||||
return x.CreationTime.CompareTo(y.CreationTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
_groupsForViewing = new List<PwGroup>(_group.Groups);
|
_groupsForViewing = new List<PwGroup>(_group.Groups);
|
||||||
}
|
}
|
||||||
|
2624
src/keepass2android/Resources/Resource.designer.cs
generated
2624
src/keepass2android/Resources/Resource.designer.cs
generated
File diff suppressed because it is too large
Load Diff
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
<item android:id="@+id/menu_sort"
|
<item android:id="@+id/menu_sort"
|
||||||
android:icon="@android:drawable/ic_menu_sort_by_size"
|
android:icon="@android:drawable/ic_menu_sort_by_size"
|
||||||
android:title="@string/sort_name"
|
android:title="@string/sort_menu"
|
||||||
android:showAsAction="never"
|
android:showAsAction="never"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -56,7 +56,9 @@
|
|||||||
<string name="omitbackup_key">omitbackup</string>
|
<string name="omitbackup_key">omitbackup</string>
|
||||||
<string name="list_size_key">list_size</string>
|
<string name="list_size_key">list_size</string>
|
||||||
<string name="design_key">design_key</string>
|
<string name="design_key">design_key</string>
|
||||||
<string name="sort_key">sort_key</string>
|
<string name="sort_key_old">sort_key</string>
|
||||||
|
<string name="sort_key">sort_key_new</string>
|
||||||
|
<string name="sortgroups_key">sortgroups_key</string>
|
||||||
<string name="TanExpiresOnUse_key">TanExpiresOnUse_key</string>
|
<string name="TanExpiresOnUse_key">TanExpiresOnUse_key</string>
|
||||||
<string name="ShowGroupnameInSearchResult_key">ShowGroupnameInSearchResult_key</string>
|
<string name="ShowGroupnameInSearchResult_key">ShowGroupnameInSearchResult_key</string>
|
||||||
<string name="ShowUsernameInList_key">ShowUsernameInList_key</string>
|
<string name="ShowUsernameInList_key">ShowUsernameInList_key</string>
|
||||||
@ -67,7 +69,6 @@
|
|||||||
<string name="BinaryDirectory_default">/mnt/sdcard/keepass2android/binaries/</string>
|
<string name="BinaryDirectory_default">/mnt/sdcard/keepass2android/binaries/</string>
|
||||||
<bool name="maskpass_default">true</bool>
|
<bool name="maskpass_default">true</bool>
|
||||||
<bool name="keyfile_default">true</bool>
|
<bool name="keyfile_default">true</bool>
|
||||||
<bool name="sort_default">true</bool>
|
|
||||||
<bool name="omitbackup_default">true</bool>
|
<bool name="omitbackup_default">true</bool>
|
||||||
<bool name="TanExpiresOnUse_default">true</bool>
|
<bool name="TanExpiresOnUse_default">true</bool>
|
||||||
<bool name="ShowUsernameInList_default">true</bool>
|
<bool name="ShowUsernameInList_default">true</bool>
|
||||||
|
@ -190,8 +190,13 @@
|
|||||||
<string name="space">Space</string>
|
<string name="space">Space</string>
|
||||||
<string name="search_label">Search</string>
|
<string name="search_label">Search</string>
|
||||||
<string name="show_password">Show password</string>
|
<string name="show_password">Show password</string>
|
||||||
|
<string name="sort_menu">Sort by...</string>
|
||||||
<string name="sort_name">Sort by name</string>
|
<string name="sort_name">Sort by name</string>
|
||||||
<string name="sort_db">Sort by creation date</string>
|
<string name="sort_db">Sort by creation date</string>
|
||||||
|
<string name="sort_moddate">Sort by modification date</string>
|
||||||
|
<string name="sort_default">Keep default order</string>
|
||||||
|
|
||||||
|
|
||||||
<string name="special">Special</string>
|
<string name="special">Special</string>
|
||||||
<string name="search_hint">Find what</string>
|
<string name="search_hint">Find what</string>
|
||||||
<string name="search_results">Search results</string>
|
<string name="search_results">Search results</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user