diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4d98a1b92..1e8be064c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -84,16 +84,20 @@ + android:configChanges="orientation|keyboardHidden" + android:windowSoftInputMode="stateHidden" /> + android:configChanges="orientation|keyboardHidden" + android:windowSoftInputMode="stateHidden" /> + android:configChanges="orientation|keyboardHidden" + android:windowSoftInputMode="stateHidden" /> + android:configChanges="orientation|keyboardHidden" + android:windowSoftInputMode="stateHidden" /> @@ -102,7 +106,6 @@ - diff --git a/app/src/main/java/com/keepassdroid/EntryEditActivity.java b/app/src/main/java/com/keepassdroid/EntryEditActivity.java index 44f06e33e..165164e6a 100644 --- a/app/src/main/java/com/keepassdroid/EntryEditActivity.java +++ b/app/src/main/java/com/keepassdroid/EntryEditActivity.java @@ -63,7 +63,8 @@ import java.util.Date; import java.util.UUID; public abstract class EntryEditActivity extends LockCloseHideActivity - implements IconPickerFragment.IconPickerListener { + implements IconPickerFragment.IconPickerListener, + GeneratePasswordFragment.GeneratePasswordListener { public static final String KEY_ENTRY = "entry"; public static final String KEY_PARENT = "parent"; @@ -170,7 +171,8 @@ public abstract class EntryEditActivity extends LockCloseHideActivity generatePassword.setOnClickListener(new OnClickListener() { public void onClick(View v) { - GeneratePasswordActivity.Launch(EntryEditActivity.this); + GeneratePasswordFragment generatePasswordFragment = new GeneratePasswordFragment(); + generatePasswordFragment.show(getSupportFragmentManager(), "PasswordGeneratorFragment"); } }); @@ -268,26 +270,6 @@ public abstract class EntryEditActivity extends LockCloseHideActivity return newEntry; } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) - { - switch (resultCode) - { - case RESULT_OK_PASSWORD_GENERATOR: - String generatedPassword = data.getStringExtra("com.keepassdroid.password.generated_password"); - EditText password = (EditText) findViewById(R.id.entry_password); - EditText confPassword = (EditText) findViewById(R.id.entry_confpassword); - - password.setText(generatedPassword); - confPassword.setText(generatedPassword); - - break; - case Activity.RESULT_CANCELED: - default: - break; - } - } @Override public boolean onCreateOptionsMenu(Menu menu) { @@ -313,6 +295,7 @@ public abstract class EntryEditActivity extends LockCloseHideActivity switch ( item.getItemId() ) { case R.id.menu_donate: try { + // TODO Encapsulate Util.gotoUrl(this, R.string.donate_url); } catch (ActivityNotFoundException e) { Toast.makeText(this, R.string.error_failed_to_launch_link, Toast.LENGTH_LONG).show(); @@ -360,7 +343,7 @@ public abstract class EntryEditActivity extends LockCloseHideActivity populateText(R.id.entry_user_name, mEntry.getUsername()); populateText(R.id.entry_url, mEntry.getUrl()); - String password = new String(mEntry.getPassword()); + String password = mEntry.getPassword(); populateText(R.id.entry_password, password); populateText(R.id.entry_confpassword, password); setPasswordStyle(); @@ -380,7 +363,22 @@ public abstract class EntryEditActivity extends LockCloseHideActivity currIconButton.setImageResource(Icons.iconToResId(mSelectedIconID)); } - private final class AfterSave extends OnFinish { + @Override + public void acceptPassword(Bundle bundle) { + String generatedPassword = bundle.getString(GeneratePasswordFragment.KEY_PASSWORD_ID); + EditText password = (EditText) findViewById(R.id.entry_password); + EditText confPassword = (EditText) findViewById(R.id.entry_confpassword); + + password.setText(generatedPassword); + confPassword.setText(generatedPassword); + } + + @Override + public void cancelPassword(Bundle bundle) { + // Do nothing here + } + + private final class AfterSave extends OnFinish { public AfterSave(Handler handler) { super(handler); diff --git a/app/src/main/java/com/keepassdroid/EntryEditActivityV4.java b/app/src/main/java/com/keepassdroid/EntryEditActivityV4.java index 187081322..f5bb3ab53 100644 --- a/app/src/main/java/com/keepassdroid/EntryEditActivityV4.java +++ b/app/src/main/java/com/keepassdroid/EntryEditActivityV4.java @@ -19,12 +19,6 @@ */ package com.keepassdroid; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.UUID; - import android.content.Context; import android.content.Intent; import android.os.Bundle; @@ -32,9 +26,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; -import android.widget.ImageButton; import android.widget.LinearLayout; -import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; @@ -51,6 +43,12 @@ import com.keepassdroid.database.security.ProtectedString; import com.keepassdroid.utils.Types; import com.keepassdroid.view.EntryEditSection; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.UUID; + public class EntryEditActivityV4 extends EntryEditActivity { private ScrollView scroll; diff --git a/app/src/main/java/com/keepassdroid/GeneratePasswordActivity.java b/app/src/main/java/com/keepassdroid/GeneratePasswordActivity.java deleted file mode 100644 index d0c74f77f..000000000 --- a/app/src/main/java/com/keepassdroid/GeneratePasswordActivity.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft. - * - * This file is part of KeePass DX. - * - * KeePass DX is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * KeePass DX is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with KeePass DX. If not, see . - * - */ -package com.keepassdroid; - -import android.app.Activity; -import android.content.Intent; -import android.os.Bundle; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.Toast; - -import com.android.keepass.KeePass; -import com.android.keepass.R; -import com.keepassdroid.password.PasswordGenerator; - -public class GeneratePasswordActivity extends LockCloseActivity { - private static final int[] BUTTON_IDS = new int [] {R.id.btn_length6, R.id.btn_length8, R.id.btn_length12, R.id.btn_length16}; - - public static void Launch(Activity act) { - Intent i = new Intent(act, GeneratePasswordActivity.class); - - act.startActivityForResult(i, 0); - } - - private OnClickListener lengthButtonsListener = new OnClickListener() { - public void onClick(View v) { - Button button = (Button) v; - - EditText editText = (EditText) findViewById(R.id.length); - editText.setText(button.getText()); - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.generate_password); - setResult(KeePass.EXIT_NORMAL); - - for (int id : BUTTON_IDS) { - Button button = (Button) findViewById(id); - button.setOnClickListener(lengthButtonsListener); - } - - Button genPassButton = (Button) findViewById(R.id.generate_password_button); - genPassButton.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - fillPassword(); - } - }); - - Button acceptButton = (Button) findViewById(R.id.accept_button); - acceptButton.setOnClickListener(new OnClickListener() { - - public void onClick(View v) { - EditText password = (EditText) findViewById(R.id.password); - - Intent intent = new Intent(); - intent.putExtra("com.keepassdroid.password.generated_password", password.getText().toString()); - - setResult(EntryEditActivity.RESULT_OK_PASSWORD_GENERATOR, intent); - - finish(); - } - }); - - Button cancelButton = (Button) findViewById(R.id.cancel_button); - cancelButton.setOnClickListener(new OnClickListener() { - - public void onClick(View v) { - setResult(RESULT_CANCELED); - - finish(); - } - }); - - // Pre-populate a password to possibly save the user a few clicks - fillPassword(); - } - - private void fillPassword() { - EditText txtPassword = (EditText) findViewById(R.id.password); - txtPassword.setText(generatePassword()); - } - - public String generatePassword() { - String password = ""; - - try { - int length = Integer.valueOf(((EditText) findViewById(R.id.length)).getText().toString()); - - ((CheckBox) findViewById(R.id.cb_uppercase)).isChecked(); - - PasswordGenerator generator = new PasswordGenerator(this); - - password = generator.generatePassword(length, - ((CheckBox) findViewById(R.id.cb_uppercase)).isChecked(), - ((CheckBox) findViewById(R.id.cb_lowercase)).isChecked(), - ((CheckBox) findViewById(R.id.cb_digits)).isChecked(), - ((CheckBox) findViewById(R.id.cb_minus)).isChecked(), - ((CheckBox) findViewById(R.id.cb_underline)).isChecked(), - ((CheckBox) findViewById(R.id.cb_space)).isChecked(), - ((CheckBox) findViewById(R.id.cb_specials)).isChecked(), - ((CheckBox) findViewById(R.id.cb_brackets)).isChecked()); - } catch (NumberFormatException e) { - Toast.makeText(this, R.string.error_wrong_length, Toast.LENGTH_LONG).show(); - } catch (IllegalArgumentException e) { - Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show(); - } - - return password; - } -} diff --git a/app/src/main/java/com/keepassdroid/GeneratePasswordFragment.java b/app/src/main/java/com/keepassdroid/GeneratePasswordFragment.java new file mode 100644 index 000000000..98052a22e --- /dev/null +++ b/app/src/main/java/com/keepassdroid/GeneratePasswordFragment.java @@ -0,0 +1,154 @@ +/* + * Copyright 2017 Brian Pellin, Jeremy Jamet / Kunzisoft. + * + * This file is part of KeePass DX. + * + * KeePass DX is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * KeePass DX is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with KeePass DX. If not, see . + * + */ +package com.keepassdroid; + +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.DialogFragment; +import android.support.v7.app.AlertDialog; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.SeekBar; +import android.widget.Toast; + +import com.android.keepass.R; +import com.keepassdroid.password.PasswordGenerator; + +public class GeneratePasswordFragment extends DialogFragment { + + public static final String KEY_PASSWORD_ID = "KEY_PASSWORD_ID"; + + private GeneratePasswordListener mListener; + private View root; + private EditText lengthTextView; + + @Override + public void onAttach(Context context) { + super.onAttach(context); + try { + mListener = (GeneratePasswordListener) context; + } catch (ClassCastException e) { + throw new ClassCastException(context.toString() + + " must implement " + GeneratePasswordListener.class.getName()); + } + } + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + LayoutInflater inflater = getActivity().getLayoutInflater(); + root = inflater.inflate(R.layout.generate_password, null); + + lengthTextView = (EditText) root.findViewById(R.id.length); + + SeekBar seekBar = (SeekBar) root.findViewById(R.id.seekbar_length); + seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + lengthTextView.setText(String.valueOf(progress)); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) {} + + @Override + public void onStopTrackingTouch(SeekBar seekBar) {} + }); + + Button genPassButton = (Button) root.findViewById(R.id.generate_password_button); + genPassButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + fillPassword(); + } + }); + + builder.setView(root) + .setPositiveButton(R.string.accept, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + EditText password = (EditText) root.findViewById(R.id.password); + Bundle bundle = new Bundle(); + bundle.putString(KEY_PASSWORD_ID, password.getText().toString()); + mListener.acceptPassword(bundle); + + dismiss(); + } + }) + .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + Bundle bundle = new Bundle(); + mListener.cancelPassword(bundle); + + dismiss(); + } + }); + + // Pre-populate a password to possibly save the user a few clicks + fillPassword(); + + return builder.create(); + } + + private void fillPassword() { + EditText txtPassword = (EditText) root.findViewById(R.id.password); + txtPassword.setText(generatePassword()); + } + + public String generatePassword() { + String password = ""; + + try { + int length = Integer.valueOf(((EditText) root.findViewById(R.id.length)).getText().toString()); + + ((CheckBox) root.findViewById(R.id.cb_uppercase)).isChecked(); + + PasswordGenerator generator = new PasswordGenerator(getActivity()); + + password = generator.generatePassword(length, + ((CheckBox) root.findViewById(R.id.cb_uppercase)).isChecked(), + ((CheckBox) root.findViewById(R.id.cb_lowercase)).isChecked(), + ((CheckBox) root.findViewById(R.id.cb_digits)).isChecked(), + ((CheckBox) root.findViewById(R.id.cb_minus)).isChecked(), + ((CheckBox) root.findViewById(R.id.cb_underline)).isChecked(), + ((CheckBox) root.findViewById(R.id.cb_space)).isChecked(), + ((CheckBox) root.findViewById(R.id.cb_specials)).isChecked(), + ((CheckBox) root.findViewById(R.id.cb_brackets)).isChecked()); + } catch (NumberFormatException e) { + Toast.makeText(getContext(), R.string.error_wrong_length, Toast.LENGTH_LONG).show(); + } catch (IllegalArgumentException e) { + Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_LONG).show(); + } + + return password; + } + + public interface GeneratePasswordListener { + void acceptPassword(Bundle bundle); + void cancelPassword(Bundle bundle); + } +} diff --git a/app/src/main/res/layout/entry_edit.xml b/app/src/main/res/layout/entry_edit.xml index 4b701e472..8c38e7347 100644 --- a/app/src/main/res/layout/entry_edit.xml +++ b/app/src/main/res/layout/entry_edit.xml @@ -104,6 +104,7 @@ android:layout_height="wrap_content"> - - - - - - - - + - + android:layout_alignParentLeft="true" + android:layout_alignParentStart="true" + android:layout_toLeftOf="@+id/generate_button" + android:layout_toStartOf="@+id/generate_button" + android:layout_below="@+id/container_entry_password"> + + + + + + . --> - -