mirror of
https://github.com/moparisthebest/keepass2android
synced 2025-01-10 21:18:18 -05:00
Improved editing of advanced fields,
display and toggle protected fields like password
This commit is contained in:
parent
43ea197fd5
commit
3218d2f907
@ -63,7 +63,8 @@ namespace keepass2android
|
||||
private int _pos;
|
||||
|
||||
AppTask _appTask;
|
||||
|
||||
private List<TextView> _protectedTextViews;
|
||||
|
||||
|
||||
protected void SetEntryView() {
|
||||
SetContentView(Resource.Layout.entry_view);
|
||||
@ -180,16 +181,15 @@ namespace keepass2android
|
||||
}
|
||||
bool hasExtraFields = false;
|
||||
foreach (var view in from pair in Entry.Strings where !PwDefs.IsStandardField(pair.Key) orderby pair.Key
|
||||
select CreateEditSection(pair.Key, pair.Value.ReadString()))
|
||||
select CreateEditSection(pair.Key, pair.Value.ReadString(), pair.Value.IsProtected))
|
||||
{
|
||||
//View view = new EntrySection(this, null, key, pair.Value.ReadString());
|
||||
extraGroup.AddView(view);
|
||||
hasExtraFields = true;
|
||||
}
|
||||
FindViewById(Resource.Id.entry_extra_strings_label).Visibility = hasExtraFields ? ViewStates.Visible : ViewStates.Gone;
|
||||
}
|
||||
|
||||
View CreateEditSection(string key, string value)
|
||||
View CreateEditSection(string key, string value, bool isProtected)
|
||||
{
|
||||
LinearLayout layout = new LinearLayout(this, null) {Orientation = Orientation.Vertical};
|
||||
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent);
|
||||
@ -199,19 +199,27 @@ namespace keepass2android
|
||||
TextView keyView = (TextView)viewInflated;
|
||||
if (key != null)
|
||||
keyView.Text = key;
|
||||
|
||||
|
||||
layout.AddView(keyView);
|
||||
TextView valueView = (TextView)LayoutInflater.Inflate(Resource.Layout.entry_extrastring_value, null);
|
||||
if (value != null)
|
||||
valueView.Text = value;
|
||||
valueView.Typeface = Typeface.Monospace;
|
||||
if (isProtected)
|
||||
RegisterProtectedTextView(valueView);
|
||||
|
||||
|
||||
if ((int)Build.VERSION.SdkInt >= 11)
|
||||
valueView.SetTextIsSelectable(true);
|
||||
layout.AddView(valueView);
|
||||
return layout;
|
||||
}
|
||||
|
||||
|
||||
private void RegisterProtectedTextView(TextView protectedTextView)
|
||||
{
|
||||
_protectedTextViews.Add(protectedTextView);
|
||||
}
|
||||
|
||||
Android.Net.Uri WriteBinaryToFile(string key, bool writeToCacheDirectory)
|
||||
{
|
||||
ProtectedBinary pb = Entry.Binaries.Get(key);
|
||||
@ -365,6 +373,7 @@ namespace keepass2android
|
||||
|
||||
protected void FillData(bool trimList)
|
||||
{
|
||||
_protectedTextViews = new List<TextView>();
|
||||
ImageView iv = (ImageView)FindViewById(Resource.Id.entry_icon);
|
||||
if (iv != null)
|
||||
{
|
||||
@ -388,7 +397,7 @@ namespace keepass2android
|
||||
|
||||
PopulateText(Resource.Id.entry_url, Resource.Id.entry_url_label, Entry.Strings.ReadSafe(PwDefs.UrlField));
|
||||
PopulateText(Resource.Id.entry_password, Resource.Id.entry_password_label, Entry.Strings.ReadSafe(PwDefs.PasswordField));
|
||||
SetPasswordStyle();
|
||||
RegisterProtectedTextView(FindViewById<TextView>(Resource.Id.entry_password));
|
||||
|
||||
PopulateText(Resource.Id.entry_created, Resource.Id.entry_created_label, getDateTime(Entry.CreationTime));
|
||||
PopulateText(Resource.Id.entry_modified, Resource.Id.entry_modified_label, getDateTime(Entry.LastModificationTime));
|
||||
@ -411,7 +420,7 @@ namespace keepass2android
|
||||
|
||||
PopulateBinaries(trimList);
|
||||
|
||||
|
||||
SetPasswordStyle();
|
||||
}
|
||||
|
||||
private void PopulateText(int viewId, int headerViewId,int resId) {
|
||||
@ -498,12 +507,17 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
private void SetPasswordStyle() {
|
||||
TextView password = (TextView) FindViewById(Resource.Id.entry_password);
|
||||
|
||||
if ( _showPassword ) {
|
||||
password.TransformationMethod = null;
|
||||
} else {
|
||||
password.TransformationMethod = PasswordTransformationMethod.Instance;
|
||||
foreach (TextView password in _protectedTextViews)
|
||||
{
|
||||
|
||||
if (_showPassword)
|
||||
{
|
||||
password.TransformationMethod = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
password.TransformationMethod = PasswordTransformationMethod.Instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected override void OnResume()
|
||||
|
@ -17,6 +17,7 @@ This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll. This file
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
@ -444,12 +445,9 @@ namespace keepass2android
|
||||
|
||||
TextView valueView = (TextView)view.FindViewById(Resource.Id.value);
|
||||
String value = valueView.Text;
|
||||
|
||||
|
||||
bool protect = true;
|
||||
ProtectedString initialString = State.EntryInDatabase.Strings.Get(key);
|
||||
if (initialString != null)
|
||||
protect = initialString.IsProtected;
|
||||
|
||||
bool protect = ((CheckBox) view.FindViewById(Resource.Id.protection)).Checked;
|
||||
entry.Strings.Set(key, new ProtectedString(protect, value));
|
||||
}
|
||||
|
||||
@ -648,7 +646,7 @@ namespace keepass2android
|
||||
ViewGroup binariesGroup = (ViewGroup)FindViewById(Resource.Id.binaries);
|
||||
binariesGroup.RemoveAllViews();
|
||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.FillParent, ViewGroup.LayoutParams.WrapContent);
|
||||
foreach (KeyValuePair<string, ProtectedBinary> pair in State.Entry.Binaries)
|
||||
foreach (KeyValuePair<string, ProtectedBinary> pair in State.Entry.Binaries.OrderBy(p => p.Key) )
|
||||
{
|
||||
String key = pair.Key;
|
||||
Button binaryButton = new Button(this) {Text = key};
|
||||
@ -790,10 +788,68 @@ namespace keepass2android
|
||||
((TextView)ees.FindViewById(Resource.Id.title)).TextChanged += (sender, e) => State.EntryModified = true;
|
||||
((TextView)ees.FindViewById(Resource.Id.value)).Text = pair.Value.ReadString();
|
||||
((TextView)ees.FindViewById(Resource.Id.value)).TextChanged += (sender, e) => State.EntryModified = true;
|
||||
ees.FindViewById(Resource.Id.delete).Click += (sender, e) => DeleteAdvancedString((View)sender);
|
||||
|
||||
((CheckBox)ees.FindViewById(Resource.Id.protection)).Checked = pair.Value.IsProtected;
|
||||
|
||||
//ees.FindViewById(Resource.Id.edit_extra).Click += (sender, e) => DeleteAdvancedString((View)sender);
|
||||
ees.FindViewById(Resource.Id.edit_extra).Click += (sender, e) => EditAdvancedString((View)sender);
|
||||
return ees;
|
||||
}
|
||||
|
||||
|
||||
private void EditAdvancedString(View sender)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
View dlgView = LayoutInflater.Inflate(Resource.Layout.edit_extra_string_dialog, null);
|
||||
builder.SetView(dlgView);
|
||||
builder.SetNegativeButton(Android.Resource.String.Cancel, (o, args) => { });
|
||||
builder.SetPositiveButton(Android.Resource.String.Ok, (o, args) =>
|
||||
{
|
||||
CopyFieldFromExtraDialog(sender, o, Resource.Id.title);
|
||||
CopyFieldFromExtraDialog(sender, o, Resource.Id.value);
|
||||
CopyCheckboxFromExtraDialog(sender, o, Resource.Id.protection);
|
||||
});
|
||||
Dialog dialog = builder.Create();
|
||||
|
||||
//setup delete button:
|
||||
var deleteButton = dlgView.FindViewById<Button>(Resource.Id.delete_extra);
|
||||
deleteButton.SetCompoundDrawablesWithIntrinsicBounds(Resources.GetDrawable(Android.Resource.Drawable.IcMenuDelete), null, null, null);
|
||||
deleteButton.Click += (o, args) =>
|
||||
{
|
||||
DeleteAdvancedString(sender);
|
||||
dialog.Dismiss();
|
||||
};
|
||||
//copy values:
|
||||
View ees = (View) sender.Parent;
|
||||
dlgView.FindViewById<EditText>(Resource.Id.title).Text = ees.FindViewById<EditText>(Resource.Id.title).Text;
|
||||
dlgView.FindViewById<EditText>(Resource.Id.value).Text = ees.FindViewById<EditText>(Resource.Id.value).Text;
|
||||
dlgView.FindViewById<CheckBox>(Resource.Id.protection).Checked = ees.FindViewById<CheckBox>(Resource.Id.protection).Checked;
|
||||
|
||||
dialog.Show();
|
||||
|
||||
}
|
||||
|
||||
private void CopyFieldFromExtraDialog(View eesButton, object dialog, int fieldId)
|
||||
{
|
||||
var sourceField = ((Dialog)dialog).FindViewById<EditText>(fieldId);
|
||||
var targetField = ((TextView)((View)eesButton.Parent).FindViewById(fieldId));
|
||||
if (sourceField.Text != targetField.Text)
|
||||
{
|
||||
targetField.Text = sourceField.Text;
|
||||
State.EntryModified = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyCheckboxFromExtraDialog(View eesButton, object dialog, int fieldId)
|
||||
{
|
||||
var sourceField = ((Dialog)dialog).FindViewById<CheckBox>(fieldId);
|
||||
var targetField = ((CheckBox)((View)eesButton.Parent).FindViewById(fieldId));
|
||||
if (sourceField.Checked != targetField.Checked)
|
||||
{
|
||||
targetField.Checked = sourceField.Checked;
|
||||
State.EntryModified = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void FillData() {
|
||||
ImageButton currIconButton = (ImageButton) FindViewById(Resource.Id.icon_button);
|
||||
App.Kp2a.GetDb().DrawableFactory.AssignDrawableTo(currIconButton, Resources, App.Kp2a.GetDb().KpDatabase, State.Entry.IconId, State.Entry.CustomIconUuid);
|
||||
|
978
src/keepass2android/Resources/Resource.designer.cs
generated
978
src/keepass2android/Resources/Resource.designer.cs
generated
File diff suppressed because it is too large
Load Diff
@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:paddingTop="1dip"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_height="wrap_content">
|
||||
<EditText
|
||||
android:id="@+id/title"
|
||||
android:singleLine="true"
|
||||
android:inputType="text"
|
||||
android:hint="@string/field_name"
|
||||
style="@style/TextAppearance_EditEntry_Value"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="2"
|
||||
android:gravity="top|left"
|
||||
android:layout_marginRight="0dip" />
|
||||
<EditText
|
||||
android:id="@+id/value"
|
||||
android:hint="@string/field_value"
|
||||
android:inputType="textMultiLine"
|
||||
style="@style/TextAppearance_EditEntry_Value"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="3"
|
||||
android:gravity="top|left"
|
||||
android:layout_marginRight="0dip" />
|
||||
<ImageButton
|
||||
android:id="@+id/delete"
|
||||
style="@style/MinusButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical" />
|
||||
</LinearLayout>
|
@ -26,10 +26,17 @@
|
||||
android:layout_weight="3"
|
||||
android:gravity="top|left"
|
||||
android:layout_marginRight="0dip" />
|
||||
<ImageButton
|
||||
android:id="@+id/delete"
|
||||
style="@style/MinusButton"
|
||||
android:layout_width="wrap_content"
|
||||
<CheckBox
|
||||
android:id="@+id/protection"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="0dip"
|
||||
android:visibility="gone"
|
||||
android:text="@string/protection"/>
|
||||
<Button
|
||||
android:id="@+id/edit_extra"
|
||||
android:text="…"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical" />
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginRight="8dip" />
|
||||
</LinearLayout>
|
@ -211,9 +211,10 @@
|
||||
<string name="error_string_key">A field name is required for each string.</string>
|
||||
<string name="field_name">Field Name</string>
|
||||
<string name="field_value">Field value</string>
|
||||
<string name="protection">Memory Protection</string>
|
||||
<string name="protection">Protected field</string>
|
||||
<string name="add_binary">Add file attachment...</string>
|
||||
<string name="add_extra_string">Add additional string</string>
|
||||
<string name="delete_extra_string">Delete additional string</string>
|
||||
<string name="database_loaded_quickunlock_enabled">Database loaded, QuickUnlock enabled.</string>
|
||||
<string name="credentials_dialog_title">Enter server credentials</string>
|
||||
<string name="UseFileTransactions_title">File transactions</string>
|
||||
@ -264,11 +265,9 @@
|
||||
* External changes are detected and merged when saving\n
|
||||
* Improved loading performance\n
|
||||
* Improved search toolbar with suggestions\n
|
||||
? New app logo!\n
|
||||
? Added support for .kdbp format for faster loading/saving\n
|
||||
? Improved editing of extra strings and hidden display when protected\n
|
||||
* Added support for .kdbp format for faster loading/saving\n
|
||||
* Improved editing of extra strings and hidden display when protected\n
|
||||
Thanks to Alex Vallat for his code contributions!\n
|
||||
Thanks to Niki Hüttner (www.close-cut.de) for the new logo!\n
|
||||
</string>
|
||||
<string name="ChangeLog_0_8_3"><b>Version 0.8.3</b>\n
|
||||
* Username/TAN index displayed in entry list (see settings)\n
|
||||
|
@ -131,7 +131,6 @@
|
||||
<Compile Include="services\CopyToClipboardService.cs" />
|
||||
<Compile Include="search\SearchActivity.cs" />
|
||||
<Compile Include="QuickUnlock.cs" />
|
||||
<Compile Include="views\EntryEditSection.cs" />
|
||||
<Compile Include="LifecycleDebugActivity.cs" />
|
||||
<Compile Include="services\QuickUnlockForegroundService.cs" />
|
||||
<Compile Include="AssemblyInfo.cs" />
|
||||
@ -172,6 +171,9 @@
|
||||
<None Include="Resources\drawable-xhdpi\2_action_about.png">
|
||||
<Visible>False</Visible>
|
||||
</None>
|
||||
<AndroidResource Include="Resources\layout\edit_extra_string_dialog.xml">
|
||||
<SubType>AndroidResource</SubType>
|
||||
</AndroidResource>
|
||||
<None Include="settings\RoundsPreference %28Kopie%29.cs">
|
||||
<Visible>False</Visible>
|
||||
</None>
|
||||
@ -565,7 +567,9 @@
|
||||
<AndroidResource Include="Resources\layout\url_credentials.xml" />
|
||||
<AndroidResource Include="Resources\drawable\section_header.xml" />
|
||||
<AndroidResource Include="Resources\drawable\extra_string_header.xml" />
|
||||
<AndroidResource Include="Resources\layout\entry_edit_section.xml" />
|
||||
<AndroidResource Include="Resources\layout\entry_edit_section.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
<AndroidResource Include="Resources\values-de\strings.xml" />
|
||||
<AndroidResource Include="Resources\values-ca\strings.xml" />
|
||||
<AndroidResource Include="Resources\values-cs\strings.xml" />
|
||||
@ -597,7 +601,6 @@
|
||||
<AndroidResource Include="Resources\layout-v14\entry_view.xml" />
|
||||
<AndroidResource Include="Resources\layout-v14\entry_edit.xml" />
|
||||
<AndroidResource Include="Resources\layout-v14\SaveButton.xml" />
|
||||
<AndroidResource Include="Resources\layout-v14\entry_edit_section.xml" />
|
||||
<AndroidResource Include="Resources\layout-v14\generate_password.xml" />
|
||||
<AndroidResource Include="Resources\layout-v14\icon_picker.xml" />
|
||||
<AndroidResource Include="Resources\layout-v14\password.xml" />
|
||||
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
This file is part of Keepass2Android, Copyright 2013 Philipp Crocoll.
|
||||
|
||||
Keepass2Android 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.
|
||||
|
||||
Keepass2Android 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 Keepass2Android. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using Android.Content;
|
||||
using Android.Runtime;
|
||||
using Android.Util;
|
||||
using Android.Widget;
|
||||
using KeePassLib.Security;
|
||||
|
||||
namespace keepass2android.view
|
||||
{
|
||||
public class EntryEditSection : LinearLayout
|
||||
{
|
||||
public event EventHandler ContentChanged;
|
||||
|
||||
public EntryEditSection (IntPtr javaReference, JniHandleOwnership transfer)
|
||||
: base(javaReference, transfer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public EntryEditSection(Context context, IAttributeSet attrs) :
|
||||
base (context, attrs)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public EntryEditSection(Context context, IAttributeSet attrs, int defStyle) :
|
||||
base (context, attrs, defStyle)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public void SetData(String title, ProtectedString value)
|
||||
{
|
||||
SetText(Resource.Id.title, title);
|
||||
SetText(Resource.Id.value, value.ReadString());
|
||||
|
||||
|
||||
}
|
||||
|
||||
public ImageButton GetDeleteButton()
|
||||
{
|
||||
return (ImageButton)FindViewById(Resource.Id.delete);
|
||||
}
|
||||
|
||||
private void SetText(int resId, String str)
|
||||
{
|
||||
if (str != null)
|
||||
{
|
||||
TextView tv = (TextView)FindViewById(resId);
|
||||
tv.Text = str;
|
||||
tv.TextChanged += (sender, e) => {
|
||||
if (ContentChanged != null)
|
||||
ContentChanged(this, new EventArgs());
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user