mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-30 12:32:17 -05:00
Remove old edit key stuff
This commit is contained in:
parent
7f463ae0df
commit
fb5c829ff7
@ -1,380 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
|
||||||
* Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
|
|
||||||
*
|
|
||||||
* 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.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.ImageButton;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TableLayout;
|
|
||||||
import android.widget.TableRow;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Button;
|
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
|
||||||
import org.sufficientlysecure.keychain.pgp.UncachedSecretKey;
|
|
||||||
|
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
|
|
||||||
public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
|
|
||||||
private UncachedSecretKey mKey;
|
|
||||||
|
|
||||||
private EditorListener mEditorListener = null;
|
|
||||||
|
|
||||||
private boolean mIsMasterKey;
|
|
||||||
ImageButton mDeleteButton;
|
|
||||||
TextView mAlgorithm;
|
|
||||||
TextView mKeyId;
|
|
||||||
TextView mCreationDate;
|
|
||||||
Button mExpiryDateButton;
|
|
||||||
Calendar mCreatedDate;
|
|
||||||
Calendar mExpiryDate;
|
|
||||||
Calendar 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.subkey_item_key_id);
|
|
||||||
mCreationDate = (TextView) findViewById(R.id.creation);
|
|
||||||
mExpiryDateButton = (Button) findViewById(R.id.expiry);
|
|
||||||
|
|
||||||
mDeleteButton = (ImageButton) 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) {
|
|
||||||
Calendar expiryDate = mExpiryDate;
|
|
||||||
if (expiryDate == null) {
|
|
||||||
expiryDate = Calendar.getInstance(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, expiryDate.get(Calendar.YEAR), expiryDate.get(Calendar.MONTH),
|
|
||||||
expiryDate.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) {
|
|
||||||
|
|
||||||
// will crash with IllegalArgumentException if we set a min date
|
|
||||||
// that is not before expiry
|
|
||||||
if (mCreatedDate != null && mCreatedDate.before(expiryDate)) {
|
|
||||||
dialog.getDatePicker()
|
|
||||||
.setMinDate(
|
|
||||||
mCreatedDate.getTime().getTime() + DateUtils.DAY_IN_MILLIS);
|
|
||||||
} else {
|
|
||||||
// When created date isn't available
|
|
||||||
dialog.getDatePicker().setMinDate(expiryDate.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(UncachedSecretKey key, boolean isMasterKey, int usage, boolean isNewKey) {
|
|
||||||
mKey = key;
|
|
||||||
|
|
||||||
mIsMasterKey = isMasterKey;
|
|
||||||
if (mIsMasterKey) {
|
|
||||||
mDeleteButton.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
mAlgorithm.setText(PgpKeyHelper.getAlgorithmInfo(getContext(), key.getAlgorithm()));
|
|
||||||
String keyIdStr = PgpKeyHelper.convertKeyIdToHex(key.getKeyId());
|
|
||||||
mKeyId.setText(keyIdStr);
|
|
||||||
|
|
||||||
boolean isElGamalKey = (key.isElGamalEncrypt());
|
|
||||||
boolean isDSAKey = (key.isDSA());
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
mIsNewKey = isNewKey;
|
|
||||||
if (isNewKey) {
|
|
||||||
mUsage = usage;
|
|
||||||
mChkCertify.setChecked(
|
|
||||||
(usage & UncachedSecretKey.CERTIFY_OTHER) == UncachedSecretKey.CERTIFY_OTHER);
|
|
||||||
mChkSign.setChecked(
|
|
||||||
(usage & UncachedSecretKey.SIGN_DATA) == UncachedSecretKey.SIGN_DATA);
|
|
||||||
mChkEncrypt.setChecked(
|
|
||||||
((usage & UncachedSecretKey.ENCRYPT_COMMS) == UncachedSecretKey.ENCRYPT_COMMS) ||
|
|
||||||
((usage & UncachedSecretKey.ENCRYPT_STORAGE) == UncachedSecretKey.ENCRYPT_STORAGE));
|
|
||||||
mChkAuthenticate.setChecked(
|
|
||||||
(usage & UncachedSecretKey.AUTHENTICATION) == UncachedSecretKey.AUTHENTICATION);
|
|
||||||
} else {
|
|
||||||
mUsage = key.getKeyUsage();
|
|
||||||
mOriginalUsage = mUsage;
|
|
||||||
if (key.isMasterKey()) {
|
|
||||||
mChkCertify.setChecked(key.canCertify());
|
|
||||||
}
|
|
||||||
mChkSign.setChecked(key.canSign());
|
|
||||||
mChkEncrypt.setChecked(key.canEncrypt());
|
|
||||||
mChkAuthenticate.setChecked(key.canAuthenticate());
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
|
||||||
cal.setTime(key.getCreationTime());
|
|
||||||
setCreatedDate(cal);
|
|
||||||
}
|
|
||||||
|
|
||||||
Date expiryDate = key.getExpiryTime();
|
|
||||||
if (expiryDate == null) {
|
|
||||||
setExpiryDate(null);
|
|
||||||
} else {
|
|
||||||
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
|
||||||
cal.setTime(expiryDate);
|
|
||||||
setExpiryDate(cal);
|
|
||||||
mOriginalExpiryDate = cal;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public UncachedSecretKey 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(Calendar date) {
|
|
||||||
mCreatedDate = date;
|
|
||||||
if (date == null) {
|
|
||||||
mCreationDate.setText(getContext().getString(R.string.none));
|
|
||||||
} else {
|
|
||||||
mCreationDate.setText(DateFormat.getDateInstance().format(date.getTime()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setExpiryDate(Calendar date) {
|
|
||||||
mExpiryDate = date;
|
|
||||||
if (date == null) {
|
|
||||||
mExpiryDateButton.setText(getContext().getString(R.string.none));
|
|
||||||
} else {
|
|
||||||
mExpiryDateButton.setText(DateFormat.getDateInstance().format(date.getTime()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Calendar getExpiryDate() {
|
|
||||||
return mExpiryDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getUsage() {
|
|
||||||
mUsage = (mUsage & ~UncachedSecretKey.CERTIFY_OTHER) |
|
|
||||||
(mChkCertify.isChecked() ? UncachedSecretKey.CERTIFY_OTHER : 0);
|
|
||||||
mUsage = (mUsage & ~UncachedSecretKey.SIGN_DATA) |
|
|
||||||
(mChkSign.isChecked() ? UncachedSecretKey.SIGN_DATA : 0);
|
|
||||||
mUsage = (mUsage & ~UncachedSecretKey.ENCRYPT_COMMS) |
|
|
||||||
(mChkEncrypt.isChecked() ? UncachedSecretKey.ENCRYPT_COMMS : 0);
|
|
||||||
mUsage = (mUsage & ~UncachedSecretKey.ENCRYPT_STORAGE) |
|
|
||||||
(mChkEncrypt.isChecked() ? UncachedSecretKey.ENCRYPT_STORAGE : 0);
|
|
||||||
mUsage = (mUsage & ~UncachedSecretKey.AUTHENTICATION) |
|
|
||||||
(mChkAuthenticate.isChecked() ? UncachedSecretKey.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));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,419 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
|
|
||||||
*
|
|
||||||
* 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.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 android.widget.ImageButton;
|
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
|
||||||
import org.sufficientlysecure.keychain.pgp.UncachedSecretKey;
|
|
||||||
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
|
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.AddSubkeyDialogFragment;
|
|
||||||
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 ImageButton 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<UncachedSecretKey> mDeletedKeys = new ArrayList<UncachedSecretKey>();
|
|
||||||
private boolean mCanBeEdited = true;
|
|
||||||
|
|
||||||
private ActionBarActivity mActivity;
|
|
||||||
|
|
||||||
private ProgressDialogFragment mGeneratingDialog;
|
|
||||||
|
|
||||||
public static final int TYPE_USER_ID = 1;
|
|
||||||
public static final int TYPE_KEY = 2;
|
|
||||||
|
|
||||||
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 TYPE_USER_ID: {
|
|
||||||
mTitle.setText(R.string.section_user_ids);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 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 = (ImageButton) 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 == TYPE_USER_ID) {
|
|
||||||
mDeletedIDs.add(((UserIdEditor) editor).getOriginalID());
|
|
||||||
} else if (mType == 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 == 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 == 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 == 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 == 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<UncachedSecretKey> 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 == 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 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 TYPE_KEY: {
|
|
||||||
// AddSubkeyDialogFragment mCreateKeyDialogFragment =
|
|
||||||
// AddSubkeyDialogFragment.newInstance(mEditors.getChildCount());
|
|
||||||
// mCreateKeyDialogFragment
|
|
||||||
// .setOnAlgorithmSelectedListener(
|
|
||||||
// new AddSubkeyDialogFragment.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 != 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<UncachedSecretKey> list, Vector<Integer> usages, boolean newKeys) {
|
|
||||||
if (mType != 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() {
|
|
||||||
|
|
||||||
// fill values for this action
|
|
||||||
Boolean isMasterKey;
|
|
||||||
|
|
||||||
String passphrase;
|
|
||||||
if (mEditors.getChildCount() > 0) {
|
|
||||||
UncachedSecretKey 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.getDataAsStringList();
|
|
||||||
UncachedSecretKey newKey = 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(UncachedSecretKey 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 = UncachedSecretKey.CERTIFY_OTHER;
|
|
||||||
}
|
|
||||||
view.setValue(newKey, newKey.isMasterKey(), usage, true);
|
|
||||||
mEditors.addView(view);
|
|
||||||
SectionView.this.updateEditorsVisible();
|
|
||||||
if (mEditorListener != null) {
|
|
||||||
mEditorListener.onEdited();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,267 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
|
|
||||||
* Copyright (C) 2010-2014 Thialfihar <thi@thialfihar.org>
|
|
||||||
*
|
|
||||||
* 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.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 android.widget.ImageButton;
|
|
||||||
|
|
||||||
import org.sufficientlysecure.keychain.R;
|
|
||||||
import org.sufficientlysecure.keychain.helper.ContactHelper;
|
|
||||||
import org.sufficientlysecure.keychain.pgp.KeyRing;
|
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
|
|
||||||
public class UserIdEditor extends LinearLayout implements Editor, OnClickListener {
|
|
||||||
private EditorListener mEditorListener = null;
|
|
||||||
|
|
||||||
private ImageButton 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 = (ImageButton) 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.user_id_item_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.getPossibleUserEmails(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,
|
|
||||||
R.drawable.uid_mail_ok, 0);
|
|
||||||
} else {
|
|
||||||
mEmail.setCompoundDrawablesWithIntrinsicBounds(0, 0,
|
|
||||||
R.drawable.uid_mail_bad, 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 = KeyRing.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; }
|
|
||||||
}
|
|
@ -1,172 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<org.sufficientlysecure.keychain.ui.widget.KeyEditor xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical" >
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal" >
|
|
||||||
|
|
||||||
<TableLayout
|
|
||||||
android:id="@+id/table_keylayout"
|
|
||||||
android:layout_width="0dip"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:stretchColumns="1" >
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/label_keyId"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:text="@string/label_key_id" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/subkey_item_key_id"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingRight="5dip"
|
|
||||||
android:text="00000000 00000000"
|
|
||||||
android:typeface="monospace" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/label_algorithm"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:text="@string/label_algorithm" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/algorithm"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingRight="5dip"
|
|
||||||
android:text="@string/label_name" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/label_creation"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:text="@string/label_creation" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/creation"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/label_expiry"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:text="@string/label_expiry" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/expiry"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:text="@string/none"
|
|
||||||
android:background="@drawable/button_edgy" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow
|
|
||||||
android:id="@+id/row_certify">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/label_usage"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:text="@string/label_usage" />
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/chkCertify"
|
|
||||||
android:enabled = "false"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/flag_certify" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow
|
|
||||||
android:id="@+id/row_sign">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/label_usage2"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip"
|
|
||||||
android:text="@string/label_usage" />
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/chkSign"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/flag_sign" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow
|
|
||||||
android:id="@+id/row_encrypt">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip" />
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/chkEncrypt"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/flag_encrypt" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow
|
|
||||||
android:id="@+id/row_authenticate">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="10dip" />
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/chkAuthenticate"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/flag_authenticate" />
|
|
||||||
</TableRow>
|
|
||||||
</TableLayout>
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/delete"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="10dp"
|
|
||||||
android:src="@drawable/minus"
|
|
||||||
android:background="@drawable/button_rounded_red"/>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/separator"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dip"
|
|
||||||
android:background="?android:attr/listDivider" />
|
|
||||||
|
|
||||||
</org.sufficientlysecure.keychain.ui.widget.KeyEditor>
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<org.sufficientlysecure.keychain.ui.widget.SectionView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical" >
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/header"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:orientation="horizontal" >
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/title"
|
|
||||||
style="@style/SectionHeader"
|
|
||||||
android:layout_width="0dip"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:ellipsize="marquee"
|
|
||||||
android:fadingEdge="horizontal"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:text="Section Name" />
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/plusbutton"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="10dp"
|
|
||||||
android:src="@drawable/plus"
|
|
||||||
android:background="@drawable/button_rounded_green"/>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/editors"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingBottom="6dip" />
|
|
||||||
|
|
||||||
</org.sufficientlysecure.keychain.ui.widget.SectionView>
|
|
@ -1,96 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<org.sufficientlysecure.keychain.ui.widget.UserIdEditor xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical" >
|
|
||||||
|
|
||||||
<RadioButton
|
|
||||||
android:id="@+id/isMainUserId"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/label_main_user_id" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal" >
|
|
||||||
|
|
||||||
<TableLayout
|
|
||||||
android:layout_width="0dip"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1" >
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/label_name"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="5dip"
|
|
||||||
android:text="@string/label_name" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/name"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:inputType="textPersonName|textCapWords" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/label_email"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="5dip"
|
|
||||||
android:text="@string/label_email" />
|
|
||||||
|
|
||||||
<AutoCompleteTextView
|
|
||||||
android:id="@+id/email"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:inputType="textEmailAddress" />
|
|
||||||
</TableRow>
|
|
||||||
|
|
||||||
<TableRow>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/label_comment"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:paddingRight="5dip"
|
|
||||||
android:text="@string/label_comment" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/user_id_item_comment"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:inputType="text"/>
|
|
||||||
</TableRow>
|
|
||||||
</TableLayout>
|
|
||||||
|
|
||||||
<ImageButton
|
|
||||||
android:id="@+id/delete"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_vertical"
|
|
||||||
android:layout_margin="10dip"
|
|
||||||
android:layout_marginLeft="4dip"
|
|
||||||
android:layout_marginRight="6dip"
|
|
||||||
android:src="@drawable/minus"
|
|
||||||
android:background="@drawable/button_rounded_red" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/separator"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dip"
|
|
||||||
android:background="?android:attr/listDivider" />
|
|
||||||
|
|
||||||
</org.sufficientlysecure.keychain.ui.widget.UserIdEditor>
|
|
Loading…
Reference in New Issue
Block a user