Improved editing of advanced fields,

display and toggle protected fields like password
This commit is contained in:
Philipp Crocoll 2013-07-12 14:17:20 +02:00
parent 43ea197fd5
commit 3218d2f907
8 changed files with 609 additions and 635 deletions

View File

@ -63,6 +63,7 @@ namespace keepass2android
private int _pos;
AppTask _appTask;
private List<TextView> _protectedTextViews;
protected void SetEntryView() {
@ -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);
@ -205,6 +205,9 @@ namespace keepass2android
if (value != null)
valueView.Text = value;
valueView.Typeface = Typeface.Monospace;
if (isProtected)
RegisterProtectedTextView(valueView);
if ((int)Build.VERSION.SdkInt >= 11)
valueView.SetTextIsSelectable(true);
@ -212,6 +215,11 @@ namespace keepass2android
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,14 +507,19 @@ namespace keepass2android
}
private void SetPasswordStyle() {
TextView password = (TextView) FindViewById(Resource.Id.entry_password);
foreach (TextView password in _protectedTextViews)
{
if ( _showPassword ) {
if (_showPassword)
{
password.TransformationMethod = null;
} else {
}
else
{
password.TransformationMethod = PasswordTransformationMethod.Instance;
}
}
}
protected override void OnResume()
{
ClearCache();

View File

@ -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;
@ -446,10 +447,7 @@ namespace keepass2android
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);

File diff suppressed because it is too large Load Diff

View File

@ -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>

View File

@ -26,10 +26,17 @@
android:layout_weight="3"
android:gravity="top|left"
android:layout_marginRight="0dip" />
<ImageButton
android:id="@+id/delete"
style="@style/MinusButton"
<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>

View File

@ -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

View File

@ -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" />

View File

@ -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());
};
}
}
}
}