Remove useless dirty, solve trash bug

This commit is contained in:
J-Jamet
2018-02-16 15:14:24 +01:00
parent bb353bc9d6
commit 79750c5320
9 changed files with 142 additions and 162 deletions

View File

@@ -45,7 +45,6 @@ import com.keepassdroid.adapters.NodeAdapter;
import com.keepassdroid.app.App;
import com.keepassdroid.compat.ActivityCompat;
import com.keepassdroid.compat.EditorCompat;
import com.keepassdroid.database.Database;
import com.keepassdroid.database.PwEntry;
import com.keepassdroid.database.PwGroup;
import com.keepassdroid.database.PwNode;
@@ -72,19 +71,6 @@ public abstract class GroupBaseActivity extends LockCloseListActivity
protected PwGroup mCurrentGroup;
@Override
protected void onResume() {
super.onResume();
refreshIfDirty();
}
public void refreshIfDirty() {
Database db = App.getDB();
if ( db.dirty.contains(mCurrentGroup) ) {
db.dirty.remove(mCurrentGroup);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -252,12 +238,6 @@ public abstract class GroupBaseActivity extends LockCloseListActivity
// Refresh menu titles
ActivityCompat.invalidateOptionsMenu(this);
// Mark all groups as dirty now to refresh them on load
Database db = App.getDB();
db.markAllGroupsAsDirty();
// We'll manually refresh this tree so we can remove it
db.dirty.remove(mCurrentGroup);
// Tell the adapter to refresh it's list
mAdapter.notifyChangeSort();
mAdapter.rebuildList(mCurrentGroup);
@@ -294,7 +274,6 @@ public abstract class GroupBaseActivity extends LockCloseListActivity
public void run(PwNode pwNode) {
super.run();
if (mSuccess) {
refreshIfDirty();
mAdapter.addNode(pwNode);
} else {
displayMessage(GroupBaseActivity.this);
@@ -313,11 +292,13 @@ public abstract class GroupBaseActivity extends LockCloseListActivity
@Override
public void run() {
if ( mSuccess) {
refreshIfDirty();
mAdapter.removeNode(pwNode);
PwGroup parent = pwNode.getParent();
PwGroup recycleBin = App.getDB().pm.getRecycleBin();
if (parent.equals(recycleBin) && !mCurrentGroup.equals(recycleBin)) {
// Add trash if it doesn't exists
if (parent.equals(recycleBin)
&& mCurrentGroup.getParent() == null
&& !mCurrentGroup.equals(recycleBin)) {
mAdapter.addNode(parent);
}
} else {

View File

@@ -46,14 +46,11 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.SyncFailedException;
import java.util.HashSet;
import java.util.Set;
/**
* @author bpellin
*/
public class Database {
public Set<PwGroup> dirty = new HashSet<PwGroup>();
public PwDatabase pm;
public Uri mUri;
public SearchDbHelper searchHelper;
@@ -220,7 +217,6 @@ public class Database {
}
public void clear() {
dirty.clear();
drawFactory.clear();
pm = null;
@@ -228,16 +224,4 @@ public class Database {
loaded = false;
passwordEncodingError = false;
}
public void markAllGroupsAsDirty() {
for ( PwGroup group : pm.getGroups() ) {
dirty.add(group);
}
// TODO: This should probably be abstracted out
// The root tree in v3 is not an 'official' tree
if ( pm instanceof PwDatabaseV3 ) {
dirty.add(pm.rootGroup);
}
}
}

View File

@@ -265,8 +265,9 @@ public abstract class PwDatabase {
public void removeGroupFrom(PwGroup remove, PwGroup parent) {
// Remove tree from parent tree
parent.removeChildGroup(remove);
if (parent != null) {
parent.removeChildGroup(remove);
}
groups.remove(remove.getId());
}
@@ -331,6 +332,11 @@ public abstract class PwDatabase {
}
}
/**
* Define if a Group must be delete or recycle
* @param group Group to remove
* @return true if group can be recycle, false elsewhere
*/
public boolean canRecycle(PwGroup group) {
return false;
}
@@ -344,20 +350,39 @@ public abstract class PwDatabase {
return false;
}
public void recycle(PwGroup group) {
// Assume calls to this are protected by calling inRecyleBin
throw new RuntimeException("Call not valid for .kdb databases.");
}
public void recycle(PwEntry entry) {
// Assume calls to this are protected by calling inRecyleBin
throw new RuntimeException("Call not valid for .kdb databases.");
}
public void undoRecycle(PwGroup group, PwGroup origParent) {
throw new RuntimeException("Call not valid for .kdb databases.");
}
public void undoRecycle(PwEntry entry, PwGroup origParent) {
throw new RuntimeException("Call not valid for .kdb databases.");
}
public void deleteGroup(PwGroup group) {
PwGroup parent = group.getParent();
removeGroupFrom(group, parent);
parent.touch(false, true);
}
public void deleteEntry(PwEntry entry) {
PwGroup parent = entry.getParent();
removeEntryFrom(entry, parent);
parent.touch(false, true);
}
// TODO Delete group
public void undoDeleteGroup(PwGroup group, PwGroup origParent) {
addGroupTo(group, origParent);
}
public void undoDeleteEntry(PwEntry entry, PwGroup origParent) {

View File

@@ -366,9 +366,7 @@ public class PwDatabaseV4 extends PwDatabase {
if (!recycleBinEnabled) {
return false;
}
PwGroup recycle = getRecycleBin();
return (recycle == null) || (!group.isContainedIn(recycle));
}
@@ -377,11 +375,25 @@ public class PwDatabaseV4 extends PwDatabase {
if (!recycleBinEnabled) {
return false;
}
PwGroup parent = entry.getParent();
return (parent != null) && canRecycle(parent);
}
@Override
public void recycle(PwGroup group) {
ensureRecycleBin();
PwGroup parent = group.getParent();
removeGroupFrom(group, parent);
parent.touch(false, true);
PwGroup recycleBin = getRecycleBin();
addGroupTo(group, recycleBin);
group.touch(false, true);
// TODO ? group.touchLocation();
}
@Override
public void recycle(PwEntry entry) {
ensureRecycleBin();
@@ -397,6 +409,15 @@ public class PwDatabaseV4 extends PwDatabase {
entry.touchLocation();
}
@Override
public void undoRecycle(PwGroup group, PwGroup origParent) {
PwGroup recycleBin = getRecycleBin();
removeGroupFrom(group, recycleBin);
addGroupTo(group, origParent);
}
@Override
public void undoRecycle(PwEntry entry, PwGroup origParent) {
@@ -409,15 +430,14 @@ public class PwDatabaseV4 extends PwDatabase {
@Override
public void deleteEntry(PwEntry entry) {
super.deleteEntry(entry);
deletedObjects.add(new PwDeletedObject(entry.getUUID()));
}
@Override
public void undoDeleteEntry(PwEntry entry, PwGroup origParent) {
super.undoDeleteEntry(entry, origParent);
deletedObjects.remove(entry);
// TODO undo delete entry
deletedObjects.remove(entry);
}
@Override

View File

@@ -24,7 +24,6 @@ import android.content.Context;
import com.keepassdroid.database.Database;
import com.keepassdroid.database.PwDatabase;
import com.keepassdroid.database.PwEntry;
import com.keepassdroid.database.PwGroup;
public class AddEntry extends RunnableOnFinish {
protected Database mDb;
@@ -59,20 +58,11 @@ public class AddEntry extends RunnableOnFinish {
@Override
public void run() {
PwDatabase pm = mDb.pm;
if ( mSuccess ) {
PwGroup parent = mEntry.getParent();
// Mark parent tree dirty
mDb.dirty.add(parent);
} else {
if ( !mSuccess ) {
pm.removeEntryFrom(mEntry, mEntry.getParent());
}
// TODO if add entry callback
super.run();
}
}
}

View File

@@ -73,13 +73,11 @@ public class AddGroup extends RunnableOnFinish {
@Override
public void run() {
PwDatabase pm = mDb.pm;
if ( mSuccess ) {
// Mark parent group dirty
mDb.dirty.add(mParent);
} else {
pm.removeGroupFrom(mGroup, mParent);
if ( !mSuccess ) {
pm.removeGroupFrom(mGroup, mParent);
}
// TODO Better callback
AfterAddNodeOnFinish afterAddNode =
(AfterAddNodeOnFinish) super.mOnFinish;
afterAddNode.mSuccess = mSuccess;

View File

@@ -71,8 +71,6 @@ public class DeleteEntry extends RunnableOnFinish {
// Commit database
SaveDB save = new SaveDB(ctx, mDb, mFinish, mDontSave);
save.run();
}
private class AfterDelete extends OnFinish {
@@ -81,7 +79,7 @@ public class DeleteEntry extends RunnableOnFinish {
private PwEntry mEntry;
private boolean recycled;
public AfterDelete(OnFinish finish, PwGroup parent, PwEntry entry, boolean r) {
AfterDelete(OnFinish finish, PwGroup parent, PwEntry entry, boolean r) {
super(finish);
mParent = parent;
@@ -92,18 +90,7 @@ public class DeleteEntry extends RunnableOnFinish {
@Override
public void run() {
PwDatabase pm = mDb.pm;
if ( mSuccess ) {
// Mark parent dirty
if ( mParent != null ) {
mDb.dirty.add(mParent);
}
if (recycled) {
PwGroup recycleBin = pm.getRecycleBin();
mDb.dirty.add(recycleBin);
mDb.dirty.add(mDb.pm.rootGroup);
}
} else {
if ( !mSuccess ) {
if (recycled) {
pm.undoRecycle(mEntry, mParent);
}
@@ -111,11 +98,9 @@ public class DeleteEntry extends RunnableOnFinish {
pm.undoDeleteEntry(mEntry, mParent);
}
}
// TODO Callback after delete entry
super.run();
}
}
}

View File

@@ -19,30 +19,32 @@
*/
package com.keepassdroid.database.edit;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import com.keepassdroid.database.Database;
import com.keepassdroid.activities.GroupBaseActivity;
import com.keepassdroid.app.App;
import com.keepassdroid.database.Database;
import com.keepassdroid.database.PwDatabase;
import com.keepassdroid.database.PwEntry;
import com.keepassdroid.database.PwGroup;
import java.util.ArrayList;
import java.util.List;
public class DeleteGroup extends RunnableOnFinish {
private Context mContext;
private Database mDb;
private PwGroup mGroup;
private GroupBaseActivity mAct;
private boolean mDontSave;
public DeleteGroup(GroupBaseActivity act, Database db, PwGroup group, OnFinish finish) {
public DeleteGroup(Context ctx, Database db, PwGroup group, OnFinish finish) {
super(finish);
setMembers(act, db, group, false);
setMembers(ctx, db, group, false);
}
public DeleteGroup(GroupBaseActivity act, Database db, PwGroup group, OnFinish finish, boolean dontSave) {
public DeleteGroup(Context ctx, Database db, PwGroup group, OnFinish finish, boolean dontSave) {
super(finish);
setMembers(act, db, group, dontSave);
setMembers(ctx, db, group, dontSave);
}
public DeleteGroup(Database db, PwGroup group, OnFinish finish, boolean dontSave) {
@@ -50,71 +52,80 @@ public class DeleteGroup extends RunnableOnFinish {
setMembers(null, db, group, dontSave);
}
private void setMembers(GroupBaseActivity act, Database db, PwGroup group, boolean dontSave) {
private void setMembers(Context ctx, Database db, PwGroup group, boolean dontSave) {
mDb = db;
mGroup = group;
mAct = act;
mContext = ctx;
mDontSave = dontSave;
mFinish = new AfterDelete(mFinish);
}
@Override
public void run() {
PwDatabase pm = mDb.pm;
PwGroup parent = mGroup.getParent();
// Remove child entries
List<PwEntry> childEnt = new ArrayList<>(mGroup.childEntries);
for ( int i = 0; i < childEnt.size(); i++ ) {
DeleteEntry task = new DeleteEntry(mAct, mDb, childEnt.get(i), null, true);
task.run();
}
// Remove Group from parent
boolean recycle = pm.canRecycle(mGroup);
if (recycle) {
pm.recycle(mGroup);
}
else {
// TODO tests
// Remove child entries
List<PwEntry> childEnt = new ArrayList<>(mGroup.childEntries);
for ( int i = 0; i < childEnt.size(); i++ ) {
DeleteEntry task = new DeleteEntry(mContext, mDb, childEnt.get(i), null, true);
task.run();
}
// Remove child groups
List<PwGroup> childGrp = new ArrayList<>(mGroup.childGroups);
for ( int i = 0; i < childGrp.size(); i++ ) {
DeleteGroup task = new DeleteGroup(mAct, mDb, childGrp.get(i), null, true);
task.run();
}
// Remove child groups
List<PwGroup> childGrp = new ArrayList<>(mGroup.childGroups);
for ( int i = 0; i < childGrp.size(); i++ ) {
DeleteGroup task = new DeleteGroup(mContext, mDb, childGrp.get(i), null, true);
task.run();
}
pm.deleteGroup(mGroup);
// Remove from PwDatabaseV3
// TODO ENcapsulate
mDb.pm.getGroups().remove(mGroup);
}
// Remove from parent
PwGroup parent = mGroup.getParent();
if ( parent != null ) {
parent.removeChildGroup(mGroup);
}
// Save
mFinish = new AfterDelete(mFinish, parent, mGroup, recycle);
// Remove from PwDatabaseV3
mDb.pm.getGroups().remove(mGroup);
// Save
SaveDB save = new SaveDB(mAct, mDb, mFinish, mDontSave);
// Commit Database
SaveDB save = new SaveDB(mContext, mDb, mFinish, mDontSave);
save.run();
}
private class AfterDelete extends OnFinish {
public AfterDelete(OnFinish finish) {
private PwGroup mParent;
private PwGroup mGroup;
private boolean recycled;
AfterDelete(OnFinish finish, PwGroup parent, PwGroup mGroup, boolean recycle) {
super(finish);
this.mParent = parent;
this.mGroup = mGroup;
this.recycled = recycle;
}
public void run() {
if ( mSuccess ) {
// Remove from tree global
mDb.pm.groups.remove(mGroup.getId());
// Remove tree from the dirty global (if it is present), not a big deal if this fails
mDb.dirty.remove(mGroup);
// Mark parent dirty
PwGroup parent = mGroup.getParent();
if ( parent != null ) {
mDb.dirty.add(parent);
}
mDb.dirty.add(mDb.pm.rootGroup);
} else {
// Let's not bother recovering from a failure to save a deleted tree. It is too much work.
App.setShutdown();
}
PwDatabase pm = mDb.pm;
if ( !mSuccess ) {
if (recycled) {
pm.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();
}

View File

@@ -23,7 +23,6 @@ import android.content.Context;
import com.keepassdroid.database.Database;
import com.keepassdroid.database.PwEntry;
import com.keepassdroid.database.PwGroup;
public class UpdateEntry extends RunnableOnFinish {
private Database mDb;
@@ -61,32 +60,19 @@ public class UpdateEntry extends RunnableOnFinish {
private class AfterUpdate extends OnFinish {
private PwEntry mBackup;
public AfterUpdate(PwEntry backup, OnFinish finish) {
AfterUpdate(PwEntry backup, OnFinish finish) {
super(finish);
mBackup = backup;
}
@Override
public void run() {
if ( mSuccess ) {
// Mark group dirty if title or icon changes
if ( ! mBackup.isContentVisuallyTheSame(mNewE) ) {
PwGroup parent = mBackup.getParent();
if ( parent != null ) {
// Mark parent group dirty
mDb.dirty.add(parent);
}
}
} else {
if ( !mSuccess ) {
// If we fail to save, back out changes to global structure
mOldE.assign(mBackup);
}
// TODO Callback for update entry
super.run();
}
}
}