mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Refactor EntryEditActivity, delete V3 and V4
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
@@ -228,37 +233,72 @@ public abstract class EntryEditActivity extends LockCloseHideActivity
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu 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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,23 +132,12 @@ 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,23 +359,27 @@ 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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
9
app/src/main/res/drawable/ic_content_copy_black_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_content_copy_black_24dp.xml
Normal 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>
|
||||
Reference in New Issue
Block a user