From 80521f8ec21b6e0d0c055df2a47ceee3cedc8619 Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Thu, 25 Feb 2021 15:13:34 +0100 Subject: [PATCH] Change list to recyclerview --- .../keepass/activities/EntryActivity.kt | 2 +- .../keepass/activities/EntryEditActivity.kt | 2 +- .../keepass/activities/GroupActivity.kt | 4 +- .../dialogs/GroupEditDialogFragment.kt | 4 +- .../dialogs/IconPickerDialogFragment.kt | 55 +++--------- .../fragments/IconCustomFragment.kt | 88 ++----------------- .../activities/fragments/IconFragment.kt | 52 +++++++++++ .../fragments/IconStandardFragment.kt | 83 ++--------------- .../kunzisoft/keepass/adapters/IconAdapter.kt | 59 +++++++++++++ .../adapters/IconPickerPagerAdapter.kt | 34 +++++++ .../kunzisoft/keepass/adapters/NodeAdapter.kt | 2 +- .../adapters/SearchEntryCursorAdapter.kt | 2 +- .../keepass/autofill/AutofillHelper.kt | 4 +- .../keepass/database/element/Database.kt | 4 +- .../element/icon/IconImageStandard.kt | 5 +- .../keepass/database/element/icon/IconPool.kt | 34 ++++--- .../file/output/DatabaseOutputKDBX.kt | 6 +- .../keepass/icons/IconDrawableFactory.kt | 41 ++------- .../com/kunzisoft/keepass/icons/IconPack.kt | 3 +- .../keepass/icons/IconPackChooser.kt | 2 +- .../layout/fragment_icon_custom_picker.xml | 35 ++++++++ .../layout/fragment_icon_standard_picker.xml | 12 ++- 22 files changed, 257 insertions(+), 276 deletions(-) create mode 100644 app/src/main/java/com/kunzisoft/keepass/activities/fragments/IconFragment.kt create mode 100644 app/src/main/java/com/kunzisoft/keepass/adapters/IconAdapter.kt create mode 100644 app/src/main/java/com/kunzisoft/keepass/adapters/IconPickerPagerAdapter.kt create mode 100644 app/src/main/res/layout/fragment_icon_custom_picker.xml diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt index 526736668..ea1bc0068 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt @@ -242,7 +242,7 @@ class EntryActivity : LockingActivity() { val entryInfo = entry.getEntryInfo(mDatabase) // Assign title icon - titleIconView?.assignDatabaseIcon(mDatabase!!.drawFactory, entryInfo.icon, iconColor) + titleIconView?.assignDatabaseIcon(mDatabase!!.iconDrawableFactory, entryInfo.icon, iconColor) // Assign title text val entryTitle = entryInfo.title diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.kt index 3484954bd..0576bba78 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.kt @@ -208,7 +208,7 @@ class EntryEditActivity : LockingActivity(), .replace(R.id.entry_edit_contents, entryEditFragment!!, ENTRY_EDIT_FRAGMENT_TAG) .commit() entryEditFragment?.apply { - drawFactory = mDatabase?.drawFactory + drawFactory = mDatabase?.iconDrawableFactory setOnDateClickListener = { expiryTime.date.let { expiresDate -> val dateTime = DateTime(expiresDate) diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.kt index 14143bd17..99f98b84e 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.kt @@ -535,8 +535,8 @@ class GroupActivity : LockingActivity(), // Assign the group icon depending of IconPack or custom icon iconView?.visibility = View.VISIBLE mCurrentGroup?.let { - if (mDatabase?.drawFactory != null) - iconView?.assignDatabaseIcon(mDatabase?.drawFactory!!, it.icon, mIconColor) + if (mDatabase?.iconDrawableFactory != null) + iconView?.assignDatabaseIcon(mDatabase?.iconDrawableFactory!!, it.icon, mIconColor) if (toolbar != null) { if (mCurrentGroup?.containsParent() == true) diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/GroupEditDialogFragment.kt b/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/GroupEditDialogFragment.kt index 03feb9482..164434cea 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/GroupEditDialogFragment.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/GroupEditDialogFragment.kt @@ -205,8 +205,8 @@ class GroupEditDialogFragment : DialogFragment(), IconPickerDialogFragment.IconP } private fun assignIconView() { - if (mDatabase?.drawFactory != null) { - iconButtonView.assignDatabaseIcon(mDatabase?.drawFactory!!, mGroupInfo.icon, iconColor) + if (mDatabase?.iconDrawableFactory != null) { + iconButtonView.assignDatabaseIcon(mDatabase?.iconDrawableFactory!!, mGroupInfo.icon, iconColor) } } diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/IconPickerDialogFragment.kt b/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/IconPickerDialogFragment.kt index ad6be1693..542816aa5 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/IconPickerDialogFragment.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/IconPickerDialogFragment.kt @@ -24,15 +24,13 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.fragment.app.* +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.FragmentActivity import androidx.viewpager.widget.ViewPager import com.google.android.material.tabs.TabLayout import com.kunzisoft.keepass.R -import com.kunzisoft.keepass.activities.fragments.IconCustomFragment -import com.kunzisoft.keepass.activities.fragments.IconStandardFragment +import com.kunzisoft.keepass.adapters.IconPickerPagerAdapter import com.kunzisoft.keepass.database.element.icon.IconImage -import com.kunzisoft.keepass.database.element.icon.IconImageCustom -import com.kunzisoft.keepass.database.element.icon.IconImageStandard class IconPickerDialogFragment : DialogFragment() { @@ -45,7 +43,12 @@ class IconPickerDialogFragment : DialogFragment() { override fun onAttach(context: Context) { super.onAttach(context) try { - iconPickerListener = context as IconPickerListener + iconPickerListener = object : IconPickerListener { + override fun iconPicked(icon: IconImage) { + (context as IconPickerListener).iconPicked(icon) + dismiss() + } + } } catch (e: ClassCastException) { // The activity doesn't implement the interface, throw exception throw ClassCastException(context.toString() @@ -82,50 +85,14 @@ class IconPickerDialogFragment : DialogFragment() { val root = layoutInflater.inflate(R.layout.fragment_icon_picker, container) viewPager = root.findViewById(R.id.icon_picker_pager) tabLayout = root.findViewById(R.id.icon_picker_tabs) - iconPickerPagerAdapter = IconPickerPagerAdapter(childFragmentManager, { icon -> - iconPickerListener?.iconPicked(IconImage(icon)) - dismiss() - }, { icon -> - iconPickerListener?.iconPicked(IconImage(icon)) - dismiss() - } - ) + iconPickerPagerAdapter = IconPickerPagerAdapter(childFragmentManager) + iconPickerPagerAdapter.iconSelected = iconPickerListener viewPager.adapter = iconPickerPagerAdapter tabLayout.setupWithViewPager(viewPager) return root } - class IconPickerPagerAdapter(fragmentManager: FragmentManager, - iconStandardSelected: (icon: IconImageStandard) -> Unit, - iconCustomSelected: (icon: IconImageCustom) -> Unit) - : FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_SET_USER_VISIBLE_HINT) { - - private val iconStandardFragment = IconStandardFragment() - private val iconCustomFragment = IconCustomFragment() - - init { - iconStandardFragment.iconStandardPickerListener = iconStandardSelected - iconCustomFragment.iconCustomPickerListener = iconCustomSelected - } - - override fun getCount(): Int = 2 - - override fun getItem(i: Int): Fragment { - return when (i) { - 1 -> iconCustomFragment - else -> iconStandardFragment - } - } - - override fun getPageTitle(position: Int): CharSequence { - return when (position) { - 1 -> "Custom" //context.getString(R.string.iconStandard) - else -> "Standard" //context.getString(R.string.iconStandard) - } - } - } - interface IconPickerListener { fun iconPicked(icon: IconImage) } diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/fragments/IconCustomFragment.kt b/app/src/main/java/com/kunzisoft/keepass/activities/fragments/IconCustomFragment.kt index 1906b0e42..3b6780e42 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/fragments/IconCustomFragment.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/fragments/IconCustomFragment.kt @@ -1,98 +1,20 @@ package com.kunzisoft.keepass.activities.fragments -import android.content.Context -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.BaseAdapter -import android.widget.GridView -import android.widget.ImageView -import androidx.fragment.app.Fragment import com.kunzisoft.keepass.R import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.icon.IconImage -import com.kunzisoft.keepass.database.element.icon.IconImageCustom -import com.kunzisoft.keepass.database.element.icon.IconPool -import com.kunzisoft.keepass.icons.IconDrawableFactory -import com.kunzisoft.keepass.icons.assignDatabaseIcon /** * Content fragments */ -class IconCustomFragment : Fragment() { +class IconCustomFragment : IconFragment() { - private lateinit var currIconGridView: GridView - private var iconPool: IconPool? = null - private var iconDrawableFactory: IconDrawableFactory? = null - var iconCustomPickerListener: ((icon: IconImageCustom) -> Unit)? = null - - override fun onDetach() { - iconCustomPickerListener = null - super.onDetach() + override fun retrieveMainLayoutId(): Int { + return R.layout.fragment_icon_custom_picker } - override fun onCreateView(inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?): View { - val root = inflater.inflate(R.layout.fragment_icon_standard_picker, container, false) - currIconGridView = root.findViewById(R.id.IconGridView) - return root - } - - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - - - val database = Database.getInstance() - iconPool = database.iconPool - iconDrawableFactory = database.drawFactory - - currIconGridView.adapter = IconCustomAdapter(requireActivity()).apply { - iconPool?.doForEachCustomIcon { - putIcon(it) - } - } - } - - inner class IconCustomAdapter(private val context: Context) : BaseAdapter() { - - private val customIconList = ArrayList() - - fun putIcon(icon: IconImageCustom) { - customIconList.add(icon) - } - - override fun getCount(): Int { - return customIconList.size - } - - override fun getItem(position: Int): Any { - return customIconList[position] - } - - override fun getItemId(position: Int): Long { - return customIconList[position].uuid.leastSignificantBits - } - - override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { - val currentView: View = convertView - ?: (context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater) - .inflate(R.layout.item_icon, parent, false) - - val iconImage = IconImage(customIconList[position]) - - iconDrawableFactory?.let { - val iconImageView = currentView.findViewById(R.id.icon_image) - iconImageView.assignDatabaseIcon(it, iconImage) - } - - currentView.setOnClickListener { - iconCustomPickerListener?.invoke(iconImage.custom) - } - - return currentView - } + override fun defineIconList(database: Database): List { + return database.iconPool.getCustomIconList() } } \ No newline at end of file diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/fragments/IconFragment.kt b/app/src/main/java/com/kunzisoft/keepass/activities/fragments/IconFragment.kt new file mode 100644 index 000000000..22a539569 --- /dev/null +++ b/app/src/main/java/com/kunzisoft/keepass/activities/fragments/IconFragment.kt @@ -0,0 +1,52 @@ +package com.kunzisoft.keepass.activities.fragments + +import android.content.Context +import android.graphics.Color +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.RecyclerView +import com.kunzisoft.keepass.R +import com.kunzisoft.keepass.activities.dialogs.IconPickerDialogFragment +import com.kunzisoft.keepass.adapters.IconAdapter +import com.kunzisoft.keepass.database.element.Database +import com.kunzisoft.keepass.database.element.icon.IconImage + +abstract class IconFragment : Fragment() { + + private lateinit var iconsGridView: RecyclerView + private lateinit var iconAdapter: IconAdapter + var iconListener: IconPickerDialogFragment.IconPickerListener? = null + + abstract fun retrieveMainLayoutId(): Int + + abstract fun defineIconList(database: Database): List + + override fun onAttach(context: Context) { + super.onAttach(context) + + val database = Database.getInstance() + + iconAdapter = IconAdapter(requireActivity()).apply { + iconDrawableFactory = database.iconDrawableFactory + setList(defineIconList(database)) + } + iconAdapter.iconPickerListener = iconListener + } + + override fun onDetach() { + iconAdapter.iconPickerListener = null + super.onDetach() + } + + override fun onCreateView(inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?): View { + val root = inflater.inflate(retrieveMainLayoutId(), container, false) + iconsGridView = root.findViewById(R.id.icons_grid_view) + iconsGridView.adapter = iconAdapter + return root + } +} \ No newline at end of file diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/fragments/IconStandardFragment.kt b/app/src/main/java/com/kunzisoft/keepass/activities/fragments/IconStandardFragment.kt index 95485b902..48dd1c0be 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/fragments/IconStandardFragment.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/fragments/IconStandardFragment.kt @@ -1,89 +1,20 @@ package com.kunzisoft.keepass.activities.fragments -import android.content.Context -import android.content.res.ColorStateList -import android.graphics.Color -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.BaseAdapter -import android.widget.GridView -import android.widget.ImageView -import androidx.core.widget.ImageViewCompat -import androidx.fragment.app.Fragment import com.kunzisoft.keepass.R -import com.kunzisoft.keepass.database.element.icon.IconImageStandard -import com.kunzisoft.keepass.icons.IconPack -import com.kunzisoft.keepass.icons.IconPackChooser +import com.kunzisoft.keepass.database.element.Database +import com.kunzisoft.keepass.database.element.icon.IconImage /** * Content fragments */ -class IconStandardFragment : Fragment() { +class IconStandardFragment : IconFragment() { - private lateinit var currIconGridView: GridView - private var iconPack: IconPack? = null - var iconStandardPickerListener: ((icon: IconImageStandard) -> Unit)? = null - - override fun onDetach() { - iconStandardPickerListener = null - super.onDetach() + override fun retrieveMainLayoutId(): Int { + return R.layout.fragment_icon_standard_picker } - override fun onCreateView(inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?): View { - val root = inflater.inflate(R.layout.fragment_icon_standard_picker, container, false) - currIconGridView = root.findViewById(R.id.IconGridView) - return root - } - - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) - - iconPack = IconPackChooser.getSelectedIconPack(requireContext()) - currIconGridView.adapter = IconStandardAdapter(requireActivity()) - } - - inner class IconStandardAdapter(private val context: Context) : BaseAdapter() { - - override fun getCount(): Int { - return iconPack?.numberOfIcons() ?: 0 - } - - override fun getItem(position: Int): Any? { - return null - } - - override fun getItemId(position: Int): Long { - return 0 - } - - override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { - val currentView: View = convertView - ?: (context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater) - .inflate(R.layout.item_icon, parent, false) - - iconPack?.let { iconPack -> - val iconImageView = currentView.findViewById(R.id.icon_image) - iconImageView.setImageResource(iconPack.iconToResId(position)) - - // Assign color if icons are tintable - if (iconPack.tintable()) { - // Retrieve the textColor to tint the icon - val ta = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColor)) - ImageViewCompat.setImageTintList(iconImageView, ColorStateList.valueOf(ta.getColor(0, Color.BLACK))) - ta.recycle() - } - } - - currentView.setOnClickListener { - iconStandardPickerListener?.invoke(IconImageStandard(position)) - } - - return currentView - } + override fun defineIconList(database: Database): List { + return database.iconPool.getStandardIconList() } } \ No newline at end of file diff --git a/app/src/main/java/com/kunzisoft/keepass/adapters/IconAdapter.kt b/app/src/main/java/com/kunzisoft/keepass/adapters/IconAdapter.kt new file mode 100644 index 000000000..b75467762 --- /dev/null +++ b/app/src/main/java/com/kunzisoft/keepass/adapters/IconAdapter.kt @@ -0,0 +1,59 @@ +package com.kunzisoft.keepass.adapters + +import android.content.Context +import android.graphics.Color +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import androidx.recyclerview.widget.RecyclerView +import com.kunzisoft.keepass.R +import com.kunzisoft.keepass.activities.dialogs.IconPickerDialogFragment +import com.kunzisoft.keepass.database.element.icon.IconImage +import com.kunzisoft.keepass.icons.IconDrawableFactory +import com.kunzisoft.keepass.icons.assignDatabaseIcon + +class IconAdapter(context: Context) : RecyclerView.Adapter() { + + private val inflater: LayoutInflater = LayoutInflater.from(context) + + private val iconList = ArrayList() + + var iconDrawableFactory: IconDrawableFactory? = null + var iconPickerListener: IconPickerDialogFragment.IconPickerListener? = null + + var tintColor : Int = Color.BLACK + + init { + // Retrieve the textColor to tint the icon + val ta = context.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColor)) + tintColor = ta.getColor(0, Color.BLACK) + ta.recycle() + } + + fun setList(icon: List) { + iconList.clear() + iconList.addAll(icon) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomIconViewHolder { + val view = inflater.inflate(R.layout.item_icon, parent, false) + return CustomIconViewHolder(view) + } + + override fun onBindViewHolder(holder: CustomIconViewHolder, position: Int) { + val icon = iconList[position] + iconDrawableFactory?.let { + holder.iconImageView.assignDatabaseIcon(it, icon, tintColor) + } + holder.itemView.setOnClickListener { iconPickerListener?.iconPicked(icon) } + } + + override fun getItemCount(): Int { + return iconList.size + } + + inner class CustomIconViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + var iconImageView: ImageView = itemView.findViewById(R.id.icon_image) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/kunzisoft/keepass/adapters/IconPickerPagerAdapter.kt b/app/src/main/java/com/kunzisoft/keepass/adapters/IconPickerPagerAdapter.kt new file mode 100644 index 000000000..65d6a0c51 --- /dev/null +++ b/app/src/main/java/com/kunzisoft/keepass/adapters/IconPickerPagerAdapter.kt @@ -0,0 +1,34 @@ +package com.kunzisoft.keepass.adapters + +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentStatePagerAdapter +import com.kunzisoft.keepass.activities.dialogs.IconPickerDialogFragment +import com.kunzisoft.keepass.activities.fragments.IconCustomFragment +import com.kunzisoft.keepass.activities.fragments.IconStandardFragment + +class IconPickerPagerAdapter(fragmentManager: FragmentManager) + : FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_SET_USER_VISIBLE_HINT) { + + var iconSelected: IconPickerDialogFragment.IconPickerListener? = null + private val iconStandardFragment = IconStandardFragment() + private val iconCustomFragment = IconCustomFragment() + + override fun getCount(): Int = 2 + + override fun getItem(i: Int): Fragment { + return when (i) { + 1 -> iconCustomFragment + else -> iconStandardFragment + }.apply { + iconListener = iconSelected + } + } + + override fun getPageTitle(position: Int): CharSequence { + return when (position) { + 1 -> "Custom" //context.getString(R.string.iconStandard) + else -> "Standard" //context.getString(R.string.iconStandard) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/kunzisoft/keepass/adapters/NodeAdapter.kt b/app/src/main/java/com/kunzisoft/keepass/adapters/NodeAdapter.kt index d38f8e421..d673cbbd2 100644 --- a/app/src/main/java/com/kunzisoft/keepass/adapters/NodeAdapter.kt +++ b/app/src/main/java/com/kunzisoft/keepass/adapters/NodeAdapter.kt @@ -304,7 +304,7 @@ class NodeAdapter (private val context: Context) } holder.imageIdentifier?.setColorFilter(iconColor) holder.icon.apply { - assignDatabaseIcon(mDatabase.drawFactory, subNode.icon, iconColor) + assignDatabaseIcon(mDatabase.iconDrawableFactory, subNode.icon, iconColor) // Relative size of the icon layoutParams?.apply { height = (mIconDefaultDimension * mPrefSizeMultiplier).toInt() diff --git a/app/src/main/java/com/kunzisoft/keepass/adapters/SearchEntryCursorAdapter.kt b/app/src/main/java/com/kunzisoft/keepass/adapters/SearchEntryCursorAdapter.kt index c3cfd04f6..eee45b078 100644 --- a/app/src/main/java/com/kunzisoft/keepass/adapters/SearchEntryCursorAdapter.kt +++ b/app/src/main/java/com/kunzisoft/keepass/adapters/SearchEntryCursorAdapter.kt @@ -82,7 +82,7 @@ class SearchEntryCursorAdapter(private val context: Context, // Assign image viewHolder.imageViewIcon?.assignDatabaseIcon( - database.drawFactory, + database.iconDrawableFactory, currentEntry.icon, iconColor) diff --git a/app/src/main/java/com/kunzisoft/keepass/autofill/AutofillHelper.kt b/app/src/main/java/com/kunzisoft/keepass/autofill/AutofillHelper.kt index aba7353a8..f60ccb5d2 100644 --- a/app/src/main/java/com/kunzisoft/keepass/autofill/AutofillHelper.kt +++ b/app/src/main/java/com/kunzisoft/keepass/autofill/AutofillHelper.kt @@ -276,7 +276,7 @@ object AutofillHelper { if (remoteViewsIcon != null) { presentation.assignDatabaseIcon(context, R.id.autofill_entry_icon, - Database.getInstance().drawFactory, + Database.getInstance().iconDrawableFactory, remoteViewsIcon, ContextCompat.getColor(context, R.color.green)) } @@ -285,7 +285,7 @@ object AutofillHelper { private fun buildIconFromEntry(context: Context, entryInfo: EntryInfo): Icon? { return createIconFromDatabaseIcon(context, - Database.getInstance().drawFactory, + Database.getInstance().iconDrawableFactory, entryInfo.icon, ContextCompat.getColor(context, R.color.green)) } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/Database.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/Database.kt index de0f8646c..812519c47 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/Database.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/Database.kt @@ -67,7 +67,7 @@ class Database { var isReadOnly = false - val drawFactory = IconDrawableFactory() + val iconDrawableFactory = IconDrawableFactory() var loaded = false set(value) { @@ -625,7 +625,7 @@ class Database { fun clear(filesDirectory: File? = null) { iconPool.clearCache() - drawFactory.clearCache() + iconDrawableFactory.clearCache() // Delete the cache of the database if present mDatabaseKDB?.clearCache() mDatabaseKDBX?.clearCache() diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/icon/IconImageStandard.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/icon/IconImageStandard.kt index bc529b681..48cad7ba5 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/icon/IconImageStandard.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/icon/IconImageStandard.kt @@ -21,6 +21,7 @@ package com.kunzisoft.keepass.database.element.icon import android.os.Parcel import android.os.Parcelable +import com.kunzisoft.keepass.icons.IconPack.Companion.NB_ICONS class IconImageStandard : Parcelable { @@ -31,7 +32,7 @@ class IconImageStandard : Parcelable { } constructor(iconId: Int) { - if (iconId < MIN_ID || iconId > MAX_ID) + if (iconId < 0 || iconId > NB_ICONS) this.id = KEY_ID else this.id = iconId @@ -72,8 +73,6 @@ class IconImageStandard : Parcelable { const val KEY_ID = 0 const val TRASH_ID = 43 const val FOLDER_ID = 48 - const val MIN_ID = 0 - const val MAX_ID = 48 @JvmField val CREATOR: Parcelable.Creator = object : Parcelable.Creator { diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/icon/IconPool.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/icon/IconPool.kt index cc1d348c6..c27cf51db 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/icon/IconPool.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/icon/IconPool.kt @@ -19,22 +19,31 @@ */ package com.kunzisoft.keepass.database.element.icon +import com.kunzisoft.keepass.icons.IconPack.Companion.NB_ICONS +import java.util.ArrayList import java.util.UUID class IconPool { - private val standardCache = HashMap() + private val standardCache = List(NB_ICONS) { + IconImageStandard(it) + } private val customCache = HashMap() fun getIcon(iconId: Int): IconImageStandard { - var icon: IconImageStandard? = standardCache[iconId] + return standardCache[iconId] + } - if (icon == null) { - icon = IconImageStandard(iconId) - standardCache[iconId] = icon - } + fun getStandardIconList(): List { + return standardCache.mapIndexed { _, iconImageStandard -> IconImage(iconImageStandard) } + } - return icon + /* + * Custom + */ + + fun putIcon(icon: IconImageCustom) { + customCache[icon.uuid] = icon } fun getIcon(iconUuid: UUID): IconImageCustom { @@ -48,25 +57,22 @@ class IconPool { return icon } - fun putIcon(icon: IconImageCustom) { - customCache[icon.uuid] = icon - } - fun containsCustomIcons(): Boolean { return customCache.isNotEmpty() } - fun doForEachCustomIcon(action: (customIcon: IconImageCustom) -> Unit) { + fun getCustomIconList(): List { + val list = ArrayList(customCache.size) for ((_, customIcon) in customCache) { - action.invoke(customIcon!!) + list.add(IconImage(customIcon!!)) } + return list } /** * Clear the cache of icons */ fun clearCache() { - standardCache.clear() customCache.clear() } } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDBX.kt b/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDBX.kt index 9944d1f48..34f695529 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDBX.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDBX.kt @@ -701,11 +701,11 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX, xml.startTag(null, DatabaseKDBXXML.ElemCustomIcons) - mDatabaseKDBX.iconPool.doForEachCustomIcon { customIcon -> + mDatabaseKDBX.iconPool.getCustomIconList().forEach { icon -> xml.startTag(null, DatabaseKDBXXML.ElemCustomIconItem) - writeUuid(DatabaseKDBXXML.ElemCustomIconItemID, customIcon.uuid) - writeObject(DatabaseKDBXXML.ElemCustomIconItemData, String(Base64.encode(customIcon.imageData, BASE_64_FLAG))) + writeUuid(DatabaseKDBXXML.ElemCustomIconItemID, icon.custom.uuid) + writeObject(DatabaseKDBXXML.ElemCustomIconItemData, String(Base64.encode(icon.custom.imageData, BASE_64_FLAG))) xml.endTag(null, DatabaseKDBXXML.ElemCustomIconItem) } diff --git a/app/src/main/java/com/kunzisoft/keepass/icons/IconDrawableFactory.kt b/app/src/main/java/com/kunzisoft/keepass/icons/IconDrawableFactory.kt index 270d74780..06a244b70 100644 --- a/app/src/main/java/com/kunzisoft/keepass/icons/IconDrawableFactory.kt +++ b/app/src/main/java/com/kunzisoft/keepass/icons/IconDrawableFactory.kt @@ -111,21 +111,16 @@ class IconDrawableFactory { fun getIconSuperDrawable(context: Context, icon: IconImage, width: Int, tint: Boolean = false, tintColor: Int = Color.WHITE): SuperDrawable { return if (!icon.custom.isUnknown) { SuperDrawable(getIconDrawable(context.resources, icon.custom)) - } else IconPackChooser.getSelectedIconPack(context)?.iconToResId(icon.standard.id)?.let { resId -> - getIconSuperDrawable(context, resId, width, tint, tintColor) - } ?: run { - SuperDrawable(PatternIcon(context.resources).blankDrawable) + } else { + val iconPack = IconPackChooser.getSelectedIconPack(context) + iconPack?.iconToResId(icon.standard.id)?.let { iconId -> + SuperDrawable(getIconDrawable(context.resources, iconId, width, tint, tintColor), iconPack.tintable()) + } ?: run { + SuperDrawable(PatternIcon(context.resources).blankDrawable) + } } } - /** - * Get the [SuperDrawable] IconImageStandard from [iconId] (cache, or build it and add it to the cache if not exists yet) - * , then [tint] it with [tintColor] if needed - */ - fun getIconSuperDrawable(context: Context, iconId: Int, width: Int, tint: Boolean, tintColor: Int): SuperDrawable { - return SuperDrawable(getIconDrawable(context.resources, iconId, width, tint, tintColor), true) - } - /** * Key class to retrieve a Drawable in the cache if it's tinted or not */ @@ -258,28 +253,6 @@ class IconDrawableFactory { } -/** - * Assign a default database icon to an ImageView and tint it with [tintColor] if needed - */ -fun ImageView.assignDefaultDatabaseIcon(iconFactory: IconDrawableFactory, - tintColor: Int = Color.WHITE) { - try { - IconPackChooser.getSelectedIconPack(context)?.let { selectedIconPack -> - iconFactory.assignDrawableToImageView( - iconFactory.getIconSuperDrawable(context, - selectedIconPack.defaultIconId, - width, - selectedIconPack.tintable(), - tintColor), - this, - selectedIconPack.tintable(), - tintColor) - } - } catch (e: Exception) { - Log.e(ImageView::class.java.name, "Unable to assign icon in image view", e) - } -} - /** * Assign a database [icon] to an ImageView and tint it with [tintColor] if needed */ diff --git a/app/src/main/java/com/kunzisoft/keepass/icons/IconPack.kt b/app/src/main/java/com/kunzisoft/keepass/icons/IconPack.kt index 09ebd8f3f..4616f9cde 100644 --- a/app/src/main/java/com/kunzisoft/keepass/icons/IconPack.kt +++ b/app/src/main/java/com/kunzisoft/keepass/icons/IconPack.kt @@ -134,7 +134,6 @@ class IconPack(packageName: String, resources: Resources, resourceId: Int) { } companion object { - - private const val NB_ICONS = 68 + const val NB_ICONS = 68 } } diff --git a/app/src/main/java/com/kunzisoft/keepass/icons/IconPackChooser.kt b/app/src/main/java/com/kunzisoft/keepass/icons/IconPackChooser.kt index f38321554..db72f9287 100644 --- a/app/src/main/java/com/kunzisoft/keepass/icons/IconPackChooser.kt +++ b/app/src/main/java/com/kunzisoft/keepass/icons/IconPackChooser.kt @@ -93,7 +93,7 @@ object IconPackChooser { fun setSelectedIconPack(iconPackIdString: String?) { for (iconPack in iconPackList) { if (iconPack.id == iconPackIdString) { - Database.getInstance().drawFactory.clearCache() + Database.getInstance().iconDrawableFactory.clearCache() iconPackSelected = iconPack break } diff --git a/app/src/main/res/layout/fragment_icon_custom_picker.xml b/app/src/main/res/layout/fragment_icon_custom_picker.xml new file mode 100644 index 000000000..f55703542 --- /dev/null +++ b/app/src/main/res/layout/fragment_icon_custom_picker.xml @@ -0,0 +1,35 @@ + + + + diff --git a/app/src/main/res/layout/fragment_icon_standard_picker.xml b/app/src/main/res/layout/fragment_icon_standard_picker.xml index ff2199f6a..f55703542 100644 --- a/app/src/main/res/layout/fragment_icon_standard_picker.xml +++ b/app/src/main/res/layout/fragment_icon_standard_picker.xml @@ -17,10 +17,14 @@ You should have received a copy of the GNU General Public License along with KeePassDX. If not, see . --> - - +