From 1d6a9651bfce397c1052a760e9f58501f123d563 Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Sun, 20 Oct 2024 18:44:06 +0200 Subject: [PATCH] fix: upgrade to API34 #1894 --- CHANGELOG | 1 + .../keepass/activities/GroupActivity.kt | 74 +++++++-------- .../keepass/adapters/BreadcrumbAdapter.kt | 14 +-- .../kunzisoft/keepass/adapters/NodeFilter.kt | 31 +++++++ .../keepass/adapters/NodesAdapter.kt | 13 +-- .../keepass/settings/PreferencesUtil.kt | 6 ++ app/src/main/res/values/donottranslate.xml | 2 + app/src/main/res/values/strings.xml | 2 + .../main/res/xml/preferences_appearance.xml | 5 ++ .../keepass/database/element/Group.kt | 89 +++++-------------- .../keepass/database/search/SearchHelper.kt | 2 +- .../metadata/android/en-US/changelogs/132.txt | 3 +- 12 files changed, 124 insertions(+), 118 deletions(-) create mode 100644 app/src/main/java/com/kunzisoft/keepass/adapters/NodeFilter.kt diff --git a/CHANGELOG b/CHANGELOG index 1b3445661..0c0687bfb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ KeePassDX(4.1.0) * Upgrade to API 34 (Android 14) + * Hide template group #1894 KeePassDX(4.0.8) * Fix graphical bug that prevented databases from being opened on some versions of Android #1848 #1850 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 c0f65fb4d..3b2b3a9bf 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.kt @@ -358,43 +358,6 @@ class GroupActivity : DatabaseLockActivity(), searchFiltersView?.closeAdvancedFilters() - mBreadcrumbAdapter = BreadcrumbAdapter(this).apply { - // Open group on breadcrumb click - onItemClickListener = { node, _ -> - // If last item & not a virtual root group - val currentGroup = mMainGroup - if (currentGroup != null && node == currentGroup - && (currentGroup != mDatabase?.rootGroup - || mDatabase?.rootGroupIsVirtual == false) - ) { - finishNodeAction() - launchDialogToShowGroupInfo(currentGroup) - } else { - if (mGroupFragment?.nodeActionSelectionMode == true) { - finishNodeAction() - } - mDatabase?.let { database -> - onNodeClick(database, node) - } - } - } - onLongItemClickListener = { node, position -> - val currentGroup = mMainGroup - if (currentGroup != null && node == currentGroup - && (currentGroup != mDatabase?.rootGroup - || mDatabase?.rootGroupIsVirtual == false) - ) { - finishNodeAction() - launchDialogForGroupUpdate(currentGroup) - } else { - onItemClickListener?.invoke(node, position) - } - } - } - breadcrumbListView?.apply { - adapter = mBreadcrumbAdapter - } - // Retrieve group if defined at launch manageIntent(intent) @@ -616,6 +579,43 @@ class GroupActivity : DatabaseLockActivity(), override fun onDatabaseRetrieved(database: ContextualDatabase?) { super.onDatabaseRetrieved(database) + mBreadcrumbAdapter = BreadcrumbAdapter(this, database).apply { + // Open group on breadcrumb click + onItemClickListener = { node, _ -> + // If last item & not a virtual root group + val currentGroup = mMainGroup + if (currentGroup != null && node == currentGroup + && (currentGroup != mDatabase?.rootGroup + || mDatabase?.rootGroupIsVirtual == false) + ) { + finishNodeAction() + launchDialogToShowGroupInfo(currentGroup) + } else { + if (mGroupFragment?.nodeActionSelectionMode == true) { + finishNodeAction() + } + mDatabase?.let { database -> + onNodeClick(database, node) + } + } + } + onLongItemClickListener = { node, position -> + val currentGroup = mMainGroup + if (currentGroup != null && node == currentGroup + && (currentGroup != mDatabase?.rootGroup + || mDatabase?.rootGroupIsVirtual == false) + ) { + finishNodeAction() + launchDialogForGroupUpdate(currentGroup) + } else { + onItemClickListener?.invoke(node, position) + } + } + } + breadcrumbListView?.apply { + adapter = mBreadcrumbAdapter + } + mGroupEditViewModel.setGroupNamesNotAllowed(database?.groupNamesNotAllowed) mRecyclingBinEnabled = !mDatabaseReadOnly diff --git a/app/src/main/java/com/kunzisoft/keepass/adapters/BreadcrumbAdapter.kt b/app/src/main/java/com/kunzisoft/keepass/adapters/BreadcrumbAdapter.kt index 6b0dafb2b..5a4fcfab5 100644 --- a/app/src/main/java/com/kunzisoft/keepass/adapters/BreadcrumbAdapter.kt +++ b/app/src/main/java/com/kunzisoft/keepass/adapters/BreadcrumbAdapter.kt @@ -10,6 +10,7 @@ import android.widget.ImageView import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.kunzisoft.keepass.R +import com.kunzisoft.keepass.database.element.Database import com.kunzisoft.keepass.database.element.Group import com.kunzisoft.keepass.database.element.node.Node import com.kunzisoft.keepass.database.element.node.Type @@ -17,7 +18,7 @@ import com.kunzisoft.keepass.icons.IconDrawableFactory import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.view.strikeOut -class BreadcrumbAdapter(val context: Context) +class BreadcrumbAdapter(val context: Context, val database: Database?) : RecyclerView.Adapter() { private val inflater: LayoutInflater = LayoutInflater.from(context) @@ -31,6 +32,8 @@ class BreadcrumbAdapter(val context: Context) var onItemClickListener: ((item: Node, position: Int)->Unit)? = null var onLongItemClickListener: ((item: Node, position: Int)->Unit)? = null + private var mNodeFilter: NodeFilter = NodeFilter(context, database) + private var mShowNumberEntries = false private var mShowUUID = false private var mIconColor: Int = 0 @@ -112,12 +115,9 @@ class BreadcrumbAdapter(val context: Context) holder.groupNumbersView?.apply { if (mShowNumberEntries) { - group.refreshNumberOfChildEntries( - Group.ChildFilter.getDefaults( - PreferencesUtil.showExpiredEntries(context) - ) - ) - text = group.recursiveNumberOfChildEntries.toString() + text = group.getNumberOfChildEntries { + mNodeFilter.getFilter(node) + }.toString() visibility = View.VISIBLE } else { visibility = View.GONE diff --git a/app/src/main/java/com/kunzisoft/keepass/adapters/NodeFilter.kt b/app/src/main/java/com/kunzisoft/keepass/adapters/NodeFilter.kt new file mode 100644 index 000000000..d23255ea7 --- /dev/null +++ b/app/src/main/java/com/kunzisoft/keepass/adapters/NodeFilter.kt @@ -0,0 +1,31 @@ +package com.kunzisoft.keepass.adapters + +import android.content.Context +import com.kunzisoft.keepass.database.element.Database +import com.kunzisoft.keepass.database.element.Entry +import com.kunzisoft.keepass.database.element.Group +import com.kunzisoft.keepass.database.element.node.Node +import com.kunzisoft.keepass.settings.PreferencesUtil + +class NodeFilter( + context: Context, + var database: Database? = null +) { + private var showExpired = PreferencesUtil.showExpiredEntries(context) + private var showTemplate = PreferencesUtil.showTemplates(context) + + fun getFilter(node: Node): Boolean { + return (when (node) { + is Entry -> { + node.entryKDB?.isMetaStream() != true + && (showTemplate || database?.templatesGroup?.let { + template -> node.isContainedIn(template) + } != true) + } + is Group -> { + showTemplate || database?.templatesGroup != node + } + else -> true + }) && (showExpired || !node.isCurrentlyExpires) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/kunzisoft/keepass/adapters/NodesAdapter.kt b/app/src/main/java/com/kunzisoft/keepass/adapters/NodesAdapter.kt index fc47ca14f..9dae37cb9 100644 --- a/app/src/main/java/com/kunzisoft/keepass/adapters/NodesAdapter.kt +++ b/app/src/main/java/com/kunzisoft/keepass/adapters/NodesAdapter.kt @@ -66,6 +66,7 @@ class NodesAdapter ( private val mNodeSortedListCallback: NodeSortedListCallback private val mNodeSortedList: SortedList private val mInflater: LayoutInflater = LayoutInflater.from(context) + private val mNodeFilter: NodeFilter = NodeFilter(context, database) private var mCalculateViewTypeTextSize = Array(2) { true } // number of view type private var mTextSizeUnit: Int = TypedValue.COMPLEX_UNIT_PX @@ -82,7 +83,7 @@ class NodesAdapter ( private var mShowNumberEntries: Boolean = true private var mShowOTP: Boolean = false private var mShowUUID: Boolean = false - private var mEntryFilters = arrayOf() + private var mNodeFilters: NodeFilter? = null private var mOldVirtualGroup = false private var mVirtualGroup = false @@ -161,9 +162,7 @@ class NodesAdapter ( this.mShowOTP = PreferencesUtil.showOTPToken(context) this.mShowUUID = PreferencesUtil.showUUID(context) - this.mEntryFilters = Group.ChildFilter.getDefaults( - PreferencesUtil.showExpiredEntries(context) - ) + this.mNodeFilters = NodeFilter(context, database) // Reinit textSize for all view type mCalculateViewTypeTextSize.forEachIndexed { index, _ -> mCalculateViewTypeTextSize[index] = true } @@ -176,7 +175,9 @@ class NodesAdapter ( mOldVirtualGroup = mVirtualGroup mVirtualGroup = group.isVirtual assignPreferences() - mNodeSortedList.replaceAll(group.getFilteredChildren(mEntryFilters)) + mNodeSortedList.replaceAll(group.getChildren { node -> + mNodeFilters?.getFilter(node) ?: true + }) } private inner class NodeSortedListCallback: SortedListAdapterCallback(this) { @@ -473,7 +474,7 @@ class NodesAdapter ( if (mShowNumberEntries) { holder.numberChildren?.apply { text = (subNode as Group) - .recursiveNumberOfChildEntries + .getNumberOfChildEntries { mNodeFilter.getFilter(subNode) } .toString() setTextSize(mTextSizeUnit, mNumberChildrenTextDefaultDimension, mPrefSizeMultiplier) visibility = View.VISIBLE diff --git a/app/src/main/java/com/kunzisoft/keepass/settings/PreferencesUtil.kt b/app/src/main/java/com/kunzisoft/keepass/settings/PreferencesUtil.kt index 7d3367341..33203dfa2 100644 --- a/app/src/main/java/com/kunzisoft/keepass/settings/PreferencesUtil.kt +++ b/app/src/main/java/com/kunzisoft/keepass/settings/PreferencesUtil.kt @@ -162,6 +162,12 @@ object PreferencesUtil { context.resources.getBoolean(R.bool.hide_expired_entries_default)) } + fun showTemplates(context: Context): Boolean { + val prefs = PreferenceManager.getDefaultSharedPreferences(context) + return ! prefs.getBoolean(context.getString(R.string.hide_templates_key), + context.resources.getBoolean(R.bool.hide_templates_default)) + } + fun getStyle(context: Context): String { val defaultStyleString = Stylish.defaultStyle(context) val styleString = PreferenceManager.getDefaultSharedPreferences(context) diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index c04db498b..a16437539 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -203,6 +203,8 @@ true hide_expired_entries_key false + hide_templates_key + true enable_education_screens_key true relaunch_education_screens_key diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f4befb9e5..f9575b3b6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -733,4 +733,6 @@ Displays foreground and background colors for an entry Hide expired entries Expired entries are not shown + Hide templates + Templates are not shown \ No newline at end of file diff --git a/app/src/main/res/xml/preferences_appearance.xml b/app/src/main/res/xml/preferences_appearance.xml index d7610d6c2..d56f42318 100644 --- a/app/src/main/res/xml/preferences_appearance.xml +++ b/app/src/main/res/xml/preferences_appearance.xml @@ -111,6 +111,11 @@ android:title="@string/hide_expired_entries_title" android:summary="@string/hide_expired_entries_summary" android:defaultValue="@bool/hide_expired_entries_default"/> + { @@ -45,8 +48,11 @@ class Group : Node, GroupVersionedInterface { // Virtual group is used to defined a detached database group var isVirtual = false + // To optimize number of children call var numberOfChildEntries: Int = 0 + private set var recursiveNumberOfChildEntries: Int = 0 + private set /** * Use this constructor to copy a Group @@ -84,20 +90,6 @@ class Group : Node, GroupVersionedInterface { isVirtual = parcel.readBooleanCompat() } - enum class ChildFilter { - META_STREAM, EXPIRED; - - companion object { - fun getDefaults(showExpiredEntries: Boolean): Array { - return if (showExpiredEntries) { - arrayOf(META_STREAM) - } else { - arrayOf(META_STREAM, EXPIRED) - } - } - } - } - companion object CREATOR : Parcelable.Creator { override fun createFromParcel(parcel: Parcel): Group { return Group(parcel) @@ -280,20 +272,6 @@ class Group : Node, GroupVersionedInterface { ArrayList() } - fun getFilteredChildGroups(filters: Array): List { - return groupKDB?.getChildGroups()?.map { - Group(it).apply { - this.refreshNumberOfChildEntries(filters) - } - } ?: - groupKDBX?.getChildGroups()?.map { - Group(it).apply { - this.refreshNumberOfChildEntries(filters) - } - } ?: - ArrayList() - } - override fun getChildEntries(): List { return groupKDB?.getChildEntries()?.map { Entry(it) @@ -312,53 +290,32 @@ class Group : Node, GroupVersionedInterface { return entriesInfo } - fun getFilteredChildEntries(filters: Array): List { - val withoutMetaStream = filters.contains(ChildFilter.META_STREAM) - val showExpiredEntries = !filters.contains(ChildFilter.EXPIRED) - - // TODO Change KDB parser to remove meta entries - return groupKDB?.getChildEntries()?.filter { - (!withoutMetaStream || (withoutMetaStream && !it.isMetaStream())) - && (!it.isCurrentlyExpires or showExpiredEntries) - }?.map { - Entry(it) - } ?: - groupKDBX?.getChildEntries()?.filter { - !it.isCurrentlyExpires or showExpiredEntries - }?.map { - Entry(it) - } ?: - ArrayList() - } - - fun refreshNumberOfChildEntries(filters: Array = emptyArray()) { - this.numberOfChildEntries = getFilteredChildEntries(filters).size - this.recursiveNumberOfChildEntries = getFilteredChildEntriesInGroups(filters) - } - /** * @return the cumulative number of entries in the current group and its children */ - private fun getFilteredChildEntriesInGroups(filters: Array): Int { + private fun getNumberOfChildEntriesInGroups(filter: (Node) -> Boolean): Int { var counter = 0 getChildGroups().forEach { childGroup -> - counter += childGroup.getFilteredChildEntriesInGroups(filters) + counter += childGroup.getNumberOfChildEntriesInGroups(filter) } - return getFilteredChildEntries(filters).size + counter + return getChildEntries().filter(filter).size + counter + } + + fun getNumberOfChildEntries( + directChildren: Boolean = true, + filter: (Node) -> Boolean = { true } + ): Int { + numberOfChildEntries = getChildEntries().filter(filter).size + recursiveNumberOfChildEntries = getNumberOfChildEntriesInGroups(filter) + return if (directChildren) numberOfChildEntries else recursiveNumberOfChildEntries } /** * Filter entries and return children * @return List of direct children (one level below) as NodeVersioned */ - fun getChildren(): List { - return getChildGroups() + getChildEntries() - } - - fun getFilteredChildren(filters: Array): List { - val nodes = getFilteredChildGroups(filters) + getFilteredChildEntries(filters) - refreshNumberOfChildEntries(filters) - return nodes + fun getChildren(filter: ((Node) -> Boolean) = { true }): List { + return getChildGroups().filter(filter) + getChildEntries().filter(filter) } override fun addChildGroup(group: Group) { diff --git a/database/src/main/java/com/kunzisoft/keepass/database/search/SearchHelper.kt b/database/src/main/java/com/kunzisoft/keepass/database/search/SearchHelper.kt index 01d8b8e52..7bb10be08 100644 --- a/database/src/main/java/com/kunzisoft/keepass/database/search/SearchHelper.kt +++ b/database/src/main/java/com/kunzisoft/keepass/database/search/SearchHelper.kt @@ -78,7 +78,7 @@ class SearchHelper { ) } - searchGroup?.refreshNumberOfChildEntries() + searchGroup?.getNumberOfChildEntries() return searchGroup } diff --git a/fastlane/metadata/android/en-US/changelogs/132.txt b/fastlane/metadata/android/en-US/changelogs/132.txt index dad2ff6c8..e7b913ee3 100644 --- a/fastlane/metadata/android/en-US/changelogs/132.txt +++ b/fastlane/metadata/android/en-US/changelogs/132.txt @@ -1 +1,2 @@ - * Upgrade to API 34 (Android 14) \ No newline at end of file + * Upgrade to API 34 (Android 14) + * Hide template group #1894 \ No newline at end of file