diff --git a/CHANGELOG b/CHANGELOG index 722462128..7fffa0976 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,5 @@ KeePassDX(3.0.0) - * + * Move groups #658 KeePassDX(2.9.17) * Import / Export app properties #839 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 d7b42797c..1e3b8f606 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/GroupActivity.kt @@ -812,74 +812,75 @@ class GroupActivity : LockingActivity(), override fun onPasteMenuClick(pasteMode: ListNodesFragment.PasteMode?, nodes: List): Boolean { - // Move or copy only if allowed (in root if allowed) - if (mCurrentGroup != mDatabase?.rootGroup - || mDatabase?.rootCanContainsEntry() == true) { - - when (pasteMode) { - ListNodesFragment.PasteMode.PASTE_FROM_COPY -> { - // Copy - mCurrentGroup?.let { newParent -> - mProgressDatabaseTaskProvider?.startDatabaseCopyNodes( - nodes, - newParent, - !mReadOnly && mAutoSaveEnable - ) - } - } - ListNodesFragment.PasteMode.PASTE_FROM_MOVE -> { - // Move - mCurrentGroup?.let { newParent -> - mProgressDatabaseTaskProvider?.startDatabaseMoveNodes( - nodes, - newParent, - !mReadOnly && mAutoSaveEnable - ) - } - } - else -> { + when (pasteMode) { + ListNodesFragment.PasteMode.PASTE_FROM_COPY -> { + // Copy + mCurrentGroup?.let { newParent -> + mProgressDatabaseTaskProvider?.startDatabaseCopyNodes( + nodes, + newParent, + !mReadOnly && mAutoSaveEnable + ) } } - } else { - coordinatorLayout?.let { coordinatorLayout -> - Snackbar.make(coordinatorLayout, - R.string.error_copy_entry_here, - Snackbar.LENGTH_LONG).asError().show() + ListNodesFragment.PasteMode.PASTE_FROM_MOVE -> { + // Move + mCurrentGroup?.let { newParent -> + mProgressDatabaseTaskProvider?.startDatabaseMoveNodes( + nodes, + newParent, + !mReadOnly && mAutoSaveEnable + ) + } } + else -> {} } finishNodeAction() return true } + private fun eachNodeRecyclable(nodes: List): Boolean { + mDatabase?.let { database -> + return nodes.find { node -> + var cannotRecycle = true + if (node is Entry) { + cannotRecycle = !database.canRecycle(node) + } else if (node is Group) { + cannotRecycle = !database.canRecycle(node) + } + cannotRecycle + } == null + } + return false + } + private fun deleteNodes(nodes: List, recycleBin: Boolean = false): Boolean { - val database = mDatabase + mDatabase?.let { database -> - // If recycle bin enabled, ensure it exists - if (database != null && database.isRecycleBinEnabled) { - database.ensureRecycleBinExists(resources) - } - - // If recycle bin enabled and not in recycle bin, move in recycle bin - if (database != null - && database.isRecycleBinEnabled - && database.recycleBin != mCurrentGroup) { - - mProgressDatabaseTaskProvider?.startDatabaseDeleteNodes( - nodes, - !mReadOnly && mAutoSaveEnable - ) - } - // else open the dialog to confirm deletion - else { - val deleteNodesDialogFragment: DeleteNodesDialogFragment = - if (recycleBin) { - EmptyRecycleBinDialogFragment.getInstance(nodes) - } else { - DeleteNodesDialogFragment.getInstance(nodes) + // If recycle bin enabled, ensure it exists + if (database.isRecycleBinEnabled) { + database.ensureRecycleBinExists(resources) } - deleteNodesDialogFragment.show(supportFragmentManager, "deleteNodesDialogFragment") + + // If recycle bin enabled and not in recycle bin, move in recycle bin + if (eachNodeRecyclable(nodes)) { + mProgressDatabaseTaskProvider?.startDatabaseDeleteNodes( + nodes, + !mReadOnly && mAutoSaveEnable + ) + } + // else open the dialog to confirm deletion + else { + val deleteNodesDialogFragment: DeleteNodesDialogFragment = + if (recycleBin) { + EmptyRecycleBinDialogFragment.getInstance(nodes) + } else { + DeleteNodesDialogFragment.getInstance(nodes) + } + deleteNodesDialogFragment.show(supportFragmentManager, "deleteNodesDialogFragment") + } + finishNodeAction() } - finishNodeAction() return true } @@ -1076,6 +1077,16 @@ class GroupActivity : LockingActivity(), } } + override fun isValidGroupName(name: String): GroupEditDialogFragment.Error { + if (name.isEmpty()) { + return GroupEditDialogFragment.Error(true, R.string.error_no_name) + } + if (mDatabase?.groupNamesNotAllowed?.find { it.equals(name, ignoreCase = true) } != null) { + return GroupEditDialogFragment.Error(true, R.string.error_word_reserved) + } + return GroupEditDialogFragment.Error(false, null) + } + override fun approveEditGroup(action: GroupEditDialogFragment.EditGroupDialogAction, groupInfo: GroupInfo) { 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 edf4917af..e1c1085a5 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 @@ -219,14 +219,19 @@ class GroupEditDialogFragment : DialogFragment() { } private fun isValid(): Boolean { - if (nameTextView.text.toString().isEmpty()) { - nameTextLayoutView.error = getString(R.string.error_no_name) - return false + val error = mEditGroupListener?.isValidGroupName(nameTextView.text.toString()) ?: Error(false, null) + error.messageId?.let { messageId -> + nameTextLayoutView.error = getString(messageId) + } ?: kotlin.run { + nameTextLayoutView.error = null } - return true + return !error.isError } + data class Error(val isError: Boolean, val messageId: Int?) + interface EditGroupListener { + fun isValidGroupName(name: String): Error fun approveEditGroup(action: EditGroupDialogAction, groupInfo: GroupInfo) fun cancelEditGroup(action: EditGroupDialogAction, diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/fragments/ListNodesFragment.kt b/app/src/main/java/com/kunzisoft/keepass/activities/fragments/ListNodesFragment.kt index 8153bc336..d44f49de8 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/fragments/ListNodesFragment.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/fragments/ListNodesFragment.kt @@ -311,13 +311,17 @@ class ListNodesFragment : StylishFragment(), SortDialogFragment.SortSelectionLis menu?.removeItem(R.id.menu_edit) } - // Copy and Move (not for groups) + // Move + if (readOnly + || isASearchResult) { + menu?.removeItem(R.id.menu_move) + } + + // Copy (not allowed for group) if (readOnly || isASearchResult || nodes.any { it.type == Type.GROUP }) { - // TODO Copy For Group menu?.removeItem(R.id.menu_copy) - menu?.removeItem(R.id.menu_move) } // Deletion diff --git a/app/src/main/java/com/kunzisoft/keepass/database/action/node/MoveNodesRunnable.kt b/app/src/main/java/com/kunzisoft/keepass/database/action/node/MoveNodesRunnable.kt index 42cc7559b..660f9c545 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/action/node/MoveNodesRunnable.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/action/node/MoveNodesRunnable.kt @@ -24,7 +24,7 @@ import android.util.Log import com.kunzisoft.keepass.database.element.* import com.kunzisoft.keepass.database.element.node.Node import com.kunzisoft.keepass.database.element.node.Type -import com.kunzisoft.keepass.database.exception.EntryDatabaseException +import com.kunzisoft.keepass.database.exception.MoveEntryDatabaseException import com.kunzisoft.keepass.database.exception.MoveGroupDatabaseException class MoveNodesRunnable constructor( @@ -47,8 +47,10 @@ class MoveNodesRunnable constructor( when (nodeToMove.type) { Type.GROUP -> { val groupToMove = nodeToMove as Group - // Move group in new parent if not in the current group - if (groupToMove != mNewParent + // Move group if the parent change + if (mOldParent != mNewParent + // and if not in the current group + && groupToMove != mNewParent && !mNewParent.isContainedIn(groupToMove)) { nodeToMove.touch(modified = true, touchParents = true) database.moveGroupTo(groupToMove, mNewParent) @@ -68,7 +70,7 @@ class MoveNodesRunnable constructor( database.moveEntryTo(entryToMove, mNewParent) } else { // Only finish thread - setError(EntryDatabaseException()) + setError(MoveEntryDatabaseException()) break@foreachNode } } 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 f297a4d2f..ba43ba7c6 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 @@ -23,7 +23,6 @@ import android.content.ContentResolver import android.content.res.Resources import android.net.Uri import android.util.Log -import com.kunzisoft.keepass.utils.readBytes4ToUInt import com.kunzisoft.keepass.database.action.node.NodeHandler import com.kunzisoft.keepass.database.crypto.EncryptionAlgorithm import com.kunzisoft.keepass.database.crypto.kdf.KdfEngine @@ -55,6 +54,7 @@ import com.kunzisoft.keepass.model.MainCredential import com.kunzisoft.keepass.tasks.ProgressTaskUpdater import com.kunzisoft.keepass.utils.SingletonHolder import com.kunzisoft.keepass.utils.UriUtil +import com.kunzisoft.keepass.utils.readBytes4ToUInt import java.io.* import java.util.* import kotlin.collections.ArrayList @@ -359,15 +359,10 @@ class Database { return null } - fun ensureRecycleBinExists(resources: Resources) { - mDatabaseKDB?.ensureBackupExists() - mDatabaseKDBX?.ensureRecycleBinExists(resources) - } - - fun removeRecycleBin() { - // Don't allow remove backup in KDB - mDatabaseKDBX?.removeRecycleBin() - } + val groupNamesNotAllowed: List + get() { + return mDatabaseKDB?.groupNamesNotAllowed ?: ArrayList() + } private fun setDatabaseKDB(databaseKDB: DatabaseKDB) { this.mDatabaseKDB = databaseKDB @@ -790,11 +785,11 @@ class Database { } fun addGroupTo(group: Group, parent: Group) { - group.groupKDB?.let { entryKDB -> - mDatabaseKDB?.addGroupTo(entryKDB, parent.groupKDB) + group.groupKDB?.let { groupKDB -> + mDatabaseKDB?.addGroupTo(groupKDB, parent.groupKDB) } - group.groupKDBX?.let { entryKDBX -> - mDatabaseKDBX?.addGroupTo(entryKDBX, parent.groupKDBX) + group.groupKDBX?.let { groupKDBX -> + mDatabaseKDBX?.addGroupTo(groupKDBX, parent.groupKDBX) } group.afterAssignNewParent() } @@ -809,11 +804,11 @@ class Database { } fun removeGroupFrom(group: Group, parent: Group) { - group.groupKDB?.let { entryKDB -> - mDatabaseKDB?.removeGroupFrom(entryKDB, parent.groupKDB) + group.groupKDB?.let { groupKDB -> + mDatabaseKDB?.removeGroupFrom(groupKDB, parent.groupKDB) } - group.groupKDBX?.let { entryKDBX -> - mDatabaseKDBX?.removeGroupFrom(entryKDBX, parent.groupKDBX) + group.groupKDBX?.let { groupKDBX -> + mDatabaseKDBX?.removeGroupFrom(groupKDBX, parent.groupKDBX) } group.afterAssignNewParent() } @@ -888,6 +883,16 @@ class Database { } } + fun ensureRecycleBinExists(resources: Resources) { + mDatabaseKDB?.ensureBackupExists() + mDatabaseKDBX?.ensureRecycleBinExists(resources) + } + + fun removeRecycleBin() { + // Don't allow remove backup in KDB + mDatabaseKDBX?.removeRecycleBin() + } + fun canRecycle(entry: Entry): Boolean { var canRecycle: Boolean? = null entry.entryKDB?.let { diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/Group.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/Group.kt index f5f06332a..c8f112c63 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/Group.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/Group.kt @@ -368,14 +368,6 @@ class Group : Node, GroupVersionedInterface { groupKDB?.nodeId = id } - fun getLevel(): Int { - return groupKDB?.level ?: -1 - } - - fun setLevel(level: Int) { - groupKDB?.level = level - } - /* ------------ KDBX Methods diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDB.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDB.kt index 7185863f5..2de7265e8 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDB.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDB.kt @@ -38,8 +38,6 @@ import kotlin.collections.ArrayList class DatabaseKDB : DatabaseVersioned() { - private var backupGroupId: Int = BACKUP_FOLDER_UNDEFINED_ID - private var kdfListV3: MutableList = ArrayList() override val version: String @@ -55,13 +53,14 @@ class DatabaseKDB : DatabaseVersioned() { return getGroupById(NodeIdInt(groupId)) } - // Retrieve backup group in index val backupGroup: GroupKDB? get() { - return if (backupGroupId == BACKUP_FOLDER_UNDEFINED_ID) - null - else - getGroupById(backupGroupId) + return retrieveBackup() + } + + val groupNamesNotAllowed: List + get() { + return listOf(BACKUP_FOLDER_TITLE) } override val kdfEngine: KdfEngine @@ -80,12 +79,7 @@ class DatabaseKDB : DatabaseVersioned() { val rootGroups: List get() { - val kids = ArrayList() - doForEachGroupInIndex { group -> - if (group.level == 0) - kids.add(group) - } - return kids + return rootGroup?.getChildGroups() ?: ArrayList() } override val passwordEncoding: String @@ -169,21 +163,14 @@ class DatabaseKDB : DatabaseVersioned() { override fun isInRecycleBin(group: GroupKDB): Boolean { var currentGroup: GroupKDB? = group + val currentBackupGroup = backupGroup ?: return false - // Init backup group variable - if (backupGroupId == BACKUP_FOLDER_UNDEFINED_ID) - findBackupGroupId() - - if (backupGroup == null) - return false - - if (currentGroup == backupGroup) + if (currentGroup == currentBackupGroup) return true + val backupGroupId = currentBackupGroup.id while (currentGroup != null) { - if (currentGroup.level == 0 - && currentGroup.title.equals(BACKUP_FOLDER_TITLE, ignoreCase = true)) { - backupGroupId = currentGroup.id + if (backupGroupId == currentGroup.id) { return true } currentGroup = currentGroup.parent @@ -191,12 +178,12 @@ class DatabaseKDB : DatabaseVersioned() { return false } - private fun findBackupGroupId() { - rootGroups.forEach { currentGroup -> - if (currentGroup.level == 0 - && currentGroup.title.equals(BACKUP_FOLDER_TITLE, ignoreCase = true)) { - backupGroupId = currentGroup.id - } + /** + * Retrieve backup group with his name + */ + private fun retrieveBackup(): GroupKDB? { + return rootGroup?.searchChildGroup { + it.title.equals(BACKUP_FOLDER_TITLE, ignoreCase = true) } } @@ -205,8 +192,6 @@ class DatabaseKDB : DatabaseVersioned() { * if it doesn't exist */ fun ensureBackupExists() { - findBackupGroupId() - if (backupGroup == null) { // Create recycle bin val recycleBinGroup = createGroup().apply { @@ -214,7 +199,6 @@ class DatabaseKDB : DatabaseVersioned() { icon.standard = getStandardIcon(IconImageStandard.TRASH_ID) } addGroupTo(recycleBinGroup, rootGroup) - backupGroupId = recycleBinGroup.id } } @@ -268,6 +252,5 @@ class DatabaseKDB : DatabaseVersioned() { val TYPE = DatabaseKDB::class.java const val BACKUP_FOLDER_TITLE = "Backup" - private const val BACKUP_FOLDER_UNDEFINED_ID = -1 } } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDBX.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDBX.kt index e4444a136..fa8728905 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDBX.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseKDBX.kt @@ -23,8 +23,6 @@ import android.content.res.Resources import android.util.Base64 import android.util.Log import com.kunzisoft.encrypt.HashManager -import com.kunzisoft.keepass.utils.UnsignedInt -import com.kunzisoft.keepass.utils.longTo8Bytes import com.kunzisoft.keepass.R import com.kunzisoft.keepass.database.action.node.NodeHandler import com.kunzisoft.keepass.database.crypto.AesEngine @@ -50,6 +48,8 @@ import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX.Companion.FILE_VER import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX.Companion.FILE_VERSION_32_4 import com.kunzisoft.keepass.utils.StringUtil.removeSpaceChars import com.kunzisoft.keepass.utils.StringUtil.toHexString +import com.kunzisoft.keepass.utils.UnsignedInt +import com.kunzisoft.keepass.utils.longTo8Bytes import org.apache.commons.codec.binary.Hex import org.w3c.dom.Node import java.io.IOException @@ -132,7 +132,6 @@ class DatabaseKDBX : DatabaseVersioned { icon.standard = getStandardIcon(IconImageStandard.FOLDER_ID) } rootGroup = group - addGroupIndex(group) } override val version: String @@ -615,6 +614,9 @@ class DatabaseKDBX : DatabaseVersioned { return false if (recycleBin == null) return false + if (node is GroupKDBX + && recycleBin!!.isContainedIn(node)) + return false if (!node.isContainedIn(recycleBin!!)) return true return false diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseVersioned.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseVersioned.kt index d5197193b..118cd9926 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseVersioned.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/database/DatabaseVersioned.kt @@ -35,7 +35,6 @@ import java.io.ByteArrayInputStream import java.io.IOException import java.io.InputStream import java.io.UnsupportedEncodingException -import java.security.MessageDigest import java.util.* abstract class DatabaseVersioned< @@ -87,6 +86,12 @@ abstract class DatabaseVersioned< abstract val availableEncryptionAlgorithms: List var rootGroup: Group? = null + set(value) { + field = value + value?.let { + addGroupIndex(it) + } + } @Throws(IOException::class) protected abstract fun getMasterKey(key: String?, keyInputStream: InputStream?): ByteArray diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/group/GroupKDB.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/group/GroupKDB.kt index a220c1655..3d25c255f 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/group/GroupKDB.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/group/GroupKDB.kt @@ -31,14 +31,12 @@ import java.util.* class GroupKDB : GroupVersioned, NodeKDBInterface { - var level = 0 // short // Used by KeePass internally, don't use var groupFlags = 0 constructor() : super() constructor(parcel: Parcel) : super(parcel) { - level = parcel.readInt() groupFlags = parcel.readInt() } @@ -52,13 +50,11 @@ class GroupKDB : GroupVersioned, NodeKDBInterface override fun writeToParcel(dest: Parcel, flags: Int) { super.writeToParcel(dest, flags) - dest.writeInt(level) dest.writeInt(groupFlags) } fun updateWith(source: GroupKDB) { super.updateWith(source) - level = source.level groupFlags = source.groupFlags } @@ -73,15 +69,12 @@ class GroupKDB : GroupVersioned, NodeKDBInterface return NodeIdInt(nodeId.id) } - override fun afterAssignNewParent() { - if (parent != null) - level = parent!!.level + 1 - } - fun setGroupId(groupId: Int) { this.nodeId = NodeIdInt(groupId) } + override fun afterAssignNewParent() {} + companion object { @JvmField diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/group/GroupVersioned.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/group/GroupVersioned.kt index 5aa9f12f2..f34a91c9f 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/group/GroupVersioned.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/group/GroupVersioned.kt @@ -63,6 +63,17 @@ abstract class GroupVersioned get() = titleGroup set(value) { titleGroup = value } + /** + * To determine the level from the root group (root group level is -1) + */ + fun getLevel(): Int { + var level = -1 + parent?.let { parent -> + level = parent.getLevel() + 1 + } + return level + } + override fun getChildGroups(): List { return childGroups } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/element/group/GroupVersionedInterface.kt b/app/src/main/java/com/kunzisoft/keepass/database/element/group/GroupVersionedInterface.kt index f4450dbf5..5eac3138d 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/element/group/GroupVersionedInterface.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/element/group/GroupVersionedInterface.kt @@ -45,23 +45,44 @@ interface GroupVersionedInterface, groupHandler.operate(this as Group) } - fun doForEachChild(entryHandler: NodeHandler, + fun doForEachChild(entryHandler: NodeHandler?, groupHandler: NodeHandler?, - stopIterationWhenGroupHandlerFails: Boolean = true): Boolean { - for (entry in this.getChildEntries()) { - if (!entryHandler.operate(entry)) - return false + stopIterationWhenGroupHandlerOperateFalse: Boolean = true): Boolean { + if (entryHandler != null) { + for (entry in this.getChildEntries()) { + if (!entryHandler.operate(entry)) + return false + } } for (group in this.getChildGroups()) { var doActionForChild = true if (groupHandler != null && !groupHandler.operate(group)) { doActionForChild = false - if (stopIterationWhenGroupHandlerFails) + if (stopIterationWhenGroupHandlerOperateFalse) return false } if (doActionForChild) - group.doForEachChild(entryHandler, groupHandler) + group.doForEachChild(entryHandler, groupHandler, stopIterationWhenGroupHandlerOperateFalse) } return true } + + fun searchChildGroup(criteria: (group: Group) -> Boolean): Group? { + return searchChildGroup(this, criteria) + } + + private fun searchChildGroup(rootGroup: GroupVersionedInterface, + criteria: (group: Group) -> Boolean): Group? { + for (childGroup in rootGroup.getChildGroups()) { + if (criteria.invoke(childGroup)) { + return childGroup + } else { + val subGroup = searchChildGroup(childGroup, criteria) + if (subGroup != null) { + return subGroup + } + } + } + return null + } } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/exception/DatabaseException.kt b/app/src/main/java/com/kunzisoft/keepass/database/exception/DatabaseException.kt index 630fbd384..736071a6e 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/exception/DatabaseException.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/exception/DatabaseException.kt @@ -114,7 +114,7 @@ class NoMemoryDatabaseException: LoadDatabaseException { constructor(exception: Throwable) : super(exception) } -class EntryDatabaseException: LoadDatabaseException { +class MoveEntryDatabaseException: LoadDatabaseException { @StringRes override var errorId: Int = R.string.error_move_entry_here constructor() : super() @@ -123,7 +123,7 @@ class EntryDatabaseException: LoadDatabaseException { class MoveGroupDatabaseException: LoadDatabaseException { @StringRes - override var errorId: Int = R.string.error_move_folder_in_itself + override var errorId: Int = R.string.error_move_group_here constructor() : super() constructor(exception: Throwable) : super(exception) } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/file/input/DatabaseInputKDB.kt b/app/src/main/java/com/kunzisoft/keepass/database/file/input/DatabaseInputKDB.kt index 61d4a6615..f692464db 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/file/input/DatabaseInputKDB.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/file/input/DatabaseInputKDB.kt @@ -40,6 +40,7 @@ import java.security.MessageDigest import java.util.* import javax.crypto.Cipher import javax.crypto.CipherInputStream +import kotlin.collections.HashMap /** @@ -154,11 +155,10 @@ class DatabaseInputKDB(cacheDirectory: File, // New manual root because KDB contains multiple root groups (here available with getRootGroups()) val newRoot = mDatabase.createGroup() - newRoot.level = -1 mDatabase.rootGroup = newRoot - mDatabase.addGroupIndex(newRoot) // Import all nodes + val groupLevelList = HashMap() var newGroup: GroupKDB? = null var newEntry: EntryKDB? = null var currentGroupNumber = 0 @@ -248,7 +248,7 @@ class DatabaseInputKDB(cacheDirectory: File, } 0x0008 -> { newGroup?.let { group -> - group.level = cipherInputStream.readBytes2ToUShort() + groupLevelList.put(group, cipherInputStream.readBytes2ToUShort()) } ?: newEntry?.let { entry -> entry.notes = cipherInputStream.readBytesToString(fieldSize) @@ -318,7 +318,7 @@ class DatabaseInputKDB(cacheDirectory: File, if (!Arrays.equals(messageDigest.digest(), header.contentsHash)) { throw InvalidCredentialsDatabaseException() } - constructTreeFromIndex() + constructTreeFromIndex(groupLevelList) stopContentTimer() @@ -339,34 +339,40 @@ class DatabaseInputKDB(cacheDirectory: File, return mDatabase } - private fun buildTreeGroups(previousGroup: GroupKDB, currentGroup: GroupKDB, groupIterator: Iterator) { + private fun buildTreeGroups(groupLevelList: HashMap, + previousGroup: GroupKDB, + currentGroup: GroupKDB, + groupIterator: Iterator) { - if (currentGroup.parent == null && (previousGroup.level + 1) == currentGroup.level) { + val previousGroupLevel = groupLevelList[previousGroup] ?: -1 + val currentGroupLevel = groupLevelList[currentGroup] ?: -1 + + if (currentGroup.parent == null && (previousGroupLevel + 1) == currentGroupLevel) { // Current group has an increment level compare to the previous, current group is a child previousGroup.addChildGroup(currentGroup) currentGroup.parent = previousGroup - } else if (previousGroup.parent != null && previousGroup.level == currentGroup.level) { + } else if (previousGroup.parent != null && previousGroupLevel == currentGroupLevel) { // In the same level, previous parent is the same as previous group previousGroup.parent!!.addChildGroup(currentGroup) currentGroup.parent = previousGroup.parent } else if (previousGroup.parent != null) { // Previous group has a higher level than the current group, check it's parent - buildTreeGroups(previousGroup.parent!!, currentGroup, groupIterator) + buildTreeGroups(groupLevelList, previousGroup.parent!!, currentGroup, groupIterator) } // Next current group if (groupIterator.hasNext()){ - buildTreeGroups(currentGroup, groupIterator.next(), groupIterator) + buildTreeGroups(groupLevelList, currentGroup, groupIterator.next(), groupIterator) } } - private fun constructTreeFromIndex() { - mDatabase.rootGroup?.let { + private fun constructTreeFromIndex(groupLevelList: HashMap) { + mDatabase.rootGroup?.let { root -> // add each group val groupIterator = mDatabase.getGroupIndexes().iterator() if (groupIterator.hasNext()) - buildTreeGroups(it, groupIterator.next(), groupIterator) + buildTreeGroups(groupLevelList, root, groupIterator.next(), groupIterator) // add each child for (currentEntry in mDatabase.getEntryIndexes()) { diff --git a/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDB.kt b/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDB.kt index becb4676c..70e51b39a 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDB.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/file/output/DatabaseOutputKDB.kt @@ -20,15 +20,15 @@ package com.kunzisoft.keepass.database.file.output import com.kunzisoft.encrypt.HashManager -import com.kunzisoft.keepass.utils.UnsignedInt -import com.kunzisoft.keepass.utils.write2BytesUShort -import com.kunzisoft.keepass.utils.write4BytesUInt import com.kunzisoft.keepass.database.crypto.EncryptionAlgorithm import com.kunzisoft.keepass.database.element.database.DatabaseKDB import com.kunzisoft.keepass.database.element.group.GroupKDB import com.kunzisoft.keepass.database.exception.DatabaseOutputException import com.kunzisoft.keepass.database.file.DatabaseHeader import com.kunzisoft.keepass.database.file.DatabaseHeaderKDB +import com.kunzisoft.keepass.utils.UnsignedInt +import com.kunzisoft.keepass.utils.write2BytesUShort +import com.kunzisoft.keepass.utils.write4BytesUInt import java.io.BufferedOutputStream import java.io.ByteArrayOutputStream import java.io.IOException @@ -59,6 +59,8 @@ class DatabaseOutputKDB(private val mDatabaseKDB: DatabaseKDB, override fun output() { // Before we output the header, we should sort our list of groups // and remove any orphaned nodes that are no longer part of the tree hierarchy + // also remove the virtual root not present in kdb + val rootGroup = mDatabaseKDB.rootGroup sortGroupsForOutput() val header = outputHeader(mOutputStream) @@ -86,8 +88,10 @@ class DatabaseOutputKDB(private val mDatabaseKDB: DatabaseKDB, throw DatabaseOutputException("Invalid algorithm parameter.", e) } catch (e: IOException) { throw DatabaseOutputException("Failed to output final encrypted part.", e) + } finally { + // Add again the virtual root group for better management + mDatabaseKDB.rootGroup = rootGroup } - } @Throws(DatabaseOutputException::class) @@ -201,7 +205,7 @@ class DatabaseOutputKDB(private val mDatabaseKDB: DatabaseKDB, private fun sortGroupsForOutput() { val groupList = ArrayList() - // Rebuild list according to coalation sorting order removing any orphaned groups + // Rebuild list according to sorting order removing any orphaned groups for (rootGroup in mDatabaseKDB.rootGroups) { sortGroup(rootGroup, groupList) } diff --git a/app/src/main/java/com/kunzisoft/keepass/database/file/output/GroupOutputKDB.kt b/app/src/main/java/com/kunzisoft/keepass/database/file/output/GroupOutputKDB.kt index 48aff795d..9a2e62c03 100644 --- a/app/src/main/java/com/kunzisoft/keepass/database/file/output/GroupOutputKDB.kt +++ b/app/src/main/java/com/kunzisoft/keepass/database/file/output/GroupOutputKDB.kt @@ -19,13 +19,9 @@ */ package com.kunzisoft.keepass.database.file.output -import com.kunzisoft.keepass.utils.UnsignedInt -import com.kunzisoft.keepass.utils.dateTo5Bytes -import com.kunzisoft.keepass.utils.uIntTo4Bytes -import com.kunzisoft.keepass.utils.uShortTo2Bytes -import com.kunzisoft.keepass.utils.writeStringToStream import com.kunzisoft.keepass.database.element.group.GroupKDB import com.kunzisoft.keepass.database.exception.DatabaseOutputException +import com.kunzisoft.keepass.utils.* import java.io.IOException import java.io.OutputStream @@ -77,7 +73,7 @@ class GroupOutputKDB(private val mGroup: GroupKDB, // Level mOutputStream.write(LEVEL_FIELD_TYPE) mOutputStream.write(LEVEL_FIELD_SIZE) - mOutputStream.write(uShortTo2Bytes(mGroup.level)) + mOutputStream.write(uShortTo2Bytes(mGroup.getLevel())) // Flags mOutputStream.write(FLAGS_FIELD_TYPE) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 00a4b4e6a..fa1746388 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -137,7 +137,6 @@ يجب أن يكون لكل سلسلة اسم حقل. أدخل عددًا صحيحًا موجبًا في حقل «الطول». تعذر تمكين خدمة الملء التلقائي. - لا يمكن نقل مجموعة إلى نفسها. تعذر إيجاد الملف. جرِّب فتحه من متصفح ملفات. مدير الملفات تعذر قراءة الإعتمادات. diff --git a/app/src/main/res/values-b+sr+Latn/strings.xml b/app/src/main/res/values-b+sr+Latn/strings.xml index 2977796bf..17f03bb3e 100644 --- a/app/src/main/res/values-b+sr+Latn/strings.xml +++ b/app/src/main/res/values-b+sr+Latn/strings.xml @@ -85,7 +85,6 @@ Ovde ne možete kopirati grupu. Ovde ne možete kopirati unos. Ovde ne možete premestiti unos. - Ne možete premestiti grupu u samu sebe. Nije moguće omogućiti uslugu automatskog popunjavanja. Unesite pozitivan ceo broj u polje \"Dužina\". Ova oznaka već postoji. diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 931119bd8..63ff75ab3 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -288,6 +288,5 @@ Aquest text no coincideix amb l\'element sol·licitat. L\'OTP existent no està reconegut per aquest formulari, la seva validació ja no pot generar correctament el token. No s\'ha pogut crear una base de dades amb aquesta contrasenya i arxiu de clau. - No pots moure un grup dintre d\'ell mateix. No s\'ha pogut habilitar el servei d\'autocompletat. \ No newline at end of file diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 831469384..06f994888 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -146,7 +146,6 @@ Databázi se nepodařilo načíst. Klíč se nepodařilo načíst, zkuste snížit \"využití paměti\" pro KDF. Službu automatického vyplňování se nepodařilo zapnout. - Není možné přesunout skupinu do ní samotné. Soubor nenalezen. Zkuste jej otevřít ze správce souborů. Zobrazit uživatelská jména V seznamech záznamů zobrazit uživatelská jména diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 7d1c9e228..6ebf7e356 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -145,7 +145,6 @@ Databasen kunne ikke indlæses. Kunne ikke indlæse nøglen. Prøv at reducere KDF \"hukommelsesforbrug\". Kunne ikke aktivere autofyld tjenesten. - Kan ikke flytte en gruppe til sig selv. Kunne ikke finde filen. Prøv at åbne den fra filhåndtering. Vis brugernavne Vis brugernavne i postlister diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index cdb8a4560..c31de301e 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -268,7 +268,6 @@ Unterstützen Symbolpaket In der App verwendetes Symbolpaket - Eine Gruppe kann nicht in sich selbst verschoben werden. Kopieren Verschieben Einfügen diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 030dbd271..a2531ec8e 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -251,7 +251,6 @@ Θέμα που χρησιμοποιείται στην εφαρμογή Πακέτο Εικονιδίων Πακέτο εικονιδίων που χρησιμοποιείται στην εφαρμογή - Δεν μπορείτε να μετακινήσετε μια ομάδα μέσα στον εαυτό της. Αντιγραφή Μετακίνηση Επικόλληση diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 2a326a1c0..b67a05309 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -267,7 +267,6 @@ Editar entrada No se pudo cargar la base de datos. No se pudo cargar la clave. Intente disminuir el uso de memoria de KDF. - No puede mover un grupo dentro de sí mismo. Enseña nombres de usuario Enseña nombres de usuador en las listras de entradas Copiar diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 8121e9be1..6ddce6250 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -141,7 +141,6 @@ شما نمی توانید یک گروه را در اینجا کپی کنید. شما نمی توانید یک ورودی را در اینجا کپی کنید. شما نمی توانید یک ورودی را به اینجا منتقل کنید. - شما نمی توانید یک گروه را به خود منتقل کنید. قادر به فعال کردن سرویس پر کردن خودکار نبود. یک عدد کامل مثبت را در زمینه \"طول\" وارد کنید. این برچسب در حال حاضر وجود دارد. diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 17825f5ad..6dd0373f1 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -308,7 +308,6 @@ Et voi kopioida ryhmää tänne. Et voi kopioida tietuetta tänne. Et voi siirtää tietuetta tänne. - Et voi siirtää ryhmää itsensä sisälle. Automaattista täyttöä ei voitu ottaa käyttöön. Solmun lapset \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index d22426531..87343482f 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -275,7 +275,6 @@ Collection d’icônes Collection d’icônes utilisées dans l’application - Vous ne pouvez pas déplacer un groupe dans lui-même. Copier Déplacer Coller diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index def9cd87b..1a7ad2d67 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -242,7 +242,6 @@ Barem jedan skup podataka za prijavu mora biti postavljen. Svaki niz mora imati ime polja. Nije moguće aktivirati uslugu automatskog ispunjavanja. - Nije moguće premjestiti grupu u samu sebe. Unos se ne može ovdje premijestiti. Unos se ne može ovdje kopirati. Grupa se ne može ovjde kopirati. diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 42d97e39a..3a5672aea 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -154,7 +154,6 @@ Az adatbázis betöltése meghiúsult. A kulcs nem tölthető be. Próbálja meg csökkenteni a KDF „Memóriahasználatot”. Az automatikus kitöltési szolgáltatás nem engedélyezhető. - Nem helyezheti át a csoportot saját magába. Felhasználónevek megjelenítése Felhasználónevek megjelenítése a bejegyzéslistákban %1$s másolata diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index 590809bdc..44ca19de3 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -72,7 +72,6 @@ Anda tidak bisa menyalin grup di sini. Anda tidak bisa menyalin entri di sini. Anda tidak bisa memindahkan entri ke sini. - Anda tidak bisa memindahkan grup ke grup itu sendiri. Tidak bisa mengaktifkan layanan IsiOtomatis. Masukkan bilangan bulat di bidang \"Panjang\". Label ini sudah ada. diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 3014df4e5..29901e257 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -154,7 +154,6 @@ ASCII esteso Seleziona un file chiave. Attivazione del servizio di auto-completamento fallita. - Non puoi spostare un gruppo in se stesso. Riempimento campi Copia Sposta diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 8deaf976b..18ac11de7 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -120,7 +120,6 @@ このラベルはすでに存在します。 [長さ] フィールドには正の整数を入力してください。 自動入力サービスを有効にできませんでした。 - グループを自分自身の中に移動することはできません。 ここではエントリーを移動することはできません。 ここではエントリーをコピーすることはできません。 ここではグループをコピーすることはできません。 diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 9ed8597ed..3f56cd507 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -78,7 +78,6 @@ 각 항목은 필드 이름을 가져야 합니다. \"길이\" 필드에는 양수를 입력하십시오. 자동 채우기 서비스를 활성화할 수 없습니다. - 그룹을 자신에게 옮길 수 없습니다. 필드 이름 필드 값 파일을 찾을 수 없습니다. 파일 탐색기에서 열리는지 확인해 주세요. diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index d3cc660e5..ac7551127 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -128,7 +128,6 @@ ഈ പാസ്‌വേഡും കീഫയലും ഉപയോഗിച്ച് ഡാറ്റാബേസ് സൃഷ്ടിക്കാൻ കഴിയില്ല. നിങ്ങൾക്ക് ഇവിടെ ഒരു ഗ്രൂപ്പ് പകർത്താൻ കഴിയില്ല. നിങ്ങൾക്ക് ഇവിടെ ഒരു എൻ‌ട്രി പകർ‌ത്താൻ‌ കഴിയില്ല. - നിങ്ങൾക്ക് ഒരു ഗ്രൂപ്പിനെ അതിലേക്ക് നീക്കാൻ കഴിയില്ല. ഈ ലേബൽ ഇതിനകം നിലവിലുണ്ട്. ഓരോ സ്ട്രിംഗിനും ഒരു ഫീൽഡ് നാമം ഉണ്ടായിരിക്കണം. \"Transformation rounds\" too high. Setting to 2147483648. diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index fa138d195..2213d6125 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -78,7 +78,6 @@ Hver streng må ha et feltnavn. Skriv inn et positivt heltall i \"Lengde\" feltet. Autofyll-tjenesten kan ikke skrus på. - Kan ikke flytte gruppe inn i seg selv. Feltnavn Feltverdi Fant ikke filen. Prøv å åpne den fra din innholdsleverandør. diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 648a4c256..768711ec4 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -143,7 +143,6 @@ De sleutel kan niet worden geladen. Probeer om het \"geheugengebruik\" van KDF te verminderen. Elke zin moet een veldnaam bevatten. De dienst automatisch aanvullen kan niet worden ingeschakeld. - Een groep kan niet naar zichzelf worden verplaatst. Veldnaam Veldwaarde Bestand niet gevonden. Probeer opnieuw te openen via bestandsbeheer. diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 6669ea333..4aa8bd8ce 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -244,7 +244,6 @@ ਡਾਟਾਬੇਸ ਫਾਈਲ ਬਣਾਉਣ ਲਈ ਅਸਮਰੱਥ। ਤੁਸੀਂ ਗਰੁੱਪ ਨੂੰ ਇੱਥੇ ਕਾਪੀ ਨਹੀਂ ਕਰ ਸਕਦੇ ਹੋ। ਤੁਸੀੰ ਇਸ ਐੰਟਰੀ ਨੂੰ ਇੱਥੇ ਕਾਪੀ ਨਹੀਂ ਕਰ ਸਕਦੇ ਹੋ। - ਤੁਸੀੰ ਗਰੁੱਪ ਨੂੰ ਖੁਦ ਵਿੱਚ ਨਹੀਂ ਭੇਜ ਸਕਦੇ ਹੋ। ਪਾਸਵਰਡ ਅੱਖਰ ਤਿਆਰ ਕੀਤੇ ਪਾਸਵਰਡਾਂ ਲਈ ਮੂਲ ਆਕਾਰ ਸੈੱਟ ਕਰਦਾ ਹੈ ਤਿਆਰ ਕੀਤੇ ਪਾਸਵਰਡ ਦਾ ਆਕਾਰ diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 3748a8073..bf97ad2ca 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -140,7 +140,6 @@ Nie można załadować klucza. Spróbuj zmniejszyć użycie pamięć KDF. Każdy ciąg musi mieć nazwę pola. Nie można włączyć usługi autouzupełniania. - Nie można przenieść grupy do samej siebie. Nazwa pola Wartość pola Nie znaleziono pliku. Spróbuj ponownie otworzyć go w przeglądarce plików. diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 32d102ad2..8a0a04ece 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -138,7 +138,6 @@ Não pôde encontrar dado de entrada. Um nome do campo é necessário para cada string. Não pôde ser habilitado o serviço de preenchimento automático. - Você não pode mover um grupo para dentro de si mesmo. Nome do campo Valor do campo Arquivo não encontrado. Tente reabri-lo de seu buscador de arquivos. diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index a0810454c..5d86b8edf 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -148,7 +148,6 @@ Permitir Não foi possível abrir a sua base de dados. Não foi possível carregar a chave. Tente descarregar o \"Uso de Memória\" do KDF. - Não pode mover um grupo para si mesmo. Mostrar nomes de utilizador Cópia de %1$s Preenchimento de formulário diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 825e79673..d092a2a09 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -13,7 +13,6 @@ Colar Mover Copiar - Não pode mover um grupo para si mesmo. Área de transferência limpa Uma implementação do gestor de palavras-chave KeePass para Android Pacote de ícones usado na app diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 66bb4fdfd..17b176daf 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -111,7 +111,6 @@ Fiecare șir trebuie să aibă un nume de câmp. Introduceți un număr întreg pozitiv în câmpul \"Lungime\". Nu s-a putut activa serviciul de completare automată. - Nu puteți muta un grup în sine. Nu puteți muta o intrare aici. Nu puteți copia o intrare aici. Nu puteți copia un grup aici. diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ba177823f..65d7960f2 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -168,7 +168,6 @@ Разрешить Невозможно загрузить базу. Невозможно загрузить ключ. Попробуйте уменьшить размер памяти, используемой функцией формирования ключа (KDF). - Нельзя переместить группу в саму себя. Показывать имя Показывать имя пользователя в списке записей Копировать diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index fc946bedf..37a822a4c 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -270,7 +270,6 @@ Tema som används i appen Ikonpaket Ikonpaket som används i appen - Du kan inte lägga en grupp i sig själv. Kopia Flytta Klistra in diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 93e40fa7e..d0e6b5824 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -78,7 +78,6 @@ Her dizginin bir alan adı olmalıdır. \"Uzunluk\" alanına pozitif bir tam sayı girin. Otomatik doldurma hizmeti etkinleştirilemedi. - Bir grubu kendine taşıyamazsın. Alan adı Alan değeri Dosya bulunamadı. Dosya tarayıcınızda yeniden açmayı deneyin. diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index cc7664ae3..b8d4767c3 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -217,7 +217,6 @@ Ви не можете копіювати групу сюди. Ви не можете копіювати записи сюди. Ви не можете перемістити запис сюди. - Ви не можете перемістити групу в себе саму. Не вдалось ввімкнути службу автозаповнення. Ця мітка вже існує. Кожен рядок повинен мати назву поля. diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 6dfa67dca..ca50bc6c2 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -139,7 +139,6 @@ 无法加载数据库。 无法加载密钥。尝试降低KDF的“内存使用”值。 无法启用自动填充服务。 - 无法将群组移至它自身之中。 找不到文件。请重新打开文件。 算法无效。 密钥文件为空。 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index d9603a2cb..789f53b15 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -128,7 +128,6 @@ 部份設備不容許其他程式使用剪貼簿。 無法清除剪貼簿 無法啟用自動填入服務。 - 無法移動一個群組至自己本身。 無效的演算法。 金鑰檔案是空白的。 表格填入 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 21475de8e..8c3e1c39c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -109,6 +109,7 @@ Make sure the path is correct. Invalid OTP secret. Enter a name. + This word is reserved and cannot be used. Select a keyfile. No memory to load your entire database. Could not load your database. @@ -121,7 +122,7 @@ This label already exists. Enter a positive integer number in the \"Length\" field. Could not enable autofill service. - You can not move a group into itself. + You can not move a group here. You can not move an entry here. You can not copy an entry here. You cannot copy a group here. diff --git a/fastlane/metadata/android/en-US/changelogs/72.txt b/fastlane/metadata/android/en-US/changelogs/72.txt index 42780ecb1..0d7523a93 100644 --- a/fastlane/metadata/android/en-US/changelogs/72.txt +++ b/fastlane/metadata/android/en-US/changelogs/72.txt @@ -1 +1 @@ - * \ No newline at end of file + * Move groups #658 \ No newline at end of file diff --git a/fastlane/metadata/android/fr-FR/changelogs/72.txt b/fastlane/metadata/android/fr-FR/changelogs/72.txt index 42780ecb1..07654207e 100644 --- a/fastlane/metadata/android/fr-FR/changelogs/72.txt +++ b/fastlane/metadata/android/fr-FR/changelogs/72.txt @@ -1 +1 @@ - * \ No newline at end of file + * Déplacement de groupes #658 \ No newline at end of file