diff options
author | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-04-06 12:57:42 +0200 |
---|---|---|
committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2014-04-06 12:57:42 +0200 |
commit | 6d1137190529dc7add74926cea52c377883319be (patch) | |
tree | fd88b29a048f3aec1daa2a84bbaf22c0efa3663f /OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget | |
parent | 17997dd362fe62d72113a0536069d0fdb9c3211b (diff) | |
download | open-keychain-6d1137190529dc7add74926cea52c377883319be.tar.gz open-keychain-6d1137190529dc7add74926cea52c377883319be.tar.bz2 open-keychain-6d1137190529dc7add74926cea52c377883319be.zip |
Rename folder structure from OpenPGP Keychain to OpenKeychain
Diffstat (limited to 'OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget')
9 files changed, 0 insertions, 1601 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/Editor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/Editor.java deleted file mode 100644 index 7b21c189d..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/Editor.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2010 Thialfihar <thi@thialfihar.org> - * - * 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. - */ - -package org.sufficientlysecure.keychain.ui.widget; - -public interface Editor { - public interface EditorListener { - public void onDeleted(Editor editor, boolean wasNewItem); - public void onEdited(); - } - - public void setEditorListener(EditorListener listener); - public boolean needsSaving(); -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FixedListView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FixedListView.java deleted file mode 100644 index da29f808a..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FixedListView.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.ListView; - -/** - * Automatically calculate height of ListView based on contained items. This enables to put this - * ListView into a ScrollView without messing up. - * <p/> - * from - * http://stackoverflow.com/questions/2419246/how-do-i-create-a-listview-thats-not-in-a-scrollview- - * or-has-the-scrollview-dis - */ -public class FixedListView extends ListView { - - public FixedListView(Context context) { - super(context); - } - - public FixedListView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - public FixedListView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - // Calculate height of the entire list by providing a very large - // height hint. But do not use the highest 2 bits of this integer; - // those are reserved for the MeasureSpec mode. - int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); - super.onMeasure(widthMeasureSpec, expandSpec); - } - -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java deleted file mode 100644 index 6b2f3bf06..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/FoldableLinearLayout.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * 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.widget; - -import android.content.Context; -import android.content.res.TypedArray; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.animation.AlphaAnimation; -import android.view.animation.Animation; -import android.widget.LinearLayout; -import android.widget.TextView; -import com.beardedhen.androidbootstrap.FontAwesomeText; -import org.sufficientlysecure.keychain.R; - -/** - * Class representing a LinearLayout that can fold and hide it's content when pressed - * To use just add the following to your xml layout - - <org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout - android:layout_width="wrap_content" - android:layout_height="wrap_content" - custom:foldedLabel="@string/TEXT_TO_DISPLAY_WHEN_FOLDED" - custom:unFoldedLabel="@string/TEXT_TO_DISPLAY_WHEN_UNFOLDED" - custom:foldedIcon="ICON_NAME_FROM_FontAwesomeText_TO_USE_WHEN_FOLDED" - custom:unFoldedIcon="ICON_NAME_FROM_FontAwesomeText_TO_USE_WHEN_UNFOLDED"> - - <include layout="@layout/ELEMENTS_TO_BE_FOLDED"/> - - </org.sufficientlysecure.keychain.ui.widget.FoldableLinearLayout> - - */ -public class FoldableLinearLayout extends LinearLayout { - - private FontAwesomeText mFoldableIcon; - private boolean mFolded; - private boolean mHasMigrated = false; - private Integer mShortAnimationDuration = null; - private TextView mFoldableTextView = null; - private LinearLayout mFoldableContainer = null; - private View mFoldableLayout = null; - - private String mFoldedIconName; - private String mUnFoldedIconName; - private String mFoldedLabel; - private String mUnFoldedLabel; - - public FoldableLinearLayout(Context context) { - super(context); - processAttributes(context, null); - } - - public FoldableLinearLayout(Context context, AttributeSet attrs) { - super(context, attrs); - processAttributes(context, attrs); - } - - public FoldableLinearLayout(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs); - processAttributes(context, attrs); - } - - /** - * Load given attributes to inner variables, - * @param context - * @param attrs - */ - private void processAttributes(Context context, AttributeSet attrs) { - if (attrs != null) { - TypedArray a = context.obtainStyledAttributes(attrs, - R.styleable.FoldableLinearLayout, 0, 0); - mFoldedIconName = a.getString(R.styleable.FoldableLinearLayout_foldedIcon); - mUnFoldedIconName = a.getString(R.styleable.FoldableLinearLayout_unFoldedIcon); - mFoldedLabel = a.getString(R.styleable.FoldableLinearLayout_foldedLabel); - mUnFoldedLabel = a.getString(R.styleable.FoldableLinearLayout_unFoldedLabel); - a.recycle(); - } - // If any attribute isn't found then set a default one - mFoldedIconName = (mFoldedIconName == null) ? "fa-chevron-right" : mFoldedIconName; - mUnFoldedIconName = (mUnFoldedIconName == null) ? "fa-chevron-down" : mUnFoldedIconName; - mFoldedLabel = (mFoldedLabel == null) ? context.getString(R.id.none) : mFoldedLabel; - mUnFoldedLabel = (mUnFoldedLabel == null) ? context.getString(R.id.none) : mUnFoldedLabel; - } - - @Override - protected void onFinishInflate() { - // if the migration has already happened - // there is no need to move any children - if (!mHasMigrated) { - migrateChildrenToContainer(); - mHasMigrated = true; - } - - initialiseInnerViews(); - - super.onFinishInflate(); - } - - /** - * Migrates Child views as declared in xml to the inner foldableContainer - */ - private void migrateChildrenToContainer() { - // Collect children of FoldableLinearLayout as declared in XML - int childNum = getChildCount(); - View[] children = new View[childNum]; - - for (int i = 0; i < childNum; i++) { - children[i] = getChildAt(i); - } - if (children[0].getId() == R.id.foldableControl) { - - } - - // remove all of them from FoldableLinearLayout - detachAllViewsFromParent(); - - // Inflate the inner foldable_linearlayout.xml - LayoutInflater inflator = (LayoutInflater) getContext().getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - - mFoldableLayout = inflator.inflate(R.layout.foldable_linearlayout, this, true); - mFoldableContainer = (LinearLayout) mFoldableLayout.findViewById(R.id.foldableContainer); - - // Push previously collected children into foldableContainer. - for (int i = 0; i < childNum; i++) { - addView(children[i]); - } - } - - private void initialiseInnerViews() { - mFoldableIcon = (FontAwesomeText) mFoldableLayout.findViewById(R.id.foldableIcon); - mFoldableIcon.setIcon(mFoldedIconName); - mFoldableTextView = (TextView) mFoldableLayout.findViewById(R.id.foldableText); - mFoldableTextView.setText(mFoldedLabel); - - // retrieve and cache the system's short animation time - mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime); - - LinearLayout foldableControl = (LinearLayout) mFoldableLayout.findViewById(R.id.foldableControl); - foldableControl.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - mFolded = !mFolded; - if (mFolded) { - mFoldableIcon.setIcon(mUnFoldedIconName); - mFoldableContainer.setVisibility(View.VISIBLE); - AlphaAnimation animation = new AlphaAnimation(0f, 1f); - animation.setDuration(mShortAnimationDuration); - mFoldableContainer.startAnimation(animation); - mFoldableTextView.setText(mUnFoldedLabel); - - } else { - mFoldableIcon.setIcon(mFoldedIconName); - AlphaAnimation animation = new AlphaAnimation(1f, 0f); - animation.setDuration(mShortAnimationDuration); - animation.setAnimationListener(new Animation.AnimationListener() { - @Override - public void onAnimationStart(Animation animation) { } - - @Override - public void onAnimationEnd(Animation animation) { - // making sure that at the end the container is completely removed from view - mFoldableContainer.setVisibility(View.GONE); - } - - @Override - public void onAnimationRepeat(Animation animation) { } - }); - mFoldableContainer.startAnimation(animation); - mFoldableTextView.setText(mFoldedLabel); - } - } - }); - - } - - /** - * Adds provided child view to foldableContainer View - * @param child - */ - @Override - public void addView(View child) { - if (mFoldableContainer != null) { - mFoldableContainer.addView(child); - } - } -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/IntegerListPreference.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/IntegerListPreference.java deleted file mode 100644 index 6e1e4c678..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/IntegerListPreference.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2010 Google Inc. - * - * 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. - */ - -package org.sufficientlysecure.keychain.ui.widget; - -import android.content.Context; -import android.preference.ListPreference; -import android.util.AttributeSet; - -/** - * A list preference which persists its values as integers instead of strings. Code reading the - * values should use {@link android.content.SharedPreferences#getInt}. When using XML-declared - * arrays for entry values, the arrays should be regular string arrays containing valid integer - * values. - * - * @author Rodrigo Damazio - */ -public class IntegerListPreference extends ListPreference { - - public IntegerListPreference(Context context) { - super(context); - - verifyEntryValues(null); - } - - public IntegerListPreference(Context context, AttributeSet attrs) { - super(context, attrs); - - verifyEntryValues(null); - } - - @Override - public void setEntryValues(CharSequence[] entryValues) { - CharSequence[] oldValues = getEntryValues(); - super.setEntryValues(entryValues); - verifyEntryValues(oldValues); - } - - @Override - public void setEntryValues(int entryValuesResId) { - CharSequence[] oldValues = getEntryValues(); - super.setEntryValues(entryValuesResId); - verifyEntryValues(oldValues); - } - - @Override - protected String getPersistedString(String defaultReturnValue) { - // During initial load, there's no known default value - int defaultIntegerValue = Integer.MIN_VALUE; - if (defaultReturnValue != null) { - defaultIntegerValue = Integer.parseInt(defaultReturnValue); - } - - // When the list preference asks us to read a string, instead read an - // integer. - int value = getPersistedInt(defaultIntegerValue); - return Integer.toString(value); - } - - @Override - protected boolean persistString(String value) { - // When asked to save a string, instead save an integer - return persistInt(Integer.parseInt(value)); - } - - private void verifyEntryValues(CharSequence[] oldValues) { - CharSequence[] entryValues = getEntryValues(); - if (entryValues == null) { - return; - } - - for (CharSequence entryValue : entryValues) { - try { - Integer.parseInt(entryValue.toString()); - } catch (NumberFormatException nfe) { - super.setEntryValues(oldValues); - throw nfe; - } - } - } -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java deleted file mode 100644 index c7bd1c987..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (C) 2010 Thialfihar <thi@thialfihar.org> - * - * 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. - */ - -package org.sufficientlysecure.keychain.ui.widget; - -import android.annotation.TargetApi; -import android.app.DatePickerDialog; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.text.format.DateUtils; -import android.util.AttributeSet; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.DatePicker; -import android.widget.LinearLayout; -import android.widget.TableLayout; -import android.widget.TableRow; -import android.widget.TextView; - -import com.beardedhen.androidbootstrap.BootstrapButton; - -import org.spongycastle.bcpg.sig.KeyFlags; -import org.spongycastle.openpgp.PGPPublicKey; -import org.spongycastle.openpgp.PGPSecretKey; - -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.util.Choice; - -import java.text.DateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.TimeZone; -import java.util.Vector; - -public class KeyEditor extends LinearLayout implements Editor, OnClickListener { - private PGPSecretKey mKey; - - private EditorListener mEditorListener = null; - - private boolean mIsMasterKey; - BootstrapButton mDeleteButton; - TextView mAlgorithm; - TextView mKeyId; - TextView mCreationDate; - BootstrapButton mExpiryDateButton; - GregorianCalendar mCreatedDate; - GregorianCalendar mExpiryDate; - GregorianCalendar mOriginalExpiryDate = null; - CheckBox mChkCertify; - CheckBox mChkSign; - CheckBox mChkEncrypt; - CheckBox mChkAuthenticate; - int mUsage; - int mOriginalUsage; - boolean mIsNewKey; - - private CheckBox.OnCheckedChangeListener mCheckChanged = new CheckBox.OnCheckedChangeListener() - { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) - { - if (mEditorListener != null) { - mEditorListener.onEdited(); - } - } - }; - - - private int mDatePickerResultCount = 0; - private DatePickerDialog.OnDateSetListener mExpiryDateSetListener = - new DatePickerDialog.OnDateSetListener() { - public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { - // Note: Ignore results after the first one - android sends multiples. - if (mDatePickerResultCount++ == 0) { - GregorianCalendar date = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - date.set(year, monthOfYear, dayOfMonth); - if (mOriginalExpiryDate != null) { - long numDays = (date.getTimeInMillis() / 86400000) - - (mOriginalExpiryDate.getTimeInMillis() / 86400000); - if (numDays == 0) { - setExpiryDate(mOriginalExpiryDate); - } else { - setExpiryDate(date); - } - } else { - setExpiryDate(date); - } - if (mEditorListener != null) { - mEditorListener.onEdited(); - } - } - } - }; - - public KeyEditor(Context context) { - super(context); - } - - public KeyEditor(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void onFinishInflate() { - setDrawingCacheEnabled(true); - setAlwaysDrawnWithCacheEnabled(true); - - mAlgorithm = (TextView) findViewById(R.id.algorithm); - mKeyId = (TextView) findViewById(R.id.keyId); - mCreationDate = (TextView) findViewById(R.id.creation); - mExpiryDateButton = (BootstrapButton) findViewById(R.id.expiry); - - mDeleteButton = (BootstrapButton) findViewById(R.id.delete); - mDeleteButton.setOnClickListener(this); - mChkCertify = (CheckBox) findViewById(R.id.chkCertify); - mChkCertify.setOnCheckedChangeListener(mCheckChanged); - mChkSign = (CheckBox) findViewById(R.id.chkSign); - mChkSign.setOnCheckedChangeListener(mCheckChanged); - mChkEncrypt = (CheckBox) findViewById(R.id.chkEncrypt); - mChkEncrypt.setOnCheckedChangeListener(mCheckChanged); - mChkAuthenticate = (CheckBox) findViewById(R.id.chkAuthenticate); - mChkAuthenticate.setOnCheckedChangeListener(mCheckChanged); - - setExpiryDate(null); - - mExpiryDateButton.setOnClickListener(new OnClickListener() { - @TargetApi(11) - public void onClick(View v) { - GregorianCalendar date = mExpiryDate; - if (date == null) { - date = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - } - /* - * Using custom DatePickerDialog which overrides the setTitle because - * the DatePickerDialog title is buggy (unix warparound bug). - * See: https://code.google.com/p/android/issues/detail?id=49066 - */ - DatePickerDialog dialog = new ExpiryDatePickerDialog(getContext(), - mExpiryDateSetListener, date.get(Calendar.YEAR), date.get(Calendar.MONTH), - date.get(Calendar.DAY_OF_MONTH)); - mDatePickerResultCount = 0; - dialog.setCancelable(true); - dialog.setButton(Dialog.BUTTON_NEGATIVE, - getContext().getString(R.string.btn_no_date), - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - // Note: Ignore results after the first one - android sends multiples. - if (mDatePickerResultCount++ == 0) { - setExpiryDate(null); - if (mEditorListener != null) { - mEditorListener.onEdited(); - } - } - } - }); - - // setCalendarViewShown() is supported from API 11 onwards. - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { - // Hide calendarView in tablets because of the unix warparound bug. - dialog.getDatePicker().setCalendarViewShown(false); - } - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { - if (dialog != null && mCreatedDate != null) { - dialog.getDatePicker() - .setMinDate( - mCreatedDate.getTime().getTime() + DateUtils.DAY_IN_MILLIS); - } else { - //When created date isn't available - dialog.getDatePicker().setMinDate(date.getTime().getTime() + DateUtils.DAY_IN_MILLIS); - } - } - - dialog.show(); - } - }); - - super.onFinishInflate(); - } - - public void setCanBeEdited(boolean canBeEdited) { - if (!canBeEdited) { - mDeleteButton.setVisibility(View.INVISIBLE); - mExpiryDateButton.setEnabled(false); - mChkSign.setEnabled(false); //certify is always disabled - mChkEncrypt.setEnabled(false); - mChkAuthenticate.setEnabled(false); - } - } - - public void setValue(PGPSecretKey key, boolean isMasterKey, int usage, boolean isNewKey) { - mKey = key; - - mIsMasterKey = isMasterKey; - if (mIsMasterKey) { - mDeleteButton.setVisibility(View.INVISIBLE); - } - - mAlgorithm.setText(PgpKeyHelper.getAlgorithmInfo(key)); - String keyIdStr = PgpKeyHelper.convertKeyIdToHex(key.getKeyID()); - mKeyId.setText(keyIdStr); - - Vector<Choice> choices = new Vector<Choice>(); - boolean isElGamalKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT); - boolean isDSAKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.DSA); - if (isElGamalKey) { - mChkSign.setVisibility(View.INVISIBLE); - TableLayout table = (TableLayout) findViewById(R.id.table_keylayout); - TableRow row = (TableRow) findViewById(R.id.row_sign); - table.removeView(row); - } - if (isDSAKey) { - mChkEncrypt.setVisibility(View.INVISIBLE); - TableLayout table = (TableLayout) findViewById(R.id.table_keylayout); - TableRow row = (TableRow) findViewById(R.id.row_encrypt); - table.removeView(row); - } - if (!mIsMasterKey) { - mChkCertify.setVisibility(View.INVISIBLE); - TableLayout table = (TableLayout) findViewById(R.id.table_keylayout); - TableRow row = (TableRow) findViewById(R.id.row_certify); - table.removeView(row); - } else { - TextView mLabelUsage2 = (TextView) findViewById(R.id.label_usage2); - mLabelUsage2.setVisibility(View.INVISIBLE); - } - - int selectId = 0; - mIsNewKey = isNewKey; - if (isNewKey) { - mUsage = usage; - mChkCertify.setChecked((usage & KeyFlags.CERTIFY_OTHER) == KeyFlags.CERTIFY_OTHER); - mChkSign.setChecked((usage & KeyFlags.SIGN_DATA) == KeyFlags.SIGN_DATA); - mChkEncrypt.setChecked(((usage & KeyFlags.ENCRYPT_COMMS) == KeyFlags.ENCRYPT_COMMS) || - ((usage & KeyFlags.ENCRYPT_STORAGE) == KeyFlags.ENCRYPT_STORAGE)); - mChkAuthenticate.setChecked((usage & KeyFlags.AUTHENTICATION) == KeyFlags.AUTHENTICATION); - } else { - mUsage = PgpKeyHelper.getKeyUsage(key); - mOriginalUsage = mUsage; - if (key.isMasterKey()) { - mChkCertify.setChecked(PgpKeyHelper.isCertificationKey(key)); - } - mChkSign.setChecked(PgpKeyHelper.isSigningKey(key)); - mChkEncrypt.setChecked(PgpKeyHelper.isEncryptionKey(key)); - mChkAuthenticate.setChecked(PgpKeyHelper.isAuthenticationKey(key)); - } - - GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - cal.setTime(PgpKeyHelper.getCreationDate(key)); - setCreatedDate(cal); - cal = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - Date expiryDate = PgpKeyHelper.getExpiryDate(key); - if (expiryDate == null) { - setExpiryDate(null); - } else { - cal.setTime(PgpKeyHelper.getExpiryDate(key)); - setExpiryDate(cal); - mOriginalExpiryDate = cal; - } - - } - - public PGPSecretKey getValue() { - return mKey; - } - - public void onClick(View v) { - final ViewGroup parent = (ViewGroup) getParent(); - if (v == mDeleteButton) { - parent.removeView(this); - if (mEditorListener != null) { - mEditorListener.onDeleted(this, mIsNewKey); - } - } - } - - public void setEditorListener(EditorListener listener) { - mEditorListener = listener; - } - - private void setCreatedDate(GregorianCalendar date) { - mCreatedDate = date; - if (date == null) { - mCreationDate.setText(getContext().getString(R.string.none)); - } else { - mCreationDate.setText(DateFormat.getDateInstance().format(date.getTime())); - } - } - - private void setExpiryDate(GregorianCalendar date) { - mExpiryDate = date; - if (date == null) { - mExpiryDateButton.setText(getContext().getString(R.string.none)); - } else { - mExpiryDateButton.setText(DateFormat.getDateInstance().format(date.getTime())); - } - } - - public GregorianCalendar getExpiryDate() { - return mExpiryDate; - } - - public int getUsage() { - mUsage = (mUsage & ~KeyFlags.CERTIFY_OTHER) | - (mChkCertify.isChecked() ? KeyFlags.CERTIFY_OTHER : 0); - mUsage = (mUsage & ~KeyFlags.SIGN_DATA) | - (mChkSign.isChecked() ? KeyFlags.SIGN_DATA : 0); - mUsage = (mUsage & ~KeyFlags.ENCRYPT_COMMS) | - (mChkEncrypt.isChecked() ? KeyFlags.ENCRYPT_COMMS : 0); - mUsage = (mUsage & ~KeyFlags.ENCRYPT_STORAGE) | - (mChkEncrypt.isChecked() ? KeyFlags.ENCRYPT_STORAGE : 0); - mUsage = (mUsage & ~KeyFlags.AUTHENTICATION) | - (mChkAuthenticate.isChecked() ? KeyFlags.AUTHENTICATION : 0); - - return mUsage; - } - - public boolean needsSaving() { - if (mIsNewKey) { - return true; - } - - boolean retval = (getUsage() != mOriginalUsage); - - boolean dateChanged; - boolean mOEDNull = (mOriginalExpiryDate == null); - boolean mEDNull = (mExpiryDate == null); - if (mOEDNull != mEDNull) { - dateChanged = true; - } else { - if (mOEDNull) { - //both null, no change - dateChanged = false; - } else { - dateChanged = ((mExpiryDate.compareTo(mOriginalExpiryDate)) != 0); - } - } - retval |= dateChanged; - - return retval; - } - - public boolean getIsNewKey() { - return mIsNewKey; - } -} - -class ExpiryDatePickerDialog extends DatePickerDialog { - - public ExpiryDatePickerDialog(Context context, OnDateSetListener callBack, - int year, int monthOfYear, int dayOfMonth) { - super(context, callBack, year, monthOfYear, dayOfMonth); - } - - //Set permanent title. - public void setTitle(CharSequence title) { - super.setTitle(getContext().getString(R.string.expiry_date_dialog_title)); - } -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java deleted file mode 100644 index 171763672..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyServerEditor.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2010 Thialfihar <thi@thialfihar.org> - * - * 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. - */ - -package org.sufficientlysecure.keychain.ui.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.TextView; -import com.beardedhen.androidbootstrap.BootstrapButton; -import org.sufficientlysecure.keychain.R; - -public class KeyServerEditor extends LinearLayout implements Editor, OnClickListener { - private EditorListener mEditorListener = null; - - BootstrapButton mDeleteButton; - TextView mServer; - - public KeyServerEditor(Context context) { - super(context); - } - - public KeyServerEditor(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void onFinishInflate() { - setDrawingCacheEnabled(true); - setAlwaysDrawnWithCacheEnabled(true); - - mServer = (TextView) findViewById(R.id.server); - - mDeleteButton = (BootstrapButton) findViewById(R.id.delete); - mDeleteButton.setOnClickListener(this); - - super.onFinishInflate(); - } - - public void setValue(String value) { - mServer.setText(value); - } - - public String getValue() { - return mServer.getText().toString().trim(); - } - - public void onClick(View v) { - final ViewGroup parent = (ViewGroup) getParent(); - if (v == mDeleteButton) { - parent.removeView(this); - if (mEditorListener != null) { - mEditorListener.onDeleted(this, false); - } - } - } - - @Override - public boolean needsSaving() { - return false; - } - - public void setEditorListener(EditorListener listener) { - mEditorListener = listener; - } -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java deleted file mode 100644 index fb59cd3b7..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Copyright (C) 2010 Thialfihar <thi@thialfihar.org> - * - * 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. - */ - -package org.sufficientlysecure.keychain.ui.widget; - -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Bundle; -import android.os.Message; -import android.os.Messenger; -import android.support.v7.app.ActionBarActivity; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.TextView; -import com.beardedhen.androidbootstrap.BootstrapButton; - -import org.spongycastle.openpgp.PGPKeyFlags; -import org.spongycastle.openpgp.PGPSecretKey; - -import org.sufficientlysecure.keychain.Id; -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.PgpConversionHelper; -import org.sufficientlysecure.keychain.service.KeychainIntentService; -import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; -import org.sufficientlysecure.keychain.service.PassphraseCacheService; -import org.sufficientlysecure.keychain.ui.dialog.CreateKeyDialogFragment; -import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; -import org.sufficientlysecure.keychain.ui.widget.Editor.EditorListener; -import org.sufficientlysecure.keychain.util.Choice; - -import java.util.ArrayList; -import java.util.List; -import java.util.Vector; - -public class SectionView extends LinearLayout implements OnClickListener, EditorListener, Editor { - private LayoutInflater mInflater; - private BootstrapButton mPlusButton; - private ViewGroup mEditors; - private TextView mTitle; - private int mType = 0; - private EditorListener mEditorListener = null; - - private Choice mNewKeyAlgorithmChoice; - private int mNewKeySize; - private boolean mOldItemDeleted = false; - private ArrayList<String> mDeletedIDs = new ArrayList<String>(); - private ArrayList<PGPSecretKey> mDeletedKeys = new ArrayList<PGPSecretKey>(); - private boolean mCanBeEdited = true; - - private ActionBarActivity mActivity; - - private ProgressDialogFragment mGeneratingDialog; - - public void setEditorListener(EditorListener listener) { - mEditorListener = listener; - } - - public SectionView(Context context) { - super(context); - mActivity = (ActionBarActivity) context; - } - - public SectionView(Context context, AttributeSet attrs) { - super(context, attrs); - mActivity = (ActionBarActivity) context; - } - - public ViewGroup getEditors() { - return mEditors; - } - - public void setType(int type) { - mType = type; - switch (type) { - case Id.type.user_id: { - mTitle.setText(R.string.section_user_ids); - break; - } - - case Id.type.key: { - mTitle.setText(R.string.section_keys); - break; - } - - default: { - break; - } - } - } - - public void setCanBeEdited(boolean canBeEdited) { - mCanBeEdited = canBeEdited; - if (!mCanBeEdited) { - mPlusButton.setVisibility(View.INVISIBLE); - } - } - - /** - * {@inheritDoc} - */ - @Override - protected void onFinishInflate() { - mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); - - setDrawingCacheEnabled(true); - setAlwaysDrawnWithCacheEnabled(true); - - mPlusButton = (BootstrapButton) findViewById(R.id.plusbutton); - mPlusButton.setOnClickListener(this); - - mEditors = (ViewGroup) findViewById(R.id.editors); - mTitle = (TextView) findViewById(R.id.title); - - updateEditorsVisible(); - super.onFinishInflate(); - } - - /** - * {@inheritDoc} - */ - public void onDeleted(Editor editor, boolean wasNewItem) { - mOldItemDeleted |= !wasNewItem; - if (mOldItemDeleted) { - if (mType == Id.type.user_id) { - mDeletedIDs.add(((UserIdEditor) editor).getOriginalID()); - } else if (mType == Id.type.key) { - mDeletedKeys.add(((KeyEditor) editor).getValue()); - } - } - this.updateEditorsVisible(); - if (mEditorListener != null) { - mEditorListener.onEdited(); - } - } - - @Override - public void onEdited() { - if (mEditorListener != null) { - mEditorListener.onEdited(); - } - } - - protected void updateEditorsVisible() { - final boolean hasChildren = mEditors.getChildCount() > 0; - mEditors.setVisibility(hasChildren ? View.VISIBLE : View.GONE); - } - - public boolean needsSaving() { - //check each view for needs saving, take account of deleted items - boolean ret = mOldItemDeleted; - for (int i = 0; i < mEditors.getChildCount(); ++i) { - Editor editor = (Editor) mEditors.getChildAt(i); - ret |= editor.needsSaving(); - if (mType == Id.type.user_id) { - ret |= ((UserIdEditor) editor).primarySwapped(); - } - } - return ret; - } - - public boolean primaryChanged() { - boolean ret = false; - for (int i = 0; i < mEditors.getChildCount(); ++i) { - Editor editor = (Editor) mEditors.getChildAt(i); - if (mType == Id.type.user_id) { - ret |= ((UserIdEditor) editor).primarySwapped(); - } - } - return ret; - } - - public String getOriginalPrimaryID() { - //NB: this will have to change when we change how Primary IDs are chosen, and so we need to be - // careful about where Master key capabilities are stored... multiple primaries and - // revoked ones make this harder than the simple case we are continuing to assume here - for (int i = 0; i < mEditors.getChildCount(); ++i) { - Editor editor = (Editor) mEditors.getChildAt(i); - if (mType == Id.type.user_id) { - if (((UserIdEditor) editor).getIsOriginallyMainUserID()) { - return ((UserIdEditor) editor).getOriginalID(); - } - } - } - return null; - } - - public ArrayList<String> getOriginalIDs() { - ArrayList<String> orig = new ArrayList<String>(); - if (mType == Id.type.user_id) { - for (int i = 0; i < mEditors.getChildCount(); ++i) { - UserIdEditor editor = (UserIdEditor) mEditors.getChildAt(i); - if (editor.isMainUserId()) { - orig.add(0, editor.getOriginalID()); - } else { - orig.add(editor.getOriginalID()); - } - } - return orig; - } else { - return null; - } - } - - public ArrayList<String> getDeletedIDs() { - return mDeletedIDs; - } - - public ArrayList<PGPSecretKey> getDeletedKeys() { - return mDeletedKeys; - } - - public List<Boolean> getNeedsSavingArray() { - ArrayList<Boolean> mList = new ArrayList<Boolean>(); - for (int i = 0; i < mEditors.getChildCount(); ++i) { - Editor editor = (Editor) mEditors.getChildAt(i); - mList.add(editor.needsSaving()); - } - return mList; - } - - public List<Boolean> getNewIDFlags() { - ArrayList<Boolean> mList = new ArrayList<Boolean>(); - for (int i = 0; i < mEditors.getChildCount(); ++i) { - UserIdEditor editor = (UserIdEditor) mEditors.getChildAt(i); - if (editor.isMainUserId()) { - mList.add(0, editor.getIsNewID()); - } else { - mList.add(editor.getIsNewID()); - } - } - return mList; - } - - public List<Boolean> getNewKeysArray() { - ArrayList<Boolean> mList = new ArrayList<Boolean>(); - if (mType == Id.type.key) { - for (int i = 0; i < mEditors.getChildCount(); ++i) { - KeyEditor editor = (KeyEditor) mEditors.getChildAt(i); - mList.add(editor.getIsNewKey()); - } - } - return mList; - } - - /** - * {@inheritDoc} - */ - public void onClick(View v) { - if (mCanBeEdited) { - switch (mType) { - case Id.type.user_id: { - UserIdEditor view = (UserIdEditor) mInflater.inflate( - R.layout.edit_key_user_id_item, mEditors, false); - view.setEditorListener(this); - view.setValue("", mEditors.getChildCount() == 0, true); - mEditors.addView(view); - if (mEditorListener != null) { - mEditorListener.onEdited(); - } - break; - } - - case Id.type.key: { - CreateKeyDialogFragment mCreateKeyDialogFragment = - CreateKeyDialogFragment.newInstance(mEditors.getChildCount()); - mCreateKeyDialogFragment - .setOnAlgorithmSelectedListener( - new CreateKeyDialogFragment.OnAlgorithmSelectedListener() { - @Override - public void onAlgorithmSelected(Choice algorithmChoice, int keySize) { - mNewKeyAlgorithmChoice = algorithmChoice; - mNewKeySize = keySize; - createKey(); - } - }); - mCreateKeyDialogFragment.show(mActivity.getSupportFragmentManager(), "createKeyDialog"); - break; - } - - default: { - break; - } - } - this.updateEditorsVisible(); - } - } - - public void setUserIds(Vector<String> list) { - if (mType != Id.type.user_id) { - return; - } - - mEditors.removeAllViews(); - for (String userId : list) { - UserIdEditor view = (UserIdEditor) mInflater.inflate(R.layout.edit_key_user_id_item, - mEditors, false); - view.setEditorListener(this); - view.setValue(userId, mEditors.getChildCount() == 0, false); - view.setCanBeEdited(mCanBeEdited); - mEditors.addView(view); - } - - this.updateEditorsVisible(); - } - - public void setKeys(Vector<PGPSecretKey> list, Vector<Integer> usages, boolean newKeys) { - if (mType != Id.type.key) { - return; - } - - mEditors.removeAllViews(); - - // go through all keys and set view based on them - for (int i = 0; i < list.size(); i++) { - KeyEditor view = (KeyEditor) mInflater.inflate(R.layout.edit_key_key_item, mEditors, - false); - view.setEditorListener(this); - boolean isMasterKey = (mEditors.getChildCount() == 0); - view.setValue(list.get(i), isMasterKey, usages.get(i), newKeys); - view.setCanBeEdited(mCanBeEdited); - mEditors.addView(view); - } - - this.updateEditorsVisible(); - } - - private void createKey() { - // Send all information needed to service to edit key in other thread - final Intent intent = new Intent(mActivity, KeychainIntentService.class); - - intent.setAction(KeychainIntentService.ACTION_GENERATE_KEY); - - // fill values for this action - Bundle data = new Bundle(); - Boolean isMasterKey; - - String passphrase; - if (mEditors.getChildCount() > 0) { - PGPSecretKey masterKey = ((KeyEditor) mEditors.getChildAt(0)).getValue(); - passphrase = PassphraseCacheService - .getCachedPassphrase(mActivity, masterKey.getKeyID()); - isMasterKey = false; - } else { - passphrase = ""; - isMasterKey = true; - } - data.putBoolean(KeychainIntentService.GENERATE_KEY_MASTER_KEY, isMasterKey); - data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase); - data.putInt(KeychainIntentService.GENERATE_KEY_ALGORITHM, mNewKeyAlgorithmChoice.getId()); - data.putInt(KeychainIntentService.GENERATE_KEY_KEY_SIZE, mNewKeySize); - - intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - - // show progress dialog - mGeneratingDialog = ProgressDialogFragment.newInstance( - getResources().getQuantityString(R.plurals.progress_generating, 1), - ProgressDialog.STYLE_SPINNER, - true, - new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - mActivity.stopService(intent); - } - }); - - // Message is received after generating is done in KeychainIntentService - KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(mActivity, - mGeneratingDialog) { - public void handleMessage(Message message) { - // handle messages by standard KeychainIntentServiceHandler first - super.handleMessage(message); - - if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) { - // get new key from data bundle returned from service - Bundle data = message.getData(); - PGPSecretKey newKey = (PGPSecretKey) PgpConversionHelper - .BytesToPGPSecretKey(data - .getByteArray(KeychainIntentService.RESULT_NEW_KEY)); - addGeneratedKeyToView(newKey); - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(saveHandler); - intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); - - mGeneratingDialog.show(mActivity.getSupportFragmentManager(), "dialog"); - - // start service with intent - mActivity.startService(intent); - } - - private void addGeneratedKeyToView(PGPSecretKey newKey) { - // add view with new key - KeyEditor view = (KeyEditor) mInflater.inflate(R.layout.edit_key_key_item, - mEditors, false); - view.setEditorListener(SectionView.this); - int usage = 0; - if (mEditors.getChildCount() == 0) { - usage = PGPKeyFlags.CAN_CERTIFY; - } - view.setValue(newKey, newKey.isMasterKey(), usage, true); - mEditors.addView(view); - SectionView.this.updateEditorsVisible(); - if (mEditorListener != null) { - mEditorListener.onEdited(); - } - } -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UnderlineTextView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UnderlineTextView.java deleted file mode 100644 index 937a48e48..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UnderlineTextView.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2013 Eric Frohnhoefer - * - * 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. - */ - -package org.sufficientlysecure.keychain.ui.widget; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.widget.TextView; - -/** - * Copied from StickyListHeaders lib example - * - * @author Eric Frohnhoefer - */ -public class UnderlineTextView extends TextView { - private final Paint mPaint = new Paint(); - private int mUnderlineHeight = 0; - - public UnderlineTextView(Context context) { - this(context, null); - } - - public UnderlineTextView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public UnderlineTextView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - init(context, attrs); - } - - private void init(Context context, AttributeSet attrs) { - Resources r = getResources(); - mUnderlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, - r.getDisplayMetrics()); - } - - @Override - public void setPadding(int left, int top, int right, int bottom) { - super.setPadding(left, top, right, bottom + mUnderlineHeight); - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - - // Draw the underline the same color as the text - mPaint.setColor(getTextColors().getDefaultColor()); - canvas.drawRect(0, getHeight() - mUnderlineHeight, getWidth(), getHeight(), mPaint); - } -} diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java deleted file mode 100644 index 2253872d5..000000000 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (C) 2010 Thialfihar <thi@thialfihar.org> - * - * 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. - */ - -package org.sufficientlysecure.keychain.ui.widget; - -import android.content.Context; -import android.text.Editable; -import android.text.TextWatcher; -import android.util.AttributeSet; -import android.util.Patterns; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.AutoCompleteTextView; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.RadioButton; -import com.beardedhen.androidbootstrap.BootstrapButton; - -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.ContactHelper; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; - -import java.util.regex.Matcher; - -public class UserIdEditor extends LinearLayout implements Editor, OnClickListener { - private EditorListener mEditorListener = null; - - private BootstrapButton mDeleteButton; - private RadioButton mIsMainUserId; - private String mOriginalID; - private EditText mName; - private String mOriginalName; - private AutoCompleteTextView mEmail; - private String mOriginalEmail; - private EditText mComment; - private String mOriginalComment; - private boolean mOriginallyMainUserID; - private boolean mIsNewId; - - public void setCanBeEdited(boolean canBeEdited) { - if (!canBeEdited) { - mDeleteButton.setVisibility(View.INVISIBLE); - mName.setEnabled(false); - mIsMainUserId.setEnabled(false); - mEmail.setEnabled(false); - mComment.setEnabled(false); - } - } - - public static class InvalidEmailException extends Exception { - static final long serialVersionUID = 0xf812773345L; - - public InvalidEmailException(String message) { - super(message); - } - } - - public UserIdEditor(Context context) { - super(context); - } - - public UserIdEditor(Context context, AttributeSet attrs) { - super(context, attrs); - } - - TextWatcher mTextWatcher = new TextWatcher() { - @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { - } - - @Override - public void afterTextChanged(Editable s) { - if (mEditorListener != null) { - mEditorListener.onEdited(); - } - } - }; - - @Override - protected void onFinishInflate() { - setDrawingCacheEnabled(true); - setAlwaysDrawnWithCacheEnabled(true); - - mDeleteButton = (BootstrapButton) findViewById(R.id.delete); - mDeleteButton.setOnClickListener(this); - mIsMainUserId = (RadioButton) findViewById(R.id.isMainUserId); - mIsMainUserId.setOnClickListener(this); - - mName = (EditText) findViewById(R.id.name); - mName.addTextChangedListener(mTextWatcher); - mEmail = (AutoCompleteTextView) findViewById(R.id.email); - mComment = (EditText) findViewById(R.id.comment); - mComment.addTextChangedListener(mTextWatcher); - - - mEmail.setThreshold(1); // Start working from first character - mEmail.setAdapter( - new ArrayAdapter<String> - (this.getContext(), android.R.layout.simple_dropdown_item_1line, - ContactHelper.getMailAccounts(getContext()) - )); - mEmail.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()) { - mEmail.setCompoundDrawablesWithIntrinsicBounds(0, 0, - android.R.drawable.presence_online, 0); - } else { - mEmail.setCompoundDrawablesWithIntrinsicBounds(0, 0, - android.R.drawable.presence_offline, 0); - } - } else { - // remove drawable if email is empty - mEmail.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); - } - if (mEditorListener != null) { - mEditorListener.onEdited(); - } - } - }); - - super.onFinishInflate(); - } - - public void setValue(String userId, boolean isMainID, boolean isNewId) { - - mName.setText(""); - mOriginalName = ""; - mComment.setText(""); - mOriginalComment = ""; - mEmail.setText(""); - mOriginalEmail = ""; - mIsNewId = isNewId; - mOriginalID = userId; - - String[] result = PgpKeyHelper.splitUserId(userId); - if (result[0] != null) { - mName.setText(result[0]); - mOriginalName = result[0]; - } - if (result[1] != null) { - mEmail.setText(result[1]); - mOriginalEmail = result[1]; - } - if (result[2] != null) { - mComment.setText(result[2]); - mOriginalComment = result[2]; - } - - mOriginallyMainUserID = isMainID; - setIsMainUserId(isMainID); - } - - public String getValue() { - String name = ("" + mName.getText()).trim(); - String email = ("" + mEmail.getText()).trim(); - String comment = ("" + mComment.getText()).trim(); - - String userId = name; - if (comment.length() > 0) { - userId += " (" + comment + ")"; - } - if (email.length() > 0) { - userId += " <" + email + ">"; - } - - if (userId.equals("")) { - // ok, empty one... - return userId; - } - //TODO: check gpg accepts an entirely empty ID packet. specs say this is allowed - return userId; - } - - public void onClick(View v) { - final ViewGroup parent = (ViewGroup) getParent(); - if (v == mDeleteButton) { - boolean wasMainUserId = mIsMainUserId.isChecked(); - parent.removeView(this); - if (mEditorListener != null) { - mEditorListener.onDeleted(this, mIsNewId); - } - if (wasMainUserId && parent.getChildCount() > 0) { - UserIdEditor editor = (UserIdEditor) parent.getChildAt(0); - editor.setIsMainUserId(true); - } - } else if (v == mIsMainUserId) { - for (int i = 0; i < parent.getChildCount(); ++i) { - UserIdEditor editor = (UserIdEditor) parent.getChildAt(i); - if (editor == this) { - editor.setIsMainUserId(true); - } else { - editor.setIsMainUserId(false); - } - } - if (mEditorListener != null) { - mEditorListener.onEdited(); - } - } - } - - public void setIsMainUserId(boolean value) { - mIsMainUserId.setChecked(value); - } - - public boolean isMainUserId() { - return mIsMainUserId.isChecked(); - } - - public void setEditorListener(EditorListener listener) { - mEditorListener = listener; - } - - @Override - public boolean needsSaving() { - boolean retval = false; //(mOriginallyMainUserID != isMainUserId()); - retval |= !(mOriginalName.equals(("" + mName.getText()).trim())); - retval |= !(mOriginalEmail.equals(("" + mEmail.getText()).trim())); - retval |= !(mOriginalComment.equals(("" + mComment.getText()).trim())); - retval |= mIsNewId; - return retval; - } - - public boolean getIsOriginallyMainUserID() { - return mOriginallyMainUserID; - } - - public boolean primarySwapped() { - return (mOriginallyMainUserID != isMainUserId()); - } - - public String getOriginalID() { - return mOriginalID; - } - - public boolean getIsNewID() { return mIsNewId; } -} |