Browse Source

Merge branch 'issue-23' of isundil/pass into master

isundil 7 years ago
parent
commit
4a05f874f1

+ 11 - 25
app/src/main/java/info/knacki/pass/generator/ui/PasswordGeneratorWizard.java

@@ -1,25 +1,24 @@
 package info.knacki.pass.generator.ui;
 
 import android.content.Context;
-import android.support.v7.widget.AppCompatCheckBox;
 import android.support.v7.widget.AppCompatSpinner;
 import android.view.View;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
-import android.widget.CompoundButton;
 import android.widget.LinearLayout;
 import android.widget.NumberPicker;
 import android.widget.TextView;
 
 import info.knacki.pass.R;
 import info.knacki.pass.generator.PasswordGenerator;
+import info.knacki.pass.ui.widget.Checkbox;
 
 public class PasswordGeneratorWizard extends LinearLayout implements PasswordGenerator.PasswordGeneratorParams {
     public final AppCompatSpinner fDifficulty;
-    public final AppCompatCheckBox fAlpha;
-    public final AppCompatCheckBox fCapitalize;
-    public final AppCompatCheckBox fNum;
-    public final AppCompatCheckBox fSpecial;
+    public final Checkbox fAlpha;
+    public final Checkbox fCapitalize;
+    public final Checkbox fNum;
+    public final Checkbox fSpecial;
     public final NumberPicker fLength;
 
     public static final int PRESET_NUM =0;
@@ -52,11 +51,11 @@ public class PasswordGeneratorWizard extends LinearLayout implements PasswordGen
         return fLength.getValue();
     }
 
-    private class ChangeListener implements CompoundButton.OnCheckedChangeListener, NumberPicker.OnValueChangeListener {
+    private class ChangeListener implements Checkbox.OnCheckedChangeListener, NumberPicker.OnValueChangeListener {
         private boolean locked = true;
 
         @Override
-        public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
+        public void onCheckedChanged(Checkbox checkbox, boolean b) {
             if (!locked)
                 fDifficulty.setSelection(4, true);
         }
@@ -76,7 +75,6 @@ public class PasswordGeneratorWizard extends LinearLayout implements PasswordGen
     public PasswordGeneratorWizard(Context c) {
         super(c);
 
-
         LinearLayout difficultyLayout = new LinearLayout(c);
         ArrayAdapter fDifficultyAdapter = new ArrayAdapter<>(c, android.R.layout.simple_spinner_item, c.getResources().getStringArray(R.array.fDifficulty));
         fDifficultyAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
@@ -97,22 +95,10 @@ public class PasswordGeneratorWizard extends LinearLayout implements PasswordGen
         difficultyLayout.addView(tv);
         difficultyLayout.addView(fDifficulty);
         addView(difficultyLayout);
-        fNum = new AppCompatCheckBox(c);
-        fNum.setText(R.string.generate_number);
-        fNum.setOnCheckedChangeListener(fChangeListener);
-        addView(fNum);
-        fAlpha = new AppCompatCheckBox(c);
-        fAlpha.setText(R.string.generate_alpha);
-        fAlpha.setOnCheckedChangeListener(fChangeListener);
-        addView(fAlpha);
-        fCapitalize = new AppCompatCheckBox(c);
-        fCapitalize.setText(R.string.generate_capitalize);
-        fCapitalize.setOnCheckedChangeListener(fChangeListener);
-        addView(fCapitalize);
-        fSpecial = new AppCompatCheckBox(c);
-        fSpecial.setText(R.string.generate_special);
-        fSpecial.setOnCheckedChangeListener(fChangeListener);
-        addView(fSpecial);
+        fNum = new Checkbox(c, R.string.generate_number, fChangeListener, this);
+        fAlpha = new Checkbox(c, R.string.generate_alpha, fChangeListener, this);
+        fCapitalize = new Checkbox(c, R.string.generate_capitalize, fChangeListener, this);
+        fSpecial = new Checkbox(c, R.string.generate_special, fChangeListener, this);
         fLength = new NumberPicker(c);
         fLength.setMinValue(4);
         fLength.setMaxValue(21);

+ 74 - 0
app/src/main/java/info/knacki/pass/input/InputService.java

@@ -12,14 +12,21 @@ import android.widget.ScrollView;
 import android.widget.Toast;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import info.knacki.pass.R;
+import info.knacki.pass.generator.PasswordGenerator;
+import info.knacki.pass.generator.ui.PasswordGeneratorWizard;
 import info.knacki.pass.io.FileInterfaceFactory;
+import info.knacki.pass.io.IFileInterface;
 import info.knacki.pass.io.OnResponseListener;
 import info.knacki.pass.io.PathUtils;
+import info.knacki.pass.settings.SettingsManager;
 import info.knacki.pass.ui.MainActivity;
+import info.knacki.pass.ui.alertPrompt.ServiceAlertPromptGenerator;
+import info.knacki.pass.ui.alertPrompt.views.SimpleTextEditWithKeyboard;
 import info.knacki.pass.ui.passwordList.PasswordClickListener;
 import info.knacki.pass.ui.passwordList.PasswordListView;
 import info.knacki.pass.ui.passwordPicker.PasswordPickerFactory;
@@ -52,10 +59,77 @@ public class InputService extends InputMethodService implements PasswordClickLis
             }
             service.showInputMethodPicker();
         });
+        fInputView.findViewById(R.id.backspaceButton).setOnClickListener(view -> {
+            getCurrentInputConnection().deleteSurroundingText(1, 0);
+        });
+        fInputView.findViewById(R.id.generateButton).setOnClickListener(view -> {
+            CreatePassword();
+        });
         fInputView.findViewById(R.id.openAppButton).setOnClickListener(view -> startActivity(new Intent(InputService.this, MainActivity.class)));
         return fInputView;
     }
 
+    protected void CreatePassword() {
+        new ServiceAlertPromptGenerator(fInputView).Generate(this)
+                .setCancelable(true)
+                .setView(new SimpleTextEditWithKeyboard(this))
+                .setPositiveButton(R.string.add, (dialogInterface, view) -> {
+                    final String filename = ((SimpleTextEditWithKeyboard) view).getStr();
+                    if (filename.length() == 0) {
+                        Toast.makeText(InputService.this, "Error: Empty file name", Toast.LENGTH_LONG).show();
+                        return;
+                    }
+                    File f = new File(fPasswordListView.fCurrentDir +"/" +filename +FileInterfaceFactory.GetExtension(SettingsManager.GetDefaultEncryptionType(InputService.this)));
+                    try {
+                        f.createNewFile();
+                        fPasswordListView.refresh();
+                    }
+                    catch (IOException e) {
+                        Toast.makeText(InputService.this, "Error: " +e.getMessage(), Toast.LENGTH_LONG).show();
+                        log.log(Level.WARNING, e.getMessage(), e);
+                        return;
+                    }
+                    GeneratePassword(f);
+                })
+                .setNegativeButton(R.string.cancel, null)
+                .setTitle(R.string.add_title)
+                .show();
+    }
+
+    protected void GeneratePassword(final File f) {
+        final PasswordGeneratorWizard wiz = new PasswordGeneratorWizard(this);
+
+        new ServiceAlertPromptGenerator(fInputView).Generate(this)
+                .setCancelable(true)
+                .setView(wiz)
+                .setPositiveButton(R.string.add, (dialogInterface, view) -> {
+                    IFileInterface writer = FileInterfaceFactory.GetFileInterface(InputService.this, PasswordPickerFactory.GetPasswordPicker(InputService.this), f);
+
+                    try {
+                        final String pwd = PasswordGenerator.generate(wiz);
+                        writer.WriteFile(pwd, new OnResponseListener<Void>() {
+                            @Override
+                            public void OnResponse(Void result) {
+                                sendPassword(pwd);
+                            }
+
+                            @Override
+                            public void OnError(final String msg, final Throwable e) {
+                            }
+                        });
+                    }
+                    catch (IFileInterface.InvalidPasswordException e) {
+                        f.delete();
+                        log.log(Level.WARNING, e.getMessage(), e);
+                        Toast.makeText(InputService.this, "Error: " +e.getMessage(), Toast.LENGTH_LONG).show();
+                        fPasswordListView.refresh();
+                    }
+                })
+                .setNegativeButton(R.string.cancel, null)
+                .setTitle(R.string.generate_title)
+                .show();
+    }
+
     public void sendPassword(String passwordContent) {
         getCurrentInputConnection().commitText(passwordContent, passwordContent.length());
         onFinishInput();

+ 2 - 2
app/src/main/java/info/knacki/pass/ui/MainActivity.java

@@ -58,7 +58,7 @@ public class MainActivity extends AppCompatActivity implements PasswordEditListe
                     }
                     fPasswordListView.refresh();
                 })
-                .setNegativeButton(R.string.cancel, (dialogInterface, s) -> dialogInterface.cancel())
+                .setNegativeButton(R.string.cancel, null)
                 .setTitle(R.string.add_title)
                 .show();
     }
@@ -192,7 +192,7 @@ public class MainActivity extends AppCompatActivity implements PasswordEditListe
                     fPasswordListView.refresh();
                 }
             })
-            .setNegativeButton(R.string.cancel, (dialogInterface, s) -> dialogInterface.cancel())
+            .setNegativeButton(R.string.cancel, null)
             .setTitle(R.string.generate_title)
             .show();
     }

+ 2 - 0
app/src/main/java/info/knacki/pass/ui/alertPrompt/AlertPrompt.java

@@ -10,6 +10,7 @@ public class AlertPrompt {
     protected android.app.AlertDialog fDialog;
     protected View fView = null;
     protected final DismissListener fOnDismiss;
+    protected final Context fContext;
 
     public interface OnClickListener {
         void onClick(DialogInterface dialogInterface, View view);
@@ -36,6 +37,7 @@ public class AlertPrompt {
     }
 
     AlertPrompt(Context c) {
+        fContext = c;
         fAlertBuilder = new AlertDialog.Builder(c);
         fOnDismiss = new DismissListener();
     }

+ 4 - 0
app/src/main/java/info/knacki/pass/ui/alertPrompt/ServiceAlertPrompt.java

@@ -5,6 +5,8 @@ import android.view.View;
 import android.view.Window;
 import android.view.WindowManager;
 
+import info.knacki.pass.R;
+
 public class ServiceAlertPrompt extends AlertPrompt {
     protected final View fInputView;
 
@@ -21,5 +23,7 @@ public class ServiceAlertPrompt extends AlertPrompt {
         lay.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
         window.setAttributes(lay);
         window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
+        final int hzPadding = fContext.getResources().getDimensionPixelSize(R.dimen.fab_margin);
+        getView().setPadding(hzPadding, 0, hzPadding, 0);
     }
 }

+ 1 - 39
app/src/main/java/info/knacki/pass/ui/alertPrompt/views/PasswordTextEdit.java

@@ -1,49 +1,11 @@
 package info.knacki.pass.ui.alertPrompt.views;
 
 import android.content.Context;
-import android.inputmethodservice.KeyboardView;
-import android.support.v7.widget.AppCompatEditText;
-import android.text.Editable;
 import android.text.InputType;
-import android.widget.LinearLayout;
-
-import info.knacki.pass.ui.alertPrompt.integratedKeyboard.KeyboardWidget;
-
-public class PasswordTextEdit extends LinearLayout implements KeyboardWidget.OnKeyListener {
-    private final AppCompatEditText fTextEdit;
 
+public class PasswordTextEdit extends SimpleTextEditWithKeyboard {
     public PasswordTextEdit(Context c) {
         super(c);
-        fTextEdit = new SimpleTextEdit(c);
         fTextEdit.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
-        fTextEdit.setFocusable(false);
-        addView(fTextEdit);
-        KeyboardView keyboard = new KeyboardWidget(c).SetListener(this);
-        addView(keyboard);
-        setOrientation(VERTICAL);
-    }
-
-    public PasswordTextEdit setText(String str) {
-        fTextEdit.setText(str);
-        fTextEdit.setSelection(str.length());
-        return this;
-    }
-
-    public String getStr() {
-        Editable text = fTextEdit.getText();
-        return null == text ? "" : text.toString().trim();
-    }
-
-    @Override
-    public void OnKeyReceived(CharSequence c) {
-        final int selectionStart = fTextEdit.getSelectionStart();
-        final int selectionEnd = fTextEdit.getSelectionEnd();
-        fTextEdit.getText().replace(selectionStart, selectionEnd, c);
-    }
-
-    public void OnBackspace() {
-        final int selectionEnd = fTextEdit.getSelectionEnd();
-        final int selectionStart = Math.max(0, fTextEdit.getSelectionStart() == fTextEdit.getSelectionEnd() ? fTextEdit.getSelectionStart() - 1 : fTextEdit.getSelectionStart());
-        fTextEdit.getText().replace(selectionStart, selectionEnd, "");
     }
 }

+ 48 - 0
app/src/main/java/info/knacki/pass/ui/alertPrompt/views/SimpleTextEditWithKeyboard.java

@@ -0,0 +1,48 @@
+package info.knacki.pass.ui.alertPrompt.views;
+
+import android.content.Context;
+import android.inputmethodservice.KeyboardView;
+import android.support.v7.widget.AppCompatEditText;
+import android.text.Editable;
+import android.widget.LinearLayout;
+
+import info.knacki.pass.ui.alertPrompt.integratedKeyboard.KeyboardWidget;
+
+public class SimpleTextEditWithKeyboard  extends LinearLayout implements KeyboardWidget.OnKeyListener {
+    protected final AppCompatEditText fTextEdit;
+
+    public SimpleTextEditWithKeyboard(Context c) {
+        super(c);
+        fTextEdit = new SimpleTextEdit(c);
+        fTextEdit.setFocusable(false);
+        addView(fTextEdit);
+        KeyboardView keyboard = new KeyboardWidget(c).SetListener(this);
+        addView(keyboard);
+        setOrientation(VERTICAL);
+    }
+
+    public SimpleTextEditWithKeyboard setText(String str) {
+        fTextEdit.setText(str);
+        fTextEdit.setSelection(str.length());
+        return this;
+    }
+
+    public String getStr() {
+        Editable text = fTextEdit.getText();
+        return null == text ? "" : text.toString().trim();
+    }
+
+    @Override
+    public void OnKeyReceived(CharSequence c) {
+        final int selectionStart = fTextEdit.getSelectionStart();
+        final int selectionEnd = fTextEdit.getSelectionEnd();
+
+        fTextEdit.getText().replace(selectionStart, selectionEnd, c);
+    }
+
+    public void OnBackspace() {
+        final int selectionEnd = fTextEdit.getSelectionEnd();
+        final int selectionStart = Math.max(0, fTextEdit.getSelectionStart() == selectionEnd ? fTextEdit.getSelectionStart() - 1 : fTextEdit.getSelectionStart());
+        fTextEdit.getText().replace(selectionStart, selectionEnd, "");
+    }
+}

+ 61 - 0
app/src/main/java/info/knacki/pass/ui/widget/Checkbox.java

@@ -0,0 +1,61 @@
+package info.knacki.pass.ui.widget;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.support.v7.widget.AppCompatImageView;
+import android.support.v7.widget.AppCompatTextView;
+import android.view.ViewGroup;
+import android.widget.Checkable;
+import android.widget.LinearLayout;
+
+@SuppressLint("ViewConstructor")
+public class Checkbox extends LinearLayout implements Checkable {
+    protected final AppCompatImageView fCheckbox;
+    protected final AppCompatTextView fTextView;
+    protected final OnCheckedChangeListener fCheckedChangeListener;
+    protected boolean fChecked;
+
+    public interface OnCheckedChangeListener {
+        void onCheckedChanged(Checkbox checkbox, boolean isChecked);
+    }
+
+    public Checkbox(Context context, int text, OnCheckedChangeListener onCheckedChangeListener, ViewGroup parent) {
+        super(context);
+        setOrientation(HORIZONTAL);
+        fCheckbox = new AppCompatImageView(context);
+        fTextView = new AppCompatTextView(context);
+        addView(fCheckbox);
+        addView(fTextView);
+        fTextView.setText(text);
+        parent.addView(this);
+        setOnClickListener(view -> {
+            toggle();
+        });
+        setChecked(false);
+        fCheckedChangeListener = onCheckedChangeListener;
+    }
+
+    private void SetIcon() {
+        fCheckbox.setImageDrawable(getContext().getResources().getDrawable(fChecked ? android.R.drawable.checkbox_on_background : android.R.drawable.checkbox_off_background));
+    }
+
+    @Override
+    public void setChecked(boolean checked) {
+        if (fChecked != checked) {
+            fChecked = checked;
+            SetIcon();
+            if (fCheckedChangeListener != null)
+                fCheckedChangeListener.onCheckedChanged(this, isChecked());
+        }
+    }
+
+    @Override
+    public boolean isChecked() {
+        return fChecked;
+    }
+
+    @Override
+    public void toggle() {
+        setChecked(!isChecked());
+    }
+}

+ 25 - 0
app/src/main/res/layout/input.xml

@@ -31,6 +31,31 @@
             android:layout_width="1dp"
             android:layout_height="match_parent"
             android:layout_weight="5" />
+        <TextView
+            style="@android:style/Widget.DeviceDefault.Light.TextView"
+            android:id="@+id/backspaceButton"
+            android:layout_width="@dimen/fab_margin"
+            android:layout_height="@dimen/fab_margin"
+            android:clickable="true"
+            android:focusable="true"
+            android:background="@drawable/sym_keyboard_delete"
+            android:maxHeight="@dimen/keyboard_key_height"
+            android:layout_weight="0.5"
+            android:layout_gravity="end"
+            android:textAlignment="textEnd"
+            android:textStyle="bold" />
+        <TextView
+            style="@android:style/Widget.DeviceDefault.Light.TextView"
+            android:id="@+id/generateButton"
+            android:layout_width="@dimen/fab_margin"
+            android:layout_height="@dimen/fab_margin"
+            android:clickable="true"
+            android:focusable="true"
+            android:background="@drawable/ic_doc_text"
+            android:layout_weight="0.5"
+            android:layout_gravity="end"
+            android:textAlignment="textEnd"
+            android:textStyle="bold" />
         <TextView
             style="@android:style/Widget.DeviceDefault.Light.TextView"
             android:id="@+id/openAppButton"

+ 1 - 1
app/src/main/res/values/dimens.xml

@@ -2,7 +2,7 @@
 <resources>
     <dimen name="keyboard_key_height">32dp</dimen>
     <dimen name="big_icon_height">64dp</dimen>
-    <dimen name="keyboard_min_height">375px</dimen>
+    <dimen name="keyboard_min_height">600px</dimen>
     <dimen name="keyboard_max_height">664px</dimen>
     <dimen name="fab_margin">16dp</dimen>
 </resources>