major elements of new app design implemented
caution: not fully functional, several features missing/crashing
BIN
src/MaterialTest2/Resources/drawable-xhdpi/ic_dashboard.png
Normal file
After Width: | Height: | Size: 132 B |
BIN
src/MaterialTest2/Resources/drawable-xhdpi/ic_discuss.png
Normal file
After Width: | Height: | Size: 247 B |
BIN
src/MaterialTest2/Resources/drawable-xhdpi/ic_done.png
Normal file
After Width: | Height: | Size: 297 B |
BIN
src/MaterialTest2/Resources/drawable-xhdpi/ic_event.png
Normal file
After Width: | Height: | Size: 225 B |
BIN
src/MaterialTest2/Resources/drawable-xhdpi/ic_forum.png
Normal file
After Width: | Height: | Size: 226 B |
BIN
src/MaterialTest2/Resources/drawable-xhdpi/ic_headset.png
Normal file
After Width: | Height: | Size: 488 B |
BIN
src/MaterialTest2/Resources/drawable-xhdpi/ic_menu.png
Normal file
After Width: | Height: | Size: 135 B |
69
src/MaterialTest2/Resources/layout/Mainold.axml
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:local="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:id="@+id/drawerLayout"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<!-- activity view -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layout_main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<include
|
||||||
|
android:id="@+id/toolbar2"
|
||||||
|
layout="@layout/toolbar2" />
|
||||||
|
<ScrollView xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:id="@+id/main_content">
|
||||||
|
<Button
|
||||||
|
android:id="@+id/MyButton"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/Hello" />
|
||||||
|
<CheckBox
|
||||||
|
android:text="CheckBox"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/checkBox1" />
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imglogo"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginBottom="12dp"
|
||||||
|
android:scaleType="fitXY"
|
||||||
|
android:src="@drawable/ic_keepass2android" />
|
||||||
|
<EditText
|
||||||
|
android:inputType="textEmailAddress"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/editText1" />
|
||||||
|
<ListView
|
||||||
|
android:id="@android:id/list"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingRight="8dp"
|
||||||
|
android:paddingLeft="8dp"
|
||||||
|
android:choiceMode="singleChoice" />
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
</LinearLayout>
|
||||||
|
<!-- navigation drawer -->
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_gravity="left|start"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:background="#fff"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
<Button
|
||||||
|
android:id="@+id/MyButton2"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/Hello" />
|
||||||
|
</RelativeLayout>
|
||||||
|
</android.support.v4.widget.DrawerLayout>
|
33
src/MaterialTest2/Resources/layout/nav_header.xml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (C) 2015 The Android Open Source Project
|
||||||
|
~
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="192dp"
|
||||||
|
android:background="?attr/colorAccent"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:theme="@style/ThemeOverlay.AppCompat.Dark"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="bottom">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Username"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
5
src/MaterialTest2/Resources/values/dimens.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<dimen name="detail_backdrop_height">200dp</dimen>
|
||||||
|
<dimen name="fab_margin">16dp</dimen>
|
||||||
|
</resources>
|
@ -10,7 +10,7 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
[Activity(Label = "@string/app_name",
|
[Activity(Label = "@string/app_name",
|
||||||
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
||||||
Theme = "@style/Base")]
|
Theme = "@style/MyTheme_ActionBar")]
|
||||||
[IntentFilter(new[] { "keepass2android.AboutActivity" }, Categories = new[] { Intent.CategoryDefault })]
|
[IntentFilter(new[] { "keepass2android.AboutActivity" }, Categories = new[] { Intent.CategoryDefault })]
|
||||||
public class AboutActivity: Activity, IDialogInterfaceOnDismissListener
|
public class AboutActivity: Activity, IDialogInterfaceOnDismissListener
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,7 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
[Activity(Label = "@string/app_name",
|
[Activity(Label = "@string/app_name",
|
||||||
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
||||||
Theme = "@style/Base")]
|
Theme = "@style/MyTheme_ActionBar")]
|
||||||
public class CreateDatabaseActivity : Activity
|
public class CreateDatabaseActivity : Activity
|
||||||
{
|
{
|
||||||
private IOConnectionInfo _ioc;
|
private IOConnectionInfo _ioc;
|
||||||
|
@ -14,7 +14,7 @@ using KeePassLib.Utility;
|
|||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
[Activity(Label = AppNames.AppName, Theme = "@style/Base")]
|
[Activity(Label = AppNames.AppName, Theme = "@style/MyTheme_ActionBar")]
|
||||||
public class DonateReminder : Activity
|
public class DonateReminder : Activity
|
||||||
{
|
{
|
||||||
class Reminder
|
class Reminder
|
||||||
|
@ -44,7 +44,8 @@ using Uri = Android.Net.Uri;
|
|||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
|
||||||
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/NoTitleBar")]
|
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden,
|
||||||
|
Theme = "@style/MyTheme_ActionBar")]
|
||||||
public class EntryActivity : LockCloseActivity
|
public class EntryActivity : LockCloseActivity
|
||||||
{
|
{
|
||||||
public const String KeyEntry = "entry";
|
public const String KeyEntry = "entry";
|
||||||
@ -125,28 +126,6 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void SetupMoveButtons() {
|
|
||||||
View moveView = FindViewById(Resource.Id.entry_move);
|
|
||||||
/* Disabled for simpler UI. Wait if users demand that button.
|
|
||||||
if (App.Kp2a.GetDb().CanWrite)
|
|
||||||
{
|
|
||||||
moveView.Visibility = ViewStates.Visible;
|
|
||||||
moveView.Click += (sender, e) =>
|
|
||||||
{
|
|
||||||
NavigateToFolderAndLaunchMoveElementTask navMoveTask =
|
|
||||||
new NavigateToFolderAndLaunchMoveElementTask(Entry.ParentGroup,Entry.Uuid, false);
|
|
||||||
navMoveTask.SetActivityResult(this, KeePass.ExitNormal );
|
|
||||||
Finish();
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else*/
|
|
||||||
{
|
|
||||||
moveView.Visibility = ViewStates.Gone;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private class PluginActionReceiver : BroadcastReceiver
|
private class PluginActionReceiver : BroadcastReceiver
|
||||||
{
|
{
|
||||||
@ -329,8 +308,9 @@ namespace keepass2android
|
|||||||
_showPassword =
|
_showPassword =
|
||||||
!prefs.GetBoolean(GetString(Resource.String.maskpass_key), Resources.GetBoolean(Resource.Boolean.maskpass_default));
|
!prefs.GetBoolean(GetString(Resource.String.maskpass_key), Resources.GetBoolean(Resource.Boolean.maskpass_default));
|
||||||
|
|
||||||
base.OnCreate(savedInstanceState);
|
|
||||||
RequestWindowFeature(WindowFeatures.IndeterminateProgress);
|
RequestWindowFeature(WindowFeatures.IndeterminateProgress);
|
||||||
|
base.OnCreate(savedInstanceState);
|
||||||
|
|
||||||
|
|
||||||
new ActivityDesign(this).ApplyTheme();
|
new ActivityDesign(this).ApplyTheme();
|
||||||
|
|
||||||
@ -375,7 +355,6 @@ namespace keepass2android
|
|||||||
FillData();
|
FillData();
|
||||||
|
|
||||||
SetupEditButtons();
|
SetupEditButtons();
|
||||||
SetupMoveButtons ();
|
|
||||||
|
|
||||||
App.Kp2a.GetDb().LastOpenedEntry = new PwEntryOutput(Entry, App.Kp2a.GetDb().KpDatabase);
|
App.Kp2a.GetDb().LastOpenedEntry = new PwEntryOutput(Entry, App.Kp2a.GetDb().KpDatabase);
|
||||||
|
|
||||||
@ -455,12 +434,14 @@ namespace keepass2android
|
|||||||
private void PopulateExtraStrings()
|
private void PopulateExtraStrings()
|
||||||
{
|
{
|
||||||
ViewGroup extraGroup = (ViewGroup) FindViewById(Resource.Id.extra_strings);
|
ViewGroup extraGroup = (ViewGroup) FindViewById(Resource.Id.extra_strings);
|
||||||
|
bool hasExtras = false;
|
||||||
foreach (var pair in Entry.Strings.Where(pair => !PwDefs.IsStandardField(pair.Key)).OrderBy(pair => pair.Key))
|
foreach (var pair in Entry.Strings.Where(pair => !PwDefs.IsStandardField(pair.Key)).OrderBy(pair => pair.Key))
|
||||||
{
|
{
|
||||||
|
hasExtras = true;
|
||||||
var stringView = CreateExtraSection(pair.Key, pair.Value.ReadString(), pair.Value.IsProtected);
|
var stringView = CreateExtraSection(pair.Key, pair.Value.ReadString(), pair.Value.IsProtected);
|
||||||
extraGroup.AddView(stringView.View);
|
extraGroup.AddView(stringView.View);
|
||||||
}
|
}
|
||||||
|
FindViewById(Resource.Id.extra_strings_container).Visibility = hasExtras ? ViewStates.Visible : ViewStates.Gone;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExtraStringView CreateExtraSection(string key, string value, bool isProtected)
|
private ExtraStringView CreateExtraSection(string key, string value, bool isProtected)
|
||||||
@ -690,7 +671,7 @@ namespace keepass2android
|
|||||||
protected void FillData()
|
protected void FillData()
|
||||||
{
|
{
|
||||||
_protectedTextViews = new List<TextView>();
|
_protectedTextViews = new List<TextView>();
|
||||||
ImageView iv = (ImageView) FindViewById(Resource.Id.entry_icon);
|
ImageView iv = (ImageView) FindViewById(Resource.Id.icon);
|
||||||
if (iv != null)
|
if (iv != null)
|
||||||
{
|
{
|
||||||
iv.SetImageDrawable(Resources.GetDrawable(Resource.Drawable.ic00));
|
iv.SetImageDrawable(Resources.GetDrawable(Resource.Drawable.ic00));
|
||||||
@ -698,8 +679,9 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ActionBar.Title = Entry.Strings.ReadSafe(PwDefs.TitleField);
|
SupportActionBar.Title = Entry.Strings.ReadSafe(PwDefs.TitleField);
|
||||||
ActionBar.SetDisplayHomeAsUpEnabled(true);
|
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
|
||||||
|
SupportActionBar.SetHomeButtonEnabled(true);
|
||||||
|
|
||||||
PopulateGroupText (Resource.Id.entry_group_name, Resource.Id.entryfield_group_container, KeyGroupFullPath);
|
PopulateGroupText (Resource.Id.entry_group_name, Resource.Id.entryfield_group_container, KeyGroupFullPath);
|
||||||
|
|
||||||
@ -914,6 +896,8 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void UpdateTogglePasswordMenu()
|
private void UpdateTogglePasswordMenu()
|
||||||
{
|
{
|
||||||
IMenuItem togglePassword = _menu.FindItem(Resource.Id.menu_toggle_pass);
|
IMenuItem togglePassword = _menu.FindItem(Resource.Id.menu_toggle_pass);
|
||||||
|
@ -33,12 +33,13 @@ using KeePassLib.Security;
|
|||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using Android.Util;
|
||||||
using File = System.IO.File;
|
using File = System.IO.File;
|
||||||
using Uri = Android.Net.Uri;
|
using Uri = Android.Net.Uri;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden, Theme="@style/NoTitleBar")]
|
[Activity(Label = "@string/app_name", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden, Theme = "@style/MyTheme_ActionBar")]
|
||||||
public class EntryEditActivity : LockCloseActivity {
|
public class EntryEditActivity : LockCloseActivity {
|
||||||
public const String KeyEntry = "entry";
|
public const String KeyEntry = "entry";
|
||||||
public const String KeyParent = "parent";
|
public const String KeyParent = "parent";
|
||||||
@ -215,8 +216,8 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
// Generate password button
|
// Generate password button
|
||||||
Button generatePassword = (Button)FindViewById(Resource.Id.generate_button);
|
FindViewById(Resource.Id.generate_button).Click += (sender, e) =>
|
||||||
generatePassword.Click += (sender, e) => {
|
{
|
||||||
UpdateEntryFromUi(State.Entry);
|
UpdateEntryFromUi(State.Entry);
|
||||||
GeneratePasswordActivity.Launch(this);
|
GeneratePasswordActivity.Launch(this);
|
||||||
};
|
};
|
||||||
@ -225,20 +226,19 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
// Save button
|
// Save button
|
||||||
ActionBar.SetCustomView(Resource.Layout.SaveButton);
|
//SupportActionBar.SetCustomView(Resource.Layout.SaveButton);
|
||||||
ActionBar.SetDisplayShowCustomEnabled(true);
|
|
||||||
ActionBar.SetDisplayShowTitleEnabled(false);
|
|
||||||
ActionBar.SetDisplayUseLogoEnabled(false);
|
|
||||||
ActionBar.SetDisplayShowHomeEnabled(false);
|
|
||||||
ActionBar.SetDisplayOptions(ActionBarDisplayOptions.ShowCustom,
|
|
||||||
ActionBarDisplayOptions.ShowCustom);
|
|
||||||
var save = FindViewById(Resource.Id.entry_save);
|
|
||||||
save.Click += (sender, e) =>
|
|
||||||
{
|
|
||||||
SaveEntry();
|
|
||||||
};
|
|
||||||
|
|
||||||
FindViewById(Resource.Id.entry_save_cancel).Click += (sender, args) => Finish();
|
if (State.IsNew)
|
||||||
|
{
|
||||||
|
SupportActionBar.Title = GetString(Resource.String.add_entry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SupportActionBar.Title = GetString(Resource.String.edit_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
|
||||||
|
SupportActionBar.SetHomeButtonEnabled(true);
|
||||||
|
|
||||||
// Respect mask password setting
|
// Respect mask password setting
|
||||||
MakePasswordVisibleOrHidden();
|
MakePasswordVisibleOrHidden();
|
||||||
@ -258,7 +258,7 @@ namespace keepass2android
|
|||||||
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
LinearLayout container = (LinearLayout) FindViewById(Resource.Id.advanced_container);
|
||||||
|
|
||||||
KeyValuePair<string, ProtectedString> pair = new KeyValuePair<string, ProtectedString>("" , new ProtectedString(true, ""));
|
KeyValuePair<string, ProtectedString> pair = new KeyValuePair<string, ProtectedString>("" , new ProtectedString(true, ""));
|
||||||
LinearLayout ees = CreateExtraStringView(pair);
|
View ees = CreateExtraStringView(pair);
|
||||||
container.AddView(ees);
|
container.AddView(ees);
|
||||||
|
|
||||||
State.EntryModified = true;
|
State.EntryModified = true;
|
||||||
@ -745,9 +745,11 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
label = "<attachment>";
|
label = "<attachment>";
|
||||||
}
|
}
|
||||||
Button binaryButton = new Button(this) {Text = label};
|
//Button binaryButton = new Button(this, null, Resource.Style.EditEntryButton) {Text = label};
|
||||||
|
Button binaryButton = (Button)LayoutInflater.Inflate(Resource.Layout.EntryEditButtonDelete, null);
|
||||||
|
binaryButton.Text = label;
|
||||||
|
|
||||||
binaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuDelete),null, null, null);
|
//binaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuDelete),null, null, null);
|
||||||
binaryButton.Click += (sender, e) =>
|
binaryButton.Click += (sender, e) =>
|
||||||
{
|
{
|
||||||
State.EntryModified = true;
|
State.EntryModified = true;
|
||||||
@ -760,9 +762,13 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Button addBinaryButton = new Button(this) {Text = GetString(Resource.String.add_binary)};
|
//Button addBinaryButton = new Button(this, null, Resource.Style.EditEntryButton ) {Text = GetString(Resource.String.add_binary)};
|
||||||
addBinaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuAdd) , null, null, null);
|
//addBinaryButton.SetCompoundDrawablesWithIntrinsicBounds( Resources.GetDrawable(Android.Resource.Drawable.IcMenuAdd) , null, null, null);
|
||||||
|
Button addBinaryButton = (Button)LayoutInflater.Inflate(Resource.Layout.EntryEditButtonAdd, null);
|
||||||
|
addBinaryButton.Text = GetString(Resource.String.add_binary);
|
||||||
|
|
||||||
addBinaryButton.Enabled = true;
|
addBinaryButton.Enabled = true;
|
||||||
|
|
||||||
if (!App.Kp2a.GetDb().DatabaseFormat.CanHaveMultipleAttachments)
|
if (!App.Kp2a.GetDb().DatabaseFormat.CanHaveMultipleAttachments)
|
||||||
addBinaryButton.Enabled = !State.Entry.Binaries.Any();
|
addBinaryButton.Enabled = !State.Entry.Binaries.Any();
|
||||||
addBinaryButton.Click += (sender, e) =>
|
addBinaryButton.Click += (sender, e) =>
|
||||||
@ -795,14 +801,19 @@ namespace keepass2android
|
|||||||
|
|
||||||
public override bool OnOptionsItemSelected(IMenuItem item) {
|
public override bool OnOptionsItemSelected(IMenuItem item) {
|
||||||
switch ( item.ItemId ) {
|
switch ( item.ItemId ) {
|
||||||
case Resource.Id.menu_donate:
|
case Resource.Id.menu_save:
|
||||||
return Util.GotoDonateUrl(this);
|
SaveEntry();
|
||||||
}
|
return true;
|
||||||
|
case Resource.Id.menu_cancel:
|
||||||
|
Finish();
|
||||||
|
return true;
|
||||||
|
case Android.Resource.Id.Home:
|
||||||
|
Finish();
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
return base.OnOptionsItemSelected(item);
|
return base.OnOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void UpdateExpires()
|
void UpdateExpires()
|
||||||
@ -819,15 +830,18 @@ namespace keepass2android
|
|||||||
FindViewById(Resource.Id.entry_expires).Enabled = State.Entry.Expires;
|
FindViewById(Resource.Id.entry_expires).Enabled = State.Entry.Expires;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Java.Lang.Object OnRetainNonConfigurationInstance()
|
/*
|
||||||
|
* TODO required??
|
||||||
|
*
|
||||||
|
* public override Java.Lang.Object OnRetainNonConfigurationInstance()
|
||||||
{
|
{
|
||||||
UpdateEntryFromUi(State.Entry);
|
UpdateEntryFromUi(State.Entry);
|
||||||
return this;
|
return this;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
LinearLayout CreateExtraStringView(KeyValuePair<string, ProtectedString> pair)
|
RelativeLayout CreateExtraStringView(KeyValuePair<string, ProtectedString> pair)
|
||||||
{
|
{
|
||||||
LinearLayout ees = (LinearLayout)LayoutInflater.Inflate(Resource.Layout.entry_edit_section, null);
|
RelativeLayout ees = (RelativeLayout)LayoutInflater.Inflate(Resource.Layout.entry_edit_section, null);
|
||||||
((TextView)ees.FindViewById(Resource.Id.title)).Text = pair.Key;
|
((TextView)ees.FindViewById(Resource.Id.title)).Text = pair.Key;
|
||||||
((TextView)ees.FindViewById(Resource.Id.title)).TextChanged += (sender, e) => State.EntryModified = true;
|
((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)).Text = pair.Value.ReadString();
|
||||||
@ -928,8 +942,7 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FindViewById(Resource.Id.entry_override_url_label).Visibility = ViewStates.Gone;
|
FindViewById(Resource.Id.entry_override_url_container).Visibility = ViewStates.Gone;
|
||||||
FindViewById(Resource.Id.entry_override_url).Visibility = ViewStates.Gone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (App.Kp2a.GetDb().DatabaseFormat.SupportsTags)
|
if (App.Kp2a.GetDb().DatabaseFormat.SupportsTags)
|
||||||
@ -1016,6 +1029,11 @@ namespace keepass2android
|
|||||||
|
|
||||||
private void PopulateText(int viewId, String text) {
|
private void PopulateText(int viewId, String text) {
|
||||||
TextView tv = (TextView) FindViewById(viewId);
|
TextView tv = (TextView) FindViewById(viewId);
|
||||||
|
if (tv == null)
|
||||||
|
{
|
||||||
|
Kp2aLog.Log("Invalid viewId " + viewId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
tv.Text = text;
|
tv.Text = text;
|
||||||
tv.TextChanged += (sender, e) => {State.EntryModified = true;};
|
tv.TextChanged += (sender, e) => {State.EntryModified = true;};
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ namespace keepass2android
|
|||||||
|
|
||||||
[Activity(Label = "@string/app_name",
|
[Activity(Label = "@string/app_name",
|
||||||
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
||||||
Theme = "@style/Base")]
|
Theme = "@style/MyTheme_ActionBar")]
|
||||||
[IntentFilter(new[] {"keepass2android.ExportDatabaseActivity"}, Categories = new[] {Intent.CategoryDefault})]
|
[IntentFilter(new[] {"keepass2android.ExportDatabaseActivity"}, Categories = new[] {Intent.CategoryDefault})]
|
||||||
public class ExportDatabaseActivity : LockCloseActivity
|
public class ExportDatabaseActivity : LockCloseActivity
|
||||||
{
|
{
|
||||||
|
@ -1,18 +1,27 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.Content;
|
using Android.Content;
|
||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
|
using Android.Content.Res;
|
||||||
|
using Android.Graphics;
|
||||||
|
using Android.Graphics.Drawables;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
|
using Android.Support.V4.Content;
|
||||||
|
using Android.Support.V7.App;
|
||||||
|
using Android.Text;
|
||||||
|
using Android.Util;
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using Android.Widget;
|
using Android.Widget;
|
||||||
using keepass2android.Io;
|
using keepass2android.Io;
|
||||||
using keepass2android.view;
|
using keepass2android.view;
|
||||||
|
using AlertDialog = Android.App.AlertDialog;
|
||||||
using Object = Java.Lang.Object;
|
using Object = Java.Lang.Object;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden , Theme="@style/NoTitleBar")]
|
[Activity(Label = "@string/app_name", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden, Theme = "@style/MyTheme")]
|
||||||
public class FileStorageSelectionActivity : ListActivity
|
public class FileStorageSelectionActivity : AppCompatActivity
|
||||||
{
|
{
|
||||||
private readonly ActivityDesign _design;
|
private readonly ActivityDesign _design;
|
||||||
|
|
||||||
@ -78,8 +87,53 @@ namespace keepass2android
|
|||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static float convertDpToPixel(float dp, Context context)
|
||||||
|
{
|
||||||
|
Resources resources = context.Resources;
|
||||||
|
DisplayMetrics metrics = resources.DisplayMetrics;
|
||||||
|
float px = dp * metrics.Density;
|
||||||
|
return px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public override View GetView(int position, View convertView, ViewGroup parent)
|
public override View GetView(int position, View convertView, ViewGroup parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Button btn;
|
||||||
|
|
||||||
|
if (convertView == null)
|
||||||
|
{ // if it's not recycled, initialize some attributes
|
||||||
|
|
||||||
|
btn = new Button(_context);
|
||||||
|
btn.LayoutParameters = new GridView.LayoutParams((int)convertDpToPixel(80, _context), (int)convertDpToPixel(100, _context));
|
||||||
|
btn.SetBackgroundResource(Resource.Drawable.storagetype_button_bg);
|
||||||
|
btn.SetPadding(8, 8, 8, 8);
|
||||||
|
btn.SetTextSize(ComplexUnitType.Sp, 12);
|
||||||
|
btn.SetTextColor(new Color(115, 115, 115));
|
||||||
|
btn.SetSingleLine(false);
|
||||||
|
btn.Click += (sender, args) => _context.OnItemSelected( (string) ((Button)sender).Tag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
btn = (Button)convertView;
|
||||||
|
}
|
||||||
|
|
||||||
|
var protocolId = _protocolIds[position];
|
||||||
|
btn.Tag = protocolId;
|
||||||
|
Drawable drawable = App.Kp2a.GetResourceDrawable("ic_storage_" + protocolId);
|
||||||
|
|
||||||
|
String title = App.Kp2a.GetResourceString("filestoragename_" + protocolId);
|
||||||
|
var str = new SpannableString(title);
|
||||||
|
|
||||||
|
btn.TextFormatted = str;
|
||||||
|
//var drawable = ContextCompat.GetDrawable(context, Resource.Drawable.Icon);
|
||||||
|
btn.SetCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null);
|
||||||
|
|
||||||
|
//TODO kp2a
|
||||||
|
return btn;
|
||||||
|
/*
|
||||||
if (_protocolIds[position] == "kp2a")
|
if (_protocolIds[position] == "kp2a")
|
||||||
{
|
{
|
||||||
return new FileStorageViewKp2a(_context);
|
return new FileStorageViewKp2a(_context);
|
||||||
@ -89,7 +143,7 @@ namespace keepass2android
|
|||||||
var view = new FileStorageView(_context, _protocolIds[position], position);
|
var view = new FileStorageView(_context, _protocolIds[position], position);
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,13 +199,29 @@ namespace keepass2android
|
|||||||
|
|
||||||
SetContentView(Resource.Layout.filestorage_selection);
|
SetContentView(Resource.Layout.filestorage_selection);
|
||||||
|
|
||||||
_fileStorageAdapter = new FileStorageAdapter(this);
|
var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
|
||||||
ListAdapter = _fileStorageAdapter;
|
|
||||||
|
|
||||||
ListView listView = FindViewById<ListView>(Android.Resource.Id.List);
|
SetSupportActionBar(toolbar);
|
||||||
listView.ItemClick +=
|
|
||||||
|
SupportActionBar.Title = RemoveTrailingColon(GetString(Resource.String.select_storage_type));
|
||||||
|
|
||||||
|
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
|
||||||
|
SupportActionBar.SetDisplayShowHomeEnabled(true);
|
||||||
|
toolbar.NavigationClick += (sender, args) => OnBackPressed();
|
||||||
|
|
||||||
|
_fileStorageAdapter = new FileStorageAdapter(this);
|
||||||
|
var gridView = FindViewById<GridView>(Resource.Id.gridview);
|
||||||
|
gridView.ItemClick +=
|
||||||
(sender, args) => OnItemSelected((string)_fileStorageAdapter.GetItem(args.Position));
|
(sender, args) => OnItemSelected((string)_fileStorageAdapter.GetItem(args.Position));
|
||||||
//listView.ItemsCanFocus = true;
|
gridView.Adapter = _fileStorageAdapter;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private string RemoveTrailingColon(string str)
|
||||||
|
{
|
||||||
|
if (str.EndsWith(":"))
|
||||||
|
return str.Substring(0, str.Length - 1);
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnResume()
|
protected override void OnResume()
|
||||||
|
@ -26,7 +26,7 @@ using Android.Widget;
|
|||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
[Activity (Label = "@string/app_name", Theme="@style/NoTitleBar")]
|
[Activity(Label = "@string/app_name", Theme = "@style/MyTheme_ActionBar")]
|
||||||
public class GeneratePasswordActivity : LockCloseActivity {
|
public class GeneratePasswordActivity : LockCloseActivity {
|
||||||
private readonly int[] _buttonIds = new[] {Resource.Id.btn_length6, Resource.Id.btn_length8, Resource.Id.btn_length12, Resource.Id.btn_length16};
|
private readonly int[] _buttonIds = new[] {Resource.Id.btn_length6, Resource.Id.btn_length8, Resource.Id.btn_length12, Resource.Id.btn_length16};
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ using Android.Content.PM;
|
|||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
[Activity (Label = "@string/app_name", ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.KeyboardHidden , Theme="@style/NoTitleBar")]
|
[Activity(Label = "@string/app_name", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden, Theme = "@style/MyTheme_ActionBar")]
|
||||||
[MetaData("android.app.default_searchable",Value="keepass2android.search.SearchResults")]
|
[MetaData("android.app.default_searchable",Value="keepass2android.search.SearchResults")]
|
||||||
public class GroupActivity : GroupBaseActivity {
|
public class GroupActivity : GroupBaseActivity {
|
||||||
|
|
||||||
@ -75,15 +75,10 @@ namespace keepass2android
|
|||||||
|
|
||||||
public override void SetupNormalButtons()
|
public override void SetupNormalButtons()
|
||||||
{
|
{
|
||||||
GroupView.SetNormalButtonVisibility(AddGroupEnabled, AddEntryEnabled);
|
SetNormalButtonVisibility(AddGroupEnabled, AddEntryEnabled);
|
||||||
GroupView.Invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool AddGroupEnabled
|
protected override bool AddEntryEnabled
|
||||||
{
|
|
||||||
get { return App.Kp2a.GetDb().CanWrite; }
|
|
||||||
}
|
|
||||||
private bool AddEntryEnabled
|
|
||||||
{
|
{
|
||||||
get { return App.Kp2a.GetDb().CanWrite && ((this.Group.ParentGroup != null) || App.Kp2a.GetDb().DatabaseFormat.CanHaveEntriesInRootGroup); }
|
get { return App.Kp2a.GetDb().CanWrite && ((this.Group.ParentGroup != null) || App.Kp2a.GetDb().DatabaseFormat.CanHaveEntriesInRootGroup); }
|
||||||
}
|
}
|
||||||
@ -121,26 +116,25 @@ namespace keepass2android
|
|||||||
|
|
||||||
if (AddGroupEnabled) {
|
if (AddGroupEnabled) {
|
||||||
// Add Group button
|
// Add Group button
|
||||||
View addGroup = FindViewById (Resource.Id.add_group);
|
View addGroup = FindViewById (Resource.Id.fabAddNewGroup);
|
||||||
addGroup.Click += (sender, e) => {
|
addGroup.Click += (sender, e) => {
|
||||||
GroupEditActivity.Launch (this, Group);
|
GroupEditActivity.Launch (this, Group);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AddEntryEnabled) {
|
|
||||||
// Add Entry button
|
|
||||||
View addEntry = FindViewById (Resource.Id.add_entry);
|
|
||||||
addEntry.Click += (sender, e) => {
|
|
||||||
EntryEditActivity.Launch (this, Group, AppTask);
|
|
||||||
|
|
||||||
};
|
if (AddEntryEnabled)
|
||||||
|
{
|
||||||
|
View addEntry = FindViewById (Resource.Id.fabAddNewEntry);
|
||||||
|
addEntry.Click += (sender, e) => { EntryEditActivity.Launch (this, Group, AppTask); };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetGroupTitle();
|
SetGroupTitle();
|
||||||
SetGroupIcon();
|
SetGroupIcon();
|
||||||
|
|
||||||
ListAdapter = new PwGroupListAdapter(this, Group);
|
FragmentManager.FindFragmentById<GroupListFragment>(Resource.Id.list_fragment).ListAdapter = new PwGroupListAdapter(this, Group);
|
||||||
RegisterForContextMenu(ListView);
|
/*TODO RegisterForContextMenu(ListView);*/
|
||||||
Log.Warn(Tag, "Finished creating group");
|
Log.Warn(Tag, "Finished creating group");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,14 @@ using keepass2android.Io;
|
|||||||
using keepass2android.database.edit;
|
using keepass2android.database.edit;
|
||||||
using keepass2android.view;
|
using keepass2android.view;
|
||||||
using Android.Graphics.Drawables;
|
using Android.Graphics.Drawables;
|
||||||
|
using Android.Support.V4.View;
|
||||||
|
using CursorAdapter = Android.Support.V4.Widget.CursorAdapter;
|
||||||
|
using Object = Java.Lang.Object;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
|
||||||
public abstract class GroupBaseActivity : LockCloseListActivity {
|
public abstract class GroupBaseActivity : LockCloseActivity {
|
||||||
public const String KeyEntry = "entry";
|
public const String KeyEntry = "entry";
|
||||||
public const String KeyMode = "mode";
|
public const String KeyMode = "mode";
|
||||||
|
|
||||||
@ -65,9 +68,61 @@ namespace keepass2android
|
|||||||
|
|
||||||
public virtual void SetupNormalButtons()
|
public virtual void SetupNormalButtons()
|
||||||
{
|
{
|
||||||
GroupView.SetNormalButtonVisibility(App.Kp2a.GetDb().CanWrite, App.Kp2a.GetDb().CanWrite);
|
SetNormalButtonVisibility(AddGroupEnabled, AddEntryEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected virtual bool AddGroupEnabled
|
||||||
|
{
|
||||||
|
get { return App.Kp2a.GetDb().CanWrite; }
|
||||||
|
}
|
||||||
|
protected virtual bool AddEntryEnabled
|
||||||
|
{
|
||||||
|
get { return App.Kp2a.GetDb().CanWrite; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetNormalButtonVisibility(bool showAddGroup, bool showAddEntry)
|
||||||
|
{
|
||||||
|
FindViewById(Resource.Id.bottom_bar).Visibility = ViewStates.Gone;
|
||||||
|
FindViewById(Resource.Id.divider2).Visibility = ViewStates.Gone;
|
||||||
|
|
||||||
|
FindViewById(Resource.Id.fabCancelAddNew).Visibility = ViewStates.Gone;
|
||||||
|
FindViewById(Resource.Id.fabAddNewGroup).Visibility = ViewStates.Gone;
|
||||||
|
FindViewById(Resource.Id.fabAddNewEntry).Visibility = ViewStates.Gone;
|
||||||
|
|
||||||
|
FindViewById(Resource.Id.fabAddNew).Visibility = (showAddGroup || showAddEntry) ? ViewStates.Visible : ViewStates.Gone;
|
||||||
|
|
||||||
|
|
||||||
|
/*TODO Remove
|
||||||
|
View insertElement = FindViewById(Resource.Id.insert_element);
|
||||||
|
insertElement.Visibility = ViewStates.Gone;
|
||||||
|
|
||||||
|
View insertElementCancel = FindViewById(Resource.Id.cancel_insert_element);
|
||||||
|
insertElementCancel.Visibility = ViewStates.Gone;
|
||||||
|
|
||||||
|
View addGroup = FindViewById(Resource.Id.add_group);
|
||||||
|
addGroup.Visibility = showAddGroup ? ViewStates.Visible : ViewStates.Gone;
|
||||||
|
|
||||||
|
|
||||||
|
View addEntry = FindViewById(Resource.Id.add_entry);
|
||||||
|
addEntry.Visibility = showAddEntry ? ViewStates.Visible : ViewStates.Gone;
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
if (!showAddEntry && !showAddGroup)
|
||||||
|
{
|
||||||
|
View divider2 = FindViewById(Resource.Id.divider2);
|
||||||
|
divider2.Visibility = ViewStates.Gone;
|
||||||
|
|
||||||
|
FindViewById(Resource.Id.bottom_bar).Visibility = ViewStates.Gone;
|
||||||
|
|
||||||
|
View list = FindViewById(Android.Resource.Id.List);
|
||||||
|
var lp = (RelativeLayout.LayoutParams)list.LayoutParameters;
|
||||||
|
|
||||||
|
lp.AddRule(LayoutRules.AlignParentBottom, (int)LayoutRules.True);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
|
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
|
||||||
{
|
{
|
||||||
base.OnActivityResult(requestCode, resultCode, data);
|
base.OnActivityResult(requestCode, resultCode, data);
|
||||||
@ -122,7 +177,7 @@ namespace keepass2android
|
|||||||
protected PwGroup Group;
|
protected PwGroup Group;
|
||||||
|
|
||||||
internal AppTask AppTask;
|
internal AppTask AppTask;
|
||||||
protected GroupView GroupView;
|
//TODO protected GroupView GroupView;
|
||||||
|
|
||||||
private String strCachedGroupUuid = null;
|
private String strCachedGroupUuid = null;
|
||||||
public String UuidGroup {
|
public String UuidGroup {
|
||||||
@ -155,13 +210,14 @@ namespace keepass2android
|
|||||||
Database db = App.Kp2a.GetDb();
|
Database db = App.Kp2a.GetDb();
|
||||||
if ( db.Dirty.Contains(Group) ) {
|
if ( db.Dirty.Contains(Group) ) {
|
||||||
db.Dirty.Remove(Group);
|
db.Dirty.Remove(Group);
|
||||||
BaseAdapter adapter = (BaseAdapter) ListAdapter;
|
/*TODO BaseAdapter adapter = (BaseAdapter) ListAdapter;
|
||||||
adapter.NotifyDataSetChanged();
|
adapter.NotifyDataSetChanged();*/
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnListItemClick(ListView l, View v, int position, long id) {
|
/*TODO
|
||||||
|
* protected override void OnListItemClick(ListView l, View v, int position, long id) {
|
||||||
base.OnListItemClick(l, v, position, id);
|
base.OnListItemClick(l, v, position, id);
|
||||||
|
|
||||||
IListAdapter adapt = ListAdapter;
|
IListAdapter adapt = ListAdapter;
|
||||||
@ -169,7 +225,7 @@ namespace keepass2android
|
|||||||
cv.OnClick();
|
cv.OnClick();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
protected override void OnCreate(Bundle savedInstanceState) {
|
protected override void OnCreate(Bundle savedInstanceState) {
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
|
|
||||||
@ -183,15 +239,33 @@ namespace keepass2android
|
|||||||
|
|
||||||
_prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
_prefs = PreferenceManager.GetDefaultSharedPreferences(this);
|
||||||
|
|
||||||
GroupView = new GroupView(this);
|
|
||||||
SetContentView(GroupView);
|
SetContentView(Resource.Layout.group);
|
||||||
|
|
||||||
|
FindViewById(Resource.Id.fabAddNew).Click += (sender, args) =>
|
||||||
|
{
|
||||||
|
FindViewById(Resource.Id.fabCancelAddNew).Visibility = ViewStates.Visible;
|
||||||
|
FindViewById(Resource.Id.fabAddNewGroup).Visibility = AddGroupEnabled ? ViewStates.Visible : ViewStates.Gone;
|
||||||
|
FindViewById(Resource.Id.fabAddNewEntry).Visibility = AddEntryEnabled ? ViewStates.Visible : ViewStates.Gone;
|
||||||
|
FindViewById(Resource.Id.fabAddNew).Visibility = ViewStates.Gone;
|
||||||
|
};
|
||||||
|
|
||||||
|
FindViewById(Resource.Id.fabCancelAddNew).Click += (sender, args) =>
|
||||||
|
{
|
||||||
|
FindViewById(Resource.Id.fabCancelAddNew).Visibility = ViewStates.Gone;
|
||||||
|
FindViewById(Resource.Id.fabAddNewGroup).Visibility = ViewStates.Gone;
|
||||||
|
FindViewById(Resource.Id.fabAddNewEntry).Visibility = ViewStates.Gone;
|
||||||
|
FindViewById(Resource.Id.fabAddNew).Visibility = ViewStates.Visible;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
FindViewById(Resource.Id.cancel_insert_element).Click += (sender, args) => StopMovingElement();
|
FindViewById(Resource.Id.cancel_insert_element).Click += (sender, args) => StopMovingElement();
|
||||||
FindViewById(Resource.Id.insert_element).Click += (sender, args) => InsertElement();
|
FindViewById(Resource.Id.insert_element).Click += (sender, args) => InsertElement();
|
||||||
|
|
||||||
SetResult(KeePass.ExitNormal);
|
SetResult(KeePass.ExitNormal);
|
||||||
|
|
||||||
StyleScrollBars();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,12 +281,6 @@ namespace keepass2android
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void StyleScrollBars() {
|
|
||||||
ListView lv = ListView;
|
|
||||||
lv.ScrollBarStyle =ScrollbarStyles.InsideInset;
|
|
||||||
lv.TextFilterEnabled = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected void SetGroupTitle()
|
protected void SetGroupTitle()
|
||||||
@ -228,31 +296,33 @@ namespace keepass2android
|
|||||||
titleText = GetText(Resource.String.root);
|
titleText = GetText(Resource.String.root);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionBar.Title = titleText;
|
SupportActionBar.Title = titleText;
|
||||||
if (clickable)
|
if (clickable)
|
||||||
ActionBar.SetDisplayHomeAsUpEnabled(true);
|
{
|
||||||
|
SupportActionBar.SetHomeButtonEnabled(true);
|
||||||
|
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
|
||||||
|
SupportActionBar.SetDisplayShowHomeEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void SetGroupIcon() {
|
protected void SetGroupIcon() {
|
||||||
if (Group != null) {
|
if (Group != null) {
|
||||||
Drawable drawable = App.Kp2a.GetDb().DrawableFactory.GetIconDrawable(Resources, App.Kp2a.GetDb().KpDatabase, Group.IconId, Group.CustomIconUuid);
|
Drawable drawable = App.Kp2a.GetDb().DrawableFactory.GetIconDrawable(Resources, App.Kp2a.GetDb().KpDatabase, Group.IconId, Group.CustomIconUuid);
|
||||||
ImageView iv = (ImageView) FindViewById(Resource.Id.icon);
|
SupportActionBar.SetDisplayShowHomeEnabled(true);
|
||||||
if (iv != null)
|
//SupportActionBar.SetIcon(drawable);
|
||||||
iv.SetImageDrawable(drawable);
|
|
||||||
if (Util.HasActionBar(this))
|
|
||||||
ActionBar.SetIcon(drawable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SuggestionListener: Java.Lang.Object, SearchView.IOnSuggestionListener
|
class SuggestionListener: Java.Lang.Object, SearchView.IOnSuggestionListener, Android.Support.V7.Widget.SearchView.IOnSuggestionListener
|
||||||
{
|
{
|
||||||
private readonly CursorAdapter _suggestionsAdapter;
|
private readonly CursorAdapter _suggestionsAdapter;
|
||||||
private readonly GroupBaseActivity _activity;
|
private readonly GroupBaseActivity _activity;
|
||||||
private readonly IMenuItem _searchItem;
|
private readonly IMenuItem _searchItem;
|
||||||
|
|
||||||
|
|
||||||
public SuggestionListener(CursorAdapter suggestionsAdapter, GroupBaseActivity activity, IMenuItem searchItem)
|
public SuggestionListener(Android.Support.V4.Widget.CursorAdapter suggestionsAdapter, GroupBaseActivity activity, IMenuItem searchItem)
|
||||||
{
|
{
|
||||||
_suggestionsAdapter = suggestionsAdapter;
|
_suggestionsAdapter = suggestionsAdapter;
|
||||||
_activity = activity;
|
_activity = activity;
|
||||||
@ -275,7 +345,7 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OnQueryTextListener: Java.Lang.Object, SearchView.IOnQueryTextListener
|
class OnQueryTextListener: Java.Lang.Object, Android.Support.V7.Widget.SearchView.IOnQueryTextListener
|
||||||
{
|
{
|
||||||
private readonly GroupBaseActivity _activity;
|
private readonly GroupBaseActivity _activity;
|
||||||
|
|
||||||
@ -311,16 +381,15 @@ namespace keepass2android
|
|||||||
|
|
||||||
MenuInflater inflater = MenuInflater;
|
MenuInflater inflater = MenuInflater;
|
||||||
inflater.Inflate(Resource.Menu.group, menu);
|
inflater.Inflate(Resource.Menu.group, menu);
|
||||||
if (Util.HasActionBar(this))
|
|
||||||
{
|
|
||||||
var searchManager = (SearchManager) GetSystemService(SearchService);
|
var searchManager = (SearchManager) GetSystemService(SearchService);
|
||||||
IMenuItem searchItem = menu.FindItem(Resource.Id.menu_search);
|
IMenuItem searchItem = menu.FindItem(Resource.Id.menu_search);
|
||||||
var searchView = (SearchView) searchItem.ActionView;
|
var view = MenuItemCompat.GetActionView(searchItem);
|
||||||
|
var searchView = view.JavaCast<Android.Support.V7.Widget.SearchView>();
|
||||||
|
|
||||||
searchView.SetSearchableInfo(searchManager.GetSearchableInfo(ComponentName));
|
searchView.SetSearchableInfo(searchManager.GetSearchableInfo(ComponentName));
|
||||||
searchView.SetOnSuggestionListener(new SuggestionListener(searchView.SuggestionsAdapter, this, searchItem));
|
searchView.SetOnSuggestionListener(new SuggestionListener(searchView.SuggestionsAdapter, this, searchItem));
|
||||||
searchView.SetOnQueryTextListener(new OnQueryTextListener(this));
|
searchView.SetOnQueryTextListener(new OnQueryTextListener(this));
|
||||||
}
|
|
||||||
var item = menu.FindItem(Resource.Id.menu_sync);
|
var item = menu.FindItem(Resource.Id.menu_sync);
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
@ -425,10 +494,11 @@ namespace keepass2android
|
|||||||
if (!String.IsNullOrEmpty(message))
|
if (!String.IsNullOrEmpty(message))
|
||||||
Toast.MakeText(this, message, ToastLength.Long).Show();
|
Toast.MakeText(this, message, ToastLength.Long).Show();
|
||||||
|
|
||||||
|
/*TODO
|
||||||
// Tell the adapter to refresh it's list
|
// Tell the adapter to refresh it's list
|
||||||
BaseAdapter adapter = (BaseAdapter)ListAdapter;
|
BaseAdapter adapter = (BaseAdapter)ListAdapter;
|
||||||
adapter.NotifyDataSetChanged();
|
adapter.NotifyDataSetChanged();
|
||||||
|
*/
|
||||||
if (App.Kp2a.GetDb().OtpAuxFileIoc != null)
|
if (App.Kp2a.GetDb().OtpAuxFileIoc != null)
|
||||||
{
|
{
|
||||||
var task2 = new SyncOtpAuxFile(App.Kp2a.GetDb().OtpAuxFileIoc);
|
var task2 = new SyncOtpAuxFile(App.Kp2a.GetDb().OtpAuxFileIoc);
|
||||||
@ -486,9 +556,10 @@ namespace keepass2android
|
|||||||
db.Dirty.Remove(Group);
|
db.Dirty.Remove(Group);
|
||||||
|
|
||||||
// Tell the adapter to refresh it's list
|
// Tell the adapter to refresh it's list
|
||||||
|
/*TODO
|
||||||
BaseAdapter adapter = (BaseAdapter)ListAdapter;
|
BaseAdapter adapter = (BaseAdapter)ListAdapter;
|
||||||
adapter.NotifyDataSetChanged();
|
adapter.NotifyDataSetChanged();
|
||||||
|
*/
|
||||||
|
|
||||||
})
|
})
|
||||||
.SetPositiveButton(Android.Resource.String.Ok, (sender, args) => ((Dialog)sender).Dismiss())
|
.SetPositiveButton(Android.Resource.String.Ok, (sender, args) => ((Dialog)sender).Dismiss())
|
||||||
@ -555,15 +626,22 @@ namespace keepass2android
|
|||||||
|
|
||||||
public void StartMovingElement()
|
public void StartMovingElement()
|
||||||
{
|
{
|
||||||
|
|
||||||
ShowInsertElementButtons();
|
ShowInsertElementButtons();
|
||||||
GroupView.ListView.InvalidateViews();
|
/*TODOGroupView.ListView.InvalidateViews();
|
||||||
BaseAdapter adapter = (BaseAdapter)ListAdapter;
|
BaseAdapter adapter = (BaseAdapter)ListAdapter;
|
||||||
adapter.NotifyDataSetChanged();
|
adapter.NotifyDataSetChanged();*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ShowInsertElementButtons()
|
public void ShowInsertElementButtons()
|
||||||
{
|
{
|
||||||
GroupView.ShowInsertButtons();
|
FindViewById(Resource.Id.fabCancelAddNew).Visibility = ViewStates.Gone;
|
||||||
|
FindViewById(Resource.Id.fabAddNewGroup).Visibility = ViewStates.Gone;
|
||||||
|
FindViewById(Resource.Id.fabAddNewEntry).Visibility = ViewStates.Gone;
|
||||||
|
FindViewById(Resource.Id.fabAddNew).Visibility = ViewStates.Gone;
|
||||||
|
|
||||||
|
FindViewById(Resource.Id.bottom_bar).Visibility = ViewStates.Visible;
|
||||||
|
FindViewById(Resource.Id.divider2).Visibility = ViewStates.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopMovingElement()
|
public void StopMovingElement()
|
||||||
@ -583,9 +661,9 @@ namespace keepass2android
|
|||||||
|
|
||||||
AppTask = new NullTask();
|
AppTask = new NullTask();
|
||||||
AppTask.SetupGroupBaseActivityButtons(this);
|
AppTask.SetupGroupBaseActivityButtons(this);
|
||||||
GroupView.ListView.InvalidateViews();
|
/*TODO GroupView.ListView.InvalidateViews();
|
||||||
BaseAdapter adapter = (BaseAdapter)ListAdapter;
|
BaseAdapter adapter = (BaseAdapter)ListAdapter;
|
||||||
adapter.NotifyDataSetChanged();
|
adapter.NotifyDataSetChanged();*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -594,5 +672,126 @@ namespace keepass2android
|
|||||||
GroupEditActivity.Launch(this, pwGroup.ParentGroup, pwGroup);
|
GroupEditActivity.Launch(this, pwGroup.ParentGroup, pwGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class GroupListFragment : ListFragment, AbsListView.IMultiChoiceModeListener
|
||||||
|
{
|
||||||
|
public override void OnActivityCreated(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
base.OnActivityCreated(savedInstanceState);
|
||||||
|
if (App.Kp2a.GetDb().CanWrite)
|
||||||
|
{
|
||||||
|
ListView.ChoiceMode = ChoiceMode.MultipleModal;
|
||||||
|
ListView.SetMultiChoiceModeListener(this);
|
||||||
|
ListView.ItemLongClick += delegate(object sender, AdapterView.ItemLongClickEventArgs args)
|
||||||
|
{
|
||||||
|
ListView.SetItemChecked(args.Position, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView.ItemClick += (sender, args) => ((GroupListItemView) args.View).OnClick();
|
||||||
|
|
||||||
|
StyleScrollBars();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void StyleScrollBars()
|
||||||
|
{
|
||||||
|
ListView lv = ListView;
|
||||||
|
lv.ScrollBarStyle =ScrollbarStyles.InsideInset;
|
||||||
|
lv.TextFilterEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnActionItemClicked(ActionMode mode, IMenuItem item)
|
||||||
|
{
|
||||||
|
switch (item.ItemId)
|
||||||
|
{
|
||||||
|
|
||||||
|
case Resource.Id.menu_delete:
|
||||||
|
/*Handler handler = new Handler();
|
||||||
|
DeleteEntry task = new DeleteEntry(Activity, App.Kp2a, _entry,
|
||||||
|
new GroupBaseActivity.RefreshTask(handler, ((GroupBaseActivity)Activity)));
|
||||||
|
task.Start();*/
|
||||||
|
Toast.MakeText(((GroupBaseActivity) Activity), "todo delete", ToastLength.Long).Show();
|
||||||
|
return true;
|
||||||
|
case Resource.Id.menu_move:
|
||||||
|
/*NavigateToFolderAndLaunchMoveElementTask navMove =
|
||||||
|
new NavigateToFolderAndLaunchMoveElementTask(_entry.ParentGroup, _entry.Uuid, _isSearchResult);
|
||||||
|
((GroupBaseActivity)Activity).StartTask(navMove);*/
|
||||||
|
Toast.MakeText(((GroupBaseActivity)Activity), "todo move", ToastLength.Long).Show();
|
||||||
|
return true;
|
||||||
|
/*TODO for search results case Resource.Id.menu_navigate:
|
||||||
|
NavigateToFolder navNavigate = new NavigateToFolder(_entry.ParentGroup, true);
|
||||||
|
((GroupBaseActivity)Activity).StartTask(navNavigate);
|
||||||
|
return true;*/
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnCreateActionMode(ActionMode mode, IMenu menu)
|
||||||
|
{
|
||||||
|
MenuInflater inflater = Activity.MenuInflater;
|
||||||
|
inflater.Inflate(Resource.Menu.group_entriesselected, menu);
|
||||||
|
//mode.Title = "Select Items";
|
||||||
|
Android.Util.Log.Debug("KP2A", "Create action mode" + mode);
|
||||||
|
((PwGroupListAdapter)ListView.Adapter).NotifyDataSetChanged();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnDestroyActionMode(ActionMode mode)
|
||||||
|
{
|
||||||
|
Android.Util.Log.Debug("KP2A", "Destroy action mode" + mode);
|
||||||
|
|
||||||
|
((PwGroupListAdapter)ListView.Adapter).NotifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool OnPrepareActionMode(ActionMode mode, IMenu menu)
|
||||||
|
{
|
||||||
|
Android.Util.Log.Debug("KP2A", "Prepare action mode" + mode);
|
||||||
|
((PwGroupListAdapter)ListView.Adapter).NotifyDataSetChanged();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnItemCheckedStateChanged(ActionMode mode, int position, long id, bool @checked)
|
||||||
|
{
|
||||||
|
var menuItem = mode.Menu.FindItem(Resource.Id.menu_edit);
|
||||||
|
if (menuItem != null)
|
||||||
|
{
|
||||||
|
menuItem.SetVisible(IsOnlyOneGroupChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsOnlyOneGroupChecked()
|
||||||
|
{
|
||||||
|
var checkedItems = ListView.CheckedItemPositions;
|
||||||
|
bool hadCheckedGroup = false;
|
||||||
|
if (checkedItems != null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < checkedItems.Size(); i++)
|
||||||
|
{
|
||||||
|
if (checkedItems.ValueAt(i))
|
||||||
|
{
|
||||||
|
if (hadCheckedGroup)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((PwGroupListAdapter) ListAdapter).IsGroupAtPosition(checkedItems.KeyAt(i)))
|
||||||
|
{
|
||||||
|
hadCheckedGroup = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hadCheckedGroup;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ namespace keepass2android
|
|||||||
SetContentView (Resource.Layout.group_edit);
|
SetContentView (Resource.Layout.group_edit);
|
||||||
|
|
||||||
ImageButton iconButton = (ImageButton)FindViewById (Resource.Id.icon_button);
|
ImageButton iconButton = (ImageButton)FindViewById (Resource.Id.icon_button);
|
||||||
|
iconButton.SetScaleType(ImageView.ScaleType.FitXy);
|
||||||
iconButton.Click += (sender, e) =>
|
iconButton.Click += (sender, e) =>
|
||||||
{
|
{
|
||||||
IconPickerActivity.Launch (this);
|
IconPickerActivity.Launch (this);
|
||||||
|
@ -24,7 +24,7 @@ using Android.Widget;
|
|||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
[Activity (Label = "@string/app_name", Theme="@style/NoTitleBar")]
|
[Activity(Label = "@string/app_name", Theme = "@style/MyTheme_ActionBar")]
|
||||||
public class IconPickerActivity : LockCloseActivity
|
public class IconPickerActivity : LockCloseActivity
|
||||||
{
|
{
|
||||||
public const String KeyIconId = "icon_id";
|
public const String KeyIconId = "icon_id";
|
||||||
|
@ -71,7 +71,7 @@ namespace keepass2android
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Launcher activity of Keepass2Android. This activity usually forwards to FileSelect but may show the revision dialog after installation or updates.
|
/// Launcher activity of Keepass2Android. This activity usually forwards to FileSelect but may show the revision dialog after installation or updates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Activity (Label = AppNames.AppName, MainLauncher = true, Theme="@style/Base")]
|
[Activity(Label = AppNames.AppName, MainLauncher = true, Theme = "@style/MyTheme_ActionBar")]
|
||||||
public class KeePass : LifecycleDebugActivity
|
public class KeePass : LifecycleDebugActivity
|
||||||
{
|
{
|
||||||
public const Result ExitNormal = Result.FirstUser;
|
public const Result ExitNormal = Result.FirstUser;
|
||||||
@ -167,6 +167,9 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#if DEBUG
|
||||||
|
showChangeLog = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (showChangeLog)
|
if (showChangeLog)
|
||||||
{
|
{
|
||||||
|
@ -19,11 +19,12 @@ using System;
|
|||||||
using Android.App;
|
using Android.App;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
using Android.Runtime;
|
||||||
|
using Android.Support.V7.App;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
|
|
||||||
public abstract class LifecycleDebugActivity : Activity
|
public abstract class LifecycleDebugActivity : AppCompatActivity
|
||||||
{
|
{
|
||||||
protected LifecycleDebugActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
protected LifecycleDebugActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||||
: base(javaReference, transfer)
|
: base(javaReference, transfer)
|
||||||
|
@ -34,6 +34,11 @@ using Java.Net;
|
|||||||
using Android.Preferences;
|
using Android.Preferences;
|
||||||
using Android.Text;
|
using Android.Text;
|
||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
|
using Android.Graphics;
|
||||||
|
using Android.Support.Design.Widget;
|
||||||
|
using Android.Support.V4.Widget;
|
||||||
|
using Android.Support.V7.App;
|
||||||
|
using keepass2android;
|
||||||
using KeePassLib.Keys;
|
using KeePassLib.Keys;
|
||||||
using KeePassLib.Serialization;
|
using KeePassLib.Serialization;
|
||||||
using KeePassLib.Utility;
|
using KeePassLib.Utility;
|
||||||
@ -41,21 +46,23 @@ using Keepass2android.Pluginsdk;
|
|||||||
using OtpKeyProv;
|
using OtpKeyProv;
|
||||||
using keepass2android.Io;
|
using keepass2android.Io;
|
||||||
using keepass2android.Utils;
|
using keepass2android.Utils;
|
||||||
using Exception = System.Exception;
|
|
||||||
using File = Java.IO.File;
|
using File = Java.IO.File;
|
||||||
using FileNotFoundException = Java.IO.FileNotFoundException;
|
using FileNotFoundException = Java.IO.FileNotFoundException;
|
||||||
using MemoryStream = System.IO.MemoryStream;
|
|
||||||
using Object = Java.Lang.Object;
|
using Object = Java.Lang.Object;
|
||||||
using Process = Android.OS.Process;
|
using Process = Android.OS.Process;
|
||||||
using String = System.String;
|
|
||||||
using KeeChallenge;
|
using KeeChallenge;
|
||||||
|
using AlertDialog = Android.App.AlertDialog;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
[Activity(Label = "@string/app_name",
|
[Activity(Label = "@string/app_name",
|
||||||
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
||||||
LaunchMode = LaunchMode.SingleInstance,
|
LaunchMode = LaunchMode.SingleInstance,
|
||||||
Theme = "@style/Base")]
|
Theme = "@style/MyTheme")] /*caution: also contained in AndroidManifest.xml*/
|
||||||
|
//TODO: rotating device crashes the app
|
||||||
public class PasswordActivity : LockingActivity {
|
public class PasswordActivity : LockingActivity {
|
||||||
|
|
||||||
enum KeyProviders
|
enum KeyProviders
|
||||||
@ -144,6 +151,10 @@ namespace keepass2android
|
|||||||
private ActivityDesign _design;
|
private ActivityDesign _design;
|
||||||
private bool _performingLoad;
|
private bool _performingLoad;
|
||||||
private bool _keepPasswordInOnResume;
|
private bool _keepPasswordInOnResume;
|
||||||
|
private Typeface _passwordFont;
|
||||||
|
|
||||||
|
private ActionBarDrawerToggle mDrawerToggle;
|
||||||
|
private DrawerLayout _drawerLayout;
|
||||||
|
|
||||||
|
|
||||||
public PasswordActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
public PasswordActivity (IntPtr javaReference, JniHandleOwnership transfer)
|
||||||
@ -300,6 +311,8 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
if (KeyProviderType == KeyProviders.KeyFile)
|
if (KeyProviderType == KeyProviders.KeyFile)
|
||||||
{
|
{
|
||||||
|
//TODO: if the user has not yet selected a keyfile, _keyFileOrProvider is empty which
|
||||||
|
//gives an (unhandled) exception here
|
||||||
var iocKeyfile = IOConnectionInfo.UnserializeFromString(_keyFileOrProvider);
|
var iocKeyfile = IOConnectionInfo.UnserializeFromString(_keyFileOrProvider);
|
||||||
|
|
||||||
App.Kp2a.GetFileStorage(iocKeyfile)
|
App.Kp2a.GetFileStorage(iocKeyfile)
|
||||||
@ -679,7 +692,6 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Intent i = Intent;
|
Intent i = Intent;
|
||||||
|
|
||||||
//only load the AppTask if this is the "first" OnCreate (not because of kill/resume, i.e. savedInstanceState==null)
|
//only load the AppTask if this is the "first" OnCreate (not because of kill/resume, i.e. savedInstanceState==null)
|
||||||
@ -748,6 +760,10 @@ namespace keepass2android
|
|||||||
|
|
||||||
|
|
||||||
SetContentView(Resource.Layout.password);
|
SetContentView(Resource.Layout.password);
|
||||||
|
|
||||||
|
InitializeToolbar();
|
||||||
|
|
||||||
|
|
||||||
InitializeFilenameView();
|
InitializeFilenameView();
|
||||||
|
|
||||||
if (KeyProviderType == KeyProviders.KeyFile)
|
if (KeyProviderType == KeyProviders.KeyFile)
|
||||||
@ -756,33 +772,44 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var passwordEdit = FindViewById<EditText>(Resource.Id.password);
|
||||||
FindViewById<EditText>(Resource.Id.password).TextChanged +=
|
passwordEdit.TextChanged +=
|
||||||
(sender, args) =>
|
(sender, args) =>
|
||||||
{
|
{
|
||||||
_password = FindViewById<EditText>(Resource.Id.password).Text;
|
_password = passwordEdit.Text;
|
||||||
UpdateOkButtonState();
|
UpdateOkButtonState();
|
||||||
};
|
};
|
||||||
FindViewById<EditText>(Resource.Id.password).EditorAction += (sender, args) =>
|
passwordEdit.EditorAction += (sender, args) =>
|
||||||
{
|
{
|
||||||
if ((args.ActionId == ImeAction.Done) || ((args.ActionId == ImeAction.ImeNull) && (args.Event.Action == KeyEventActions.Down)))
|
if ((args.ActionId == ImeAction.Done) || ((args.ActionId == ImeAction.ImeNull) && (args.Event.Action == KeyEventActions.Down)))
|
||||||
OnOk();
|
OnOk();
|
||||||
};
|
};
|
||||||
|
passwordEdit.FocusChange += (sender, args) =>
|
||||||
|
{
|
||||||
|
FindViewById(Resource.Id.unlock_img_button).Visibility = args.HasFocus ? ViewStates.Visible : ViewStates.Gone;
|
||||||
|
};
|
||||||
|
|
||||||
FindViewById<EditText>(Resource.Id.pass_otpsecret).TextChanged += (sender, args) => UpdateOkButtonState();
|
FindViewById<EditText>(Resource.Id.pass_otpsecret).TextChanged += (sender, args) => UpdateOkButtonState();
|
||||||
|
|
||||||
|
|
||||||
EditText passwordEdit = FindViewById<EditText>(Resource.Id.password);
|
|
||||||
passwordEdit.Text = _password;
|
passwordEdit.Text = _password;
|
||||||
passwordEdit.RequestFocus();
|
passwordEdit.RequestFocus();
|
||||||
Window.SetSoftInputMode(SoftInput.StateVisible);
|
Window.SetSoftInputMode(SoftInput.StateVisible);
|
||||||
|
|
||||||
InitializeOkButton();
|
|
||||||
|
var passwordFont = Typeface.CreateFromAsset(Assets, "SourceCodePro-Regular.ttf");
|
||||||
|
passwordEdit.Typeface = passwordFont;
|
||||||
|
|
||||||
|
|
||||||
|
FindViewById(Resource.Id.unlock_img_button).Click += (sender, args) => OnOk();
|
||||||
|
|
||||||
|
InitializeBottomBarButtons();
|
||||||
|
|
||||||
InitializePasswordModeSpinner();
|
InitializePasswordModeSpinner();
|
||||||
|
|
||||||
InitializeOtpSecretSpinner();
|
InitializeOtpSecretSpinner();
|
||||||
|
|
||||||
|
InitializeNavDrawerButtons();
|
||||||
|
|
||||||
UpdateOkButtonState();
|
UpdateOkButtonState();
|
||||||
|
|
||||||
InitializeTogglePasswordButton();
|
InitializeTogglePasswordButton();
|
||||||
@ -800,6 +827,69 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitializeNavDrawerButtons()
|
||||||
|
{
|
||||||
|
FindViewById(Resource.Id.btn_nav_change_db).Click += (sender, args) =>
|
||||||
|
{
|
||||||
|
GoToFileSelectActivity();
|
||||||
|
};
|
||||||
|
|
||||||
|
FindViewById(Resource.Id.btn_nav_donate).Click += (sender, args) =>
|
||||||
|
{
|
||||||
|
Util.GotoDonateUrl(this);
|
||||||
|
};
|
||||||
|
FindViewById(Resource.Id.btn_nav_about).Click += (sender, args) =>
|
||||||
|
{
|
||||||
|
AboutDialog dialog = new AboutDialog(this);
|
||||||
|
dialog.Show();
|
||||||
|
};
|
||||||
|
|
||||||
|
FindViewById(Resource.Id.btn_nav_settings).Click += (sender, args) =>
|
||||||
|
{
|
||||||
|
AppSettingsActivity.Launch(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeToolbar()
|
||||||
|
{
|
||||||
|
var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
|
||||||
|
|
||||||
|
SetSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
var collapsingToolbar = FindViewById<CollapsingToolbarLayout>(Resource.Id.collapsing_toolbar);
|
||||||
|
collapsingToolbar.SetTitle(GetString(Resource.String.unlock_database_title));
|
||||||
|
|
||||||
|
_drawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
|
||||||
|
mDrawerToggle = new ActionBarDrawerToggle(this, _drawerLayout,
|
||||||
|
Resource.String.menu_open,
|
||||||
|
Resource.String.menu_close);
|
||||||
|
|
||||||
|
|
||||||
|
_drawerLayout.SetDrawerListener(mDrawerToggle);
|
||||||
|
|
||||||
|
|
||||||
|
SupportActionBar.SetDisplayHomeAsUpEnabled(true);
|
||||||
|
SupportActionBar.SetHomeButtonEnabled(true);
|
||||||
|
mDrawerToggle.SyncState();
|
||||||
|
|
||||||
|
//TODO REMOVE
|
||||||
|
//SupportActionBar.SetDisplayHomeAsUpEnabled(true);
|
||||||
|
//SupportActionBar.SetDisplayShowHomeEnabled(true);
|
||||||
|
|
||||||
|
//toolbar.NavigationClick += (sender, args) => OnBackPressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnBackPressed()
|
||||||
|
{
|
||||||
|
if (_drawerLayout.IsDrawerOpen((int) GravityFlags.Start))
|
||||||
|
{
|
||||||
|
_drawerLayout.CloseDrawer((int)GravityFlags.Start);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
base.OnBackPressed();
|
||||||
|
}
|
||||||
|
|
||||||
private void InitializeOtpSecretSpinner()
|
private void InitializeOtpSecretSpinner()
|
||||||
{
|
{
|
||||||
Spinner spinner = FindViewById<Spinner>(Resource.Id.otpsecret_format_spinner);
|
Spinner spinner = FindViewById<Spinner>(Resource.Id.otpsecret_format_spinner);
|
||||||
@ -892,13 +982,15 @@ namespace keepass2android
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeOkButton()
|
private void InitializeBottomBarButtons()
|
||||||
{
|
{
|
||||||
Button confirmButton = (Button) FindViewById(Resource.Id.pass_ok);
|
Button confirmButton = (Button) FindViewById(Resource.Id.pass_ok);
|
||||||
confirmButton.Click += (sender, e) =>
|
confirmButton.Click += (sender, e) =>
|
||||||
{
|
{
|
||||||
OnOk();
|
OnOk();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FindViewById(Resource.Id.change_db).Click += (sender, args) => GoToFileSelectActivity();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnOk()
|
private void OnOk()
|
||||||
@ -1012,17 +1104,18 @@ namespace keepass2android
|
|||||||
|
|
||||||
private void UpdateOkButtonState()
|
private void UpdateOkButtonState()
|
||||||
{
|
{
|
||||||
|
bool enabled = false;
|
||||||
switch (KeyProviderType)
|
switch (KeyProviderType)
|
||||||
{
|
{
|
||||||
case KeyProviders.None:
|
case KeyProviders.None:
|
||||||
FindViewById(Resource.Id.pass_ok).Enabled = true;
|
enabled = true;
|
||||||
break;
|
break;
|
||||||
case KeyProviders.KeyFile:
|
case KeyProviders.KeyFile:
|
||||||
FindViewById(Resource.Id.pass_ok).Enabled = _keyFileOrProvider != "" || _password != "";
|
enabled = _keyFileOrProvider != "" || _password != "";
|
||||||
break;
|
break;
|
||||||
case KeyProviders.Otp:
|
case KeyProviders.Otp:
|
||||||
|
|
||||||
bool enabled = true;
|
enabled = true;
|
||||||
if (_otpInfo == null)
|
if (_otpInfo == null)
|
||||||
enabled = false;
|
enabled = false;
|
||||||
else
|
else
|
||||||
@ -1040,18 +1133,20 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FindViewById(Resource.Id.pass_ok).Enabled = enabled;
|
|
||||||
break;
|
break;
|
||||||
case KeyProviders.OtpRecovery:
|
case KeyProviders.OtpRecovery:
|
||||||
case KeyProviders.ChalRecovery:
|
case KeyProviders.ChalRecovery:
|
||||||
FindViewById(Resource.Id.pass_ok).Enabled = FindViewById<EditText>(Resource.Id.pass_otpsecret).Text != "";
|
enabled = FindViewById<EditText>(Resource.Id.pass_otpsecret).Text != "";
|
||||||
break;
|
break;
|
||||||
case KeyProviders.Challenge:
|
case KeyProviders.Challenge:
|
||||||
FindViewById(Resource.Id.pass_ok).Enabled = _challengeSecret != null;
|
enabled = _challengeSecret != null;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
FindViewById(Resource.Id.pass_ok).Enabled = enabled;
|
||||||
|
FindViewById(Resource.Id.unlock_img_button).Enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateKeyProviderUiState()
|
private void UpdateKeyProviderUiState()
|
||||||
@ -1216,11 +1311,22 @@ namespace keepass2android
|
|||||||
if (_showPassword)
|
if (_showPassword)
|
||||||
{
|
{
|
||||||
password.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
password.InputType = InputTypes.ClassText | InputTypes.TextVariationVisiblePassword;
|
||||||
|
SetPasswordTypeface(password);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
password.InputType = InputTypes.ClassText | InputTypes.TextVariationPassword;
|
password.InputType = InputTypes.ClassText | InputTypes.TextVariationPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetPasswordTypeface(TextView textView)
|
||||||
|
{
|
||||||
|
if (_passwordFont == null)
|
||||||
|
{
|
||||||
|
_passwordFont = Typeface.CreateFromAsset(Assets, "SourceCodePro-Regular.ttf");
|
||||||
|
}
|
||||||
|
textView.Typeface = _passwordFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetNewDefaultFile()
|
private void SetNewDefaultFile()
|
||||||
@ -1514,14 +1620,6 @@ namespace keepass2android
|
|||||||
|
|
||||||
private void InitializeFilenameView() {
|
private void InitializeFilenameView() {
|
||||||
SetEditText(Resource.Id.filename, App.Kp2a.GetFileStorage(_ioConnection).GetDisplayName(_ioConnection));
|
SetEditText(Resource.Id.filename, App.Kp2a.GetFileStorage(_ioConnection).GetDisplayName(_ioConnection));
|
||||||
if (App.Kp2a.FileDbHelper.NumberOfRecentFiles() < 2)
|
|
||||||
{
|
|
||||||
FindViewById(Resource.Id.filename_group).Visibility = ViewStates.Gone;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FindViewById(Resource.Id.filename_group).Visibility = ViewStates.Visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1548,28 +1646,11 @@ namespace keepass2android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnCreateOptionsMenu(IMenu menu) {
|
|
||||||
base.OnCreateOptionsMenu(menu);
|
|
||||||
|
|
||||||
MenuInflater inflate = MenuInflater;
|
|
||||||
inflate.Inflate(Resource.Menu.password, menu);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnOptionsItemSelected(IMenuItem item) {
|
public override bool OnOptionsItemSelected(IMenuItem item) {
|
||||||
switch ( item.ItemId ) {
|
switch ( item.ItemId ) {
|
||||||
case Resource.Id.menu_about:
|
|
||||||
AboutDialog dialog = new AboutDialog(this);
|
|
||||||
dialog.Show();
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case Resource.Id.menu_app_settings:
|
case Android.Resource.Id.Home:
|
||||||
AppSettingsActivity.Launch(this);
|
_drawerLayout.OpenDrawer(Android.Support.V4.View.GravityCompat.Start);
|
||||||
return true;
|
|
||||||
|
|
||||||
case Resource.Id.menu_change_db:
|
|
||||||
GoToFileSelectActivity();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:configChanges="keyboardHidden|orientation" android:label="@string/app_name" android:theme="@style/Base" android:name="keepass2android.PasswordActivity">
|
<activity android:configChanges="keyboardHidden|orientation" android:label="@string/app_name" android:theme="@style/MyTheme" android:name="keepass2android.PasswordActivity">
|
||||||
<intent-filter android:label="@string/app_name">
|
<intent-filter android:label="@string/app_name">
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
@ -57,7 +57,7 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:configChanges="keyboardHidden|orientation" android:label="@string/app_name" android:theme="@style/Base" android:name="keepass2android.PasswordActivity">
|
<activity android:configChanges="keyboardHidden|orientation" android:label="@string/app_name" android:theme="@style/MyTheme" android:name="keepass2android.PasswordActivity">
|
||||||
<intent-filter android:label="@string/app_name">
|
<intent-filter android:label="@string/app_name">
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity android:configChanges="keyboardHidden|orientation" android:label="@string/app_name" android:theme="@style/Base" android:name="keepass2android.PasswordActivity">
|
<activity android:configChanges="keyboardHidden|orientation" android:label="@string/app_name" android:theme="@style/MyTheme" android:name="keepass2android.PasswordActivity">
|
||||||
<intent-filter android:label="@string/app_name">
|
<intent-filter android:label="@string/app_name">
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
@ -276,6 +276,11 @@ namespace keepass2android
|
|||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsGroupAtPosition(int position)
|
||||||
|
{
|
||||||
|
return position < _groupsForViewing.Count;
|
||||||
|
}
|
||||||
|
|
||||||
public override long GetItemId(int position) {
|
public override long GetItemId(int position) {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
@ -288,6 +293,7 @@ namespace keepass2android
|
|||||||
} else {
|
} else {
|
||||||
return CreateEntryView(position - size, convertView);
|
return CreateEntryView(position - size, convertView);
|
||||||
}
|
}
|
||||||
|
//TODO remove right arrow in actionmode
|
||||||
}
|
}
|
||||||
|
|
||||||
private View CreateGroupView(int position, View convertView) {
|
private View CreateGroupView(int position, View convertView) {
|
||||||
|
@ -16,7 +16,7 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
[Activity(Label = "@string/app_name",
|
[Activity(Label = "@string/app_name",
|
||||||
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
||||||
Theme = "@style/Base")]
|
Theme = "@style/MyTheme_ActionBar")]
|
||||||
[IntentFilter(new[] { Strings.ActionQueryCredentials},
|
[IntentFilter(new[] { Strings.ActionQueryCredentials},
|
||||||
Categories = new[] { Intent.CategoryDefault })]
|
Categories = new[] { Intent.CategoryDefault })]
|
||||||
[IntentFilter(new[] { Strings.ActionQueryCredentialsForOwnPackage },
|
[IntentFilter(new[] { Strings.ActionQueryCredentialsForOwnPackage },
|
||||||
|
@ -30,7 +30,7 @@ using KeePassLib.Serialization;
|
|||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
[Activity(Label = "@string/app_name", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
[Activity(Label = "@string/app_name", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
||||||
Theme = "@style/Base")]
|
Theme = "@style/MyTheme")]
|
||||||
public class QuickUnlock : LifecycleDebugActivity
|
public class QuickUnlock : LifecycleDebugActivity
|
||||||
{
|
{
|
||||||
private IOConnectionInfo _ioc;
|
private IOConnectionInfo _ioc;
|
||||||
|
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 773 B |
Before Width: | Height: | Size: 968 B |
Before Width: | Height: | Size: 196 B |