diff options
Diffstat (limited to 'OpenKeychain/src/main')
14 files changed, 733 insertions, 297 deletions
| diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java index 0b1d521ad..0a1822798 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/ui/AccountSettingsFragment.java @@ -32,9 +32,12 @@ import android.widget.Button;  import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.pgp.KeyRing; +import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;  import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;  import org.sufficientlysecure.keychain.provider.ProviderHelper;  import org.sufficientlysecure.keychain.remote.AccountSettings; +import org.sufficientlysecure.keychain.ui.CreateKeyActivity;  import org.sufficientlysecure.keychain.ui.EditKeyActivityOld;  import org.sufficientlysecure.keychain.ui.SelectSecretKeyLayoutFragment;  import org.sufficientlysecure.keychain.ui.adapter.KeyValueSpinnerAdapter; @@ -163,11 +166,11 @@ public class AccountSettingsFragment extends Fragment implements      }      private void createKey() { -        Intent intent = new Intent(getActivity(), EditKeyActivityOld.class); -        intent.setAction(EditKeyActivityOld.ACTION_CREATE_KEY); -        intent.putExtra(EditKeyActivityOld.EXTRA_GENERATE_DEFAULT_KEYS, true); -        // set default user id to account name -        intent.putExtra(EditKeyActivityOld.EXTRA_USER_IDS, mAccSettings.getAccountName()); +        String[] userId = KeyRing.splitUserId(mAccSettings.getAccountName()); + +        Intent intent = new Intent(getActivity(), CreateKeyActivity.class); +        intent.putExtra(CreateKeyActivity.EXTRA_NAME, userId[0]); +        intent.putExtra(CreateKeyActivity.EXTRA_EMAIL, userId[1]);          startActivityForResult(intent, REQUEST_CODE_CREATE_KEY);      } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java index 3cf89f6a4..40e8af72d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyActivity.java @@ -17,233 +17,65 @@  package org.sufficientlysecure.keychain.ui; -import android.app.ProgressDialog; -import android.content.Context; -import android.content.Intent; -import android.net.Uri;  import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction;  import android.support.v7.app.ActionBarActivity; -import android.text.Editable; -import android.text.TextWatcher; -import android.util.Patterns; -import android.view.View; -import android.widget.ArrayAdapter; -import android.widget.AutoCompleteTextView; -import android.widget.Button; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.Spinner; -import com.devspark.appmsg.AppMsg; - -import org.spongycastle.bcpg.sig.KeyFlags; -import org.sufficientlysecure.keychain.Constants;  import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.ContactHelper; -import org.sufficientlysecure.keychain.service.KeychainIntentService; -import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; -import org.sufficientlysecure.keychain.service.SaveKeyringParcel; - -import java.util.regex.Matcher;  public class CreateKeyActivity extends ActionBarActivity { -    AutoCompleteTextView mNameEdit; -    AutoCompleteTextView mEmailEdit; -    EditText mPassphraseEdit; -    View mCreateButton; -    CheckBox mUploadCheckbox; +    public static final String EXTRA_NAME = "name"; +    public static final String EXTRA_EMAIL = "email"; + +    public static final int ANIM_NO = 0; +    public static final int ANIM_TO_RIGHT = 1; +    public static final int ANIM_TO_LEFT = 2;      @Override -    protected void onCreate(Bundle savedInstanceState) { +    public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.create_key_activity); -        mNameEdit = (AutoCompleteTextView) findViewById(R.id.name); -        mEmailEdit = (AutoCompleteTextView) findViewById(R.id.email); -        mPassphraseEdit = (EditText) findViewById(R.id.passphrase); -        mCreateButton = findViewById(R.id.create_key_button); -        mUploadCheckbox = (CheckBox) findViewById(R.id.create_key_upload); - -        mEmailEdit.setThreshold(1); // Start working from first character -        mEmailEdit.setAdapter( -                new ArrayAdapter<String> -                        (this, android.R.layout.simple_spinner_dropdown_item, -                                ContactHelper.getPossibleUserEmails(this) -                        ) -        ); -        mEmailEdit.addTextChangedListener(new TextWatcher() { -            @Override -            public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { -            } - -            @Override -            public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { -            } - -            @Override -            public void afterTextChanged(Editable editable) { -                String email = editable.toString(); -                if (email.length() > 0) { -                    Matcher emailMatcher = Patterns.EMAIL_ADDRESS.matcher(email); -                    if (emailMatcher.matches()) { -                        mEmailEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0, -                                R.drawable.uid_mail_ok, 0); -                    } else { -                        mEmailEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0, -                                R.drawable.uid_mail_bad, 0); -                    } -                } else { -                    // remove drawable if email is empty -                    mEmailEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); -                } -            } -        }); - -        mNameEdit.setThreshold(1); // Start working from first character -        mNameEdit.setAdapter( -                new ArrayAdapter<String> -                        (this, android.R.layout.simple_spinner_dropdown_item, -                                ContactHelper.getPossibleUserNames(this) -                        ) -        ); - -        mCreateButton.setOnClickListener(new View.OnClickListener() { -            @Override -            public void onClick(View v) { -                createKeyCheck(); -            } -        }); - +        // pass extras into fragment +        CreateKeyInputFragment frag = +                CreateKeyInputFragment.newInstance( +                        getIntent().getStringExtra(EXTRA_NAME), +                        getIntent().getStringExtra(EXTRA_EMAIL) +                ); +        loadFragment(null, frag, ANIM_NO);      } -    private void createKeyCheck() { -        if (isEditTextNotEmpty(this, mNameEdit) -                && isEditTextNotEmpty(this, mEmailEdit) -                && isEditTextNotEmpty(this, mPassphraseEdit)) { -            createKey(); +    public void loadFragment(Bundle savedInstanceState, Fragment fragment, int animation) { +        // However, if we're being restored from a previous state, +        // then we don't need to do anything and should return or else +        // we could end up with overlapping fragments. +        if (savedInstanceState != null) { +            return;          } -    } - -    private void createKey() { -        Intent intent = new Intent(this, KeychainIntentService.class); -        intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING); - -        // Message is received after importing is done in KeychainIntentService -        KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( -                this, -                getString(R.string.progress_importing), -                ProgressDialog.STYLE_HORIZONTAL) { -            public void handleMessage(Message message) { -                // handle messages by standard KeychainIntentServiceHandler first -                super.handleMessage(message); - -                // TODO -//                if (mUploadCheckbox.isChecked()) { -//                    uploadKey(); -//                } else { -                    if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { -                        CreateKeyActivity.this.setResult(RESULT_OK); -                        CreateKeyActivity.this.finish(); -                    } -//                } -            } -        }; - -        // fill values for this action -        Bundle data = new Bundle(); - -        SaveKeyringParcel parcel = new SaveKeyringParcel(); -        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.CERTIFY_OTHER, null)); -        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.SIGN_DATA, null)); -        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, null)); -        String userId = mNameEdit.getText().toString() + " <" + mEmailEdit.getText().toString() + ">"; -        parcel.mAddUserIds.add(userId); -        parcel.mNewPassphrase = mPassphraseEdit.getText().toString(); - -        // get selected key entries -        data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, parcel); - -        intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - -        // Create a new Messenger for the communication back -        Messenger messenger = new Messenger(saveHandler); -        intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); -        saveHandler.showProgressDialog(this); - -        startService(intent); -    } - -    private void uploadKey() { -        // Send all information needed to service to upload key in other thread -        Intent intent = new Intent(this, KeychainIntentService.class); - -        intent.setAction(KeychainIntentService.ACTION_UPLOAD_KEYRING); - -        // set data uri as path to keyring -        // TODO -//        Uri blobUri = KeychainContract.KeyRingData.buildPublicKeyRingUri(mDataUri); -//        intent.setData(blobUri); - -        // fill values for this action -        Bundle data = new Bundle(); - -        Spinner keyServer = (Spinner) findViewById(R.id.upload_key_keyserver); -        String server = (String) keyServer.getSelectedItem(); -        data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, server); - -        intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - -        // Message is received after uploading is done in KeychainIntentService -        KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this, -                getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) { -            public void handleMessage(Message message) { -                // handle messages by standard KeychainIntentServiceHandler first -                super.handleMessage(message); - -                if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { -                    AppMsg.makeText(CreateKeyActivity.this, R.string.key_send_success, -                            AppMsg.STYLE_INFO).show(); - -                    CreateKeyActivity.this.setResult(RESULT_OK); -                    CreateKeyActivity.this.finish(); -                } -            } -        }; - -        // Create a new Messenger for the communication back -        Messenger messenger = new Messenger(saveHandler); -        intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); - -        // show progress dialog -        saveHandler.showProgressDialog(this); - -        // start service with intent -        startService(intent); -    } - -    /** -     * Checks if text of given EditText is not empty. If it is empty an error is -     * set and the EditText gets the focus. -     * -     * @param context -     * @param editText -     * @return true if EditText is not empty -     */ -    private static boolean isEditTextNotEmpty(Context context, EditText editText) { -        boolean output = true; -        if (editText.getText().toString().length() == 0) { -            editText.setError(context.getString(R.string.create_key_empty)); -            editText.requestFocus(); -            output = false; -        } else { -            editText.setError(null); +        // Add the fragment to the 'fragment_container' FrameLayout +        // NOTE: We use commitAllowingStateLoss() to prevent weird crashes! +        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); + +        switch (animation) { +            case ANIM_NO: +                transaction.setCustomAnimations(0, 0); +                break; +            case ANIM_TO_LEFT: +                transaction.setCustomAnimations(R.anim.frag_slide_in_from_left, R.anim.frag_slide_out_to_right); +                break; +            case ANIM_TO_RIGHT: +                transaction.setCustomAnimations(R.anim.frag_slide_out_to_left, R.anim.frag_slide_in_from_right); +                transaction.addToBackStack("back"); +                break;          } - -        return output; +        transaction.replace(R.id.create_key_fragment_container, fragment) +                .commitAllowingStateLoss(); +        // do it immediately! +        getSupportFragmentManager().executePendingTransactions();      } +  } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java new file mode 100644 index 000000000..dffdfe448 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyFinalFragment.java @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.ui; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.Bundle; +import android.os.Message; +import android.os.Messenger; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.Spinner; +import android.widget.TextView; + +import com.devspark.appmsg.AppMsg; + +import org.spongycastle.bcpg.sig.KeyFlags; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel; + +public class CreateKeyFinalFragment extends Fragment { + +    CreateKeyActivity mCreateKeyActivity; + +    TextView mNameEdit; +    TextView mEmailEdit; +    CheckBox mUploadCheckbox; +    View mBackButton; +    View mCreateButton; + +    public static final String ARG_NAME = "name"; +    public static final String ARG_EMAIL = "email"; +    public static final String ARG_PASSPHRASE = "passphrase"; + +    String mName; +    String mEmail; +    String mPassphrase; + +    /** +     * Creates new instance of this fragment +     */ +    public static CreateKeyFinalFragment newInstance(String name, String email, String passphrase) { +        CreateKeyFinalFragment frag = new CreateKeyFinalFragment(); + +        Bundle args = new Bundle(); +        args.putString(ARG_NAME, name); +        args.putString(ARG_EMAIL, email); +        args.putString(ARG_PASSPHRASE, passphrase); + +        frag.setArguments(args); + +        return frag; +    } + +    @Override +    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { +        View view = inflater.inflate(R.layout.create_key_final_fragment, container, false); + +        mNameEdit = (TextView) view.findViewById(R.id.name); +        mEmailEdit = (TextView) view.findViewById(R.id.email); +        mUploadCheckbox = (CheckBox) view.findViewById(R.id.create_key_upload); +        mBackButton = view.findViewById(R.id.create_key_back_button); +        mCreateButton = view.findViewById(R.id.create_key_create_button); + +        // get args +        mName = getArguments().getString(ARG_NAME); +        mEmail = getArguments().getString(ARG_EMAIL); +        mPassphrase = getArguments().getString(ARG_PASSPHRASE); + +        // set values +        mNameEdit.setText(mName); +        mEmailEdit.setText(mEmail); + +        mCreateButton.setOnClickListener(new View.OnClickListener() { +            @Override +            public void onClick(View v) { +                createKey(); +            } +        }); + +        mBackButton.setOnClickListener(new View.OnClickListener() { +            @Override +            public void onClick(View v) { +                CreateKeyInputFragment frag = +                        CreateKeyInputFragment.newInstance(mName, mEmail); +                mCreateKeyActivity.loadFragment(null, frag, CreateKeyActivity.ANIM_TO_LEFT); +            } +        }); + +        return view; +    } + +    @Override +    public void onActivityCreated(Bundle savedInstanceState) { +        super.onActivityCreated(savedInstanceState); + +        mCreateKeyActivity = (CreateKeyActivity) getActivity(); +    } + +    private void createKey() { +        Intent intent = new Intent(getActivity(), KeychainIntentService.class); +        intent.setAction(KeychainIntentService.ACTION_SAVE_KEYRING); + +        // Message is received after importing is done in KeychainIntentService +        KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler( +                getActivity(), +                getString(R.string.progress_importing), +                ProgressDialog.STYLE_HORIZONTAL) { +            public void handleMessage(Message message) { +                // handle messages by standard KeychainIntentServiceHandler first +                super.handleMessage(message); + +                // TODO +//                if (mUploadCheckbox.isChecked()) { +//                    uploadKey(); +//                } else { +                if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { +                    getActivity().setResult(Activity.RESULT_OK); +                    getActivity().finish(); +                } +//                } +            } +        }; + +        // fill values for this action +        Bundle data = new Bundle(); + +        SaveKeyringParcel parcel = new SaveKeyringParcel(); +        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.CERTIFY_OTHER, null)); +        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.SIGN_DATA, null)); +        parcel.mAddSubKeys.add(new SaveKeyringParcel.SubkeyAdd(Constants.choice.algorithm.rsa, 4096, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE, null)); +        String userId = mName + " <" + mEmail + ">"; +        parcel.mAddUserIds.add(userId); +        parcel.mNewPassphrase = mPassphrase; + +        // get selected key entries +        data.putParcelable(KeychainIntentService.SAVE_KEYRING_PARCEL, parcel); + +        intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + +        // Create a new Messenger for the communication back +        Messenger messenger = new Messenger(saveHandler); +        intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + +        saveHandler.showProgressDialog(getActivity()); + +        getActivity().startService(intent); +    } + +    private void uploadKey() { +        // Send all information needed to service to upload key in other thread +        Intent intent = new Intent(getActivity(), KeychainIntentService.class); + +        intent.setAction(KeychainIntentService.ACTION_UPLOAD_KEYRING); + +        // set data uri as path to keyring +        // TODO +//        Uri blobUri = KeychainContract.KeyRingData.buildPublicKeyRingUri(mDataUri); +//        intent.setData(blobUri); + +        // fill values for this action +        Bundle data = new Bundle(); + +        Spinner keyServer = (Spinner) getActivity().findViewById(R.id.upload_key_keyserver); +        String server = (String) keyServer.getSelectedItem(); +        data.putString(KeychainIntentService.UPLOAD_KEY_SERVER, server); + +        intent.putExtra(KeychainIntentService.EXTRA_DATA, data); + +        // Message is received after uploading is done in KeychainIntentService +        KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(getActivity(), +                getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) { +            public void handleMessage(Message message) { +                // handle messages by standard KeychainIntentServiceHandler first +                super.handleMessage(message); + +                if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { +                    AppMsg.makeText(getActivity(), R.string.key_send_success, +                            AppMsg.STYLE_INFO).show(); + +                    getActivity().setResult(Activity.RESULT_OK); +                    getActivity().finish(); +                } +            } +        }; + +        // Create a new Messenger for the communication back +        Messenger messenger = new Messenger(saveHandler); +        intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); + +        // show progress dialog +        saveHandler.showProgressDialog(getActivity()); + +        // start service with intent +        getActivity().startService(intent); +    } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java new file mode 100644 index 000000000..78e8af14e --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyInputFragment.java @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de> + * + * This program 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 3 of the License, or + * (at your option) any later version. + * + * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +package org.sufficientlysecure.keychain.ui; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.Message; +import android.os.Messenger; +import android.support.v4.app.Fragment; +import android.text.Editable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.util.Patterns; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; +import android.widget.EditText; +import android.widget.Spinner; + +import com.devspark.appmsg.AppMsg; + +import org.spongycastle.bcpg.sig.KeyFlags; +import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.ContactHelper; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel; + +import java.util.regex.Matcher; + +public class CreateKeyInputFragment extends Fragment { + +    CreateKeyActivity mCreateKeyActivity; + +    AutoCompleteTextView mNameEdit; +    AutoCompleteTextView mEmailEdit; +    EditText mPassphraseEdit; +    View mCreateButton; + +    public static final String ARG_NAME = "name"; +    public static final String ARG_EMAIL = "email"; + +    /** +     * Creates new instance of this fragment +     */ +    public static CreateKeyInputFragment newInstance(String name, String email) { +        CreateKeyInputFragment frag = new CreateKeyInputFragment(); + +        Bundle args = new Bundle(); +        args.putString(ARG_NAME, name); +        args.putString(ARG_EMAIL, email); + +        frag.setArguments(args); + +        return frag; +    } + +    @Override +    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { +        View view = inflater.inflate(R.layout.create_key_input_fragment, container, false); + +        mNameEdit = (AutoCompleteTextView) view.findViewById(R.id.name); +        mEmailEdit = (AutoCompleteTextView) view.findViewById(R.id.email); +        mPassphraseEdit = (EditText) view.findViewById(R.id.passphrase); +        // TODO: second passphrase field +        mCreateButton = view.findViewById(R.id.create_key_button); + +        // initial values +        String name = getArguments().getString(ARG_NAME); +        String email = getArguments().getString(ARG_EMAIL); +        mNameEdit.setText(name); +        mEmailEdit.setText(email); + +        // focus non-empty edit fields +        if (name != null && email != null) { +            mPassphraseEdit.requestFocus(); +        } else if (name != null) { +            mEmailEdit.requestFocus(); +        } + +        mEmailEdit.setThreshold(1); // Start working from first character +        mEmailEdit.setAdapter( +                new ArrayAdapter<String> +                        (getActivity(), android.R.layout.simple_spinner_dropdown_item, +                                ContactHelper.getPossibleUserEmails(getActivity()) +                        ) +        ); +        mEmailEdit.addTextChangedListener(new TextWatcher() { +            @Override +            public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { +            } + +            @Override +            public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { +            } + +            @Override +            public void afterTextChanged(Editable editable) { +                String email = editable.toString(); +                if (email.length() > 0) { +                    Matcher emailMatcher = Patterns.EMAIL_ADDRESS.matcher(email); +                    if (emailMatcher.matches()) { +                        mEmailEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0, +                                R.drawable.uid_mail_ok, 0); +                    } else { +                        mEmailEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0, +                                R.drawable.uid_mail_bad, 0); +                    } +                } else { +                    // remove drawable if email is empty +                    mEmailEdit.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); +                } +            } +        }); + +        mNameEdit.setThreshold(1); // Start working from first character +        mNameEdit.setAdapter( +                new ArrayAdapter<String> +                        (getActivity(), android.R.layout.simple_spinner_dropdown_item, +                                ContactHelper.getPossibleUserNames(getActivity()) +                        ) +        ); + +        mCreateButton.setOnClickListener(new View.OnClickListener() { +            @Override +            public void onClick(View v) { +                createKeyCheck(); +            } +        }); + +        return view; +    } + +    @Override +    public void onActivityCreated(Bundle savedInstanceState) { +        super.onActivityCreated(savedInstanceState); + +        mCreateKeyActivity = (CreateKeyActivity) getActivity(); +    } + + +    private void createKeyCheck() { +        if (isEditTextNotEmpty(getActivity(), mNameEdit) +                && isEditTextNotEmpty(getActivity(), mEmailEdit) +                && isEditTextNotEmpty(getActivity(), mPassphraseEdit)) { + +            CreateKeyFinalFragment frag = +                    CreateKeyFinalFragment.newInstance( +                            mNameEdit.getText().toString(), +                            mEmailEdit.getText().toString(), +                            mPassphraseEdit.getText().toString() +                    ); +            mCreateKeyActivity.loadFragment(null, frag, CreateKeyActivity.ANIM_TO_RIGHT); +        } +    } + +    /** +     * Checks if text of given EditText is not empty. If it is empty an error is +     * set and the EditText gets the focus. +     * +     * @param context +     * @param editText +     * @return true if EditText is not empty +     */ +    private static boolean isEditTextNotEmpty(Context context, EditText editText) { +        boolean output = true; +        if (editText.getText().toString().length() == 0) { +            editText.setError(context.getString(R.string.create_key_empty)); +            editText.requestFocus(); +            output = false; +        } else { +            editText.setError(null); +        } + +        return output; +    } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeActivity.java index f4d395ae6..44416a25a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/QrCodeActivity.java @@ -100,7 +100,7 @@ public class QrCodeActivity extends ActionBarActivity {          super.onResume();          // custom activity transition to get zoom in effect -        this.overridePendingTransition(R.anim.zoom_enter, android.R.anim.fade_out); +        this.overridePendingTransition(R.anim.qr_code_zoom_enter, android.R.anim.fade_out);      }      @Override @@ -108,7 +108,7 @@ public class QrCodeActivity extends ActionBarActivity {          super.onPause();          // custom activity transition to get zoom out effect -        this.overridePendingTransition(0, R.anim.zoom_exit); +        this.overridePendingTransition(0, R.anim.qr_code_zoom_exit);      }  }
\ No newline at end of file diff --git a/OpenKeychain/src/main/res/anim/frag_slide_in_from_left.xml b/OpenKeychain/src/main/res/anim/frag_slide_in_from_left.xml new file mode 100644 index 000000000..4a021c676 --- /dev/null +++ b/OpenKeychain/src/main/res/anim/frag_slide_in_from_left.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<set> +    <translate xmlns:android="http://schemas.android.com/apk/res/android" +        android:fromXDelta="-100%" +        android:toXDelta="0" +        android:interpolator="@android:anim/decelerate_interpolator" +        android:duration="500" /> +</set>
\ No newline at end of file diff --git a/OpenKeychain/src/main/res/anim/frag_slide_in_from_right.xml b/OpenKeychain/src/main/res/anim/frag_slide_in_from_right.xml new file mode 100644 index 000000000..1329f8bef --- /dev/null +++ b/OpenKeychain/src/main/res/anim/frag_slide_in_from_right.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<set> +    <translate xmlns:android="http://schemas.android.com/apk/res/android" +        android:fromXDelta="100%" +        android:toXDelta="0" +        android:interpolator="@android:anim/decelerate_interpolator" +        android:duration="500" /> +</set>
\ No newline at end of file diff --git a/OpenKeychain/src/main/res/anim/frag_slide_out_to_left.xml b/OpenKeychain/src/main/res/anim/frag_slide_out_to_left.xml new file mode 100644 index 000000000..4e02af2a4 --- /dev/null +++ b/OpenKeychain/src/main/res/anim/frag_slide_out_to_left.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<set> +    <translate xmlns:android="http://schemas.android.com/apk/res/android" +        android:fromXDelta="0" +        android:toXDelta="-100%" +        android:interpolator="@android:anim/decelerate_interpolator" +        android:duration="500" /> +</set>
\ No newline at end of file diff --git a/OpenKeychain/src/main/res/anim/frag_slide_out_to_right.xml b/OpenKeychain/src/main/res/anim/frag_slide_out_to_right.xml new file mode 100644 index 000000000..7b5f63e0d --- /dev/null +++ b/OpenKeychain/src/main/res/anim/frag_slide_out_to_right.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<set> +    <translate xmlns:android="http://schemas.android.com/apk/res/android" +        android:fromXDelta="0" +        android:toXDelta="100%" +        android:interpolator="@android:anim/decelerate_interpolator" +        android:duration="500" /> +</set>
\ No newline at end of file diff --git a/OpenKeychain/src/main/res/anim/zoom_enter.xml b/OpenKeychain/src/main/res/anim/qr_code_zoom_enter.xml index 2b95cfba6..2b95cfba6 100644 --- a/OpenKeychain/src/main/res/anim/zoom_enter.xml +++ b/OpenKeychain/src/main/res/anim/qr_code_zoom_enter.xml diff --git a/OpenKeychain/src/main/res/anim/zoom_exit.xml b/OpenKeychain/src/main/res/anim/qr_code_zoom_exit.xml index 772375739..772375739 100644 --- a/OpenKeychain/src/main/res/anim/zoom_exit.xml +++ b/OpenKeychain/src/main/res/anim/qr_code_zoom_exit.xml diff --git a/OpenKeychain/src/main/res/layout/create_key_activity.xml b/OpenKeychain/src/main/res/layout/create_key_activity.xml index 9d56950a8..1e1d0ab9e 100644 --- a/OpenKeychain/src/main/res/layout/create_key_activity.xml +++ b/OpenKeychain/src/main/res/layout/create_key_activity.xml @@ -1,84 +1,13 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" -    android:layout_width="wrap_content" +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +    android:orientation="vertical" +    android:layout_width="match_parent"      android:layout_height="match_parent"> -    <LinearLayout +    <FrameLayout +        android:id="@+id/create_key_fragment_container"          android:layout_width="match_parent" -        android:layout_height="wrap_content" -        android:paddingLeft="16dp" -        android:paddingRight="16dp" -        android:orientation="vertical"> +        android:layout_height="match_parent" +        android:orientation="vertical" /> -        <TextView -            android:layout_width="match_parent" -            android:layout_height="wrap_content" -            android:paddingTop="16dp" -            android:paddingBottom="8dp" -            android:text="@string/create_key_text" -            android:textAppearance="?android:attr/textAppearanceMedium" /> - -        <AutoCompleteTextView -            android:layout_width="match_parent" -            android:layout_height="wrap_content" -            android:layout_marginBottom="8dp" -            android:imeOptions="actionNext" -            android:inputType="textPersonName" -            android:hint="@string/label_name" -            android:ems="10" -            android:id="@+id/name" /> - -        <AutoCompleteTextView -            android:id="@+id/email" -            android:layout_width="match_parent" -            android:layout_height="wrap_content" -            android:layout_marginBottom="8dp" -            android:imeOptions="actionNext" -            android:hint="@string/label_email" -            android:ems="10" -            android:inputType="textEmailAddress" /> - -        <EditText -            android:layout_width="match_parent" -            android:layout_height="wrap_content" -            android:layout_marginBottom="8dp" -            android:inputType="textPassword" -            android:hint="@string/label_passphrase" -            android:ems="10" -            android:id="@+id/passphrase" -            android:layout_gravity="center_horizontal" /> - -        <CheckBox -            android:layout_width="match_parent" -            android:layout_height="wrap_content" -            android:layout_marginBottom="8dp" -            android:text="@string/create_key_upload" -            android:id="@+id/create_key_upload" /> - -        <View -            android:layout_width="match_parent" -            android:layout_height="1dip" -            android:background="?android:attr/listDivider" /> - -        <TextView -            android:id="@+id/create_key_button" -            android:paddingLeft="8dp" -            android:paddingRight="8dp" -            android:textAppearance="?android:attr/textAppearanceMedium" -            android:layout_width="match_parent" -            android:layout_height="match_parent" -            android:text="@string/first_time_create_key" -            android:minHeight="?android:attr/listPreferredItemHeight" -            android:drawableRight="@drawable/ic_action_new_account" -            android:drawablePadding="8dp" -            android:gravity="center_vertical" -            android:clickable="true" -            style="@style/SelectableItem" /> - -        <View -            android:layout_width="match_parent" -            android:layout_height="1dip" -            android:background="?android:attr/listDivider" /> - -    </LinearLayout> -</ScrollView>
\ No newline at end of file +</LinearLayout>
\ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml b/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml new file mode 100644 index 000000000..57ba4ea75 --- /dev/null +++ b/OpenKeychain/src/main/res/layout/create_key_final_fragment.xml @@ -0,0 +1,130 @@ +<?xml version="1.0" encoding="UTF-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" +    android:layout_width="wrap_content" +    android:layout_height="match_parent"> + +    <ScrollView +        android:layout_width="match_parent" +        android:layout_height="match_parent"> + +        <LinearLayout +            android:layout_width="match_parent" +            android:layout_height="wrap_content" +            android:paddingLeft="16dp" +            android:paddingRight="16dp" +            android:orientation="vertical"> + +            <TextView +                android:layout_width="match_parent" +                android:layout_height="wrap_content" +                android:paddingTop="16dp" +                android:paddingBottom="8dp" +                android:text="You entered the following credentials:" +                android:textAppearance="?android:attr/textAppearanceMedium" /> + +            <TextView +                android:layout_width="match_parent" +                android:layout_height="wrap_content" +                android:layout_marginBottom="2dp" +                android:text="Name" +                android:textColor="@color/tertiary_text_light" +                android:textAppearance="?android:attr/textAppearanceSmall" /> + +            <TextView +                android:id="@+id/name" +                android:layout_width="match_parent" +                android:layout_height="wrap_content" +                android:layout_marginBottom="8dp" +                android:layout_marginLeft="8dp" +                android:text="Max Mustermann" +                android:textAppearance="?android:attr/textAppearanceMedium" /> + +            <TextView +                android:layout_width="match_parent" +                android:layout_height="wrap_content" +                android:layout_marginBottom="2dp" +                android:text="Email" +                android:textColor="@color/tertiary_text_light" +                android:textAppearance="?android:attr/textAppearanceSmall" /> + +            <TextView +                android:id="@+id/email" +                android:layout_width="match_parent" +                android:layout_height="wrap_content" +                android:text="max@musterman.com" +                android:textAppearance="?android:attr/textAppearanceMedium" +                android:layout_marginBottom="32dp" +                android:layout_marginLeft="8dp" /> + +            <CheckBox +                android:layout_width="match_parent" +                android:layout_height="wrap_content" +                android:layout_marginBottom="8dp" +                android:textAppearance="?android:attr/textAppearanceMedium" +                android:text="@string/create_key_upload" +                android:id="@+id/create_key_upload" /> + +        </LinearLayout> +    </ScrollView> + +    <LinearLayout +        android:layout_width="match_parent" +        android:layout_height="wrap_content" +        android:orientation="horizontal" +        android:layout_alignParentBottom="true" +        android:layout_alignParentLeft="true" +        android:layout_alignParentStart="true" +        android:layout_marginLeft="16dp" +        android:layout_marginRight="16dp" +        android:id="@+id/linearLayout2"> + +        <TextView +            android:id="@+id/create_key_back_button" +            android:paddingLeft="8dp" +            android:paddingRight="8dp" +            android:textAppearance="?android:attr/textAppearanceMedium" +            android:layout_width="match_parent" +            android:layout_height="wrap_content" +            android:layout_weight="1" +            android:text="back" +            android:minHeight="?android:attr/listPreferredItemHeight" +            android:gravity="center_vertical" +            android:clickable="true" +            style="@style/SelectableItem" +            android:layout_gravity="center_vertical"/> + +        <View +            android:layout_width="1dp" +            android:layout_height="match_parent" +            android:layout_marginTop="8dp" +            android:layout_marginBottom="8dp" +            android:background="?android:attr/listDivider" /> + +        <TextView +            android:id="@+id/create_key_create_button" +            android:paddingLeft="8dp" +            android:paddingRight="8dp" +            android:textAppearance="?android:attr/textAppearanceMedium" +            android:layout_width="match_parent" +            android:layout_height="wrap_content" +            android:layout_weight="1" +            android:text="@string/title_create_key" +            android:minHeight="?android:attr/listPreferredItemHeight" +            android:drawableRight="@drawable/ic_action_new_account" +            android:drawablePadding="8dp" +            android:gravity="center_vertical" +            android:clickable="true" +            style="@style/SelectableItem" +            android:layout_gravity="center_vertical" /> +    </LinearLayout> + +    <View +        android:layout_width="match_parent" +        android:layout_height="1dip" +        android:background="?android:attr/listDivider" +        android:layout_alignTop="@+id/linearLayout2" +        android:layout_marginLeft="16dp" +        android:layout_marginRight="16dp" +        android:layout_alignParentLeft="true" +        android:layout_alignParentStart="true" /> +</RelativeLayout>
\ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/create_key_input_fragment.xml b/OpenKeychain/src/main/res/layout/create_key_input_fragment.xml new file mode 100644 index 000000000..739323019 --- /dev/null +++ b/OpenKeychain/src/main/res/layout/create_key_input_fragment.xml @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="UTF-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" +    android:layout_width="wrap_content" +    android:layout_height="match_parent"> + +    <ScrollView +        android:layout_width="match_parent" +        android:layout_height="match_parent" +        android:fillViewport="false"> + +        <LinearLayout +            android:layout_width="match_parent" +            android:layout_height="wrap_content" +            android:paddingLeft="16dp" +            android:paddingRight="16dp" +            android:orientation="vertical"> + +            <TextView +                android:layout_width="match_parent" +                android:layout_height="wrap_content" +                android:paddingTop="16dp" +                android:paddingBottom="8dp" +                android:text="@string/create_key_text" +                android:textAppearance="?android:attr/textAppearanceMedium" /> + +            <AutoCompleteTextView +                android:layout_width="match_parent" +                android:layout_height="wrap_content" +                android:layout_marginBottom="8dp" +                android:imeOptions="actionNext" +                android:inputType="textPersonName" +                android:hint="@string/label_name" +                android:ems="10" +                android:id="@+id/name" /> + +            <AutoCompleteTextView +                android:id="@+id/email" +                android:layout_width="match_parent" +                android:layout_height="wrap_content" +                android:layout_marginBottom="8dp" +                android:imeOptions="actionNext" +                android:hint="@string/label_email" +                android:ems="10" +                android:inputType="textEmailAddress" /> + +            <EditText +                android:layout_width="match_parent" +                android:layout_height="wrap_content" +                android:layout_marginBottom="8dp" +                android:inputType="textPassword" +                android:hint="@string/label_passphrase" +                android:ems="10" +                android:id="@+id/passphrase" +                android:layout_gravity="center_horizontal" /> + + +        </LinearLayout> +    </ScrollView> + +    <View +        android:layout_width="match_parent" +        android:layout_height="1dip" +        android:layout_marginLeft="16dp" +        android:layout_marginRight="16dp" +        android:background="?android:attr/listDivider" +        android:layout_alignTop="@+id/create_key_button" +        android:layout_alignParentLeft="true" +        android:layout_alignParentStart="true" /> + +    <TextView +        android:id="@+id/create_key_button" +        android:paddingLeft="8dp" +        android:paddingRight="8dp" +        android:layout_marginLeft="16dp" +        android:layout_marginRight="16dp" +        android:textAppearance="?android:attr/textAppearanceMedium" +        android:layout_width="match_parent" +        android:layout_height="wrap_content" +        android:text="@string/first_time_create_key" +        android:minHeight="?android:attr/listPreferredItemHeight" +        android:drawableRight="@drawable/ic_action_new_account" +        android:drawablePadding="8dp" +        android:gravity="center_vertical" +        android:clickable="true" +        style="@style/SelectableItem" +        android:layout_alignParentBottom="true" +        android:layout_alignParentLeft="true" +        android:layout_alignParentStart="true" /> + +</RelativeLayout>
\ No newline at end of file | 
