keepass2android/src/keepass2android/icons/DrawableFactory.cs

184 lines
5.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 Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Widget;
using Android.Graphics.Drawables;
using Android.Content.Res;
using KeePassLib;
using Android.Graphics;
using Android.Preferences;
namespace keepass2android
{
/// <summary>
/// Factory to create password icons
/// </summary>
public class DrawableFactory: IDrawableFactory
{
private static Drawable _blank;
private static int _blankWidth = -1;
private static int _blankHeight = -1;
/** customIconMap
* Cache for icon drawable.
* Keys: UUID, Values: Drawables
*/
private readonly Dictionary<PwUuid, Drawable> _customIconMap = new Dictionary<PwUuid, Drawable>(new PwUuidEqualityComparer());
/** standardIconMap
* Cache for icon drawable.
* Keys: Integer, Values: Drawables
*/
private readonly Dictionary<int/*icon key*/, Drawable> _standardIconMap = new Dictionary<int, Drawable>();
public void AssignDrawableTo(ImageView iv, Context context, PwDatabase db, PwIcon icon, PwUuid customIconId, bool forGroup)
{
Drawable draw = GetIconDrawable (context, db, icon, customIconId, forGroup);
if (draw != null)
{
draw = draw.Mutate();
iv.SetImageDrawable(draw);
}
else
Kp2aLog.LogUnexpectedError(new Exception("icon not found : " + icon));
}
public Drawable GetIconDrawable (Context context, PwDatabase db, PwIcon icon, PwUuid customIconId, bool forGroup)
{
if ((customIconId != null) && (!customIconId.Equals(PwUuid.Zero))) {
return GetIconDrawable (context, db, customIconId);
}
return GetIconDrawable (context, icon, forGroup);
}
public bool IsWhiteIconSet
{
get
{
var context = Application.Context;
string packageName = PreferenceManager.GetDefaultSharedPreferences(Application.Context).GetString("IconSetKey", context.PackageName);
//assume that at the momemt only the built in icons are white
return packageName == context.PackageName;
}
}
private static void InitBlank(Context context)
{
if (_blank == null) {
_blank = context.Resources.GetDrawable (Resource.Drawable.ic99_blank);
_blankWidth = _blank.IntrinsicWidth;
_blankHeight = _blank.IntrinsicHeight;
}
}
public Drawable GetIconDrawable (Context context, PwIcon icon, bool forGroup)
{
//int resId = DefaultIcons.IconToResId (icon, forGroup);
int dictKey = GetDictionaryKey(icon, forGroup);
Drawable draw;
if (!_standardIconMap.TryGetValue(dictKey, out draw))
{
string packageName = PreferenceManager.GetDefaultSharedPreferences(Application.Context).GetString("IconSetKey", context.PackageName);
Resources res = context.PackageManager.GetResourcesForApplication(packageName);
try
{
int resId = GetResourceId(res, dictKey, packageName);
if (resId == 0)
draw = context.Resources.GetDrawable(Resource.Drawable.ic99_blank);
else
draw = res.GetDrawable(resId);
}
catch (System.Exception e)
{
Kp2aLog.LogUnexpectedError(e);
draw = context.Resources.GetDrawable(Resource.Drawable.ic99_blank);
}
}
_standardIconMap[dictKey] = draw;
return draw;
}
private const int FolderOffset = 10000;
private int GetResourceId(Resources res, int dictKey, string packageName)
{
bool forFolder = dictKey >= FolderOffset;
int iconId = dictKey%FolderOffset;
var name = (forFolder? "icf" : "ic") + iconId.ToString("D2");
int resId = res.GetIdentifier(name, "drawable", packageName);
if ((forFolder) && (resId == 0)) //if no explicit folder icon was found, retry a normal icon
{
name = "ic" + iconId.ToString("D2");
resId = res.GetIdentifier(name, "drawable", packageName);
}
//return what we found, may still be 0
return resId;
}
private int GetDictionaryKey(PwIcon icon, bool forGroup)
{
return ((int)icon) + (forGroup ? FolderOffset : 0);
}
public Drawable GetIconDrawable(Context context, PwDatabase db, PwUuid icon)
{
InitBlank (context);
if (icon.Equals(PwUuid.Zero)) {
return _blank;
}
Drawable draw;
if (!_customIconMap.TryGetValue(icon, out draw))
{
Bitmap bitmap = db.GetCustomIcon(icon);
// Could not understand custom icon
if (bitmap == null) {
return _blank;
}
draw = new BitmapDrawable(context.Resources, bitmap);
_customIconMap[icon] = draw;
}
return draw;
}
public void Clear ()
{
_standardIconMap.Clear ();
_customIconMap.Clear ();
}
}
}