keepass2android/src/keepass2android/PwGroupListAdapter.cs

350 lines
8.2 KiB
C#

/*
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
the Free Software Foundation, either version 3 of the License, or
(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;
using System.Globalization;
using Android.Content;
using Android.Views;
using Android.Widget;
using Android.Preferences;
using KeePassLib;
using keepass2android.view;
using KeePassLib.Interfaces;
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.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase);
}
}
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
{
private readonly GroupBaseActivity _act;
private readonly PwGroup _group;
private List<PwGroup> _groupsForViewing;
private List<PwEntry> _entriesForViewing;
public bool InActionMode { get; set; }
public PwGroupListAdapter(GroupBaseActivity act, PwGroup group) {
_act = act;
_group = group;
FilterAndSort();
}
public override void NotifyDataSetChanged() {
base.NotifyDataSetChanged();
FilterAndSort();
}
public override void NotifyDataSetInvalidated() {
base.NotifyDataSetInvalidated();
FilterAndSort();
}
private void FilterAndSort() {
_entriesForViewing = new List<PwEntry>();
foreach (PwEntry entry in _group.Entries)
{
_entriesForViewing.Add(entry);
}
GroupViewSortOrderManager sortOrderManager = new GroupViewSortOrderManager(_act);
var sortOrder = sortOrderManager.GetCurrentSortOrder();
if ( sortOrder.RequiresSort )
{
var sortGroups = sortOrderManager.SortGroups;
_groupsForViewing = new List<PwGroup>(_group.Groups);
_groupsForViewing.Sort( (x, y) =>
{
if (sortGroups)
return sortOrder.CompareGroups(x, y);
else
return String.Compare (x.Name, y.Name, true);
});
_entriesForViewing.Sort(sortOrder.CompareEntries);
} else {
_groupsForViewing = new List<PwGroup>(_group.Groups);
}
}
public override int Count
{
get{
return _groupsForViewing.Count + _entriesForViewing.Count;
}
}
public override Java.Lang.Object GetItem(int position) {
return position;
}
public bool IsGroupAtPosition(int position)
{
return position < _groupsForViewing.Count;
}
public override long GetItemId(int position) {
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent) {
int size = _groupsForViewing.Count;
GroupListItemView view;
if ( position < size ) {
view = CreateGroupView(position, convertView);
} else {
view = CreateEntryView(position - size, convertView);
}
view.SetRightArrowVisibility(!InActionMode);
return view;
}
private PwGroupView CreateGroupView(int position, View convertView) {
PwGroup g = _groupsForViewing[position];
PwGroupView gv;
if (convertView == null || !(convertView is PwGroupView)) {
gv = PwGroupView.GetInstance(_act, g);
}
else {
gv = (PwGroupView) convertView;
gv.ConvertView(g);
}
return gv;
}
private PwEntryView CreateEntryView(int position, View convertView) {
PwEntry entry = _entriesForViewing[position];
PwEntryView ev;
if (convertView == null || !(convertView is PwEntryView)) {
ev = PwEntryView.GetInstance(_act, entry, position);
}
else {
ev = (PwEntryView) convertView;
ev.ConvertView(entry, position);
}
return ev;
}
public IStructureItem GetItemAtPosition(int keyAt)
{
if (keyAt < _groupsForViewing.Count)
{
return _groupsForViewing[keyAt];
}
else
{
return _entriesForViewing[keyAt - _groupsForViewing.Count];
}
}
}
}