Refactor EntryEditActivity, delete V3 and V4

This commit is contained in:
J-Jamet
2018-02-21 16:26:46 +01:00
parent 1f2ebf0825
commit f0b5b1bcb5
17 changed files with 258 additions and 365 deletions

View File

@@ -50,7 +50,7 @@ public class PwEntryTestV4 extends TestCase {
entry.icon = new PwIconStandard(5);
entry.overrideURL = "override";
entry.parent = new PwGroupV4();
entry.strings.put("key2", new ProtectedString(false, "value2"));
entry.addField("key2", new ProtectedString(false, "value2"));
entry.url = "http://localhost";
entry.uuid = UUID.randomUUID();

View File

@@ -111,11 +111,7 @@
android:configChanges="orientation|keyboardHidden"
android:windowSoftInputMode="stateHidden" />
<activity
android:name="com.keepassdroid.activities.EntryEditActivityV3"
android:configChanges="orientation|keyboardHidden"
android:windowSoftInputMode="stateHidden" />
<activity
android:name="com.keepassdroid.activities.EntryEditActivityV4"
android:name="com.keepassdroid.activities.EntryEditActivity"
android:configChanges="orientation|keyboardHidden"
android:windowSoftInputMode="stateHidden" />
<activity android:name="com.keepassdroid.search.SearchResultsActivity" android:launchMode="standard">

View File

@@ -260,9 +260,11 @@ public class EntryActivity extends LockCloseHideActivity {
entryContentsView.assignComment(mEntry.getNotes(true, pm));
// Assign custom fields
entryContentsView.clearExtraFields();
for (Map.Entry<String, String> field : mEntry.getExtraFields(pm).entrySet()) {
entryContentsView.addExtraField(field.getKey(), field.getValue());
if (mEntry.allowExtraFields()) {
entryContentsView.clearExtraFields();
for (Map.Entry<String, String> field : mEntry.getExtraFields(pm).entrySet()) {
entryContentsView.addExtraField(field.getKey(), field.getValue());
}
}
// Assign dates

View File

@@ -29,26 +29,28 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import com.keepassdroid.app.App;
import com.keepassdroid.database.Database;
import com.keepassdroid.database.PwDatabase;
import com.keepassdroid.database.PwDatabaseV4;
import com.keepassdroid.database.PwEntry;
import com.keepassdroid.database.PwEntryV3;
import com.keepassdroid.database.PwEntryV4;
import com.keepassdroid.database.PwGroup;
import com.keepassdroid.database.PwGroupId;
import com.keepassdroid.database.PwGroupV3;
import com.keepassdroid.database.PwGroupV4;
import com.keepassdroid.database.PwIconStandard;
import com.keepassdroid.database.edit.AddEntry;
import com.keepassdroid.database.edit.OnFinish;
import com.keepassdroid.database.edit.RunnableOnFinish;
import com.keepassdroid.database.edit.UpdateEntry;
import com.keepassdroid.database.security.ProtectedString;
import com.keepassdroid.fragments.GeneratePasswordDialogFragment;
import com.keepassdroid.fragments.IconPickerDialogFragment;
import com.keepassdroid.icons.Icons;
@@ -56,14 +58,17 @@ import com.keepassdroid.tasks.ProgressTask;
import com.keepassdroid.utils.MenuUtil;
import com.keepassdroid.utils.Types;
import com.keepassdroid.utils.Util;
import com.keepassdroid.view.EntryEditNewField;
import com.kunzisoft.keepass.KeePass;
import com.kunzisoft.keepass.R;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
public abstract class EntryEditActivity extends LockCloseHideActivity
public class EntryEditActivity extends LockCloseHideActivity
implements IconPickerDialogFragment.IconPickerListener,
GeneratePasswordDialogFragment.GeneratePasswordListener {
@@ -82,52 +87,31 @@ public abstract class EntryEditActivity extends LockCloseHideActivity
protected boolean mIsNew;
protected int mSelectedIconID = -1;
private ScrollView scrollView;
private ViewGroup extraFieldsContainer;
/**
* launch EntryEditActivity to update an existing entry
* @param act from activity
* @param pw Entry to update
*/
public static void Launch(Activity act, PwEntry pw) {
Intent i;
if (pw instanceof PwEntryV3) {
i = new Intent(act, EntryEditActivityV3.class);
}
else if (pw instanceof PwEntryV4) {
i = new Intent(act, EntryEditActivityV4.class);
}
else {
throw new RuntimeException("Not yet implemented.");
}
i.putExtra(KEY_ENTRY, Types.UUIDtoBytes(pw.getUUID()));
act.startActivityForResult(i, ADD_OR_UPDATE_ENTRY_REQUEST_CODE);
Intent intent = new Intent(act, EntryEditActivity.class);
intent.putExtra(KEY_ENTRY, Types.UUIDtoBytes(pw.getUUID()));
act.startActivityForResult(intent, ADD_OR_UPDATE_ENTRY_REQUEST_CODE);
}
/**
* launch EntryEditActivity to add a new entry
* @param act from activity
* @param pw Group who will contains new entry
* @param pwGroup Group who will contains new entry
*/
public static void Launch(Activity act, PwGroup pw) {
Intent i;
if (pw instanceof PwGroupV3) {
i = new Intent(act, EntryEditActivityV3.class);
EntryEditActivityV3.putParentId(i, KEY_PARENT, (PwGroupV3)pw);
}
else if (pw instanceof PwGroupV4) {
i = new Intent(act, EntryEditActivityV4.class);
EntryEditActivityV4.putParentId(i, KEY_PARENT, (PwGroupV4)pw);
}
else {
throw new RuntimeException("Not yet implemented.");
}
act.startActivityForResult(i, ADD_OR_UPDATE_ENTRY_REQUEST_CODE);
public static void Launch(Activity act, PwGroup pwGroup) {
Intent intent = new Intent(act, EntryEditActivity.class);
intent.putExtra(KEY_PARENT, pwGroup.getId());
act.startActivityForResult(intent, ADD_OR_UPDATE_ENTRY_REQUEST_CODE);
}
protected abstract PwGroupId getParentGroupId(Intent i, String key);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -148,17 +132,15 @@ public abstract class EntryEditActivity extends LockCloseHideActivity
return;
}
Intent i = getIntent();
byte[] uuidBytes = i.getByteArrayExtra(KEY_ENTRY);
Intent intent = getIntent();
byte[] uuidBytes = intent.getByteArrayExtra(KEY_ENTRY);
PwDatabase pm = db.pm;
if ( uuidBytes == null ) {
PwGroupId parentId = getParentGroupId(i, KEY_PARENT);
PwGroupId parentId = (PwGroupId) intent.getSerializableExtra(KEY_PARENT);
PwGroup parent = pm.groups.get(parentId);
mEntry = PwEntry.getInstance(parent);
mIsNew = true;
} else {
UUID uuid = Types.bytestoUUID(uuidBytes);
mEntry = pm.entries.get(uuid);
@@ -166,11 +148,12 @@ public abstract class EntryEditActivity extends LockCloseHideActivity
fillData();
}
View scrollView = findViewById(R.id.entry_scroll);
scrollView = (ScrollView) findViewById(R.id.entry_scroll);
scrollView.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
View iconButton = findViewById(R.id.icon_button);
iconButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
IconPickerDialogFragment.launch(EntryEditActivity.this);
}
@@ -194,7 +177,6 @@ public abstract class EntryEditActivity extends LockCloseHideActivity
if (!validateBeforeSaving()) {
return;
}
mCallbackNewEntry = populateNewEntry();
OnFinish onFinish = new AfterSave();
@@ -210,6 +192,29 @@ public abstract class EntryEditActivity extends LockCloseHideActivity
}
});
extraFieldsContainer = (ViewGroup) findViewById(R.id.advanced_container);
if (mEntry.allowExtraFields()) {
View add = findViewById(R.id.add_new_field);
add.setVisibility(View.VISIBLE);
add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EntryEditNewField ees = new EntryEditNewField(EntryEditActivity.this);
ees.setData("", new ProtectedString(false, ""));
extraFieldsContainer.addView(ees);
// Scroll bottom
scrollView.post(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
});
}
}
protected boolean validateBeforeSaving() {
@@ -227,39 +232,74 @@ public abstract class EntryEditActivity extends LockCloseHideActivity
Toast.makeText(this, R.string.error_pass_match, Toast.LENGTH_LONG).show();
return false;
}
return true;
// Validate extra fields
if (mEntry.allowExtraFields()) {
for (int i = 0; i < extraFieldsContainer.getChildCount(); i++) {
EntryEditNewField ees = (EntryEditNewField) extraFieldsContainer.getChildAt(i);
String key = ees.getLabel();
if (key == null || key.length() == 0) {
Toast.makeText(this, R.string.error_string_key, Toast.LENGTH_LONG).show();
return false;
}
}
}
return true;
}
protected PwEntry populateNewEntry() {
return populateNewEntry(null);
}
protected PwEntry populateNewEntry(PwEntry entry) {
PwEntry newEntry;
if (entry == null) {
newEntry = mEntry.clone(true);
}
else {
newEntry = entry;
}
Date now = Calendar.getInstance().getTime();
newEntry.setLastAccessTime(now);
newEntry.setLastModificationTime(now);
PwDatabase db = App.getDB().pm;
newEntry.setTitle(Util.getEditText(this, R.id.entry_title), db);
if(mSelectedIconID != -1)
newEntry.setIcon(new PwIconStandard(mSelectedIconID));
newEntry.setUrl(Util.getEditText(this, R.id.entry_url), db);
newEntry.setUsername(Util.getEditText(this, R.id.entry_user_name), db);
newEntry.setNotes(Util.getEditText(this, R.id.entry_comment), db);
newEntry.setPassword(Util.getEditText(this, R.id.entry_password), db);
return newEntry;
if (mEntry instanceof PwEntryV4) {
// TODO backup
PwEntryV4 newEntry = (PwEntryV4) mEntry.clone(true);
newEntry.history = (ArrayList<PwEntryV4>) newEntry.history.clone();
newEntry.createBackup((PwDatabaseV4) App.getDB().pm);
}
PwEntry newEntry = mEntry.clone(true);
Date now = Calendar.getInstance().getTime();
newEntry.setLastAccessTime(now);
newEntry.setLastModificationTime(now);
PwDatabase db = App.getDB().pm;
newEntry.setTitle(Util.getEditText(this, R.id.entry_title), db);
if(mSelectedIconID != -1)
// or TODO icon factory newEntry.setIcon(App.getDB().pm.iconFactory.getIcon(mSelectedIconID));
newEntry.setIcon(new PwIconStandard(mSelectedIconID));
else {
if (mIsNew) {
newEntry.setIcon(App.getDB().pm.iconFactory.getIcon(0));
}
else {
// Keep previous icon, if no new one was selected
newEntry.setIcon(mEntry.icon);
}
}
newEntry.setUrl(Util.getEditText(this, R.id.entry_url), db);
newEntry.setUsername(Util.getEditText(this, R.id.entry_user_name), db);
newEntry.setNotes(Util.getEditText(this, R.id.entry_comment), db);
newEntry.setPassword(Util.getEditText(this, R.id.entry_password), db);
if (newEntry.allowExtraFields()) {
// Delete all new standard strings
newEntry.removeExtraFields();
// Add extra fields from views
for (int i = 0; i < extraFieldsContainer.getChildCount(); i++) {
EntryEditNewField view = (EntryEditNewField) extraFieldsContainer.getChildAt(i);
String key = view.getLabel();
String value = view.getValue();
boolean protect = view.isProtected();
newEntry.addField(key, new ProtectedString(protect, value));
}
}
return newEntry;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
@@ -295,6 +335,15 @@ public abstract class EntryEditActivity extends LockCloseHideActivity
populateText(R.id.entry_confpassword, password);
populateText(R.id.entry_comment, mEntry.getNotes());
if (mEntry.allowExtraFields()) {
LinearLayout container = (LinearLayout) findViewById(R.id.advanced_container);
for (Map.Entry<String, ProtectedString> pair : mEntry.getExtraProtectedFields().entrySet()) {
EntryEditNewField ees = new EntryEditNewField(EntryEditActivity.this);
ees.setData(pair.getKey(), pair.getValue());
container.addView(ees);
}
}
}
private void populateText(int viewId, String text) {

View File

@@ -1,62 +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 2 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.keepassdroid.activities;
import android.content.Intent;
import com.keepassdroid.app.App;
import com.keepassdroid.database.PwEntry;
import com.keepassdroid.database.PwGroupId;
import com.keepassdroid.database.PwGroupIdV3;
import com.keepassdroid.database.PwGroupV3;
public class EntryEditActivityV3 extends EntryEditActivity {
@Override
protected PwEntry populateNewEntry(PwEntry entry) {
PwEntry newEntry = super.populateNewEntry(entry);
if (mSelectedIconID == -1) {
if (mIsNew) {
newEntry.icon = App.getDB().pm.iconFactory.getIcon(0);
}
else {
// Keep previous icon, if no new one was selected
newEntry.icon = mEntry.icon;
}
}
else {
newEntry.icon = App.getDB().pm.iconFactory.getIcon(mSelectedIconID);
}
return newEntry;
}
protected static void putParentId(Intent i, String parentKey, PwGroupV3 parent) {
i.putExtra(parentKey, parent.groupId);
}
@Override
protected PwGroupId getParentGroupId(Intent i, String key) {
int groupId = i.getIntExtra(key, -1);
return new PwGroupIdV3(groupId);
}
}

View File

@@ -1,173 +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 2 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.keepassdroid.activities;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import com.keepassdroid.app.App;
import com.keepassdroid.database.PwDatabaseV4;
import com.keepassdroid.database.PwEntry;
import com.keepassdroid.database.PwEntryV4;
import com.keepassdroid.database.PwGroupId;
import com.keepassdroid.database.PwGroupIdV4;
import com.keepassdroid.database.PwGroupV4;
import com.keepassdroid.database.security.ProtectedString;
import com.keepassdroid.utils.Types;
import com.keepassdroid.view.EntryEditNewField;
import com.kunzisoft.keepass.R;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
public class EntryEditActivityV4 extends EntryEditActivity {
private ScrollView scroll;
protected static void putParentId(Intent i, String parentKey, PwGroupV4 parent) {
PwGroupId id = parent.getId();
PwGroupIdV4 id4 = (PwGroupIdV4) id;
i.putExtra(parentKey, Types.UUIDtoBytes(id4.getId()));
}
@Override
protected PwGroupId getParentGroupId(Intent i, String key) {
byte[] buf = i.getByteArrayExtra(key);
UUID id = Types.bytestoUUID(buf);
return new PwGroupIdV4(id);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
scroll = (ScrollView) findViewById(R.id.entry_scroll);
View add = findViewById(R.id.add_new_field);
add.setVisibility(View.VISIBLE);
add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LinearLayout container = (LinearLayout) findViewById(R.id.advanced_container);
EntryEditNewField ees = new EntryEditNewField(EntryEditActivityV4.this);
ees.setData("", new ProtectedString(false, ""));
container.addView(ees);
// Scroll bottom
scroll.post(new Runnable() {
@Override
public void run() {
scroll.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
});
}
@Override
protected void fillData() {
super.fillData();
PwEntryV4 entry = (PwEntryV4) mEntry;
LinearLayout container = (LinearLayout) findViewById(R.id.advanced_container);
if (entry.strings.size() > 0) {
for (Entry<String, ProtectedString> pair : entry.strings.entrySet()) {
String key = pair.getKey();
if (!PwEntryV4.IsStandardString(key)) {
EntryEditNewField ees = new EntryEditNewField(EntryEditActivityV4.this);
ees.setData(key, pair.getValue());
container.addView(ees);
}
}
}
}
@SuppressWarnings("unchecked")
@Override
protected PwEntry populateNewEntry() {
PwEntryV4 newEntry = (PwEntryV4) mEntry.clone(true);
newEntry.history = (ArrayList<PwEntryV4>) newEntry.history.clone();
newEntry.createBackup((PwDatabaseV4)App.getDB().pm);
newEntry = (PwEntryV4) super.populateNewEntry(newEntry);
Map<String, ProtectedString> strings = newEntry.strings;
// Delete all new standard strings
Iterator<Entry<String, ProtectedString>> iter = strings.entrySet().iterator();
while (iter.hasNext()) {
Entry<String, ProtectedString> pair = iter.next();
if (!PwEntryV4.IsStandardString(pair.getKey())) {
iter.remove();
}
}
LinearLayout container = (LinearLayout) findViewById(R.id.advanced_container);
for (int i = 0; i < container.getChildCount(); i++) {
EntryEditNewField view = (EntryEditNewField) container.getChildAt(i);
String key = view.getLabel();
String value = view.getValue();
boolean protect = view.isProtected();
strings.put(key, new ProtectedString(protect, value));
}
return newEntry;
}
@Override
protected boolean validateBeforeSaving() {
if(!super.validateBeforeSaving()) {
return false;
}
ViewGroup container = (ViewGroup) findViewById(R.id.advanced_container);
for (int i = 0; i < container.getChildCount(); i++) {
EntryEditNewField ees = (EntryEditNewField) container.getChildAt(i);
String key = ees.getLabel();
if (key == null || key.length() == 0) {
Toast.makeText(this, R.string.error_string_key, Toast.LENGTH_LONG).show();
return false;
}
}
return true;
}
}

View File

@@ -35,10 +35,6 @@ public abstract class PwEntry extends PwNode implements Cloneable {
public PwIconStandard icon = PwIconStandard.FIRST;
public static PwEntry getInstance(PwGroup parent) {
return PwEntry.getInstance(parent, true, true);
}
public static PwEntry getInstance(PwGroup parent, boolean initId, boolean initDates) {
if (parent instanceof PwGroupV3) {
return new PwEntryV3((PwGroupV3)parent);
}
@@ -140,6 +136,16 @@ public abstract class PwEntry extends PwNode implements Cloneable {
}
}
// TODO encapsulate extra fields
/**
* To redefine if version of entry allow extra field,
* @return true if entry allows extra field
*/
public boolean allowExtraFields() {
return false;
}
/**
* Retrieve extra fields to show, key is the label, value is the value of field
* @param pm Database
@@ -149,6 +155,26 @@ public abstract class PwEntry extends PwNode implements Cloneable {
return new HashMap<>();
}
/**
* Retrieve extra protected fields to show, key is the label, value is the value protected of field
* @return Map of label/value
*/
public Map<String, ProtectedString> getExtraProtectedFields() {
return new HashMap<>();
}
/**
* Add an extra field to the list
* @param label Label of field, must be unique
* @param value Value of field
*/
public void addField(String label, ProtectedString value) {}
/**
* Delete all extra fields
*/
public void removeExtraFields() {}
public boolean isMetaStream() {
return false;
}

View File

@@ -22,13 +22,13 @@ package com.keepassdroid.database;
import com.keepassdroid.database.security.ProtectedBinary;
import com.keepassdroid.database.security.ProtectedString;
import com.keepassdroid.utils.SprEngine;
import com.keepassdroid.utils.SprEngineV4;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -43,14 +43,14 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
public PwGroupV4 parent;
public UUID uuid = PwDatabaseV4.UUID_ZERO;
public HashMap<String, ProtectedString> strings = new HashMap<String, ProtectedString>();
public HashMap<String, ProtectedBinary> binaries = new HashMap<String, ProtectedBinary>();
private HashMap<String, ProtectedString> fields = new HashMap<>();
public HashMap<String, ProtectedBinary> binaries = new HashMap<>();
public PwIconCustom customIcon = PwIconCustom.ZERO;
public String foregroundColor = "";
public String backgroupColor = "";
public String overrideURL = "";
public AutoType autoType = new AutoType();
public ArrayList<PwEntryV4> history = new ArrayList<PwEntryV4>();
public ArrayList<PwEntryV4> history = new ArrayList<>();
private Date parentGroupLastMod = PwDatabaseV4.DEFAULT_NOW;
private Date creation = PwDatabaseV4.DEFAULT_NOW;
@@ -132,22 +132,11 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
PwEntryV4 entry = (PwEntryV4) super.clone(deepStrings);
if (deepStrings) {
entry.strings = (HashMap<String, ProtectedString>) strings.clone();
entry.fields = (HashMap<String, ProtectedString>) fields.clone();
}
return entry;
}
@SuppressWarnings("unchecked")
public PwEntryV4 cloneDeep() {
PwEntryV4 entry = (PwEntryV4) clone(true);
entry.binaries = (HashMap<String, ProtectedBinary>) binaries.clone();
entry.history = (ArrayList<PwEntryV4>) history.clone();
entry.autoType = (AutoType) autoType.clone();
return entry;
}
@Override
public void assign(PwEntry source) {
@@ -165,7 +154,7 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
private void assign(PwEntryV4 source) {
parent = source.parent;
uuid = source.uuid;
strings = source.strings;
fields = source.fields;
binaries = source.binaries;
customIcon = source.customIcon;
foregroundColor = source.foregroundColor;
@@ -316,7 +305,7 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
}
public String getString(String key) {
ProtectedString value = strings.get(key);
ProtectedString value = fields.get(key);
if ( value == null ) return new String("");
@@ -325,7 +314,7 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
public void setString(String key, String value, boolean protect) {
ProtectedString ps = new ProtectedString(protect, value);
strings.put(key, ps);
fields.put(key, ps);
}
public Date getLocationChanged() {
@@ -370,22 +359,26 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
} else {
return customIcon;
}
}
public static boolean IsStandardString(String key) {
return key.equals(STR_TITLE) || key.equals(STR_USERNAME)
|| key.equals(STR_PASSWORD) || key.equals(STR_URL)
|| key.equals(STR_NOTES);
}
public void createBackup(PwDatabaseV4 db) {
PwEntryV4 copy = cloneDeep();
copy.history = new ArrayList<PwEntryV4>();
copy.history = new ArrayList<>();
history.add(copy);
if (db != null) maintainBackups(db);
}
@SuppressWarnings("unchecked")
public PwEntryV4 cloneDeep() {
PwEntryV4 entry = (PwEntryV4) clone(true);
entry.binaries = (HashMap<String, ProtectedBinary>) binaries.clone();
entry.history = (ArrayList<PwEntryV4>) history.clone();
entry.autoType = (AutoType) autoType.clone();
return entry;
}
private boolean maintainBackups(PwDatabaseV4 db) {
boolean deleted = false;
@@ -437,28 +430,71 @@ public class PwEntryV4 extends PwEntry implements ITimeLogger {
}
@Override
public boolean allowExtraFields() {
return true;
}
public Map<String, ProtectedString> getFields() {
return fields;
}
@Override
public Map<String, ProtectedString> getExtraProtectedFields() {
Map<String, ProtectedString> protectedFields = super.getExtraProtectedFields();
if (fields.size() > 0) {
for (Map.Entry<String, ProtectedString> pair : fields.entrySet()) {
String key = pair.getKey();
if (!PwEntryV4.IsStandardField(key)) {
protectedFields.put(key, pair.getValue());
}
}
}
return protectedFields;
}
@Override
public Map<String, String> getExtraFields(PwDatabase pm) {
Map<String, String> fields = super.getExtraFields(pm);
Map<String, String> extraFields = super.getExtraFields(pm);
SprEngine spr = SprEngine.getInstance(pm);
// Display custom strings
if (strings.size() > 0) {
for (Map.Entry<String, ProtectedString> pair : strings.entrySet()) {
// Display custom fields
if (fields.size() > 0) {
for (Map.Entry<String, ProtectedString> pair : fields.entrySet()) {
String key = pair.getKey();
// TODO Add hidden style for protection field
if (!PwEntryV4.IsStandardString(key)) {
String text = pair.getValue().toString();
fields.put(key, spr.compile(text, this, pm));
if (!PwEntryV4.IsStandardField(key)) {
extraFields.put(key, spr.compile(pair.getValue().toString(), this, pm));
}
}
}
return fields;
return extraFields;
}
public static boolean IsStandardField(String key) {
return key.equals(STR_TITLE) || key.equals(STR_USERNAME)
|| key.equals(STR_PASSWORD) || key.equals(STR_URL)
|| key.equals(STR_NOTES);
}
public void addField(String label, ProtectedString value) {
fields.put(label, value);
}
@Override
public void removeExtraFields() {
Iterator<Entry<String, ProtectedString>> iter = fields.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, ProtectedString> pair = iter.next();
if (!PwEntryV4.IsStandardField(pair.getKey())) {
iter.remove();
}
}
}
private static final long FIXED_LENGTH_SIZE = 128; // Approximate fixed length size
public long getSize() {
long size = FIXED_LENGTH_SIZE;
for (Entry<String, ProtectedString> pair : strings.entrySet()) {
for (Entry<String, ProtectedString> pair : fields.entrySet()) {
size += pair.getKey().length();
size += pair.getValue().length();
}

View File

@@ -30,6 +30,11 @@ Copyright 2006 Bill Zwicky <billzwicky@users.sourceforge.net>
package com.keepassdroid.database;
import android.content.Intent;
import android.os.Bundle;
import com.keepassdroid.utils.Types;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

View File

@@ -19,6 +19,11 @@
*/
package com.keepassdroid.database;
import android.content.Intent;
import android.os.Bundle;
import com.keepassdroid.utils.Types;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

View File

@@ -35,14 +35,14 @@ public class EntrySearchStringIteratorV4 extends EntrySearchStringIterator {
public EntrySearchStringIteratorV4(PwEntryV4 entry) {
this.sp = SearchParametersV4.DEFAULT;
setIterator = entry.strings.entrySet().iterator();
setIterator = entry.getFields().entrySet().iterator();
advance();
}
public EntrySearchStringIteratorV4(PwEntryV4 entry, SearchParametersV4 sp) {
this.sp = sp;
setIterator = entry.strings.entrySet().iterator();
setIterator = entry.getFields().entrySet().iterator();
advance();
}

View File

@@ -862,7 +862,7 @@ public class ImporterV4 extends Importer {
} else if ( ctx == KdbContext.EntryTimes && name.equalsIgnoreCase(ElemTimes) ) {
return KdbContext.Entry;
} else if ( ctx == KdbContext.EntryString && name.equalsIgnoreCase(ElemString) ) {
ctxEntry.strings.put(ctxStringName, ctxStringValue);
ctxEntry.addField(ctxStringName, ctxStringValue);
ctxStringName = null;
ctxStringValue = null;

View File

@@ -475,7 +475,7 @@ public class PwDbV4Output extends PwDbOutput {
writeList(ElemTimes, entry);
writeList(entry.strings, true);
writeList(entry.getFields(), true);
writeList(entry.binaries);
writeList(ElemAutoType, entry.autoType);

View File

@@ -132,7 +132,7 @@ public class EntryContentsView extends LinearLayout {
}
public void addExtraField(String title, String value) {
View view = new EntrySection(getContext(), null, title, value);
View view = new EntryNewField(getContext(), null, title, value);
extrasView.addView(view);
}

View File

@@ -27,17 +27,17 @@ import android.widget.TextView;
import com.kunzisoft.keepass.R;
public class EntrySection extends LinearLayout {
public class EntryNewField extends LinearLayout {
public EntrySection(Context context) {
public EntryNewField(Context context) {
this(context, null);
}
public EntrySection(Context context, AttributeSet attrs) {
public EntryNewField(Context context, AttributeSet attrs) {
this(context, attrs, null, null);
}
public EntrySection(Context context, AttributeSet attrs, String title, String value) {
public EntryNewField(Context context, AttributeSet attrs, String title, String value) {
super(context, attrs);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -45,7 +45,7 @@ public class EntrySection extends LinearLayout {
}
protected int getLayout() {
return R.layout.entry_section;
return R.layout.entry_new_field;
}
protected void inflate(LayoutInflater inflater, Context context, String title, String value) {

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z"/>
</vector>