Skip to content

Commit

Permalink
Merge branch 'release/2.5.0.0beta22'
Browse files Browse the repository at this point in the history
  • Loading branch information
J-Jamet committed Aug 19, 2019
2 parents c2781af + b9a792e commit 78354e4
Show file tree
Hide file tree
Showing 37 changed files with 408 additions and 132 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
KeepassDX (2.5.0.0beta22)
* Rebuild code for actions
* Add UUID as entry view
* Fix bug with natural order
* Fix number of entries in databaseV1
* New entry views

KeepassDX (2.5.0.0beta21)
* Fix nested groups no longer visible in V1 databases
* Improved data import algorithm for V1 databases
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ android {
applicationId "com.kunzisoft.keepass"
minSdkVersion 14
targetSdkVersion 27
versionCode = 21
versionName = "2.5.0.0beta21"
versionCode = 22
versionName = "2.5.0.0beta22"
multiDexEnabled true

testApplicationId = "com.kunzisoft.keepass.tests"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class EntryActivity : LockingHideActivity() {
titleIconView?.assignDatabaseIcon(database.drawFactory, entry.icon, iconColor)

// Assign title text
val entryTitle = entry.getVisualTitle()
val entryTitle = entry.title
collapsingToolbarLayout?.title = entryTitle
toolbar?.title = entryTitle

Expand Down Expand Up @@ -236,6 +236,9 @@ class EntryActivity : LockingHideActivity() {
entryContentsView?.assignExpiresDate(getString(R.string.never))
}

// Assign special data
entryContentsView?.assignUUID(entry.nodeId.id)

database.stopManageEntry(entry)
}

Expand Down
40 changes: 25 additions & 15 deletions app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ import com.kunzisoft.keepass.autofill.AutofillHelper
import com.kunzisoft.keepass.database.SortNodeEnum
import com.kunzisoft.keepass.database.action.ProgressDialogSaveDatabaseThread
import com.kunzisoft.keepass.database.action.node.*
import com.kunzisoft.keepass.database.action.node.ActionNodeDatabaseRunnable.Companion.NODE_POSITION_FOR_ACTION_NATURAL_ORDER_KEY
import com.kunzisoft.keepass.database.element.*
import com.kunzisoft.keepass.education.GroupActivityEducation
import com.kunzisoft.keepass.icons.assignDatabaseIcon
import com.kunzisoft.keepass.magikeyboard.KeyboardHelper
import com.kunzisoft.keepass.magikeyboard.MagikIME
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.LOCK_ACTION
import com.kunzisoft.keepass.utils.MenuUtil
import com.kunzisoft.keepass.view.AddNodeButtonView
import net.cachapa.expandablelayout.ExpandableLayout
Expand Down Expand Up @@ -523,10 +523,10 @@ class GroupActivity : LockingActivity(),
MoveGroupRunnable(
this,
Database.getInstance(),
groupToMove,
newParent,
AfterAddNodeRunnable(),
!readOnly)
groupToMove,
newParent,
AfterAddNodeRunnable(),
!readOnly)
}.start()
}

Expand Down Expand Up @@ -812,20 +812,30 @@ class GroupActivity : LockingActivity(),
override fun onActionNodeFinish(actionNodeValues: ActionNodeValues) {
runOnUiThread {
if (actionNodeValues.result.isSuccess) {
actionNodeValues.oldNode?.let { oldNode ->

mListNodesFragment?.removeNode(oldNode)
// If the action register the position, use it to remove the entry view
val positionNode = actionNodeValues.result.data?.getInt(NODE_POSITION_FOR_ACTION_NATURAL_ORDER_KEY)
if (PreferencesUtil.getListSort(this@GroupActivity) == SortNodeEnum.DB
&& positionNode != null) {
mListNodesFragment?.removeNodeAt(positionNode)
} else {
// else use the old Node that was the entry unchanged with the old parent
actionNodeValues.oldNode?.let { oldNode ->
mListNodesFragment?.removeNode(oldNode)
}
}

// TODO Move trash view
// Add trash in views list if it doesn't exists
val database = Database.getInstance()
if (database.isRecycleBinEnabled) {
val recycleBin = database.recycleBin
if (mCurrentGroup != null && recycleBin != null
// Add trash in views list if it doesn't exists
val database = Database.getInstance()
if (database.isRecycleBinEnabled) {
val recycleBin = database.recycleBin
if (mCurrentGroup != null && recycleBin != null
&& mCurrentGroup!!.parent == null
&& mCurrentGroup != recycleBin) {
mListNodesFragment?.addNode(recycleBin)
}
if (mListNodesFragment?.contains(recycleBin) == true)
mListNodesFragment?.updateNode(recycleBin)
else
mListNodesFragment?.addNode(recycleBin)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,18 +252,26 @@ class ListNodesFragment : StylishFragment(), SortDialogFragment.SortSelectionLis
}
}

fun contains(node: NodeVersioned): Boolean {
return mAdapter?.contains(node) ?: false
}

fun addNode(newNode: NodeVersioned) {
mAdapter?.addNode(newNode)
}

fun updateNode(oldNode: NodeVersioned, newNode: NodeVersioned) {
mAdapter?.updateNode(oldNode, newNode)
fun updateNode(oldNode: NodeVersioned, newNode: NodeVersioned? = null) {
mAdapter?.updateNode(oldNode, newNode ?: oldNode)
}

fun removeNode(pwNode: NodeVersioned) {
mAdapter?.removeNode(pwNode)
}

fun removeNodeAt(position: Int) {
mAdapter?.removeNodeAt(position)
}

interface OnScrollListener {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ class SortDialogFragment : DialogFragment() {
private var mAscending: Boolean = true
private var mRecycleBinBottom: Boolean = true

private var recycleBinBottomView: CompoundButton? = null

override fun onAttach(context: Context?) {
super.onAttach(context)
try {
Expand Down Expand Up @@ -73,14 +75,14 @@ class SortDialogFragment : DialogFragment() {
}
}

mCheckedId = retrieveViewFromEnum(mSortNodeEnum!!)
mCheckedId = retrieveViewFromEnum(mSortNodeEnum)

val rootView = activity.layoutInflater.inflate(R.layout.fragment_sort_selection, null)
builder.setTitle(R.string.sort_menu)
builder.setView(rootView)
// Add action buttons
.setPositiveButton(android.R.string.ok
) { _, _ -> mListener?.onSortSelected(mSortNodeEnum!!, mAscending, mGroupsBefore, mRecycleBinBottom) }
) { _, _ -> mListener?.onSortSelected(mSortNodeEnum, mAscending, mGroupsBefore, mRecycleBinBottom) }
.setNegativeButton(R.string.cancel) { _, _ -> }

val ascendingView = rootView.findViewById<CompoundButton>(R.id.sort_selection_ascending)
Expand All @@ -93,25 +95,35 @@ class SortDialogFragment : DialogFragment() {
groupsBeforeView.isChecked = mGroupsBefore
groupsBeforeView.setOnCheckedChangeListener { _, isChecked -> mGroupsBefore = isChecked }

val recycleBinBottomView = rootView.findViewById<CompoundButton>(R.id.sort_selection_recycle_bin_bottom)
recycleBinBottomView = rootView.findViewById(R.id.sort_selection_recycle_bin_bottom)
if (!recycleBinAllowed) {
recycleBinBottomView.visibility = View.GONE
recycleBinBottomView?.visibility = View.GONE
} else {
// Check if recycle bin at the bottom
recycleBinBottomView.isChecked = mRecycleBinBottom
recycleBinBottomView.setOnCheckedChangeListener { _, isChecked -> mRecycleBinBottom = isChecked }
recycleBinBottomView?.isChecked = mRecycleBinBottom
recycleBinBottomView?.setOnCheckedChangeListener { _, isChecked -> mRecycleBinBottom = isChecked }

disableRecycleBinBottomOptionIfNaturalOrder()
}

val sortSelectionRadioGroupView = rootView.findViewById<RadioGroup>(R.id.sort_selection_radio_group)
// Check value by default
sortSelectionRadioGroupView.check(mCheckedId)
sortSelectionRadioGroupView.setOnCheckedChangeListener { _, checkedId -> mSortNodeEnum = retrieveSortEnumFromViewId(checkedId) }
sortSelectionRadioGroupView.setOnCheckedChangeListener { _, checkedId ->
mSortNodeEnum = retrieveSortEnumFromViewId(checkedId)
disableRecycleBinBottomOptionIfNaturalOrder()
}

return builder.create()
}
return super.onCreateDialog(savedInstanceState)
}

private fun disableRecycleBinBottomOptionIfNaturalOrder() {
// Disable recycle bin if natural order
recycleBinBottomView?.isEnabled = mSortNodeEnum != SortNodeEnum.DB
}

@IdRes
private fun retrieveViewFromEnum(sortNodeEnum: SortNodeEnum): Int {
return when (sortNodeEnum) {
Expand Down
17 changes: 15 additions & 2 deletions app/src/main/java/com/kunzisoft/keepass/adapters/NodeAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ class NodeAdapter
}

override fun areContentsTheSame(oldItem: NodeVersioned, newItem: NodeVersioned): Boolean {
return oldItem.title == newItem.title && oldItem.icon == newItem.icon
return oldItem.type == newItem.type
&& oldItem.title == newItem.title
&& oldItem.icon == newItem.icon
}

override fun areItemsTheSame(item1: NodeVersioned, item2: NodeVersioned): Boolean {
Expand Down Expand Up @@ -149,6 +151,10 @@ class NodeAdapter
}
}

fun contains(node: NodeVersioned): Boolean {
return nodeSortedList.indexOf(node) != SortedList.INVALID_POSITION
}

/**
* Add a node to the list
* @param node Node to add
Expand All @@ -165,6 +171,13 @@ class NodeAdapter
nodeSortedList.remove(node)
}

/**
* Remove a node at [position] in the list
*/
fun removeNodeAt(position: Int) {
nodeSortedList.removeItemAt(position)
}

/**
* Update a node in the list
* @param oldNode Node before the update
Expand Down Expand Up @@ -245,7 +258,7 @@ class NodeAdapter
if (subNode.type == Type.GROUP) {
if (showNumberEntries) {
holder.numberChildren?.apply {
text = (subNode as GroupVersioned).getChildEntries().size.toString()
text = (subNode as GroupVersioned).getChildEntries(true).size.toString()
textSize = infoTextSize
visibility = View.VISIBLE
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ enum class SortNodeEnum {

fun getNodeComparator(ascending: Boolean, groupsBefore: Boolean, recycleBinBottom: Boolean): Comparator<NodeVersioned> {
return when (this) {
DB -> NodeNaturalComparator(ascending, groupsBefore, recycleBinBottom)
DB -> NodeNaturalComparator(ascending, groupsBefore, false) // Force false because natural order contains recycle bin
TITLE -> NodeTitleComparator(ascending, groupsBefore, recycleBinBottom)
USERNAME -> NodeUsernameComparator(ascending, groupsBefore, recycleBinBottom)
CREATION_TIME -> NodeCreationComparator(ascending, groupsBefore, recycleBinBottom)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.kunzisoft.keepass.database.action.node

import android.support.v4.app.FragmentActivity
import android.util.Log
import com.kunzisoft.keepass.database.action.SaveDatabaseRunnable
import com.kunzisoft.keepass.database.element.Database

Expand All @@ -23,6 +24,7 @@ abstract class ActionNodeDatabaseRunnable(
super.run()
finishRun(true)
} catch (e: Exception) {
Log.e("ActionNodeDBRunnable", e.message)
finishRun(false, e.message)
}
}
Expand All @@ -43,4 +45,8 @@ abstract class ActionNodeDatabaseRunnable(

super.onFinishRun(result)
}

companion object {
const val NODE_POSITION_FOR_ACTION_NATURAL_ORDER_KEY = "NODE_POSITION_FOR_ACTION_NATURAL_ORDER_KEY"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package com.kunzisoft.keepass.database.action.node

import android.support.v4.app.FragmentActivity
import android.util.Log
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.EntryVersioned
import com.kunzisoft.keepass.database.element.GroupVersioned
Expand All @@ -37,9 +38,18 @@ class CopyEntryRunnable constructor(
private var mEntryCopied: EntryVersioned? = null

override fun nodeAction() {
// Update entry with new values
mNewParent.touch(modified = false, touchParents = true)
mEntryCopied = database.copyEntryTo(mEntryToCopy, mNewParent)
// Condition
var conditionAccepted = true
if(mNewParent == database.rootGroup && !database.rootCanContainsEntry())
conditionAccepted = false
if (conditionAccepted) {
// Update entry with new values
mNewParent.touch(modified = false, touchParents = true)
mEntryCopied = database.copyEntryTo(mEntryToCopy, mNewParent)
} else {
// Only finish thread
throw Exception(context.getString(R.string.error_copy_entry_here))
}

mEntryCopied?.apply {
touch(modified = true, touchParents = true)
Expand All @@ -56,7 +66,6 @@ class CopyEntryRunnable constructor(
} catch (e: Exception) {
Log.i(TAG, "Unable to delete the copied entry")
}

}
return ActionNodeValues(result, mEntryToCopy, mEntryCopied)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/
package com.kunzisoft.keepass.database.action.node

import android.os.Bundle
import android.support.v4.app.FragmentActivity
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.EntryVersioned
Expand All @@ -35,11 +36,19 @@ class DeleteEntryRunnable constructor(
private var mParent: GroupVersioned? = null
private var mCanRecycle: Boolean = false

private var mEntryToDeleteBackup: EntryVersioned? = null
private var mNodePosition: Int? = null

override fun nodeAction() {
mParent = mEntryToDelete.parent
mParent?.touch(modified = false, touchParents = true)

// Get the node position
mNodePosition = mEntryToDelete.nodePositionInParent

// Create a copy to keep the old ref and remove it visually
mEntryToDeleteBackup = EntryVersioned(mEntryToDelete)

// Remove Entry from parent
mCanRecycle = database.canRecycle(mEntryToDelete)
if (mCanRecycle) {
Expand All @@ -59,6 +68,16 @@ class DeleteEntryRunnable constructor(
}
}
}
return ActionNodeValues(result, mEntryToDelete, null)

// Add position in bundle to delete the node in view
mNodePosition?.let { position ->
result.data = Bundle().apply {
putInt(NODE_POSITION_FOR_ACTION_NATURAL_ORDER_KEY, position )
}
}

// Return a copy of unchanged entry as old param
// and entry deleted or moved in recycle bin as new param
return ActionNodeValues(result, mEntryToDeleteBackup, mEntryToDelete)
}
}
Loading

0 comments on commit 78354e4

Please sign in to comment.