mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Add search filters view
This commit is contained in:
@@ -40,6 +40,7 @@ import androidx.appcompat.view.ActionMode
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.dialogs.*
|
||||
@@ -55,6 +56,7 @@ import com.kunzisoft.keepass.database.element.node.Node
|
||||
import com.kunzisoft.keepass.database.element.node.NodeId
|
||||
import com.kunzisoft.keepass.database.element.node.Type
|
||||
import com.kunzisoft.keepass.database.search.SearchHelper
|
||||
import com.kunzisoft.keepass.database.search.SearchParameters
|
||||
import com.kunzisoft.keepass.education.GroupActivityEducation
|
||||
import com.kunzisoft.keepass.model.GroupInfo
|
||||
import com.kunzisoft.keepass.model.RegisterInfo
|
||||
@@ -89,11 +91,8 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
private var databaseNameContainer: ViewGroup? = null
|
||||
private var databaseColorView: ImageView? = null
|
||||
private var databaseNameView: TextView? = null
|
||||
private var searchContainer: ViewGroup? = null
|
||||
private var searchAdvanceFiltersContainer: ViewGroup? = null
|
||||
private var searchExpandButton: ImageView? = null
|
||||
private var searchNumbers: TextView? = null
|
||||
private var searchView: SearchView? = null
|
||||
private var searchFiltersView: SearchFiltersView? = null
|
||||
private var toolbarBreadcrumb: Toolbar? = null
|
||||
private var toolbarAction: ToolbarAction? = null
|
||||
private var numberChildrenView: TextView? = null
|
||||
@@ -121,34 +120,47 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
private var mPreviousGroupsIds = mutableListOf<GroupState>()
|
||||
private var mOldGroupToUpdate: Group? = null
|
||||
|
||||
private val mOnSearchActionExpandListener = object : MenuItem.OnActionExpandListener {
|
||||
override fun onMenuItemActionExpand(p0: MenuItem?): Boolean {
|
||||
toolbarBreadcrumb?.hideByFading()
|
||||
searchAdvanceFiltersContainer?.visibility = View.GONE
|
||||
searchContainer?.showByFading()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onMenuItemActionCollapse(p0: MenuItem?): Boolean {
|
||||
searchContainer?.hideByFading()
|
||||
if (searchAdvanceFiltersContainer?.visibility == View.VISIBLE) {
|
||||
searchAdvanceFiltersContainer?.visibility = View.INVISIBLE
|
||||
searchAdvanceFiltersContainer?.collapse()
|
||||
}
|
||||
toolbarBreadcrumb?.showByFading()
|
||||
mSearchGroup = null
|
||||
loadGroup(mDatabase)
|
||||
return true
|
||||
}
|
||||
}
|
||||
private val mOnSearchQueryTextListener = object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||
loadSearchGroup(query)
|
||||
if (query != null) {
|
||||
searchFiltersView?.setQuery(query)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
loadSearchGroup(newText)
|
||||
if (newText != null) {
|
||||
searchFiltersView?.setQuery(newText)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
private val mOnSearchFiltersChangeListener = object : ((SearchParameters) -> Unit) {
|
||||
override fun invoke(searchParameters: SearchParameters) {
|
||||
mGroupViewModel.loadGroupFromSearch(
|
||||
mDatabase,
|
||||
searchParameters,
|
||||
PreferencesUtil.omitBackup(this@GroupActivity)
|
||||
)
|
||||
}
|
||||
}
|
||||
private val mOnSearchActionExpandListener = object : MenuItem.OnActionExpandListener {
|
||||
override fun onMenuItemActionExpand(p0: MenuItem?): Boolean {
|
||||
toolbarBreadcrumb?.hideByFading()
|
||||
searchFiltersView?.isVisible = true
|
||||
searchView?.setOnQueryTextListener(mOnSearchQueryTextListener)
|
||||
searchFiltersView?.onParametersChangeListener = mOnSearchFiltersChangeListener
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onMenuItemActionCollapse(p0: MenuItem?): Boolean {
|
||||
searchFiltersView?.onParametersChangeListener = null
|
||||
searchView?.setOnQueryTextListener(null)
|
||||
searchFiltersView?.isVisible = false
|
||||
toolbarBreadcrumb?.showByFading()
|
||||
|
||||
removeSearch()
|
||||
loadGroup(mDatabase)
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -178,10 +190,7 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
databaseNameContainer = findViewById(R.id.database_name_container)
|
||||
databaseColorView = findViewById(R.id.database_color)
|
||||
databaseNameView = findViewById(R.id.database_name)
|
||||
searchContainer = findViewById(R.id.search_container)
|
||||
searchAdvanceFiltersContainer = findViewById(R.id.search_advance_filters)
|
||||
searchExpandButton = findViewById(R.id.search_expand)
|
||||
searchNumbers = findViewById(R.id.search_numbers)
|
||||
searchFiltersView = findViewById(R.id.search_filters)
|
||||
toolbarBreadcrumb = findViewById(R.id.toolbar_breadcrumb)
|
||||
breadcrumbListView = findViewById(R.id.breadcrumb_list)
|
||||
toolbarAction = findViewById(R.id.toolbar_action)
|
||||
@@ -259,20 +268,6 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
savedInstanceState.remove(PREVIOUS_GROUPS_IDS_KEY)
|
||||
}
|
||||
|
||||
// Expand menu with button
|
||||
searchExpandButton?.setOnClickListener {
|
||||
searchAdvanceFiltersContainer?.let { advanceSearch ->
|
||||
val isVisible = advanceSearch.visibility == View.VISIBLE
|
||||
if (isVisible)
|
||||
advanceSearch.collapse()
|
||||
else {
|
||||
advanceSearch.expand(true,
|
||||
resources.getDimension(R.dimen.advanced_search_height).toInt()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the fragment with the list
|
||||
mGroupFragment =
|
||||
supportFragmentManager.findFragmentByTag(GROUP_FRAGMENT_TAG) as GroupFragment?
|
||||
@@ -422,15 +417,12 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
}
|
||||
|
||||
private fun loadGroup(database: Database?) {
|
||||
loadingView?.showByFading()
|
||||
when {
|
||||
Intent.ACTION_SEARCH == intent.action -> {
|
||||
finishNodeAction()
|
||||
val searchString =
|
||||
searchFiltersView?.setQuery(
|
||||
intent.getStringExtra(SearchManager.QUERY)?.trim { it <= ' ' } ?: ""
|
||||
mGroupViewModel.loadGroupFromSearch(
|
||||
database,
|
||||
searchString,
|
||||
PreferencesUtil.omitBackup(this)
|
||||
)
|
||||
}
|
||||
mCurrentGroupState == null -> {
|
||||
@@ -606,7 +598,7 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
// TODO in real time
|
||||
// Assign title
|
||||
if (group?.isVirtual == true) {
|
||||
searchNumbers?.text = SearchHelper.showNumberOfSearchResults(group.numberOfChildEntries)
|
||||
searchFiltersView?.setNumbers(SearchHelper.showNumberOfSearchResults(group.numberOfChildEntries))
|
||||
toolbarBreadcrumb?.navigationIcon = null
|
||||
} else {
|
||||
// Add breadcrumb
|
||||
@@ -1017,7 +1009,6 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
|
||||
*/
|
||||
isIconified = false
|
||||
setOnQueryTextListener(mOnSearchQueryTextListener)
|
||||
}
|
||||
// Expand the search view if defined in settings
|
||||
if (mRequestStartupSearch
|
||||
@@ -1042,16 +1033,6 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
return true
|
||||
}
|
||||
|
||||
private fun loadSearchGroup(query: String?) {
|
||||
if (query != null) {
|
||||
mGroupViewModel.loadGroupFromSearch(
|
||||
mDatabase,
|
||||
query,
|
||||
PreferencesUtil.omitBackup(this)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun performedNextEducation(
|
||||
groupActivityEducation: GroupActivityEducation,
|
||||
menu: Menu
|
||||
@@ -1176,6 +1157,7 @@ class GroupActivity : DatabaseLockActivity(),
|
||||
}
|
||||
|
||||
private fun removeSearch() {
|
||||
mSearchGroup = null
|
||||
intent.removeExtra(AUTO_SEARCH_KEY)
|
||||
if (Intent.ACTION_SEARCH == intent.action) {
|
||||
intent.action = Intent.ACTION_DEFAULT
|
||||
|
||||
@@ -788,13 +788,11 @@ class Database {
|
||||
false
|
||||
}
|
||||
|
||||
fun createVirtualGroupFromSearch(searchQuery: String,
|
||||
fun createVirtualGroupFromSearch(searchParameters: SearchParameters,
|
||||
omitBackup: Boolean,
|
||||
max: Int = Integer.MAX_VALUE): Group? {
|
||||
return mSearchHelper?.createVirtualGroupWithSearchResult(this,
|
||||
SearchParameters().apply {
|
||||
this.searchQuery = searchQuery
|
||||
}, omitBackup, max)
|
||||
searchParameters,omitBackup, max)
|
||||
}
|
||||
|
||||
fun createVirtualGroupFromSearchInfo(searchInfoString: String,
|
||||
@@ -804,7 +802,7 @@ class Database {
|
||||
SearchParameters().apply {
|
||||
searchQuery = searchInfoString
|
||||
searchInTitles = true
|
||||
searchInUserNames = false
|
||||
searchInUsernames = false
|
||||
searchInPasswords = false
|
||||
searchInUrls = true
|
||||
searchInNotes = true
|
||||
|
||||
@@ -144,16 +144,23 @@ class SearchHelper {
|
||||
fun searchInEntry(entry: Entry,
|
||||
searchParameters: SearchParameters): Boolean {
|
||||
val searchQuery = searchParameters.searchQuery
|
||||
// Entry contains string if the search string is empty
|
||||
|
||||
// Not found if the search string is empty
|
||||
if (searchQuery.isEmpty())
|
||||
return true
|
||||
return false
|
||||
|
||||
// Exclude entry expired
|
||||
if (searchParameters.excludeExpired) {
|
||||
if (entry.isCurrentlyExpires)
|
||||
return false
|
||||
}
|
||||
|
||||
// Search all strings in the KDBX entry
|
||||
if (searchParameters.searchInTitles) {
|
||||
if (checkSearchQuery(entry.title, searchParameters))
|
||||
return true
|
||||
}
|
||||
if (searchParameters.searchInUserNames) {
|
||||
if (searchParameters.searchInUsernames) {
|
||||
if (checkSearchQuery(entry.username, searchParameters))
|
||||
return true
|
||||
}
|
||||
@@ -171,7 +178,9 @@ class SearchHelper {
|
||||
}
|
||||
if (searchParameters.searchInUUIDs) {
|
||||
val hexString = UuidUtil.toHexString(entry.nodeId.id)
|
||||
if (hexString != null && hexString.contains(searchQuery, true))
|
||||
if (hexString != null
|
||||
&& hexString.contains(searchQuery, true)
|
||||
)
|
||||
return true
|
||||
}
|
||||
if (searchParameters.searchInOther) {
|
||||
@@ -183,6 +192,10 @@ class SearchHelper {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (searchParameters.searchInTags) {
|
||||
if (checkSearchQuery(entry.tags.toString(), searchParameters))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -190,14 +203,12 @@ class SearchHelper {
|
||||
/*
|
||||
// TODO Search settings
|
||||
var regularExpression = false
|
||||
var ignoreCase = true
|
||||
var removeAccents = true <- Too much time, to study
|
||||
var excludeExpired = false
|
||||
var searchOnlyInCurrentGroup = false
|
||||
*/
|
||||
return stringToCheck.isNotEmpty()
|
||||
&& stringToCheck.contains(
|
||||
searchParameters.searchQuery, true)
|
||||
searchParameters.searchQuery, !searchParameters.caseSensitive)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,15 +25,18 @@ package com.kunzisoft.keepass.database.search
|
||||
class SearchParameters {
|
||||
var searchQuery: String = ""
|
||||
|
||||
var caseSensitive = false
|
||||
var excludeExpired = false
|
||||
|
||||
var searchInTitles = true
|
||||
var searchInUserNames = true
|
||||
var searchInUsernames = true
|
||||
var searchInPasswords = false
|
||||
var searchInUrls = true
|
||||
var searchInNotes = true
|
||||
var searchInOTP = false
|
||||
var searchInOther = true
|
||||
var searchInUUIDs = false
|
||||
var searchInTags = true
|
||||
var searchInTags = false
|
||||
|
||||
var searchInTemplates = false
|
||||
}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
package com.kunzisoft.keepass.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.CompoundButton
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.database.search.SearchParameters
|
||||
|
||||
class SearchFiltersView @JvmOverloads constructor(context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyle: Int = 0)
|
||||
: LinearLayout(context, attrs, defStyle) {
|
||||
|
||||
private var searchContainer: ViewGroup
|
||||
private var searchAdvanceFiltersContainer: ViewGroup
|
||||
private var searchExpandButton: ImageView
|
||||
private var searchNumbers: TextView
|
||||
private var searchCaseSensitive: CompoundButton
|
||||
private var searchExpires: CompoundButton
|
||||
private var searchTitle: CompoundButton
|
||||
private var searchUsername: CompoundButton
|
||||
private var searchPassword: CompoundButton
|
||||
private var searchURL: CompoundButton
|
||||
private var searchNotes: CompoundButton
|
||||
private var searchOther: CompoundButton
|
||||
private var searchUUID: CompoundButton
|
||||
private var searchTag: CompoundButton
|
||||
|
||||
var searchParameters = SearchParameters()
|
||||
get() {
|
||||
return field.apply {
|
||||
this.caseSensitive = searchCaseSensitive.isChecked
|
||||
this.excludeExpired = !(searchExpires.isChecked)
|
||||
this.searchInTitles = searchTitle.isChecked
|
||||
this.searchInUsernames = searchUsername.isChecked
|
||||
this.searchInPasswords = searchPassword.isChecked
|
||||
this.searchInUrls = searchURL.isChecked
|
||||
this.searchInNotes = searchNotes.isChecked
|
||||
this.searchInOther = searchOther.isChecked
|
||||
this.searchInUUIDs = searchUUID.isChecked
|
||||
this.searchInTags = searchTag.isChecked
|
||||
}
|
||||
}
|
||||
private set
|
||||
|
||||
var onParametersChangeListener: ((searchParameters: SearchParameters) -> Unit)? = null
|
||||
|
||||
init {
|
||||
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
|
||||
inflater?.inflate(R.layout.view_search_filters, this)
|
||||
|
||||
searchContainer = findViewById(R.id.search_container)
|
||||
searchAdvanceFiltersContainer = findViewById(R.id.search_advance_filters)
|
||||
searchExpandButton = findViewById(R.id.search_expand)
|
||||
searchNumbers = findViewById(R.id.search_numbers)
|
||||
searchCaseSensitive = findViewById(R.id.search_chip_case_sensitive)
|
||||
searchExpires = findViewById(R.id.search_chip_expires)
|
||||
searchTitle = findViewById(R.id.search_chip_title)
|
||||
searchUsername = findViewById(R.id.search_chip_username)
|
||||
searchPassword = findViewById(R.id.search_chip_password)
|
||||
searchURL = findViewById(R.id.search_chip_url)
|
||||
searchNotes = findViewById(R.id.search_chip_note)
|
||||
searchUUID = findViewById(R.id.search_chip_uuid)
|
||||
searchOther = findViewById(R.id.search_chip_other)
|
||||
searchTag = findViewById(R.id.search_chip_tag)
|
||||
|
||||
// Expand menu with button
|
||||
searchExpandButton.setOnClickListener {
|
||||
val isVisible = searchAdvanceFiltersContainer.visibility == View.VISIBLE
|
||||
if (isVisible)
|
||||
searchAdvanceFiltersContainer.collapse()
|
||||
else {
|
||||
searchAdvanceFiltersContainer.expand(true,
|
||||
resources.getDimension(R.dimen.advanced_search_height).toInt()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
searchCaseSensitive.setOnCheckedChangeListener { _, isChecked ->
|
||||
searchParameters.caseSensitive = isChecked
|
||||
onParametersChangeListener?.invoke(searchParameters)
|
||||
}
|
||||
searchExpires.setOnCheckedChangeListener { _, isChecked ->
|
||||
searchParameters.excludeExpired = !isChecked
|
||||
onParametersChangeListener?.invoke(searchParameters)
|
||||
}
|
||||
searchTitle.setOnCheckedChangeListener { _, isChecked ->
|
||||
searchParameters.searchInTitles = isChecked
|
||||
onParametersChangeListener?.invoke(searchParameters)
|
||||
}
|
||||
searchUsername.setOnCheckedChangeListener { _, isChecked ->
|
||||
searchParameters.searchInUsernames = isChecked
|
||||
onParametersChangeListener?.invoke(searchParameters)
|
||||
}
|
||||
searchPassword.setOnCheckedChangeListener { _, isChecked ->
|
||||
searchParameters.searchInPasswords = isChecked
|
||||
onParametersChangeListener?.invoke(searchParameters)
|
||||
}
|
||||
searchURL.setOnCheckedChangeListener { _, isChecked ->
|
||||
searchParameters.searchInUrls = isChecked
|
||||
onParametersChangeListener?.invoke(searchParameters)
|
||||
}
|
||||
searchNotes.setOnCheckedChangeListener { _, isChecked ->
|
||||
searchParameters.searchInNotes = isChecked
|
||||
onParametersChangeListener?.invoke(searchParameters)
|
||||
}
|
||||
searchUUID.setOnCheckedChangeListener { _, isChecked ->
|
||||
searchParameters.searchInUUIDs = isChecked
|
||||
onParametersChangeListener?.invoke(searchParameters)
|
||||
}
|
||||
searchOther.setOnCheckedChangeListener { _, isChecked ->
|
||||
searchParameters.searchInOther = isChecked
|
||||
onParametersChangeListener?.invoke(searchParameters)
|
||||
}
|
||||
searchTag.setOnCheckedChangeListener { _, isChecked ->
|
||||
searchParameters.searchInTags = isChecked
|
||||
onParametersChangeListener?.invoke(searchParameters)
|
||||
}
|
||||
}
|
||||
|
||||
fun setQuery(query: String) {
|
||||
searchParameters.searchQuery = query
|
||||
onParametersChangeListener?.invoke(searchParameters)
|
||||
}
|
||||
|
||||
fun setNumbers(stringNumbers: String) {
|
||||
searchNumbers.text = stringNumbers
|
||||
}
|
||||
|
||||
override fun setVisibility(visibility: Int) {
|
||||
//super.setVisibility(visibility)
|
||||
when (visibility) {
|
||||
View.VISIBLE -> {
|
||||
searchAdvanceFiltersContainer.visibility = View.GONE
|
||||
searchContainer.showByFading()
|
||||
}
|
||||
else -> {
|
||||
searchContainer.hideByFading()
|
||||
if (searchAdvanceFiltersContainer.visibility == View.VISIBLE) {
|
||||
searchAdvanceFiltersContainer.visibility = View.INVISIBLE
|
||||
searchAdvanceFiltersContainer.collapse()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import com.kunzisoft.keepass.app.database.IOActionTask
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.element.Group
|
||||
import com.kunzisoft.keepass.database.search.SearchHelper
|
||||
import com.kunzisoft.keepass.database.search.SearchParameters
|
||||
|
||||
|
||||
class GroupViewModel: ViewModel() {
|
||||
@@ -71,12 +72,12 @@ class GroupViewModel: ViewModel() {
|
||||
}
|
||||
|
||||
fun loadGroupFromSearch(database: Database?,
|
||||
searchQuery: String,
|
||||
searchParameters: SearchParameters,
|
||||
omitBackup: Boolean) {
|
||||
IOActionTask(
|
||||
{
|
||||
database?.createVirtualGroupFromSearch(
|
||||
searchQuery,
|
||||
searchParameters,
|
||||
omitBackup,
|
||||
SearchHelper.MAX_SEARCH_ENTRY
|
||||
)
|
||||
|
||||
@@ -95,135 +95,10 @@
|
||||
android:orientation="horizontal" />
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
<LinearLayout
|
||||
<com.kunzisoft.keepass.view.SearchFiltersView
|
||||
android:id="@+id/search_filters"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:orientation="vertical">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/search_container"
|
||||
android:layout_width="match_parent"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:visibility="gone">
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/search_numbers"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/default_margin"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
android:layout_marginEnd="@dimen/default_margin"
|
||||
android:layout_marginRight="@dimen/default_margin"
|
||||
android:layout_gravity="center"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
tools:text="3" />
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/default_margin"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/search_expand"
|
||||
app:layout_constraintStart_toEndOf="@+id/search_numbers"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_case_sensitive"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/case_sensitive" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_expires"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/entry_expires" />
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
<ImageButton
|
||||
android:id="@+id/search_expand"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
style="@style/KeepassDXStyle.ImageButton.Simple"
|
||||
android:src="@drawable/ic_list_white_24dp"
|
||||
app:tint="?attr/textColorInverse"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<FrameLayout
|
||||
android:id="@+id/search_advance_filters"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/advanced_search_height"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:visibility="gone">
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:chipSpacingVertical="16dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingStart="@dimen/default_margin"
|
||||
android:paddingLeft="@dimen/default_margin"
|
||||
android:paddingEnd="@dimen/default_margin"
|
||||
android:paddingRight="@dimen/default_margin"
|
||||
android:paddingBottom="@dimen/default_margin">
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/entry_title"/>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_username"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/entry_user_name"/>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_password"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/entry_password"/>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_url"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/entry_url"/>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_note"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/entry_notes"/>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_other"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/other"/>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_uuid"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/entry_UUID"/>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_tag"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/tags"/>
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
android:layout_height="wrap_content" />
|
||||
</FrameLayout>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
140
app/src/main/res/layout/view_search_filters.xml
Normal file
140
app/src/main/res/layout/view_search_filters.xml
Normal file
@@ -0,0 +1,140 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:orientation="vertical">
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/search_container"
|
||||
android:layout_width="match_parent"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:visibility="gone">
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/search_numbers"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/default_margin"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
android:layout_marginEnd="@dimen/default_margin"
|
||||
android:layout_marginRight="@dimen/default_margin"
|
||||
android:layout_gravity="center"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
tools:text="3" />
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/default_margin"
|
||||
android:layout_marginLeft="@dimen/default_margin"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/search_expand"
|
||||
app:layout_constraintStart_toEndOf="@+id/search_numbers"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_case_sensitive"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/case_sensitive" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_expires"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/entry_expires" />
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
<ImageButton
|
||||
android:id="@+id/search_expand"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
style="@style/KeepassDXStyle.ImageButton.Simple"
|
||||
android:src="@drawable/ic_list_white_24dp"
|
||||
app:tint="?attr/textColorInverse"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<FrameLayout
|
||||
android:id="@+id/search_advance_filters"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/advanced_search_height"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:visibility="gone">
|
||||
<com.google.android.material.chip.ChipGroup
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
app:chipSpacingVertical="16dp"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingStart="@dimen/default_margin"
|
||||
android:paddingLeft="@dimen/default_margin"
|
||||
android:paddingEnd="@dimen/default_margin"
|
||||
android:paddingRight="@dimen/default_margin"
|
||||
android:paddingBottom="@dimen/default_margin">
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/entry_title"/>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_username"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/entry_user_name"/>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_password"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/entry_password"/>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_url"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/entry_url"/>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_note"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/entry_notes"/>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_other"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/other"/>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_uuid"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/entry_UUID"/>
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/search_chip_tag"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="false"
|
||||
style="@style/KeepassDXStyle.Chip.Filter"
|
||||
android:text="@string/tags"/>
|
||||
</com.google.android.material.chip.ChipGroup>
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
Reference in New Issue
Block a user