mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Refactor runnable action
This commit is contained in:
@@ -19,8 +19,6 @@
|
||||
*/
|
||||
package com.kunzisoft.keepass.tests.database;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import android.content.Context;
|
||||
import android.test.AndroidTestCase;
|
||||
|
||||
@@ -30,9 +28,11 @@ import com.kunzisoft.keepass.database.PwDatabaseV3;
|
||||
import com.kunzisoft.keepass.database.PwEntry;
|
||||
import com.kunzisoft.keepass.database.PwEntryV3;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
import com.kunzisoft.keepass.database.action.DeleteGroupRunnable;
|
||||
import com.kunzisoft.keepass.database.action.node.DeleteGroupRunnable;
|
||||
import com.kunzisoft.keepass.search.SearchDbHelper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DeleteEntry extends AndroidTestCase {
|
||||
private static final String GROUP1_NAME = "Group1";
|
||||
private static final String ENTRY1_NAME = "Test1";
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.content.Intent;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
@@ -49,10 +48,11 @@ import com.kunzisoft.keepass.database.PwEntry;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
import com.kunzisoft.keepass.database.PwGroupId;
|
||||
import com.kunzisoft.keepass.database.PwIconStandard;
|
||||
import com.kunzisoft.keepass.database.action.AddEntryRunnable;
|
||||
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
|
||||
import com.kunzisoft.keepass.database.PwNode;
|
||||
import com.kunzisoft.keepass.database.action.RunnableOnFinish;
|
||||
import com.kunzisoft.keepass.database.action.UpdateEntryRunnable;
|
||||
import com.kunzisoft.keepass.database.action.node.AddEntryRunnable;
|
||||
import com.kunzisoft.keepass.database.action.node.AfterActionNodeOnFinish;
|
||||
import com.kunzisoft.keepass.database.action.node.UpdateEntryRunnable;
|
||||
import com.kunzisoft.keepass.database.security.ProtectedString;
|
||||
import com.kunzisoft.keepass.dialogs.GeneratePasswordDialogFragment;
|
||||
import com.kunzisoft.keepass.dialogs.IconPickerDialogFragment;
|
||||
@@ -67,6 +67,8 @@ import com.kunzisoft.keepass.view.EntryEditCustomField;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.kunzisoft.keepass.dialogs.IconPickerDialogFragment.UNDEFINED_ICON_ID;
|
||||
|
||||
public class EntryEditActivity extends LockingHideActivity
|
||||
@@ -251,7 +253,7 @@ public class EntryEditActivity extends LockingHideActivity
|
||||
mCallbackNewEntry = populateNewEntry();
|
||||
|
||||
// Open a progress dialog and save entry
|
||||
OnFinishRunnable onFinish = new AfterSave();
|
||||
AfterActionNodeOnFinish onFinish = new AfterSave();
|
||||
EntryEditActivity act = EntryEditActivity.this;
|
||||
RunnableOnFinish task;
|
||||
if ( mIsNew ) {
|
||||
@@ -560,14 +562,10 @@ public class EntryEditActivity extends LockingHideActivity
|
||||
}
|
||||
}
|
||||
|
||||
private final class AfterSave extends OnFinishRunnable {
|
||||
|
||||
AfterSave() {
|
||||
super(new Handler());
|
||||
}
|
||||
private final class AfterSave extends AfterActionNodeOnFinish {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
public void run(@Nullable PwNode oldNode, @Nullable PwNode newNode) {
|
||||
runOnUiThread(() -> {
|
||||
if ( mSuccess ) {
|
||||
finish();
|
||||
@@ -578,6 +576,6 @@ public class EntryEditActivity extends LockingHideActivity
|
||||
SaveDatabaseProgressTaskDialogFragment.stop(EntryEditActivity.this);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -58,15 +58,14 @@ import com.kunzisoft.keepass.database.PwGroupId;
|
||||
import com.kunzisoft.keepass.database.PwIcon;
|
||||
import com.kunzisoft.keepass.database.PwIconStandard;
|
||||
import com.kunzisoft.keepass.database.PwNode;
|
||||
import com.kunzisoft.keepass.database.action.AddGroupRunnable;
|
||||
import com.kunzisoft.keepass.database.action.AfterActionNodeOnFinish;
|
||||
import com.kunzisoft.keepass.database.action.CopyEntryRunnable;
|
||||
import com.kunzisoft.keepass.database.action.DeleteEntryRunnable;
|
||||
import com.kunzisoft.keepass.database.action.DeleteGroupRunnable;
|
||||
import com.kunzisoft.keepass.database.action.MoveEntryRunnable;
|
||||
import com.kunzisoft.keepass.database.action.MoveGroupRunnable;
|
||||
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
|
||||
import com.kunzisoft.keepass.database.action.UpdateGroupRunnable;
|
||||
import com.kunzisoft.keepass.database.action.node.AddGroupRunnable;
|
||||
import com.kunzisoft.keepass.database.action.node.AfterActionNodeOnFinish;
|
||||
import com.kunzisoft.keepass.database.action.node.CopyEntryRunnable;
|
||||
import com.kunzisoft.keepass.database.action.node.DeleteEntryRunnable;
|
||||
import com.kunzisoft.keepass.database.action.node.DeleteGroupRunnable;
|
||||
import com.kunzisoft.keepass.database.action.node.MoveEntryRunnable;
|
||||
import com.kunzisoft.keepass.database.action.node.MoveGroupRunnable;
|
||||
import com.kunzisoft.keepass.database.action.node.UpdateGroupRunnable;
|
||||
import com.kunzisoft.keepass.dialogs.AssignMasterKeyDialogFragment;
|
||||
import com.kunzisoft.keepass.dialogs.GroupEditDialogFragment;
|
||||
import com.kunzisoft.keepass.dialogs.IconPickerDialogFragment;
|
||||
@@ -329,7 +328,7 @@ public class GroupActivity extends ListNodesActivity
|
||||
|
||||
private void copyNode(PwEntry entryToCopy, PwGroup newParent) {
|
||||
CopyEntryRunnable task = new CopyEntryRunnable(this, App.getDB(), entryToCopy, newParent,
|
||||
new AfterAddNode(new Handler()));
|
||||
new AfterAddNode());
|
||||
task.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(this,
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
@@ -365,7 +364,7 @@ public class GroupActivity extends ListNodesActivity
|
||||
|
||||
private void moveGroup(PwGroup groupToMove, PwGroup newParent) {
|
||||
MoveGroupRunnable task = new MoveGroupRunnable(this, App.getDB(), groupToMove, newParent,
|
||||
new AfterAddNode(new Handler()));
|
||||
new AfterAddNode());
|
||||
task.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(this,
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
@@ -376,7 +375,7 @@ public class GroupActivity extends ListNodesActivity
|
||||
|
||||
private void moveEntry(PwEntry entryToMove, PwGroup newParent) {
|
||||
MoveEntryRunnable task = new MoveEntryRunnable(this, App.getDB(), entryToMove, newParent,
|
||||
new AfterAddNode(new Handler()));
|
||||
new AfterAddNode());
|
||||
task.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(this,
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
@@ -400,8 +399,11 @@ public class GroupActivity extends ListNodesActivity
|
||||
|
||||
private void deleteGroup(PwGroup group) {
|
||||
//TODO Verify trash recycle bin
|
||||
DeleteGroupRunnable task = new DeleteGroupRunnable(this, App.getDB(), group,
|
||||
new AfterDeleteNode(new Handler(), group));
|
||||
DeleteGroupRunnable task = new DeleteGroupRunnable(
|
||||
this,
|
||||
App.getDB(),
|
||||
group,
|
||||
new AfterDeleteNode());
|
||||
task.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(this,
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
@@ -411,8 +413,11 @@ public class GroupActivity extends ListNodesActivity
|
||||
}
|
||||
|
||||
private void deleteEntry(PwEntry entry) {
|
||||
DeleteEntryRunnable task = new DeleteEntryRunnable(this, App.getDB(), entry,
|
||||
new AfterDeleteNode(new Handler(), entry));
|
||||
DeleteEntryRunnable task = new DeleteEntryRunnable(
|
||||
this,
|
||||
App.getDB(),
|
||||
entry,
|
||||
new AfterDeleteNode());
|
||||
task.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(this,
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
@@ -674,7 +679,7 @@ public class GroupActivity extends ListNodesActivity
|
||||
AddGroupRunnable addGroupRunnable = new AddGroupRunnable(this,
|
||||
App.getDB(),
|
||||
newGroup,
|
||||
new AfterAddNode(new Handler()));
|
||||
new AfterAddNode());
|
||||
addGroupRunnable.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(this,
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
@@ -701,7 +706,7 @@ public class GroupActivity extends ListNodesActivity
|
||||
App.getDB(),
|
||||
oldGroupToUpdate,
|
||||
updateGroup,
|
||||
new AfterUpdateNode(new Handler()));
|
||||
new AfterUpdateNode());
|
||||
updateGroupRunnable.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(this,
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
@@ -715,9 +720,6 @@ public class GroupActivity extends ListNodesActivity
|
||||
}
|
||||
|
||||
class AfterAddNode extends AfterActionNodeOnFinish {
|
||||
AfterAddNode(Handler handler) {
|
||||
super(handler);
|
||||
}
|
||||
|
||||
public void run(PwNode oldNode, PwNode newNode) {
|
||||
super.run();
|
||||
@@ -736,9 +738,6 @@ public class GroupActivity extends ListNodesActivity
|
||||
}
|
||||
|
||||
class AfterUpdateNode extends AfterActionNodeOnFinish {
|
||||
AfterUpdateNode(Handler handler) {
|
||||
super(handler);
|
||||
}
|
||||
|
||||
public void run(PwNode oldNode, PwNode newNode) {
|
||||
super.run();
|
||||
@@ -756,25 +755,19 @@ public class GroupActivity extends ListNodesActivity
|
||||
}
|
||||
}
|
||||
|
||||
class AfterDeleteNode extends OnFinishRunnable {
|
||||
private PwNode pwNode;
|
||||
|
||||
AfterDeleteNode(Handler handler, PwNode pwNode) {
|
||||
super(handler);
|
||||
this.pwNode = pwNode;
|
||||
}
|
||||
class AfterDeleteNode extends AfterActionNodeOnFinish {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
public void run(PwNode oldNode, PwNode newNode) {
|
||||
super.run();
|
||||
|
||||
runOnUiThread(() -> {
|
||||
if ( mSuccess) {
|
||||
|
||||
if (listNodesFragment != null)
|
||||
listNodesFragment.removeNode(pwNode);
|
||||
listNodesFragment.removeNode(oldNode);
|
||||
|
||||
PwGroup parent = pwNode.getParent();
|
||||
PwGroup parent = oldNode.getParent();
|
||||
Database db = App.getDB();
|
||||
PwDatabase database = db.getPwDatabase();
|
||||
if (db.isRecycleBinAvailable() &&
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
|
||||
public abstract class ActionDatabaseRunnable extends RunnableOnFinish {
|
||||
|
||||
protected Database mDb;
|
||||
protected Context mContext;
|
||||
protected boolean mDontSave;
|
||||
|
||||
public ActionDatabaseRunnable(Context context, Database db, OnFinishRunnable finish, boolean dontSave) {
|
||||
super(finish);
|
||||
|
||||
this.mDb = db;
|
||||
this.mContext = context;
|
||||
this.mDontSave = dontSave;
|
||||
this.mFinish = new AfterActionRunnable(finish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// Commit to disk
|
||||
SaveDatabaseRunnable save = new SaveDatabaseRunnable(mContext, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
}
|
||||
|
||||
abstract protected void onFinish(boolean success);
|
||||
|
||||
private class AfterActionRunnable extends OnFinishRunnable {
|
||||
|
||||
AfterActionRunnable(OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
onFinish(mSuccess);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,77 +30,56 @@ import com.kunzisoft.keepass.utils.UriUtil;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class AssignPasswordInDBRunnable extends RunnableOnFinish {
|
||||
public class AssignPasswordInDBRunnable extends ActionDatabaseRunnable {
|
||||
|
||||
private String mPassword;
|
||||
private Uri mKeyfile;
|
||||
private Database mDb;
|
||||
private boolean mDontSave;
|
||||
private Context ctx;
|
||||
private byte[] mBackupKey;
|
||||
|
||||
public AssignPasswordInDBRunnable(Context ctx, Database db, String password, Uri keyfile, OnFinishRunnable finish) {
|
||||
this(ctx, db, password, keyfile, finish, false);
|
||||
|
||||
}
|
||||
|
||||
public AssignPasswordInDBRunnable(Context ctx, Database db, String password, Uri keyfile, OnFinishRunnable finish, boolean dontSave) {
|
||||
super(finish);
|
||||
super(ctx, db, finish, dontSave);
|
||||
|
||||
mDb = db;
|
||||
mPassword = password;
|
||||
mKeyfile = keyfile;
|
||||
mDontSave = dontSave;
|
||||
this.ctx = ctx;
|
||||
this.mPassword = password;
|
||||
this.mKeyfile = keyfile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PwDatabase pm = mDb.getPwDatabase();
|
||||
|
||||
byte[] backupKey = new byte[pm.getMasterKey().length];
|
||||
System.arraycopy(pm.getMasterKey(), 0, backupKey, 0, backupKey.length);
|
||||
mBackupKey = new byte[pm.getMasterKey().length];
|
||||
System.arraycopy(pm.getMasterKey(), 0, mBackupKey, 0, mBackupKey.length);
|
||||
|
||||
// Set key
|
||||
try {
|
||||
InputStream is = UriUtil.getUriInputStream(ctx, mKeyfile);
|
||||
InputStream is = UriUtil.getUriInputStream(mContext, mKeyfile);
|
||||
pm.retrieveMasterKey(mPassword, is);
|
||||
} catch (InvalidKeyFileException e) {
|
||||
erase(backupKey);
|
||||
erase(mBackupKey);
|
||||
finish(false, e.getMessage());
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
erase(backupKey);
|
||||
erase(mBackupKey);
|
||||
finish(false, e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
// Save Database
|
||||
mFinish = new AfterSave(backupKey, mFinish);
|
||||
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
super.run();
|
||||
}
|
||||
|
||||
private class AfterSave extends OnFinishRunnable {
|
||||
private byte[] mBackup;
|
||||
|
||||
public AfterSave(byte[] backup, OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
|
||||
mBackup = backup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( ! mSuccess ) {
|
||||
// Erase the current master key
|
||||
erase(mDb.getPwDatabase().getMasterKey());
|
||||
mDb.getPwDatabase().setMasterKey(mBackup);
|
||||
}
|
||||
|
||||
super.run();
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
protected void onFinish(boolean success) {
|
||||
if (!success) {
|
||||
// Erase the current master key
|
||||
erase(mDb.getPwDatabase().getMasterKey());
|
||||
mDb.getPwDatabase().setMasterKey(mBackupKey);
|
||||
}
|
||||
}
|
||||
|
||||
/** Overwrite the array as soon as we don't need it to avoid keeping the extra data in memory
|
||||
* @param array
|
||||
|
||||
@@ -56,7 +56,7 @@ public class CreateDBRunnable extends RunnableOnFinish {
|
||||
App.clearShutdown();
|
||||
|
||||
// Commit changes
|
||||
SaveDBRunnable save = new SaveDBRunnable(ctx, db, mFinish, mDontSave);
|
||||
SaveDatabaseRunnable save = new SaveDatabaseRunnable(ctx, db, mFinish, mDontSave);
|
||||
mFinish = null;
|
||||
save.run();
|
||||
}
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
|
||||
*
|
||||
* This file is part of KeePass DX.
|
||||
*
|
||||
* KeePass DX is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* KeePass DX is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwEntry;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
|
||||
/** Task to delete entries
|
||||
* @author bpellin
|
||||
*
|
||||
*/
|
||||
public class DeleteEntryRunnable extends RunnableOnFinish {
|
||||
|
||||
private Database mDb;
|
||||
private PwEntry mEntry;
|
||||
private boolean mDontSave;
|
||||
private Context ctx;
|
||||
|
||||
public DeleteEntryRunnable(Context ctx, Database db, PwEntry entry, OnFinishRunnable finish) {
|
||||
this(ctx, db, entry, finish, false);
|
||||
}
|
||||
|
||||
public DeleteEntryRunnable(Context ctx, Database db, PwEntry entry, OnFinishRunnable finish, boolean dontSave) {
|
||||
super(finish);
|
||||
|
||||
this.mDb = db;
|
||||
this.mEntry = entry;
|
||||
this.mDontSave = dontSave;
|
||||
this.ctx = ctx;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PwGroup parent = mEntry.getParent();
|
||||
|
||||
// Remove Entry from parent
|
||||
boolean recycle = mDb.canRecycle(mEntry);
|
||||
if (recycle) {
|
||||
mDb.recycle(mEntry);
|
||||
}
|
||||
else {
|
||||
mDb.deleteEntry(mEntry);
|
||||
}
|
||||
|
||||
// Save
|
||||
mFinish = new AfterDelete(mFinish, parent, mEntry, recycle);
|
||||
|
||||
// Commit database
|
||||
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
}
|
||||
|
||||
private class AfterDelete extends OnFinishRunnable {
|
||||
|
||||
private PwGroup mParent;
|
||||
private PwEntry mEntry;
|
||||
private boolean recycled;
|
||||
|
||||
AfterDelete(OnFinishRunnable finish, PwGroup parent, PwEntry entry, boolean r) {
|
||||
super(finish);
|
||||
|
||||
mParent = parent;
|
||||
mEntry = entry;
|
||||
recycled = r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( !mSuccess ) {
|
||||
if (recycled) {
|
||||
mDb.undoRecycle(mEntry, mParent);
|
||||
}
|
||||
else {
|
||||
mDb.undoDeleteEntry(mEntry, mParent);
|
||||
}
|
||||
}
|
||||
// TODO Callback after delete entry
|
||||
|
||||
super.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
|
||||
*
|
||||
* This file is part of KeePass DX.
|
||||
*
|
||||
* KeePass DX is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* KeePass DX is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.kunzisoft.keepass.app.App;
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwEntry;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DeleteGroupRunnable extends RunnableOnFinish {
|
||||
|
||||
private Context mContext;
|
||||
private Database mDb;
|
||||
private PwGroup<PwGroup, PwGroup, PwEntry> mGroup;
|
||||
private boolean mDontSave;
|
||||
|
||||
public DeleteGroupRunnable(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
setMembers(ctx, db, group, false);
|
||||
}
|
||||
|
||||
public DeleteGroupRunnable(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, OnFinishRunnable finish, boolean dontSave) {
|
||||
super(finish);
|
||||
setMembers(ctx, db, group, dontSave);
|
||||
}
|
||||
|
||||
private void setMembers(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, boolean dontSave) {
|
||||
mDb = db;
|
||||
mGroup = group;
|
||||
mContext = ctx;
|
||||
mDontSave = dontSave;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PwGroup parent = mGroup.getParent();
|
||||
|
||||
// Remove Group from parent
|
||||
boolean recycle = mDb.canRecycle(mGroup);
|
||||
if (recycle) {
|
||||
mDb.recycle(mGroup);
|
||||
}
|
||||
else {
|
||||
// TODO tests
|
||||
// Remove child entries
|
||||
List<PwEntry> childEnt = new ArrayList<>(mGroup.getChildEntries()); // TODO new Methods
|
||||
for ( int i = 0; i < childEnt.size(); i++ ) {
|
||||
DeleteEntryRunnable task = new DeleteEntryRunnable(mContext, mDb, childEnt.get(i), null, true);
|
||||
task.run();
|
||||
}
|
||||
|
||||
// Remove child groups
|
||||
List<PwGroup> childGrp = new ArrayList<>(mGroup.getChildGroups());
|
||||
for ( int i = 0; i < childGrp.size(); i++ ) {
|
||||
DeleteGroupRunnable task = new DeleteGroupRunnable(mContext, mDb, childGrp.get(i), null, true);
|
||||
task.run();
|
||||
}
|
||||
mDb.deleteGroup(mGroup);
|
||||
|
||||
// Remove from PwDatabaseV3
|
||||
// TODO ENcapsulate
|
||||
mDb.getPwDatabase().getGroups().remove(mGroup);
|
||||
}
|
||||
|
||||
// Save
|
||||
mFinish = new AfterDelete(mFinish, parent, mGroup, recycle);
|
||||
|
||||
// Commit Database
|
||||
SaveDBRunnable save = new SaveDBRunnable(mContext, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
}
|
||||
|
||||
private class AfterDelete extends OnFinishRunnable {
|
||||
|
||||
private PwGroup mParent;
|
||||
private PwGroup mGroup;
|
||||
private boolean recycled;
|
||||
|
||||
AfterDelete(OnFinishRunnable finish, PwGroup parent, PwGroup mGroup, boolean recycle) {
|
||||
super(finish);
|
||||
|
||||
this.mParent = parent;
|
||||
this.mGroup = mGroup;
|
||||
this.recycled = recycle;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
if ( !mSuccess ) {
|
||||
if (recycled) {
|
||||
mDb.undoRecycle(mGroup, mParent);
|
||||
}
|
||||
else {
|
||||
// Let's not bother recovering from a failure to save a deleted tree. It is too much work.
|
||||
App.setShutdown();
|
||||
// TODO TEST pm.undoDeleteGroup(mGroup, mParent);
|
||||
}
|
||||
}
|
||||
// TODO Callback after delete group
|
||||
|
||||
super.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import android.net.Uri;
|
||||
import java.io.Serializable;
|
||||
|
||||
public class FileOnFinishRunnable extends OnFinishRunnable implements Serializable {
|
||||
|
||||
private Uri mFilename = null;
|
||||
protected FileOnFinishRunnable mOnFinish;
|
||||
|
||||
|
||||
@@ -83,4 +83,19 @@ public class OnFinishRunnable implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return mSuccess;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean mSuccess) {
|
||||
this.mSuccess = mSuccess;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return mMessage;
|
||||
}
|
||||
|
||||
public void setMessage(String mMessage) {
|
||||
this.mMessage = mMessage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,13 +26,13 @@ import com.kunzisoft.keepass.database.exception.PwDbOutputException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SaveDBRunnable extends RunnableOnFinish {
|
||||
public class SaveDatabaseRunnable extends RunnableOnFinish {
|
||||
|
||||
private Context mCtx;
|
||||
private Database mDb;
|
||||
private boolean mDontSave;
|
||||
|
||||
public SaveDBRunnable(Context ctx, Database db, OnFinishRunnable finish, boolean dontSave) {
|
||||
public SaveDatabaseRunnable(Context ctx, Database db, OnFinishRunnable finish, boolean dontSave) {
|
||||
super(finish);
|
||||
|
||||
this.mDb = db;
|
||||
@@ -40,7 +40,7 @@ public class SaveDBRunnable extends RunnableOnFinish {
|
||||
this.mCtx = ctx;
|
||||
}
|
||||
|
||||
public SaveDBRunnable(Context ctx, Database db, OnFinishRunnable finish) {
|
||||
public SaveDatabaseRunnable(Context ctx, Database db, OnFinishRunnable finish) {
|
||||
this(ctx, db, finish, false);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.kunzisoft.keepass.database.action.node;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwNode;
|
||||
import com.kunzisoft.keepass.database.action.ActionDatabaseRunnable;
|
||||
|
||||
abstract class ActionNodeDatabaseRunnable extends ActionDatabaseRunnable {
|
||||
|
||||
private AfterActionNodeOnFinish callbackRunnable;
|
||||
|
||||
public ActionNodeDatabaseRunnable(Context context, Database db, AfterActionNodeOnFinish finish, boolean dontSave) {
|
||||
super(context, db, finish, dontSave);
|
||||
this.callbackRunnable = finish;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback method who return the node(s) modified after an action
|
||||
* - Add : @param oldNode NULL, @param newNode CreatedNode
|
||||
* - Copy : @param oldNode NodeToCopy, @param newNode NodeCopied
|
||||
* - Delete : @param oldNode NodeToDelete, @param NULL
|
||||
* - Move : @param oldNode NULL, @param NodeToMove
|
||||
* - Update : @param oldNode NodeToUpdate, @param NodeUpdated
|
||||
*/
|
||||
protected void callbackNodeAction(boolean success, PwNode oldNode, PwNode newNode) {
|
||||
if (callbackRunnable != null) {
|
||||
callbackRunnable.setSuccess(success);
|
||||
callbackRunnable.run(oldNode, newNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,57 +17,40 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
package com.kunzisoft.keepass.database.action.node;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwEntry;
|
||||
|
||||
public class AddEntryRunnable extends RunnableOnFinish {
|
||||
public class AddEntryRunnable extends ActionNodeDatabaseRunnable {
|
||||
|
||||
protected Database mDb;
|
||||
private PwEntry mEntry;
|
||||
private Context ctx;
|
||||
private boolean mDontSave;
|
||||
private PwEntry mNewEntry;
|
||||
|
||||
public AddEntryRunnable(Context ctx, Database db, PwEntry entry, OnFinishRunnable finish) {
|
||||
this(ctx, db, entry, finish, false);
|
||||
public AddEntryRunnable(Context ctx, Database db, PwEntry entryToAdd, AfterActionNodeOnFinish finish) {
|
||||
this(ctx, db, entryToAdd, finish, false);
|
||||
}
|
||||
|
||||
public AddEntryRunnable(Context ctx, Database db, PwEntry entry, OnFinishRunnable finish, boolean dontSave) {
|
||||
super(finish);
|
||||
public AddEntryRunnable(Context ctx, Database db, PwEntry entryToAdd, AfterActionNodeOnFinish finish, boolean dontSave) {
|
||||
super(ctx, db, finish, dontSave);
|
||||
|
||||
this.mDb = db;
|
||||
this.mEntry = entry;
|
||||
this.ctx = ctx;
|
||||
this.mDontSave = dontSave;
|
||||
|
||||
this.mFinish = new AfterAdd(mFinish);
|
||||
this.mNewEntry = entryToAdd;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
mDb.addEntryTo(mEntry, mEntry.getParent());
|
||||
mDb.addEntryTo(mNewEntry, mNewEntry.getParent());
|
||||
|
||||
// Commit to disk
|
||||
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
super.run();
|
||||
}
|
||||
|
||||
private class AfterAdd extends OnFinishRunnable {
|
||||
|
||||
AfterAdd(OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( !mSuccess ) {
|
||||
mDb.removeEntryFrom(mEntry, mEntry.getParent());
|
||||
}
|
||||
// TODO if add entry callback
|
||||
super.run();
|
||||
@Override
|
||||
protected void onFinish(boolean success) {
|
||||
if ( !success ) {
|
||||
mDb.removeEntryFrom(mNewEntry, mNewEntry.getParent());
|
||||
}
|
||||
callbackNodeAction(success, null, mNewEntry);
|
||||
}
|
||||
}
|
||||
@@ -17,34 +17,25 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
package com.kunzisoft.keepass.database.action.node;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
|
||||
public class AddGroupRunnable extends RunnableOnFinish {
|
||||
public class AddGroupRunnable extends ActionNodeDatabaseRunnable {
|
||||
|
||||
protected Database mDb;
|
||||
private PwGroup mNewGroup;
|
||||
private Context ctx;
|
||||
private boolean mDontSave;
|
||||
|
||||
public AddGroupRunnable(Context ctx, Database db, PwGroup newGroup, AfterActionNodeOnFinish afterAddNode) {
|
||||
this(ctx, db, newGroup, afterAddNode, false);
|
||||
}
|
||||
|
||||
public AddGroupRunnable(Context ctx, Database db, PwGroup newGroup, AfterActionNodeOnFinish afterAddNode,
|
||||
boolean dontSave) {
|
||||
super(afterAddNode);
|
||||
public AddGroupRunnable(Context ctx, Database db, PwGroup newGroup, AfterActionNodeOnFinish afterAddNode, boolean dontSave) {
|
||||
super(ctx, db, afterAddNode, dontSave);
|
||||
|
||||
this.mDb = db;
|
||||
this.mNewGroup = newGroup;
|
||||
this.mDontSave = dontSave;
|
||||
this.ctx = ctx;
|
||||
|
||||
this.mFinish = new AfterAdd(mFinish);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,28 +43,14 @@ public class AddGroupRunnable extends RunnableOnFinish {
|
||||
mDb.addGroupTo(mNewGroup, mNewGroup.getParent());
|
||||
|
||||
// Commit to disk
|
||||
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
super.run();
|
||||
}
|
||||
|
||||
private class AfterAdd extends OnFinishRunnable {
|
||||
|
||||
AfterAdd(OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( !mSuccess ) {
|
||||
mDb.removeGroupFrom(mNewGroup, mNewGroup.getParent());
|
||||
}
|
||||
|
||||
// TODO Better callback
|
||||
AfterActionNodeOnFinish afterAddNode =
|
||||
(AfterActionNodeOnFinish) super.mOnFinish;
|
||||
afterAddNode.mSuccess = mSuccess;
|
||||
afterAddNode.mMessage = mMessage;
|
||||
afterAddNode.run(null, mNewGroup);
|
||||
}
|
||||
@Override
|
||||
protected void onFinish(boolean success) {
|
||||
if ( !success ) {
|
||||
mDb.removeGroupFrom(mNewGroup, mNewGroup.getParent());
|
||||
}
|
||||
callbackNodeAction(success, null, mNewGroup);
|
||||
}
|
||||
}
|
||||
@@ -17,16 +17,20 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
package com.kunzisoft.keepass.database.action.node;
|
||||
|
||||
import android.os.Handler;
|
||||
|
||||
import com.kunzisoft.keepass.database.PwNode;
|
||||
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class AfterActionNodeOnFinish extends OnFinishRunnable {
|
||||
public AfterActionNodeOnFinish(Handler handler) {
|
||||
super(handler);
|
||||
|
||||
public AfterActionNodeOnFinish() {
|
||||
super(new Handler());
|
||||
}
|
||||
|
||||
public abstract void run(PwNode oldNode, PwNode newNode);
|
||||
public abstract void run(@Nullable PwNode oldNode, @Nullable PwNode newNode);
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
package com.kunzisoft.keepass.database.action.node;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
@@ -26,31 +26,23 @@ import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwEntry;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
|
||||
public class CopyEntryRunnable extends RunnableOnFinish {
|
||||
public class CopyEntryRunnable extends ActionNodeDatabaseRunnable {
|
||||
|
||||
private static final String TAG = CopyEntryRunnable.class.getName();
|
||||
|
||||
private Database mDb;
|
||||
private PwEntry mEntryToCopy;
|
||||
private PwEntry mEntryCopied;
|
||||
private PwGroup mNewParent;
|
||||
private Context mContext;
|
||||
private boolean mDontSave;
|
||||
|
||||
public CopyEntryRunnable(Context context, Database db, PwEntry oldE, PwGroup newParent, AfterActionNodeOnFinish afterAddNode) {
|
||||
this(context, db, oldE, newParent, afterAddNode, false);
|
||||
}
|
||||
|
||||
public CopyEntryRunnable(Context context, Database db, PwEntry oldE, PwGroup newParent, AfterActionNodeOnFinish afterAddNode, boolean dontSave) {
|
||||
super(afterAddNode);
|
||||
super(context, db, afterAddNode, dontSave);
|
||||
|
||||
this.mDb = db;
|
||||
this.mEntryToCopy = oldE;
|
||||
this.mNewParent = newParent;
|
||||
this.mContext = context;
|
||||
this.mDontSave = dontSave;
|
||||
|
||||
this.mFinish = new AfterCopy(afterAddNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,37 +54,22 @@ public class CopyEntryRunnable extends RunnableOnFinish {
|
||||
mEntryCopied.touch(true, true);
|
||||
|
||||
// Commit to disk
|
||||
SaveDBRunnable save = new SaveDBRunnable(mContext, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
super.run();
|
||||
} else {
|
||||
Log.e(TAG, "Unable to create a copy of the entry");
|
||||
}
|
||||
}
|
||||
|
||||
private class AfterCopy extends OnFinishRunnable {
|
||||
|
||||
AfterCopy(OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( !mSuccess ) {
|
||||
// If we fail to save, try to delete the copy
|
||||
try {
|
||||
mDb.deleteEntry(mEntryCopied);
|
||||
} catch (Exception e) {
|
||||
Log.i(TAG, "Unable to delete the copied entry");
|
||||
}
|
||||
@Override
|
||||
protected void onFinish(boolean success) {
|
||||
if ( !success ) {
|
||||
// If we fail to save, try to delete the copy
|
||||
try {
|
||||
mDb.deleteEntry(mEntryCopied);
|
||||
} catch (Exception e) {
|
||||
Log.i(TAG, "Unable to delete the copied entry");
|
||||
}
|
||||
// TODO Better callback
|
||||
AfterActionNodeOnFinish afterAddNode =
|
||||
(AfterActionNodeOnFinish) super.mOnFinish;
|
||||
afterAddNode.mSuccess = mSuccess;
|
||||
afterAddNode.mMessage = mMessage;
|
||||
afterAddNode.run(null, mEntryCopied);
|
||||
|
||||
super.run();
|
||||
}
|
||||
callbackNodeAction(success, mEntryToCopy, mEntryCopied);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
|
||||
*
|
||||
* This file is part of KeePass DX.
|
||||
*
|
||||
* KeePass DX is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* KeePass DX is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.action.node;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwEntry;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
|
||||
public class DeleteEntryRunnable extends ActionNodeDatabaseRunnable {
|
||||
|
||||
private PwEntry mEntryToDelete;
|
||||
private PwGroup mParent;
|
||||
private boolean mRecycle;
|
||||
|
||||
public DeleteEntryRunnable(Context ctx, Database db, PwEntry entry, AfterActionNodeOnFinish finish) {
|
||||
this(ctx, db, entry, finish, false);
|
||||
}
|
||||
|
||||
public DeleteEntryRunnable(Context ctx, Database db, PwEntry entry, AfterActionNodeOnFinish finish, boolean dontSave) {
|
||||
super(ctx, db, finish, dontSave);
|
||||
|
||||
this.mEntryToDelete = entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
mParent = mEntryToDelete.getParent();
|
||||
|
||||
// Remove Entry from parent
|
||||
mRecycle = mDb.canRecycle(mEntryToDelete);
|
||||
if (mRecycle) {
|
||||
mDb.recycle(mEntryToDelete);
|
||||
}
|
||||
else {
|
||||
mDb.deleteEntry(mEntryToDelete);
|
||||
}
|
||||
|
||||
// Commit database
|
||||
super.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinish(boolean success) {
|
||||
if ( !success ) {
|
||||
if (mRecycle) {
|
||||
mDb.undoRecycle(mEntryToDelete, mParent);
|
||||
}
|
||||
else {
|
||||
mDb.undoDeleteEntry(mEntryToDelete, mParent);
|
||||
}
|
||||
}
|
||||
callbackNodeAction(success, mEntryToDelete, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft.
|
||||
*
|
||||
* This file is part of KeePass DX.
|
||||
*
|
||||
* KeePass DX is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* KeePass DX is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.action.node;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.kunzisoft.keepass.app.App;
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwEntry;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DeleteGroupRunnable extends ActionNodeDatabaseRunnable {
|
||||
|
||||
private PwGroup<PwGroup, PwGroup, PwEntry> mGroupToDelete;
|
||||
private PwGroup mParent;
|
||||
private boolean mRecycle;
|
||||
|
||||
public DeleteGroupRunnable(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, AfterActionNodeOnFinish finish) {
|
||||
this(ctx, db, group, finish, false);
|
||||
}
|
||||
|
||||
public DeleteGroupRunnable(Context ctx, Database db, PwGroup<PwGroup, PwGroup, PwEntry> group, AfterActionNodeOnFinish finish, boolean dontSave) {
|
||||
super(ctx, db, finish, dontSave);
|
||||
mGroupToDelete = group;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
mParent = mGroupToDelete.getParent();
|
||||
|
||||
// Remove Group from parent
|
||||
mRecycle = mDb.canRecycle(mGroupToDelete);
|
||||
if (mRecycle) {
|
||||
mDb.recycle(mGroupToDelete);
|
||||
}
|
||||
else {
|
||||
// TODO tests
|
||||
// Remove child entries
|
||||
List<PwEntry> childEnt = new ArrayList<>(mGroupToDelete.getChildEntries()); // TODO new Methods
|
||||
for ( int i = 0; i < childEnt.size(); i++ ) {
|
||||
DeleteEntryRunnable task = new DeleteEntryRunnable(mContext, mDb, childEnt.get(i), null, true);
|
||||
task.run();
|
||||
}
|
||||
|
||||
// Remove child groups
|
||||
List<PwGroup> childGrp = new ArrayList<>(mGroupToDelete.getChildGroups());
|
||||
for ( int i = 0; i < childGrp.size(); i++ ) {
|
||||
DeleteGroupRunnable task = new DeleteGroupRunnable(mContext, mDb, childGrp.get(i), null, true);
|
||||
task.run();
|
||||
}
|
||||
mDb.deleteGroup(mGroupToDelete);
|
||||
|
||||
// Remove from PwDatabaseV3
|
||||
// TODO ENcapsulate
|
||||
mDb.getPwDatabase().getGroups().remove(mGroupToDelete);
|
||||
}
|
||||
|
||||
// Commit Database
|
||||
super.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinish(boolean success) {
|
||||
if ( !success ) {
|
||||
if (mRecycle) {
|
||||
mDb.undoRecycle(mGroupToDelete, mParent);
|
||||
}
|
||||
else {
|
||||
// Let's not bother recovering from a failure to save a deleted tree. It is too much work.
|
||||
App.setShutdown();
|
||||
// TODO TEST pm.undoDeleteGroup(mGroup, mParent);
|
||||
}
|
||||
}
|
||||
callbackNodeAction(success, mGroupToDelete, null);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
package com.kunzisoft.keepass.database.action.node;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
@@ -26,31 +26,23 @@ import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwEntry;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
|
||||
public class MoveEntryRunnable extends RunnableOnFinish {
|
||||
public class MoveEntryRunnable extends ActionNodeDatabaseRunnable {
|
||||
|
||||
private static final String TAG = MoveEntryRunnable.class.getName();
|
||||
|
||||
private Database mDb;
|
||||
private PwEntry mEntryToMove;
|
||||
private PwGroup mOldParent;
|
||||
private PwGroup mNewParent;
|
||||
private Context mContext;
|
||||
private boolean mDontSave;
|
||||
|
||||
public MoveEntryRunnable(Context context, Database db, PwEntry oldE, PwGroup newParent, AfterActionNodeOnFinish afterAddNode) {
|
||||
this(context, db, oldE, newParent, afterAddNode, false);
|
||||
}
|
||||
|
||||
public MoveEntryRunnable(Context context, Database db, PwEntry oldE, PwGroup newParent, AfterActionNodeOnFinish afterAddNode, boolean dontSave) {
|
||||
super(afterAddNode);
|
||||
super(context, db, afterAddNode, dontSave);
|
||||
|
||||
this.mDb = db;
|
||||
this.mEntryToMove = oldE;
|
||||
this.mNewParent = newParent;
|
||||
this.mContext = context;
|
||||
this.mDontSave = dontSave;
|
||||
|
||||
this.mFinish = new AfterMove(afterAddNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,37 +56,22 @@ public class MoveEntryRunnable extends RunnableOnFinish {
|
||||
mEntryToMove.touch(true, true);
|
||||
|
||||
// Commit to disk
|
||||
SaveDBRunnable save = new SaveDBRunnable(mContext, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
super.run();
|
||||
} else {
|
||||
Log.e(TAG, "Unable to create a copy of the entry");
|
||||
}
|
||||
}
|
||||
|
||||
private class AfterMove extends OnFinishRunnable {
|
||||
|
||||
AfterMove(OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( !mSuccess ) {
|
||||
// If we fail to save, try to remove in the first place
|
||||
try {
|
||||
mDb.moveEntry(mEntryToMove, mOldParent);
|
||||
} catch (Exception e) {
|
||||
Log.i(TAG, "Unable to replace the entry");
|
||||
}
|
||||
@Override
|
||||
protected void onFinish(boolean success) {
|
||||
if ( !success ) {
|
||||
// If we fail to save, try to remove in the first place
|
||||
try {
|
||||
mDb.moveEntry(mEntryToMove, mOldParent);
|
||||
} catch (Exception e) {
|
||||
Log.i(TAG, "Unable to replace the entry");
|
||||
}
|
||||
// TODO Better callback
|
||||
AfterActionNodeOnFinish afterAddNode =
|
||||
(AfterActionNodeOnFinish) super.mOnFinish;
|
||||
afterAddNode.mSuccess = mSuccess;
|
||||
afterAddNode.mMessage = mMessage;
|
||||
afterAddNode.run(null, mEntryToMove);
|
||||
|
||||
super.run();
|
||||
}
|
||||
callbackNodeAction(success, null, mEntryToMove);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
package com.kunzisoft.keepass.database.action.node;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
@@ -25,31 +25,23 @@ import android.util.Log;
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
|
||||
public class MoveGroupRunnable extends RunnableOnFinish {
|
||||
public class MoveGroupRunnable extends ActionNodeDatabaseRunnable {
|
||||
|
||||
private static final String TAG = MoveGroupRunnable.class.getName();
|
||||
|
||||
private Database mDb;
|
||||
private PwGroup mGroupToMove;
|
||||
private PwGroup mOldParent;
|
||||
private PwGroup mNewParent;
|
||||
private Context mContext;
|
||||
private boolean mDontSave;
|
||||
|
||||
public MoveGroupRunnable(Context context, Database db, PwGroup groupToMove, PwGroup newParent, AfterActionNodeOnFinish afterAddNode) {
|
||||
this(context, db, groupToMove, newParent, afterAddNode, false);
|
||||
}
|
||||
|
||||
public MoveGroupRunnable(Context context, Database db, PwGroup groupToMove, PwGroup newParent, AfterActionNodeOnFinish afterAddNode, boolean dontSave) {
|
||||
super(afterAddNode);
|
||||
super(context, db, afterAddNode, dontSave);
|
||||
|
||||
this.mDb = db;
|
||||
this.mGroupToMove = groupToMove;
|
||||
this.mNewParent = newParent;
|
||||
this.mContext = context;
|
||||
this.mDontSave = dontSave;
|
||||
|
||||
this.mFinish = new AfterMove(afterAddNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,8 +56,7 @@ public class MoveGroupRunnable extends RunnableOnFinish {
|
||||
mGroupToMove.touch(true, true);
|
||||
|
||||
// Commit to disk
|
||||
SaveDBRunnable save = new SaveDBRunnable(mContext, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
super.run();
|
||||
} else {
|
||||
Log.e(TAG, "Unable to create a copy of the group");
|
||||
}
|
||||
@@ -77,30 +68,16 @@ public class MoveGroupRunnable extends RunnableOnFinish {
|
||||
}
|
||||
}
|
||||
|
||||
private class AfterMove extends OnFinishRunnable {
|
||||
|
||||
AfterMove(OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( !mSuccess ) {
|
||||
// If we fail to save, try to move in the first place
|
||||
try {
|
||||
mDb.moveGroup(mGroupToMove, mOldParent);
|
||||
} catch (Exception e) {
|
||||
Log.i(TAG, "Unable to replace the group");
|
||||
}
|
||||
}
|
||||
// TODO Better callback
|
||||
AfterActionNodeOnFinish afterAddNode =
|
||||
(AfterActionNodeOnFinish) super.mOnFinish;
|
||||
afterAddNode.mSuccess = mSuccess;
|
||||
afterAddNode.mMessage = mMessage;
|
||||
afterAddNode.run(null, mGroupToMove);
|
||||
|
||||
super.run();
|
||||
}
|
||||
@Override
|
||||
protected void onFinish(boolean success) {
|
||||
if ( !success ) {
|
||||
// If we fail to save, try to move in the first place
|
||||
try {
|
||||
mDb.moveGroup(mGroupToMove, mOldParent);
|
||||
} catch (Exception e) {
|
||||
Log.i(TAG, "Unable to replace the group");
|
||||
}
|
||||
}
|
||||
callbackNodeAction(success, null, mGroupToMove);
|
||||
}
|
||||
}
|
||||
@@ -17,68 +17,47 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
package com.kunzisoft.keepass.database.action.node;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwEntry;
|
||||
|
||||
public class UpdateEntryRunnable extends RunnableOnFinish {
|
||||
public class UpdateEntryRunnable extends ActionNodeDatabaseRunnable {
|
||||
|
||||
private Database mDb;
|
||||
private PwEntry mOldE;
|
||||
private PwEntry mNewE;
|
||||
private Context ctx;
|
||||
private boolean mDontSave;
|
||||
private PwEntry mOldEntry;
|
||||
private PwEntry mNewEntry;
|
||||
private PwEntry mBackupEntry;
|
||||
|
||||
public UpdateEntryRunnable(Context ctx, Database db, PwEntry oldE, PwEntry newE, OnFinishRunnable finish) {
|
||||
public UpdateEntryRunnable(Context ctx, Database db, PwEntry oldE, PwEntry newE, AfterActionNodeOnFinish finish) {
|
||||
this(ctx, db, oldE, newE, finish, false);
|
||||
}
|
||||
|
||||
public UpdateEntryRunnable(Context ctx, Database db, PwEntry oldE, PwEntry newE, OnFinishRunnable finish, boolean dontSave) {
|
||||
super(finish);
|
||||
|
||||
this.mDb = db;
|
||||
this.mOldE = oldE;
|
||||
this.mNewE = newE;
|
||||
this.ctx = ctx;
|
||||
this.mDontSave = dontSave;
|
||||
public UpdateEntryRunnable(Context ctx, Database db, PwEntry oldE, PwEntry newE, AfterActionNodeOnFinish finish, boolean dontSave) {
|
||||
super(ctx, db, finish, dontSave);
|
||||
|
||||
this.mOldEntry = oldE;
|
||||
this.mNewEntry = newE;
|
||||
// Keep backup of original values in case save fails
|
||||
PwEntry backup;
|
||||
backup = mOldE.clone();
|
||||
|
||||
mFinish = new AfterUpdate(backup, finish);
|
||||
this.mBackupEntry = mOldEntry.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// Update entry with new values
|
||||
mDb.updateEntry(mOldE, mNewE);
|
||||
mOldE.touch(true, true);
|
||||
mDb.updateEntry(mOldEntry, mNewEntry);
|
||||
mOldEntry.touch(true, true);
|
||||
|
||||
// Commit to disk
|
||||
SaveDBRunnable save = new SaveDBRunnable(ctx, mDb, mFinish, mDontSave);
|
||||
save.run();
|
||||
super.run();
|
||||
}
|
||||
|
||||
private class AfterUpdate extends OnFinishRunnable {
|
||||
private PwEntry mBackup;
|
||||
|
||||
AfterUpdate(PwEntry backup, OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
mBackup = backup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( !mSuccess ) {
|
||||
// If we fail to save, back out changes to global structure
|
||||
mDb.updateEntry(mOldE, mBackup);
|
||||
}
|
||||
// TODO Callback for update entry
|
||||
super.run();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected void onFinish(boolean success) {
|
||||
if ( !success ) {
|
||||
// If we fail to save, back out changes to global structure
|
||||
mDb.updateEntry(mOldEntry, mBackupEntry);
|
||||
}
|
||||
callbackNodeAction(success, mOldEntry, mNewEntry);
|
||||
}
|
||||
}
|
||||
@@ -17,39 +17,30 @@
|
||||
* along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.kunzisoft.keepass.database.action;
|
||||
package com.kunzisoft.keepass.database.action.node;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.PwGroup;
|
||||
|
||||
public class UpdateGroupRunnable extends RunnableOnFinish {
|
||||
public class UpdateGroupRunnable extends ActionNodeDatabaseRunnable {
|
||||
|
||||
private Database mDb;
|
||||
private PwGroup mOldGroup;
|
||||
private PwGroup mNewGroup;
|
||||
private Context ctx;
|
||||
private boolean mDontSave;
|
||||
private PwGroup mBackupGroup;
|
||||
|
||||
public UpdateGroupRunnable(Context ctx, Database db, PwGroup oldGroup, PwGroup newGroup, AfterActionNodeOnFinish finish) {
|
||||
this(ctx, db, oldGroup, newGroup, finish, false);
|
||||
}
|
||||
|
||||
public UpdateGroupRunnable(Context ctx, Database db, PwGroup oldGroup, PwGroup newGroup, AfterActionNodeOnFinish finish, boolean dontSave) {
|
||||
super(finish);
|
||||
super(ctx, db, finish, dontSave);
|
||||
|
||||
this.mDb = db;
|
||||
this.mOldGroup = oldGroup;
|
||||
this.mNewGroup = newGroup;
|
||||
this.ctx = ctx;
|
||||
this.mDontSave = dontSave;
|
||||
|
||||
// Keep backup of original values in case save fails
|
||||
PwGroup backup;
|
||||
backup = mOldGroup.clone();
|
||||
|
||||
this.mFinish = new AfterUpdate(backup, finish);
|
||||
this.mBackupGroup = mOldGroup.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,30 +50,15 @@ public class UpdateGroupRunnable extends RunnableOnFinish {
|
||||
mOldGroup.touch(true, true);
|
||||
|
||||
// Commit to disk
|
||||
new SaveDBRunnable(ctx, mDb, mFinish, mDontSave).run();
|
||||
super.run();
|
||||
}
|
||||
|
||||
private class AfterUpdate extends OnFinishRunnable {
|
||||
private PwGroup mBackup;
|
||||
|
||||
AfterUpdate(PwGroup backup, OnFinishRunnable finish) {
|
||||
super(finish);
|
||||
mBackup = backup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if ( !mSuccess ) {
|
||||
// If we fail to save, back out changes to global structure
|
||||
mDb.updateGroup(mOldGroup, mBackup);
|
||||
}
|
||||
|
||||
// TODO Better callback
|
||||
AfterActionNodeOnFinish afterActionNodeOnFinish =
|
||||
(AfterActionNodeOnFinish) super.mOnFinish;
|
||||
afterActionNodeOnFinish.mSuccess = mSuccess;
|
||||
afterActionNodeOnFinish.mMessage = mMessage;
|
||||
afterActionNodeOnFinish.run(mOldGroup, mNewGroup);
|
||||
@Override
|
||||
protected void onFinish(boolean success) {
|
||||
if ( !success ) {
|
||||
// If we fail to save, back out changes to global structure
|
||||
mDb.updateGroup(mOldGroup, mBackupGroup);
|
||||
}
|
||||
callbackNodeAction(success, mOldGroup, mNewGroup);
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import android.view.View;
|
||||
import com.kunzisoft.keepass.app.App;
|
||||
import com.kunzisoft.keepass.database.Database;
|
||||
import com.kunzisoft.keepass.database.action.OnFinishRunnable;
|
||||
import com.kunzisoft.keepass.database.action.SaveDBRunnable;
|
||||
import com.kunzisoft.keepass.database.action.SaveDatabaseRunnable;
|
||||
import com.kunzisoft.keepass.tasks.SaveDatabaseProgressTaskDialogFragment;
|
||||
import com.kunzisoft.keepass.tasks.UpdateProgressTaskStatus;
|
||||
|
||||
@@ -47,15 +47,15 @@ public abstract class DatabaseSavePreferenceDialogFragmentCompat extends InputP
|
||||
assert getActivity() != null;
|
||||
|
||||
if (database != null && afterSaveDatabase != null) {
|
||||
SaveDBRunnable saveDBRunnable = new SaveDBRunnable(getContext(),
|
||||
SaveDatabaseRunnable saveDatabaseRunnable = new SaveDatabaseRunnable(getContext(),
|
||||
database,
|
||||
afterSaveDatabase);
|
||||
saveDBRunnable.setUpdateProgressTaskStatus(
|
||||
saveDatabaseRunnable.setUpdateProgressTaskStatus(
|
||||
new UpdateProgressTaskStatus(getContext(),
|
||||
SaveDatabaseProgressTaskDialogFragment.start(
|
||||
getActivity().getSupportFragmentManager())
|
||||
));
|
||||
new Thread(saveDBRunnable).start();
|
||||
new Thread(saveDatabaseRunnable).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user