/* 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 . */ 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 { /// /// Factory to create password icons /// 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 _customIconMap = new Dictionary(new PwUuidEqualityComparer()); /** standardIconMap * Cache for icon drawable. * Keys: Integer, Values: Drawables */ private readonly Dictionary _standardIconMap = new Dictionary(); 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 (); } } }