2013-02-23 11:43:42 -05:00
|
|
|
/*
|
|
|
|
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file is based on Keepassdroid, Copyright Brian Pellin.
|
|
|
|
|
|
|
|
Keepass2Android is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
2014-01-26 08:27:27 -05:00
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
2013-02-23 11:43:42 -05:00
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
Keepass2Android is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
2013-11-13 15:34:39 -05:00
|
|
|
using System.Globalization;
|
2013-02-23 11:43:42 -05:00
|
|
|
using Android.Content;
|
|
|
|
using Android.Views;
|
|
|
|
using Android.Widget;
|
|
|
|
using Android.Preferences;
|
|
|
|
using KeePassLib;
|
|
|
|
using keepass2android.view;
|
|
|
|
|
|
|
|
namespace keepass2android
|
|
|
|
{
|
2014-12-23 14:29:27 -05:00
|
|
|
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)
|
|
|
|
{
|
2015-02-19 14:30:26 -05:00
|
|
|
return -a.LastModificationTime.CompareTo(b.LastModificationTime);
|
2014-12-23 14:29:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public int CompareGroups(PwGroup a, PwGroup b)
|
|
|
|
{
|
2015-02-19 14:30:26 -05:00
|
|
|
return -a.LastModificationTime.CompareTo(b.LastModificationTime);
|
2014-12-23 14:29:27 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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)
|
|
|
|
{
|
2015-04-01 15:26:56 -04:00
|
|
|
return String.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase);
|
2014-12-23 14:29:27 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2013-02-23 11:43:42 -05:00
|
|
|
|
|
|
|
public class PwGroupListAdapter : BaseAdapter
|
|
|
|
{
|
|
|
|
|
2013-06-15 06:40:01 -04:00
|
|
|
private readonly GroupBaseActivity _act;
|
|
|
|
private readonly PwGroup _group;
|
|
|
|
private List<PwGroup> _groupsForViewing;
|
|
|
|
private List<PwEntry> _entriesForViewing;
|
2013-02-23 11:43:42 -05:00
|
|
|
|
2014-12-23 14:29:27 -05:00
|
|
|
|
2013-02-23 11:43:42 -05:00
|
|
|
|
|
|
|
public PwGroupListAdapter(GroupBaseActivity act, PwGroup group) {
|
2013-06-15 06:40:01 -04:00
|
|
|
_act = act;
|
|
|
|
_group = group;
|
2014-12-23 14:29:27 -05:00
|
|
|
|
2013-02-23 11:43:42 -05:00
|
|
|
|
2013-06-15 06:40:01 -04:00
|
|
|
FilterAndSort();
|
2013-02-23 11:43:42 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void NotifyDataSetChanged() {
|
|
|
|
base.NotifyDataSetChanged();
|
|
|
|
|
2013-06-15 06:40:01 -04:00
|
|
|
FilterAndSort();
|
2013-02-23 11:43:42 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void NotifyDataSetInvalidated() {
|
|
|
|
base.NotifyDataSetInvalidated();
|
|
|
|
|
2013-06-15 06:40:01 -04:00
|
|
|
FilterAndSort();
|
2013-02-23 11:43:42 -05:00
|
|
|
}
|
|
|
|
|
2013-06-15 06:40:01 -04:00
|
|
|
private void FilterAndSort() {
|
|
|
|
_entriesForViewing = new List<PwEntry>();
|
2013-02-23 11:43:42 -05:00
|
|
|
|
2013-06-15 06:40:01 -04:00
|
|
|
foreach (PwEntry entry in _group.Entries)
|
2013-02-23 11:43:42 -05:00
|
|
|
{
|
2013-06-15 06:40:01 -04:00
|
|
|
_entriesForViewing.Add(entry);
|
2013-02-23 11:43:42 -05:00
|
|
|
}
|
2014-12-23 14:29:27 -05:00
|
|
|
GroupViewSortOrderManager sortOrderManager = new GroupViewSortOrderManager(_act);
|
|
|
|
var sortOrder = sortOrderManager.GetCurrentSortOrder();
|
|
|
|
|
|
|
|
if ( sortOrder.RequiresSort )
|
2013-02-23 11:43:42 -05:00
|
|
|
{
|
2014-12-23 14:29:27 -05:00
|
|
|
var sortGroups = sortOrderManager.SortGroups;
|
2013-06-15 06:40:01 -04:00
|
|
|
_groupsForViewing = new List<PwGroup>(_group.Groups);
|
2014-12-23 14:29:27 -05:00
|
|
|
_groupsForViewing.Sort( (x, y) =>
|
|
|
|
{
|
|
|
|
if (sortGroups)
|
|
|
|
return sortOrder.CompareGroups(x, y);
|
|
|
|
else
|
|
|
|
return String.Compare (x.Name, y.Name, true);
|
|
|
|
});
|
|
|
|
_entriesForViewing.Sort(sortOrder.CompareEntries);
|
2013-02-23 11:43:42 -05:00
|
|
|
} else {
|
2013-06-15 06:40:01 -04:00
|
|
|
_groupsForViewing = new List<PwGroup>(_group.Groups);
|
2013-02-23 11:43:42 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public override int Count
|
|
|
|
{
|
|
|
|
get{
|
|
|
|
|
2013-06-15 06:40:01 -04:00
|
|
|
return _groupsForViewing.Count + _entriesForViewing.Count;
|
2013-02-23 11:43:42 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public override Java.Lang.Object GetItem(int position) {
|
|
|
|
return position;
|
|
|
|
}
|
|
|
|
|
|
|
|
public override long GetItemId(int position) {
|
|
|
|
return position;
|
|
|
|
}
|
|
|
|
|
|
|
|
public override View GetView(int position, View convertView, ViewGroup parent) {
|
2013-06-15 06:40:01 -04:00
|
|
|
int size = _groupsForViewing.Count;
|
2013-02-23 11:43:42 -05:00
|
|
|
|
|
|
|
if ( position < size ) {
|
2013-06-15 06:40:01 -04:00
|
|
|
return CreateGroupView(position, convertView);
|
2013-02-23 11:43:42 -05:00
|
|
|
} else {
|
2013-06-15 06:40:01 -04:00
|
|
|
return CreateEntryView(position - size, convertView);
|
2013-02-23 11:43:42 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-15 06:40:01 -04:00
|
|
|
private View CreateGroupView(int position, View convertView) {
|
|
|
|
PwGroup g = _groupsForViewing[position];
|
2013-02-23 11:43:42 -05:00
|
|
|
PwGroupView gv;
|
|
|
|
|
|
|
|
if (convertView == null || !(convertView is PwGroupView)) {
|
|
|
|
|
2013-06-15 06:40:01 -04:00
|
|
|
gv = PwGroupView.GetInstance(_act, g);
|
2013-02-23 11:43:42 -05:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
gv = (PwGroupView) convertView;
|
2013-06-15 06:40:01 -04:00
|
|
|
gv.ConvertView(g);
|
2013-02-23 11:43:42 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return gv;
|
|
|
|
}
|
|
|
|
|
2013-06-15 06:40:01 -04:00
|
|
|
private PwEntryView CreateEntryView(int position, View convertView) {
|
|
|
|
PwEntry entry = _entriesForViewing[position];
|
2013-02-23 11:43:42 -05:00
|
|
|
PwEntryView ev;
|
|
|
|
|
|
|
|
if (convertView == null || !(convertView is PwEntryView)) {
|
2013-06-15 06:40:01 -04:00
|
|
|
ev = PwEntryView.GetInstance(_act, entry, position);
|
2013-02-23 11:43:42 -05:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
ev = (PwEntryView) convertView;
|
2013-06-15 06:40:01 -04:00
|
|
|
ev.ConvertView(entry, position);
|
2013-02-23 11:43:42 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return ev;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|