diff options
author | Thialfihar <thialfihar@gmail.com> | 2010-08-17 21:49:34 +0000 |
---|---|---|
committer | Thialfihar <thialfihar@gmail.com> | 2010-08-17 21:49:34 +0000 |
commit | 446f4b493d35c48ebfc54a81e137a08babc0e236 (patch) | |
tree | a8c51303ff257480555f3dfad468638807e26d3b | |
parent | e4dd80005c4839f74c76270b1f7c2668e8007305 (diff) | |
download | open-keychain-446f4b493d35c48ebfc54a81e137a08babc0e236.tar.gz open-keychain-446f4b493d35c48ebfc54a81e137a08babc0e236.tar.bz2 open-keychain-446f4b493d35c48ebfc54a81e137a08babc0e236.zip |
added a key server preference, allowing multiple key servers to be added
Update issue 9
Key server preference added.
-rw-r--r-- | AndroidManifest.xml | 5 | ||||
-rw-r--r-- | res/layout/key_server_editor.xml | 52 | ||||
-rw-r--r-- | res/layout/key_server_preference.xml | 115 | ||||
-rw-r--r-- | res/values/strings.xml | 3 | ||||
-rw-r--r-- | res/xml/apg_preferences.xml | 5 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/Apg.java | 1 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/Constants.java | 5 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/Id.java | 1 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/KeyServerPreferenceActivity.java | 125 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/Preferences.java | 33 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/PreferencesActivity.java | 36 | ||||
-rw-r--r-- | src/org/thialfihar/android/apg/ui/widget/KeyServerEditor.java | 98 |
12 files changed, 479 insertions, 0 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 25e824962..4bbf1f773 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -187,6 +187,11 @@ android:label="@string/title_preferences" android:configChanges="keyboardHidden|orientation|keyboard"/> + <activity + android:name=".KeyServerPreferenceActivity" + android:label="@string/title_keyServerPreference" + android:configChanges="keyboardHidden|orientation|keyboard"/> + <service android:name=".Service" /> <provider diff --git a/res/layout/key_server_editor.xml b/res/layout/key_server_editor.xml new file mode 100644 index 000000000..e4c25b316 --- /dev/null +++ b/res/layout/key_server_editor.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<org.thialfihar.android.apg.ui.widget.KeyServerEditor + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <LinearLayout + android:layout_height="wrap_content" + android:layout_width="fill_parent" + android:orientation="horizontal" + android:layout_marginLeft="3dip"> + + <EditText + android:id="@+id/server" + android:layout_weight="1" + android:layout_height="wrap_content" + android:layout_width="fill_parent" + android:inputType="textUri"/> + + <ImageButton + android:id="@+id/delete" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + style="@style/MinusButton" + android:layout_gravity="center_vertical" + android:layout_marginRight="3dip"/> + + </LinearLayout> + + <View + android:id="@+id/separator" + android:layout_width="fill_parent" + android:layout_height="1dip" + android:background="?android:attr/listDivider"/> + +</org.thialfihar.android.apg.ui.widget.KeyServerEditor> diff --git a/res/layout/key_server_preference.xml b/res/layout/key_server_preference.xml new file mode 100644 index 000000000..2f5645f62 --- /dev/null +++ b/res/layout/key_server_preference.xml @@ -0,0 +1,115 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical"> + + <LinearLayout + android:id="@+android:id/text_layout" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:minHeight="?android:attr/listPreferredItemHeight" + android:gravity="center_vertical"> + + <RelativeLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="16sp" + android:layout_marginRight="6sp" + android:layout_marginTop="6sp" + android:layout_marginBottom="6sp" + android:layout_weight="1" + android:focusable="true" + android:background="@android:drawable/menuitem_background"> + + <TextView + android:id="@+id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:focusable="true" + android:singleLine="true" + android:textAppearance="?android:attr/textAppearanceLarge" /> + + <TextView + android:id="@+id/summary" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@android:id/title" + android:layout_alignLeft="@android:id/title" + android:textAppearance="?android:attr/textAppearanceSmall" + android:maxLines="2" /> + + </RelativeLayout> + + <ImageView + android:id="@+id/add" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginLeft="4dip" + android:layout_marginRight="6dip" + android:layout_gravity="center_vertical" + android:clickable="true" + style="@style/PlusButton"/> + + </LinearLayout> + + <View + android:id="@+id/separator" + android:layout_width="fill_parent" + android:layout_height="1dip" + android:background="?android:attr/listDivider"/> + + <ScrollView + android:layout_width="fill_parent" + android:layout_height="0dip" + android:layout_weight="1" + android:orientation="vertical"> + + <LinearLayout + android:id="@+id/editors" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical"/> + + </ScrollView> + + <LinearLayout + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + style="@android:style/ButtonBar"> + + <Button + android:text="@android:string/ok" + android:id="@+id/btn_ok" + android:layout_width="0dip" + android:layout_height="wrap_content" + android:layout_weight="1"/> + + <Button + android:text="@android:string/cancel" + android:id="@+id/btn_cancel" + android:layout_width="0dip" + android:layout_height="wrap_content" + android:layout_weight="1"/> + + </LinearLayout> + +</LinearLayout> diff --git a/res/values/strings.xml b/res/values/strings.xml index 472e43770..dabade473 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -29,6 +29,7 @@ <string name="title_createKey">Create Key</string> <string name="title_editKey">Edit Key</string> <string name="title_preferences">Preferences</string> + <string name="title_keyServerPreference">Key Server Preference</string> <string name="title_changePassPhrase">Change Pass Phrase</string> <string name="title_setPassPhrase">Set Pass Phrase</string> <string name="title_sendEmail">"Send Mail..."</string> @@ -111,6 +112,7 @@ <string name="label_fileCompression">File Compression</string> <string name="label_language">Language</string> <string name="label_forceV3Signature">Force V3 Signatures</string> + <string name="label_keyServers">Key Servers</string> <string name="noKeysSelected">Select</string> <string name="oneKeySelected">1 Selected</string> @@ -125,6 +127,7 @@ <string name="canSign">can sign</string> <string name="expired">expired</string> <string name="notValid">not valid</string> + <string name="nKeyServers">%s key server(s)</string> <!-- choice_lowerCase: capitalized first word, no punctuation --> <string name="choice_none">None</string> diff --git a/res/xml/apg_preferences.xml b/res/xml/apg_preferences.xml index aa2defc87..faa5f9e3f 100644 --- a/res/xml/apg_preferences.xml +++ b/res/xml/apg_preferences.xml @@ -34,6 +34,11 @@ android:entryValues="@array/pass_phrase_cache_ttl_values" android:title="@string/label_passPhraseCacheTtl" /> + <PreferenceScreen + android:persistent="false" + android:key="keyServers" + android:title="@string/label_keyServers" /> + </PreferenceCategory> <PreferenceCategory diff --git a/src/org/thialfihar/android/apg/Apg.java b/src/org/thialfihar/android/apg/Apg.java index 125001024..6dd5b9330 100644 --- a/src/org/thialfihar/android/apg/Apg.java +++ b/src/org/thialfihar/android/apg/Apg.java @@ -141,6 +141,7 @@ public class Apg { public static final String EXTRA_MESSAGE = "message"; public static final String EXTRA_ASCII_ARMOUR = "asciiArmour"; public static final String EXTRA_BINARY = "binary"; + public static final String EXTRA_KEY_SERVERS = "keyServers"; public static final String EXTRA_PROGRESS = "progress"; public static final String EXTRA_PROGRESS_MAX = "max"; diff --git a/src/org/thialfihar/android/apg/Constants.java b/src/org/thialfihar/android/apg/Constants.java index b8704117c..4c34dbc62 100644 --- a/src/org/thialfihar/android/apg/Constants.java +++ b/src/org/thialfihar/android/apg/Constants.java @@ -34,5 +34,10 @@ public final class Constants { public static final String pass_phrase_cache_ttl = "passPhraseCacheTtl"; public static final String language = "language"; public static final String force_v3_signatures = "forceV3Signatures"; + public static final String key_servers = "keyServers"; + } + + public static final class defaults { + public static final String key_servers = "pool.sks-keyservers.net, subkeys.pgp.net, pgp.mit.edu"; } } diff --git a/src/org/thialfihar/android/apg/Id.java b/src/org/thialfihar/android/apg/Id.java index ce67444cd..32febc604 100644 --- a/src/org/thialfihar/android/apg/Id.java +++ b/src/org/thialfihar/android/apg/Id.java @@ -57,6 +57,7 @@ public final class Id { public static final int secret_keys = 0x21070002; public static final int filename = 0x21070003; public static final int output_filename = 0x21070004; + public static final int key_server_preference = 0x21070005; } public static final class dialog { diff --git a/src/org/thialfihar/android/apg/KeyServerPreferenceActivity.java b/src/org/thialfihar/android/apg/KeyServerPreferenceActivity.java new file mode 100644 index 000000000..6d7dc1914 --- /dev/null +++ b/src/org/thialfihar/android/apg/KeyServerPreferenceActivity.java @@ -0,0 +1,125 @@ +/* + * 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.thialfihar.android.apg; + +import java.util.Vector; + +import org.thialfihar.android.apg.ui.widget.Editor; +import org.thialfihar.android.apg.ui.widget.Editor.EditorListener; +import org.thialfihar.android.apg.ui.widget.KeyServerEditor; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.TextView; + +public class KeyServerPreferenceActivity extends BaseActivity + implements OnClickListener, EditorListener { + private LayoutInflater mInflater; + private ViewGroup mEditors; + private View mAdd; + private TextView mTitle; + private TextView mSummary; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.key_server_preference); + + mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + mTitle = (TextView) findViewById(R.id.title); + mSummary = (TextView) findViewById(R.id.summary); + + mTitle.setText(R.string.label_keyServers); + + mEditors = (ViewGroup) findViewById(R.id.editors); + mAdd = findViewById(R.id.add); + mAdd.setOnClickListener(this); + + Intent intent = getIntent(); + String servers[] = intent.getStringArrayExtra(Apg.EXTRA_KEY_SERVERS); + if (servers != null) { + for (int i = 0; i < servers.length; ++i) { + KeyServerEditor view = (KeyServerEditor) mInflater.inflate(R.layout.key_server_editor, mEditors, false); + view.setEditorListener(this); + view.setValue(servers[i]); + mEditors.addView(view); + } + } + + Button okButton = (Button) findViewById(R.id.btn_ok); + okButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + okClicked(); + } + }); + + Button cancelButton = (Button) findViewById(R.id.btn_cancel); + cancelButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + cancelClicked(); + } + }); + } + + public void onDeleted(Editor editor) { + // nothing to do + } + + public void onClick(View v) { + KeyServerEditor view = (KeyServerEditor) mInflater.inflate(R.layout.key_server_editor, mEditors, false); + view.setEditorListener(this); + mEditors.addView(view); + } + + private void cancelClicked() { + setResult(RESULT_CANCELED, null); + finish(); + } + + private void okClicked() { + Intent data = new Intent(); + Vector<String> servers = new Vector<String>(); + for (int i = 0; i < mEditors.getChildCount(); ++i) { + KeyServerEditor editor = (KeyServerEditor) mEditors.getChildAt(i); + String tmp = editor.getValue(); + if (tmp.length() > 0) { + servers.add(tmp); + } + } + String[] dummy = new String[0]; + data.putExtra(Apg.EXTRA_KEY_SERVERS, servers.toArray(dummy)); + setResult(RESULT_OK, data); + finish(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // override this, so no option menu is added (as would be in BaseActivity), since + // we're still in preferences + return true; + } +} diff --git a/src/org/thialfihar/android/apg/Preferences.java b/src/org/thialfihar/android/apg/Preferences.java index 705da21cc..d22565804 100644 --- a/src/org/thialfihar/android/apg/Preferences.java +++ b/src/org/thialfihar/android/apg/Preferences.java @@ -1,5 +1,7 @@ package org.thialfihar.android.apg; +import java.util.Vector; + import org.bouncycastle2.bcpg.HashAlgorithmTags; import org.bouncycastle2.openpgp.PGPEncryptedData; @@ -133,4 +135,35 @@ public class Preferences { editor.putBoolean(Constants.pref.has_seen_help, value); editor.commit(); } + + public String[] getKeyServers() { + String rawData = mSharedPreferences.getString(Constants.pref.key_servers, + Constants.defaults.key_servers); + Vector<String> servers = new Vector<String>(); + String chunks[] = rawData.split(","); + for (int i = 0; i < chunks.length; ++i) { + String tmp = chunks[i].trim(); + if (tmp.length() > 0) { + servers.add(tmp); + } + } + return servers.toArray(chunks); + } + + public void setKeyServers(String[] value) { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + String rawData = ""; + for (int i = 0; i < value.length; ++i) { + String tmp = value[i].trim(); + if (tmp.length() == 0) { + continue; + } + if (!"".equals(rawData)) { + rawData += ","; + } + rawData += tmp; + } + editor.putString(Constants.pref.key_servers, rawData); + editor.commit(); + } } diff --git a/src/org/thialfihar/android/apg/PreferencesActivity.java b/src/org/thialfihar/android/apg/PreferencesActivity.java index c226a8b2a..f50b9f05c 100644 --- a/src/org/thialfihar/android/apg/PreferencesActivity.java +++ b/src/org/thialfihar/android/apg/PreferencesActivity.java @@ -23,11 +23,13 @@ import java.util.Vector; import org.bouncycastle2.bcpg.HashAlgorithmTags; import org.bouncycastle2.openpgp.PGPEncryptedData; +import android.content.Intent; import android.os.Bundle; import android.preference.CheckBoxPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceActivity; +import android.preference.PreferenceScreen; public class PreferencesActivity extends PreferenceActivity { private ListPreference mLanguage = null; @@ -38,6 +40,7 @@ public class PreferencesActivity extends PreferenceActivity { private IntegerListPreference mFileCompression = null; private CheckBoxPreference mAsciiArmour = null; private CheckBoxPreference mForceV3Signatures = null; + private PreferenceScreen mKeyServerPreference = null; private Preferences mPreferences; @Override @@ -223,6 +226,39 @@ public class PreferencesActivity extends PreferenceActivity { return false; } }); + + mKeyServerPreference = (PreferenceScreen) findPreference(Constants.pref.key_servers); + String servers[] = mPreferences.getKeyServers(); + mKeyServerPreference.setSummary(getResources().getString(R.string.nKeyServers, servers.length)); + mKeyServerPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + Intent intent = new Intent(PreferencesActivity.this, + KeyServerPreferenceActivity.class); + intent.putExtra(Apg.EXTRA_KEY_SERVERS, mPreferences.getKeyServers()); + startActivityForResult(intent, Id.request.key_server_preference); + return false; + } + }); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case Id.request.key_server_preference: { + if (resultCode == RESULT_CANCELED || data == null) { + return; + } + String servers[] = data.getStringArrayExtra(Apg.EXTRA_KEY_SERVERS); + mPreferences.setKeyServers(servers); + mKeyServerPreference.setSummary(getResources().getString(R.string.nKeyServers, servers.length)); + break; + } + + default: { + super.onActivityResult(requestCode, resultCode, data); + break; + } + } } } diff --git a/src/org/thialfihar/android/apg/ui/widget/KeyServerEditor.java b/src/org/thialfihar/android/apg/ui/widget/KeyServerEditor.java new file mode 100644 index 000000000..b58fc6036 --- /dev/null +++ b/src/org/thialfihar/android/apg/ui/widget/KeyServerEditor.java @@ -0,0 +1,98 @@ +/* + * 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.thialfihar.android.apg.ui.widget; + +import java.text.DateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Vector; + +import org.bouncycastle2.openpgp.PGPPublicKey; +import org.bouncycastle2.openpgp.PGPSecretKey; +import org.thialfihar.android.apg.Apg; +import org.thialfihar.android.apg.Id; +import org.thialfihar.android.apg.R; +import org.thialfihar.android.apg.utils.Choice; + +import android.app.DatePickerDialog; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.util.AttributeSet; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.DatePicker; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.Spinner; +import android.widget.TextView; + +public class KeyServerEditor extends LinearLayout implements Editor, OnClickListener { + private EditorListener mEditorListener = null; + + ImageButton 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 = (ImageButton) 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(); + } + + @Override + public void onClick(View v) { + final ViewGroup parent = (ViewGroup)getParent(); + if (v == mDeleteButton) { + parent.removeView(this); + if (mEditorListener != null) { + mEditorListener.onDeleted(this); + } + } + } + + @Override + public void setEditorListener(EditorListener listener) { + mEditorListener = listener; + } +} |