aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-02-09 21:17:30 +0100
committerDominik Schürmann <dominik@dominikschuermann.de>2014-02-09 21:17:30 +0100
commit0c4b809195f9219352d8ed7041fbeb678c9a0ea5 (patch)
treec504f2059c2f6829b94c74baa34a0d53e9c71406 /OpenPGP-Keychain
parent8f8a787cc97fe16206aa45fb4d15a8569744296c (diff)
downloadopen-keychain-0c4b809195f9219352d8ed7041fbeb678c9a0ea5.tar.gz
open-keychain-0c4b809195f9219352d8ed7041fbeb678c9a0ea5.tar.bz2
open-keychain-0c4b809195f9219352d8ed7041fbeb678c9a0ea5.zip
rework key view into fragments to later add certifications
Diffstat (limited to 'OpenPGP-Keychain')
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java8
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentAbout.java)13
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java91
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java (renamed from OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentHtml.java)19
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java332
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java92
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java313
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java84
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/view_key_activity.xml233
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml31
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml3
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml222
-rw-r--r--OpenPGP-Keychain/src/main/res/layout/view_key_userids_item.xml7
-rw-r--r--OpenPGP-Keychain/src/main/res/values/strings.xml2
15 files changed, 824 insertions, 630 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
index 53ec4870c..9bee42973 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java
@@ -30,6 +30,7 @@ import org.spongycastle.openpgp.PGPPublicKey;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.spongycastle.openpgp.PGPSecretKey;
import org.spongycastle.openpgp.PGPSecretKeyRing;
+import org.spongycastle.openpgp.PGPSignature;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.pgp.PgpConversionHelper;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
@@ -212,6 +213,13 @@ public class ProviderHelper {
++userIdRank;
}
+ for (PGPSignature certification : new IterableIterator<PGPSignature>(masterKey.getSignaturesOfType(PGPSignature.POSITIVE_CERTIFICATION))) {
+ //TODO: how to do this?? we need to verify the signatures again and again when they are displayed...
+// if (certification.verify
+// operations.add(buildPublicKeyOperations(context, keyRingRowId, key, rank));
+ }
+
+
try {
context.getContentResolver().applyBatch(KeychainContract.CONTENT_AUTHORITY, operations);
} catch (RemoteException e) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentAbout.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java
index be7c50dbb..12d689274 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentAbout.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpAboutFragment.java
@@ -33,18 +33,7 @@ import android.view.ViewGroup;
import android.widget.TextView;
-public class HelpFragmentAbout extends Fragment {
-
- /**
- * Workaround for Android Bug. See
- * http://stackoverflow.com/questions/8748064/starting-activity-from
- * -fragment-causes-nullpointerexception
- */
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- setUserVisibleHint(true);
- }
+public class HelpAboutFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
index 2fe7c56e6..9ccd7e088 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
@@ -20,12 +20,13 @@ package org.sufficientlysecure.keychain.ui;
import java.util.ArrayList;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentPagerAdapter;
+import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
@@ -37,8 +38,6 @@ public class HelpActivity extends ActionBarActivity {
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
- TextView tabCenter;
- TextView tabText;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -63,93 +62,21 @@ public class HelpActivity extends ActionBarActivity {
}
Bundle startBundle = new Bundle();
- startBundle.putInt(HelpFragmentHtml.ARG_HTML_FILE, R.raw.help_start);
+ startBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_start);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_start)),
- HelpFragmentHtml.class, startBundle, (selectedTab == 0 ? true : false));
+ HelpHtmlFragment.class, startBundle, (selectedTab == 0 ? true : false));
Bundle nfcBundle = new Bundle();
- nfcBundle.putInt(HelpFragmentHtml.ARG_HTML_FILE, R.raw.help_nfc_beam);
+ nfcBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_nfc_beam);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_nfc_beam)),
- HelpFragmentHtml.class, nfcBundle, (selectedTab == 1 ? true : false));
+ HelpHtmlFragment.class, nfcBundle, (selectedTab == 1 ? true : false));
Bundle changelogBundle = new Bundle();
- changelogBundle.putInt(HelpFragmentHtml.ARG_HTML_FILE, R.raw.help_changelog);
+ changelogBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_changelog);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_changelog)),
- HelpFragmentHtml.class, changelogBundle, (selectedTab == 2 ? true : false));
+ HelpHtmlFragment.class, changelogBundle, (selectedTab == 2 ? true : false));
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_about)),
- HelpFragmentAbout.class, null, (selectedTab == 3 ? true : false));
- }
-
- public static class TabsAdapter extends FragmentPagerAdapter implements ActionBar.TabListener,
- ViewPager.OnPageChangeListener {
- private final Context mContext;
- private final ActionBar mActionBar;
- private final ViewPager mViewPager;
- private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
-
- static final class TabInfo {
- private final Class<?> clss;
- private final Bundle args;
-
- TabInfo(Class<?> _class, Bundle _args) {
- clss = _class;
- args = _args;
- }
- }
-
- public TabsAdapter(ActionBarActivity activity, ViewPager pager) {
- super(activity.getSupportFragmentManager());
- mContext = activity;
- mActionBar = activity.getSupportActionBar();
- mViewPager = pager;
- mViewPager.setAdapter(this);
- mViewPager.setOnPageChangeListener(this);
- }
-
- public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args, boolean selected) {
- TabInfo info = new TabInfo(clss, args);
- tab.setTag(info);
- tab.setTabListener(this);
- mTabs.add(info);
- mActionBar.addTab(tab, selected);
- notifyDataSetChanged();
- }
-
- @Override
- public int getCount() {
- return mTabs.size();
- }
-
- @Override
- public Fragment getItem(int position) {
- TabInfo info = mTabs.get(position);
- return Fragment.instantiate(mContext, info.clss.getName(), info.args);
- }
-
- public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- }
-
- public void onPageSelected(int position) {
- mActionBar.setSelectedNavigationItem(position);
- }
-
- public void onPageScrollStateChanged(int state) {
- }
-
- public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
- Object tag = tab.getTag();
- for (int i = 0; i < mTabs.size(); i++) {
- if (mTabs.get(i) == tag) {
- mViewPager.setCurrentItem(i);
- }
- }
- }
-
- public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
- }
-
- public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
- }
+ HelpAboutFragment.class, null, (selectedTab == 3 ? true : false));
}
} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentHtml.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java
index fb6747db0..3afb5bbe0 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpFragmentHtml.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpHtmlFragment.java
@@ -28,7 +28,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
-public class HelpFragmentHtml extends Fragment {
+public class HelpHtmlFragment extends Fragment {
private Activity mActivity;
private int htmlFile;
@@ -36,10 +36,10 @@ public class HelpFragmentHtml extends Fragment {
public static final String ARG_HTML_FILE = "htmlFile";
/**
- * Create a new instance of HelpFragmentHtml, providing "htmlFile" as an argument.
+ * Create a new instance of HelpHtmlFragment, providing "htmlFile" as an argument.
*/
- static HelpFragmentHtml newInstance(int htmlFile) {
- HelpFragmentHtml f = new HelpFragmentHtml();
+ static HelpHtmlFragment newInstance(int htmlFile) {
+ HelpHtmlFragment f = new HelpHtmlFragment();
// Supply html raw file input as an argument.
Bundle args = new Bundle();
@@ -49,17 +49,6 @@ public class HelpFragmentHtml extends Fragment {
return f;
}
- /**
- * Workaround for Android Bug. See
- * http://stackoverflow.com/questions/8748064/starting-activity-from
- * -fragment-causes-nullpointerexception
- */
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- setUserVisibleHint(true);
- }
-
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mActivity = getActivity();
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
index 14640480e..0a452bc8a 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
@@ -18,8 +18,17 @@
package org.sufficientlysecure.keychain.ui;
-import java.util.ArrayList;
-import java.util.Date;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.support.v4.view.ViewPager;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.ActionBarActivity;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.Toast;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
@@ -27,64 +36,25 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.helper.ExportHelper;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
-import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
-import org.sufficientlysecure.keychain.ui.adapter.ViewKeyKeysAdapter;
-import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter;
+import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter;
import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.ShareNfcDialogFragment;
import org.sufficientlysecure.keychain.ui.dialog.ShareQrCodeDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.CursorLoader;
-import android.support.v4.content.Loader;
-import android.support.v7.app.ActionBarActivity;
-import android.text.format.DateFormat;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.beardedhen.androidbootstrap.BootstrapButton;
+import java.util.ArrayList;
-public class ViewKeyActivity extends ActionBarActivity implements
- LoaderManager.LoaderCallbacks<Cursor> {
+public class ViewKeyActivity extends ActionBarActivity {
ExportHelper mExportHelper;
protected Uri mDataUri;
- private TextView mName;
- private TextView mEmail;
- private TextView mComment;
- private TextView mAlgorithm;
- private TextView mKeyId;
- private TextView mExpiry;
- private TextView mCreation;
- private TextView mFingerprint;
- private BootstrapButton mActionEncrypt;
- private BootstrapButton mActionCertify;
-
- private ListView mUserIds;
- private ListView mKeys;
-
- private static final int LOADER_ID_KEYRING = 0;
- private static final int LOADER_ID_USER_IDS = 1;
- private static final int LOADER_ID_KEYS = 2;
- private ViewKeyUserIdsAdapter mUserIdsAdapter;
- private ViewKeyKeysAdapter mKeysAdapter;
+ public static final String EXTRA_SELECTED_TAB = "selectedTab";
+
+ ViewPager mViewPager;
+ TabsAdapter mTabsAdapter;
private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006;
@@ -95,26 +65,35 @@ public class ViewKeyActivity extends ActionBarActivity implements
mExportHelper = new ExportHelper(this);
// let the actionbar look like Android's contact app
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- getSupportActionBar().setIcon(android.R.color.transparent);
- getSupportActionBar().setHomeButtonEnabled(true);
+ ActionBar actionBar = getSupportActionBar();
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setIcon(android.R.color.transparent);
+ actionBar.setHomeButtonEnabled(true);
+ actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
setContentView(R.layout.view_key_activity);
- mName = (TextView) findViewById(R.id.name);
- mEmail = (TextView) findViewById(R.id.email);
- mComment = (TextView) findViewById(R.id.comment);
- mKeyId = (TextView) findViewById(R.id.key_id);
- mAlgorithm = (TextView) findViewById(R.id.algorithm);
- mCreation = (TextView) findViewById(R.id.creation);
- mExpiry = (TextView) findViewById(R.id.expiry);
- mFingerprint = (TextView) findViewById(R.id.fingerprint);
- mUserIds = (ListView) findViewById(R.id.user_ids);
- mKeys = (ListView) findViewById(R.id.keys);
- mActionEncrypt = (BootstrapButton) findViewById(R.id.action_encrypt);
- mActionCertify = (BootstrapButton) findViewById(R.id.action_certify);
-
- loadData(getIntent());
+ mViewPager = (ViewPager) findViewById(R.id.pager);
+
+ mTabsAdapter = new TabsAdapter(this, mViewPager);
+
+ int selectedTab = 0;
+ Intent intent = getIntent();
+ if (intent.getExtras() != null && intent.getExtras().containsKey(EXTRA_SELECTED_TAB)) {
+ selectedTab = intent.getExtras().getInt(EXTRA_SELECTED_TAB);
+ }
+
+ mDataUri = getIntent().getData();
+
+ Bundle mainBundle = new Bundle();
+ mainBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, mDataUri);
+ mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.key_view_tab_main)),
+ ViewKeyMainFragment.class, mainBundle, (selectedTab == 0 ? true : false));
+
+ Bundle certBundle = new Bundle();
+ certBundle.putParcelable(ViewKeyCertsFragment.ARG_DATA_URI, mDataUri);
+ mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.key_view_tab_certs)),
+ ViewKeyCertsFragment.class, certBundle, (selectedTab == 1 ? true : false));
}
@Override
@@ -168,210 +147,6 @@ public class ViewKeyActivity extends ActionBarActivity implements
return super.onOptionsItemSelected(item);
}
- private void loadData(Intent intent) {
- if (intent.getData().equals(mDataUri)) {
- Log.d(Constants.TAG, "Same URI, no need to load the data again!");
- return;
- }
-
- mDataUri = intent.getData();
- if (mDataUri == null) {
- Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!");
- finish();
- return;
- }
-
- Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
-
- mActionEncrypt.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- encryptToContact(mDataUri);
- }
- });
- mActionCertify.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- certifyKey(mDataUri);
- }
- });
-
- mUserIdsAdapter = new ViewKeyUserIdsAdapter(this, null, 0);
- mUserIds.setAdapter(mUserIdsAdapter);
- // mUserIds.setEmptyView(findViewById(android.R.id.empty));
- // mUserIds.setClickable(true);
- // mUserIds.setOnItemClickListener(new AdapterView.OnItemClickListener() {
- // @Override
- // public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
- // }
- // });
-
- mKeysAdapter = new ViewKeyKeysAdapter(this, null, 0);
- mKeys.setAdapter(mKeysAdapter);
-
- // Prepare the loaders. Either re-connect with an existing ones,
- // or start new ones.
- getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this);
- getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
- getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this);
- }
-
- static final String[] KEYRING_PROJECTION = new String[]{KeyRings._ID, KeyRings.MASTER_KEY_ID,
- UserIds.USER_ID};
- static final int KEYRING_INDEX_ID = 0;
- static final int KEYRING_INDEX_MASTER_KEY_ID = 1;
- static final int KEYRING_INDEX_USER_ID = 2;
-
- static final String[] USER_IDS_PROJECTION = new String[]{UserIds._ID, UserIds.USER_ID,
- UserIds.RANK,};
- // not the main user id
- static final String USER_IDS_SELECTION = UserIds.RANK + " > 0 ";
- static final String USER_IDS_SORT_ORDER = UserIds.USER_ID + " COLLATE LOCALIZED ASC";
-
- static final String[] KEYS_PROJECTION = new String[]{Keys._ID, Keys.KEY_ID,
- Keys.IS_MASTER_KEY, Keys.ALGORITHM, Keys.KEY_SIZE, Keys.CAN_CERTIFY, Keys.CAN_SIGN,
- Keys.CAN_ENCRYPT, Keys.CREATION, Keys.EXPIRY, Keys.FINGERPRINT};
- static final String KEYS_SORT_ORDER = Keys.RANK + " ASC";
- static final int KEYS_INDEX_ID = 0;
- static final int KEYS_INDEX_KEY_ID = 1;
- static final int KEYS_INDEX_IS_MASTER_KEY = 2;
- static final int KEYS_INDEX_ALGORITHM = 3;
- static final int KEYS_INDEX_KEY_SIZE = 4;
- static final int KEYS_INDEX_CAN_CERTIFY = 5;
- static final int KEYS_INDEX_CAN_SIGN = 6;
- static final int KEYS_INDEX_CAN_ENCRYPT = 7;
- static final int KEYS_INDEX_CREATION = 8;
- static final int KEYS_INDEX_EXPIRY = 9;
- static final int KEYS_INDEX_FINGERPRINT = 10;
-
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- switch (id) {
- case LOADER_ID_KEYRING: {
- Uri baseUri = mDataUri;
-
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(this, baseUri, KEYRING_PROJECTION, null, null, null);
- }
- case LOADER_ID_USER_IDS: {
- Uri baseUri = UserIds.buildUserIdsUri(mDataUri);
-
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(this, baseUri, USER_IDS_PROJECTION, USER_IDS_SELECTION, null,
- USER_IDS_SORT_ORDER);
- }
- case LOADER_ID_KEYS: {
- Uri baseUri = Keys.buildKeysUri(mDataUri);
-
- // Now create and return a CursorLoader that will take care of
- // creating a Cursor for the data being displayed.
- return new CursorLoader(this, baseUri, KEYS_PROJECTION, null, null, KEYS_SORT_ORDER);
- }
-
- default:
- return null;
- }
- }
-
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- // Swap the new cursor in. (The framework will take care of closing the
- // old cursor once we return.)
- switch (loader.getId()) {
- case LOADER_ID_KEYRING:
- if (data.moveToFirst()) {
- // get name, email, and comment from USER_ID
- String[] mainUserId = PgpKeyHelper.splitUserId(data
- .getString(KEYRING_INDEX_USER_ID));
- if (mainUserId[0] != null) {
- setTitle(mainUserId[0]);
- mName.setText(mainUserId[0]);
- } else {
- setTitle(R.string.user_id_no_name);
- mName.setText(R.string.user_id_no_name);
- }
- mEmail.setText(mainUserId[1]);
- mComment.setText(mainUserId[2]);
- }
-
- break;
- case LOADER_ID_USER_IDS:
- mUserIdsAdapter.swapCursor(data);
- break;
- case LOADER_ID_KEYS:
- // the first key here is our master key
- if (data.moveToFirst()) {
- // get key id from MASTER_KEY_ID
- long keyId = data.getLong(KEYS_INDEX_KEY_ID);
-
- String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
- mKeyId.setText(keyIdStr);
-
- // get creation date from CREATION
- if (data.isNull(KEYS_INDEX_CREATION)) {
- mCreation.setText(R.string.none);
- } else {
- Date creationDate = new Date(data.getLong(KEYS_INDEX_CREATION) * 1000);
-
- mCreation.setText(DateFormat.getDateFormat(getApplicationContext()).format(
- creationDate));
- }
-
- // get expiry date from EXPIRY
- if (data.isNull(KEYS_INDEX_EXPIRY)) {
- mExpiry.setText(R.string.none);
- } else {
- Date expiryDate = new Date(data.getLong(KEYS_INDEX_EXPIRY) * 1000);
-
- mExpiry.setText(DateFormat.getDateFormat(getApplicationContext()).format(
- expiryDate));
- }
-
- String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
- data.getInt(KEYS_INDEX_ALGORITHM), data.getInt(KEYS_INDEX_KEY_SIZE));
- mAlgorithm.setText(algorithmStr);
-
- byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT);
- if (fingerprintBlob == null) {
- // FALLBACK for old database entries
- fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri);
- }
- String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);
- fingerprint = fingerprint.replace(" ", "\n");
-
- mFingerprint.setText(fingerprint);
- }
-
- mKeysAdapter.swapCursor(data);
- break;
-
- default:
- break;
- }
- }
-
- /**
- * This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
- * We need to make sure we are no longer using it.
- */
- public void onLoaderReset(Loader<Cursor> loader) {
- switch (loader.getId()) {
- case LOADER_ID_KEYRING:
- // No resources need to be freed for this ID
- break;
- case LOADER_ID_USER_IDS:
- mUserIdsAdapter.swapCursor(null);
- break;
- case LOADER_ID_KEYS:
- mKeysAdapter.swapCursor(null);
- break;
- default:
- break;
- }
- }
-
private void uploadToKeyserver(Uri dataUri) {
Intent uploadIntent = new Intent(this, UploadKeyActivity.class);
uploadIntent.setData(dataUri);
@@ -394,25 +169,8 @@ public class ViewKeyActivity extends ActionBarActivity implements
startActivityForResult(queryIntent, RESULT_CODE_LOOKUP_KEY);
}
- private void encryptToContact(Uri dataUri) {
- long keyId = ProviderHelper.getMasterKeyId(ViewKeyActivity.this, dataUri);
-
- long[] encryptionKeyIds = new long[]{keyId};
- Intent intent = new Intent(ViewKeyActivity.this, EncryptActivity.class);
- intent.setAction(EncryptActivity.ACTION_ENCRYPT);
- intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
- // used instead of startActivity set actionbar based on callingPackage
- startActivityForResult(intent, 0);
- }
-
- private void certifyKey(Uri dataUri) {
- Intent signIntent = new Intent(this, CertifyKeyActivity.class);
- signIntent.setData(dataUri);
- startActivity(signIntent);
- }
-
private void shareKey(Uri dataUri, boolean fingerprintOnly) {
- String content = null;
+ String content;
if (fingerprintOnly) {
byte[] fingerprintBlob = ProviderHelper.getFingerprint(this, dataUri);
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, false);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java
index a2e3e4339..59037d9ff 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivityJB.java
@@ -23,7 +23,6 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import android.annotation.TargetApi;
-import android.database.Cursor;
import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
@@ -35,12 +34,11 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.support.v4.app.LoaderManager;
import android.widget.Toast;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class ViewKeyActivityJB extends ViewKeyActivity implements CreateNdefMessageCallback,
- OnNdefPushCompleteCallback, LoaderManager.LoaderCallbacks<Cursor> {
+ OnNdefPushCompleteCallback {
// NFC
private NfcAdapter mNfcAdapter;
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java
new file mode 100644
index 000000000..36d3e6ace
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.beardedhen.androidbootstrap.BootstrapButton;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.util.Log;
+
+
+public class ViewKeyCertsFragment extends Fragment {
+
+ public static final String ARG_DATA_URI = "uri";
+
+ private BootstrapButton mActionCertify;
+
+ private Uri mDataUri;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.view_key_certs_fragment, container, false);
+
+ mActionCertify = (BootstrapButton) view.findViewById(R.id.action_certify);
+
+ return view;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
+ if (dataUri == null) {
+ Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
+ getActivity().finish();
+ return;
+ }
+
+ loadData(dataUri);
+ }
+
+ private void loadData(Uri dataUri) {
+ if (dataUri.equals(mDataUri)) {
+ Log.d(Constants.TAG, "Same URI, no need to load the data again!");
+ return;
+ }
+
+ mDataUri = dataUri;
+
+ Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
+
+ mActionCertify.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ certifyKey(mDataUri);
+ }
+ });
+
+ }
+
+ private void certifyKey(Uri dataUri) {
+ Intent signIntent = new Intent(getActivity(), CertifyKeyActivity.class);
+ signIntent.setData(dataUri);
+ startActivity(signIntent);
+ }
+
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
new file mode 100644
index 000000000..495764eaf
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui;
+
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.text.format.DateFormat;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.beardedhen.androidbootstrap.BootstrapButton;
+
+import org.sufficientlysecure.keychain.Constants;
+import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
+import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import org.sufficientlysecure.keychain.ui.adapter.ViewKeyKeysAdapter;
+import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter;
+import org.sufficientlysecure.keychain.util.Log;
+
+import java.util.Date;
+
+
+public class ViewKeyMainFragment extends Fragment implements
+ LoaderManager.LoaderCallbacks<Cursor>{
+
+ public static final String ARG_DATA_URI = "uri";
+
+ private TextView mName;
+ private TextView mEmail;
+ private TextView mComment;
+ private TextView mAlgorithm;
+ private TextView mKeyId;
+ private TextView mExpiry;
+ private TextView mCreation;
+ private TextView mFingerprint;
+ private BootstrapButton mActionEncrypt;
+
+ private ListView mUserIds;
+ private ListView mKeys;
+
+ private static final int LOADER_ID_KEYRING = 0;
+ private static final int LOADER_ID_USER_IDS = 1;
+ private static final int LOADER_ID_KEYS = 2;
+
+ private ViewKeyUserIdsAdapter mUserIdsAdapter;
+ private ViewKeyKeysAdapter mKeysAdapter;
+
+ private Uri mDataUri;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.view_key_main_fragment, container, false);
+
+ mName = (TextView) view.findViewById(R.id.name);
+ mEmail = (TextView) view.findViewById(R.id.email);
+ mComment = (TextView) view.findViewById(R.id.comment);
+ mKeyId = (TextView) view.findViewById(R.id.key_id);
+ mAlgorithm = (TextView) view.findViewById(R.id.algorithm);
+ mCreation = (TextView) view.findViewById(R.id.creation);
+ mExpiry = (TextView) view.findViewById(R.id.expiry);
+ mFingerprint = (TextView) view.findViewById(R.id.fingerprint);
+ mUserIds = (ListView) view.findViewById(R.id.user_ids);
+ mKeys = (ListView) view.findViewById(R.id.keys);
+ mActionEncrypt = (BootstrapButton) view.findViewById(R.id.action_encrypt);
+
+ return view;
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ Uri dataUri = getArguments().getParcelable(ARG_DATA_URI);
+ if (dataUri == null) {
+ Log.e(Constants.TAG, "Data missing. Should be Uri of key!");
+ getActivity().finish();
+ return;
+ }
+
+ loadData(dataUri);
+ }
+
+ private void loadData(Uri dataUri) {
+ if (dataUri.equals(mDataUri)) {
+ Log.d(Constants.TAG, "Same URI, no need to load the data again!");
+ return;
+ }
+
+ mDataUri = dataUri;
+
+ Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString());
+
+ mActionEncrypt.setOnClickListener(new View.OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ encryptToContact(mDataUri);
+ }
+ });
+
+ mUserIdsAdapter = new ViewKeyUserIdsAdapter(getActivity(), null, 0);
+ mUserIds.setAdapter(mUserIdsAdapter);
+
+ mKeysAdapter = new ViewKeyKeysAdapter(getActivity(), null, 0);
+ mKeys.setAdapter(mKeysAdapter);
+
+ // Prepare the loaders. Either re-connect with an existing ones,
+ // or start new ones.
+ getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this);
+ getActivity().getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
+ getActivity().getSupportLoaderManager().initLoader(LOADER_ID_KEYS, null, this);
+ }
+
+ static final String[] KEYRING_PROJECTION = new String[]{KeychainContract.KeyRings._ID, KeychainContract.KeyRings.MASTER_KEY_ID,
+ KeychainContract.UserIds.USER_ID};
+ static final int KEYRING_INDEX_ID = 0;
+ static final int KEYRING_INDEX_MASTER_KEY_ID = 1;
+ static final int KEYRING_INDEX_USER_ID = 2;
+
+ static final String[] USER_IDS_PROJECTION = new String[]{KeychainContract.UserIds._ID, KeychainContract.UserIds.USER_ID,
+ KeychainContract.UserIds.RANK,};
+ // not the main user id
+ static final String USER_IDS_SELECTION = KeychainContract.UserIds.RANK + " > 0 ";
+ static final String USER_IDS_SORT_ORDER = KeychainContract.UserIds.USER_ID + " COLLATE LOCALIZED ASC";
+
+ static final String[] KEYS_PROJECTION = new String[]{KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID,
+ KeychainContract.Keys.IS_MASTER_KEY, KeychainContract.Keys.ALGORITHM, KeychainContract.Keys.KEY_SIZE, KeychainContract.Keys.CAN_CERTIFY, KeychainContract.Keys.CAN_SIGN,
+ KeychainContract.Keys.CAN_ENCRYPT, KeychainContract.Keys.CREATION, KeychainContract.Keys.EXPIRY, KeychainContract.Keys.FINGERPRINT};
+ static final String KEYS_SORT_ORDER = KeychainContract.Keys.RANK + " ASC";
+ static final int KEYS_INDEX_ID = 0;
+ static final int KEYS_INDEX_KEY_ID = 1;
+ static final int KEYS_INDEX_IS_MASTER_KEY = 2;
+ static final int KEYS_INDEX_ALGORITHM = 3;
+ static final int KEYS_INDEX_KEY_SIZE = 4;
+ static final int KEYS_INDEX_CAN_CERTIFY = 5;
+ static final int KEYS_INDEX_CAN_SIGN = 6;
+ static final int KEYS_INDEX_CAN_ENCRYPT = 7;
+ static final int KEYS_INDEX_CREATION = 8;
+ static final int KEYS_INDEX_EXPIRY = 9;
+ static final int KEYS_INDEX_FINGERPRINT = 10;
+
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ switch (id) {
+ case LOADER_ID_KEYRING: {
+ Uri baseUri = mDataUri;
+
+ // Now create and return a CursorLoader that will take care of
+ // creating a Cursor for the data being displayed.
+ return new CursorLoader(getActivity(), baseUri, KEYRING_PROJECTION, null, null, null);
+ }
+ case LOADER_ID_USER_IDS: {
+ Uri baseUri = KeychainContract.UserIds.buildUserIdsUri(mDataUri);
+
+ // Now create and return a CursorLoader that will take care of
+ // creating a Cursor for the data being displayed.
+ return new CursorLoader(getActivity(), baseUri, USER_IDS_PROJECTION, USER_IDS_SELECTION, null,
+ USER_IDS_SORT_ORDER);
+ }
+ case LOADER_ID_KEYS: {
+ Uri baseUri = KeychainContract.Keys.buildKeysUri(mDataUri);
+
+ // Now create and return a CursorLoader that will take care of
+ // creating a Cursor for the data being displayed.
+ return new CursorLoader(getActivity(), baseUri, KEYS_PROJECTION, null, null, KEYS_SORT_ORDER);
+ }
+
+ default:
+ return null;
+ }
+ }
+
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ // Swap the new cursor in. (The framework will take care of closing the
+ // old cursor once we return.)
+ switch (loader.getId()) {
+ case LOADER_ID_KEYRING:
+ if (data.moveToFirst()) {
+ // get name, email, and comment from USER_ID
+ String[] mainUserId = PgpKeyHelper.splitUserId(data
+ .getString(KEYRING_INDEX_USER_ID));
+ if (mainUserId[0] != null) {
+ getActivity().setTitle(mainUserId[0]);
+ mName.setText(mainUserId[0]);
+ } else {
+ getActivity().setTitle(R.string.user_id_no_name);
+ mName.setText(R.string.user_id_no_name);
+ }
+ mEmail.setText(mainUserId[1]);
+ mComment.setText(mainUserId[2]);
+ }
+
+ break;
+ case LOADER_ID_USER_IDS:
+ mUserIdsAdapter.swapCursor(data);
+ break;
+ case LOADER_ID_KEYS:
+ // the first key here is our master key
+ if (data.moveToFirst()) {
+ // get key id from MASTER_KEY_ID
+ long keyId = data.getLong(KEYS_INDEX_KEY_ID);
+
+ String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
+ mKeyId.setText(keyIdStr);
+
+ // get creation date from CREATION
+ if (data.isNull(KEYS_INDEX_CREATION)) {
+ mCreation.setText(R.string.none);
+ } else {
+ Date creationDate = new Date(data.getLong(KEYS_INDEX_CREATION) * 1000);
+
+ mCreation.setText(DateFormat.getDateFormat(getActivity().getApplicationContext()).format(
+ creationDate));
+ }
+
+ // get expiry date from EXPIRY
+ if (data.isNull(KEYS_INDEX_EXPIRY)) {
+ mExpiry.setText(R.string.none);
+ } else {
+ Date expiryDate = new Date(data.getLong(KEYS_INDEX_EXPIRY) * 1000);
+
+ mExpiry.setText(DateFormat.getDateFormat(getActivity().getApplicationContext()).format(
+ expiryDate));
+ }
+
+ String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
+ data.getInt(KEYS_INDEX_ALGORITHM), data.getInt(KEYS_INDEX_KEY_SIZE));
+ mAlgorithm.setText(algorithmStr);
+
+ byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT);
+ if (fingerprintBlob == null) {
+ // FALLBACK for old database entries
+ fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), mDataUri);
+ }
+ String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);
+ fingerprint = fingerprint.replace(" ", "\n");
+
+ mFingerprint.setText(fingerprint);
+ }
+
+ mKeysAdapter.swapCursor(data);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /**
+ * This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
+ * We need to make sure we are no longer using it.
+ */
+ public void onLoaderReset(Loader<Cursor> loader) {
+ switch (loader.getId()) {
+ case LOADER_ID_KEYRING:
+ // No resources need to be freed for this ID
+ break;
+ case LOADER_ID_USER_IDS:
+ mUserIdsAdapter.swapCursor(null);
+ break;
+ case LOADER_ID_KEYS:
+ mKeysAdapter.swapCursor(null);
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ private void encryptToContact(Uri dataUri) {
+ long keyId = ProviderHelper.getMasterKeyId(getActivity(), dataUri);
+
+ long[] encryptionKeyIds = new long[]{keyId};
+ Intent intent = new Intent(getActivity(), EncryptActivity.class);
+ intent.setAction(EncryptActivity.ACTION_ENCRYPT);
+ intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, encryptionKeyIds);
+ // used instead of startActivity set actionbar based on callingPackage
+ startActivityForResult(intent, 0);
+ }
+
+ private void certifyKey(Uri dataUri) {
+ Intent signIntent = new Intent(getActivity(), CertifyKeyActivity.class);
+ signIntent.setData(dataUri);
+ startActivity(signIntent);
+ }
+
+
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java
new file mode 100644
index 000000000..924a70897
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java
@@ -0,0 +1,84 @@
+package org.sufficientlysecure.keychain.ui.adapter;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentStatePagerAdapter;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v4.view.ViewPager;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.ActionBarActivity;
+
+import java.util.ArrayList;
+
+public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar.TabListener,
+ ViewPager.OnPageChangeListener {
+ private final Context mContext;
+ private final ActionBar mActionBar;
+ private final ViewPager mViewPager;
+ private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
+
+ static final class TabInfo {
+ private final Class<?> clss;
+ private final Bundle args;
+
+ TabInfo(Class<?> _class, Bundle _args) {
+ clss = _class;
+ args = _args;
+ }
+ }
+
+ public TabsAdapter(ActionBarActivity activity, ViewPager pager) {
+ super(activity.getSupportFragmentManager());
+ mContext = activity;
+ mActionBar = activity.getSupportActionBar();
+ mViewPager = pager;
+ mViewPager.setAdapter(this);
+ mViewPager.setOnPageChangeListener(this);
+ }
+
+ public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args, boolean selected) {
+ TabInfo info = new TabInfo(clss, args);
+ tab.setTag(info);
+ tab.setTabListener(this);
+ mTabs.add(info);
+ mActionBar.addTab(tab, selected);
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mTabs.size();
+ }
+
+ @Override
+ public Fragment getItem(int position) {
+ TabInfo info = mTabs.get(position);
+ return Fragment.instantiate(mContext, info.clss.getName(), info.args);
+ }
+
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ }
+
+ public void onPageSelected(int position) {
+ mActionBar.setSelectedNavigationItem(position);
+ }
+
+ public void onPageScrollStateChanged(int state) {
+ }
+
+ public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
+ Object tag = tab.getTag();
+ for (int i = 0; i < mTabs.size(); i++) {
+ if (mTabs.get(i) == tag) {
+ mViewPager.setCurrentItem(i);
+ }
+ }
+ }
+
+ public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
+ }
+
+ public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
+ }
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_activity.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_activity.xml
index 1c937430a..58e4919dc 100644
--- a/OpenPGP-Keychain/src/main/res/layout/view_key_activity.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/view_key_activity.xml
@@ -1,229 +1,12 @@
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
- <LinearLayout
+ <android.support.v4.view.ViewPager
+ android:id="@+id/pager"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:paddingLeft="16dp"
- android:paddingRight="16dp">
+ android:layout_height="match_parent" />
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="4dp"
- android:layout_marginTop="14dp"
- android:text="@string/section_master_user_id" />
-
- <TableLayout
- android:layout_width="wrap_content"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:stretchColumns="1">
-
- <TableRow>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top"
- android:paddingRight="10dip"
- android:text="@string/label_name" />
-
- <TextView
- android:id="@+id/name"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:paddingRight="5dip"
- android:text="" />
- </TableRow>
-
- <TableRow>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top"
- android:paddingRight="10dip"
- android:text="@string/label_email" />
-
- <TextView
- android:id="@+id/email"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:paddingRight="5dip"
- android:text="" />
- </TableRow>
-
- <TableRow>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top"
- android:paddingRight="10dip"
- android:text="@string/label_comment" />
-
- <TextView
- android:id="@+id/comment"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:paddingRight="5dip"
- android:text="" />
- </TableRow>
- </TableLayout>
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="4dp"
- android:layout_marginTop="14dp"
- android:text="@string/section_master_key" />
-
- <TableLayout
- android:layout_width="wrap_content"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:stretchColumns="1">
-
- <TableRow>
-
- <TextView
- 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/key_id"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingRight="5dip"
- android:text=""
- 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="" />
- </TableRow>
-
- <TableRow>
-
- <TextView
- 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:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:paddingRight="10dip"
- android:text="@string/label_expiry" />
-
- <TextView
- android:id="@+id/expiry"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- </TableRow>
-
- <TableRow>
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:paddingRight="10dip"
- android:text="@string/label_fingerprint" />
-
- <TextView
- android:id="@+id/fingerprint"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:typeface="monospace" />
- </TableRow>
- </TableLayout>
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="4dp"
- android:layout_marginTop="14dp"
- android:text="@string/section_user_ids" />
-
- <org.sufficientlysecure.keychain.ui.widget.FixedListView
- android:id="@+id/user_ids"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="4dp"
- android:layout_marginTop="14dp"
- android:text="@string/section_keys" />
-
- <org.sufficientlysecure.keychain.ui.widget.FixedListView
- android:id="@+id/keys"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- <TextView
- style="@style/SectionHeader"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="4dp"
- android:layout_marginTop="14dp"
- android:text="@string/section_actions" />
-
- <com.beardedhen.androidbootstrap.BootstrapButton
- android:id="@+id/action_encrypt"
- android:layout_width="match_parent"
- android:layout_height="60dp"
- android:padding="4dp"
- android:text="@string/key_view_action_encrypt"
- bootstrapbutton:bb_icon_left="fa-lock"
- bootstrapbutton:bb_type="info" />
-
- <com.beardedhen.androidbootstrap.BootstrapButton
- android:id="@+id/action_certify"
- android:layout_width="match_parent"
- android:layout_height="60dp"
- android:padding="4dp"
- android:text="@string/key_view_action_certify"
- bootstrapbutton:bb_icon_left="fa-pencil"
- bootstrapbutton:bb_type="info" />
- </LinearLayout>
-
-</ScrollView> \ No newline at end of file
+</LinearLayout> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml
new file mode 100644
index 000000000..2a3dafc93
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml
@@ -0,0 +1,31 @@
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp">
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
+ android:layout_marginTop="14dp"
+ android:text="@string/section_actions" />
+
+ <com.beardedhen.androidbootstrap.BootstrapButton
+ android:id="@+id/action_certify"
+ android:layout_width="match_parent"
+ android:layout_height="60dp"
+ android:padding="4dp"
+ android:text="@string/key_view_action_certify"
+ bootstrapbutton:bb_icon_left="fa-pencil"
+ bootstrapbutton:bb_type="info" />
+ </LinearLayout>
+
+</ScrollView> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml
index b50253980..c44835bb0 100644
--- a/OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/view_key_keys_item.xml
@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:layout_marginRight="?android:attr/scrollbarSize"
+ android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingLeft="8dip"
android:paddingRight="3dip"
diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml
new file mode 100644
index 000000000..3cbea3e9b
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/res/layout/view_key_main_fragment.xml
@@ -0,0 +1,222 @@
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp">
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
+ android:layout_marginTop="14dp"
+ android:text="@string/section_master_user_id" />
+
+ <TableLayout
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:stretchColumns="1">
+
+ <TableRow>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:paddingRight="10dip"
+ android:text="@string/label_name" />
+
+ <TextView
+ android:id="@+id/name"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:paddingRight="5dip"
+ android:text="" />
+ </TableRow>
+
+ <TableRow>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:paddingRight="10dip"
+ android:text="@string/label_email" />
+
+ <TextView
+ android:id="@+id/email"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:paddingRight="5dip"
+ android:text="" />
+ </TableRow>
+
+ <TableRow>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:paddingRight="10dip"
+ android:text="@string/label_comment" />
+
+ <TextView
+ android:id="@+id/comment"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:paddingRight="5dip"
+ android:text="" />
+ </TableRow>
+ </TableLayout>
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
+ android:layout_marginTop="14dp"
+ android:text="@string/section_actions" />
+
+ <com.beardedhen.androidbootstrap.BootstrapButton
+ android:id="@+id/action_encrypt"
+ android:layout_width="match_parent"
+ android:layout_height="60dp"
+ android:padding="4dp"
+ android:text="@string/key_view_action_encrypt"
+ bootstrapbutton:bb_icon_left="fa-lock"
+ bootstrapbutton:bb_type="info" />
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
+ android:layout_marginTop="14dp"
+ android:text="@string/section_master_key" />
+
+ <TableLayout
+ android:layout_width="wrap_content"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:stretchColumns="1">
+
+ <TableRow>
+
+ <TextView
+ 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/key_id"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="5dip"
+ android:text=""
+ 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="" />
+ </TableRow>
+
+ <TableRow>
+
+ <TextView
+ 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:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:paddingRight="10dip"
+ android:text="@string/label_expiry" />
+
+ <TextView
+ android:id="@+id/expiry"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ </TableRow>
+
+ <TableRow>
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:paddingRight="10dip"
+ android:text="@string/label_fingerprint" />
+
+ <TextView
+ android:id="@+id/fingerprint"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:typeface="monospace" />
+ </TableRow>
+ </TableLayout>
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
+ android:layout_marginTop="14dp"
+ android:text="@string/section_user_ids" />
+
+ <org.sufficientlysecure.keychain.ui.widget.FixedListView
+ android:id="@+id/user_ids"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ style="@style/SectionHeader"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
+ android:layout_marginTop="14dp"
+ android:text="@string/section_keys" />
+
+ <org.sufficientlysecure.keychain.ui.widget.FixedListView
+ android:id="@+id/keys"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="14dp" />
+
+ </LinearLayout>
+
+</ScrollView> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_userids_item.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_userids_item.xml
index 2d022ba13..508d080a6 100644
--- a/OpenPGP-Keychain/src/main/res/layout/view_key_userids_item.xml
+++ b/OpenPGP-Keychain/src/main/res/layout/view_key_userids_item.xml
@@ -1,16 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:layout_marginRight="?android:attr/scrollbarSize"
+ android:layout_height="wrap_content"
android:orientation="vertical"
- android:singleLine="true" >
+ android:paddingRight="3dip"
+ android:singleLine="true">
<TextView
android:id="@+id/userId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingRight="3dip"
android:text="User ID"
android:textAppearance="?android:attr/textAppearanceSmall" />
diff --git a/OpenPGP-Keychain/src/main/res/values/strings.xml b/OpenPGP-Keychain/src/main/res/values/strings.xml
index 059b6ca9e..3a719afed 100644
--- a/OpenPGP-Keychain/src/main/res/values/strings.xml
+++ b/OpenPGP-Keychain/src/main/res/values/strings.xml
@@ -414,6 +414,8 @@
<!-- Key view -->
<string name="key_view_action_encrypt">Encrypt to this contact</string>
<string name="key_view_action_certify">Certify this contact\'s key</string>
+ <string name="key_view_tab_main">Info</string>
+ <string name="key_view_tab_certs">Certifications</string>
<!-- Navigation Drawer -->
<string name="nav_contacts">Contacts</string>