From 555381c4e2ef07a3da95296af5041dfc118bcacb Mon Sep 17 00:00:00 2001 From: Dominik Date: Wed, 31 Oct 2012 15:18:19 +0100 Subject: [PATCH] fix crash in KeyListAdapter by changing from different child layouts to one, which is changed on the fly in bindChildView() --- ...master_key.xml => key_list_child_item.xml} | 74 ++++++++++------ .../layout/key_list_child_item_sub_key.xml | 72 --------------- .../layout/key_list_child_item_user_id.xml | 33 ------- .../android/apg/ui/KeyListFragment.java | 88 +++++++++++++++++++ .../android/apg/ui/KeyListSecretActivity.java | 14 --- .../android/apg/ui/widget/KeyListAdapter.java | 47 ++++++---- 6 files changed, 162 insertions(+), 166 deletions(-) rename org_apg/res/layout/{key_list_child_item_master_key.xml => key_list_child_item.xml} (60%) delete mode 100644 org_apg/res/layout/key_list_child_item_sub_key.xml delete mode 100644 org_apg/res/layout/key_list_child_item_user_id.xml create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/KeyListFragment.java diff --git a/org_apg/res/layout/key_list_child_item_master_key.xml b/org_apg/res/layout/key_list_child_item.xml similarity index 60% rename from org_apg/res/layout/key_list_child_item_master_key.xml rename to org_apg/res/layout/key_list_child_item.xml index 998ba256f..868989cf6 100644 --- a/org_apg/res/layout/key_list_child_item_master_key.xml +++ b/org_apg/res/layout/key_list_child_item.xml @@ -1,5 +1,6 @@ - - + android:layout_marginRight="?android:attr/scrollbarSize" + android:orientation="vertical" + android:singleLine="true" > + android:paddingLeft="8dip" + android:paddingRight="3dip" > + android:layout_gravity="center_vertical" + android:paddingRight="6dip" + android:src="@drawable/key_small" /> + android:text="Key ID" + android:textAppearance="?android:attr/textAppearanceMedium" + android:typeface="monospace" /> + android:layout_height="wrap_content" + android:text="(RSA, 1024bit)" + android:textAppearance="?android:attr/textAppearanceSmall" /> + android:paddingTop="2dip" > + android:layout_height="wrap_content" + android:src="@drawable/encrypted_small" /> - + android:layout_height="wrap_content" + android:src="@drawable/signed_small" /> - - + + + + + + \ No newline at end of file diff --git a/org_apg/res/layout/key_list_child_item_sub_key.xml b/org_apg/res/layout/key_list_child_item_sub_key.xml deleted file mode 100644 index ac7c217a6..000000000 --- a/org_apg/res/layout/key_list_child_item_sub_key.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/org_apg/res/layout/key_list_child_item_user_id.xml b/org_apg/res/layout/key_list_child_item_user_id.xml deleted file mode 100644 index 598dcef22..000000000 --- a/org_apg/res/layout/key_list_child_item_user_id.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyListFragment.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyListFragment.java new file mode 100644 index 000000000..82fa89fa2 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyListFragment.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2012 Dominik Schürmann + * Copyright (C) 2010 Thialfihar + * + * 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; + +import org.thialfihar.android.apg.Id; +import org.thialfihar.android.apg.R; +import org.thialfihar.android.apg.ui.widget.ExpandableListFragment; + +import android.os.Bundle; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.View; +import android.widget.ExpandableListView; +import android.widget.ExpandableListView.ExpandableListContextMenuInfo; + +public class KeyListFragment extends ExpandableListFragment { + protected KeyListActivity mKeyListActivity; + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mKeyListActivity = (KeyListActivity) getActivity(); + + // register long press context menu + registerForContextMenu(getListView()); + + // Give some text to display if there is no data. In a real + // application this would come from a resource. + setEmptyText(getString(R.string.listEmpty)); + } + + /** + * Context Menu on Long Click + */ + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + // TODO: better inflate menu from xml + // android.view.MenuInflater inflater = (android.view.MenuInflater) mActivity + // .getMenuInflater(); + // menu.setHeaderTitle(R.string.checkbox_list_context_title); + // inflater.inflate(R.menu.checkbox_list_context, menu); + + menu.add(0, Id.menu.export, 0, R.string.menu_exportKey); + menu.add(0, Id.menu.delete, 1, R.string.menu_deleteKey); + } + + @Override + public boolean onContextItemSelected(android.view.MenuItem item) { + ExpandableListContextMenuInfo expInfo = (ExpandableListContextMenuInfo) item.getMenuInfo(); + + // expInfo.id would also return row id of childs, but we always want to get the row id of + // the group item, thus we are using the following way + int groupPosition = ExpandableListView.getPackedPositionGroup(expInfo.packedPosition); + long keyRingRowId = getExpandableListAdapter().getGroupId(groupPosition); + + switch (item.getItemId()) { + case Id.menu.export: + mKeyListActivity.showExportKeysDialog(keyRingRowId); + return true; + + case Id.menu.delete: + mKeyListActivity.showDeleteKeyDialog(keyRingRowId); + return true; + + default: + return super.onContextItemSelected(item); + + } + } + +} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretActivity.java index 2bf02d8bf..6b75c8e0a 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretActivity.java @@ -33,10 +33,6 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Messenger; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.View; -import android.widget.ExpandableListView; public class KeyListSecretActivity extends KeyListActivity { @@ -49,8 +45,6 @@ public class KeyListSecretActivity extends KeyListActivity { setContentView(R.layout.key_list_secret_activity); mExportFilename = Constants.path.APP_DIR + "/secexport.asc"; - - // mList.setOnChildClickListener(this); } @Override @@ -76,14 +70,6 @@ public class KeyListSecretActivity extends KeyListActivity { } } - // - // public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, - // int childPosition, long id) { - // mSelectedItem = groupPosition; - // checkPassPhraseAndEdit(); - // return true; - // } - // public void checkPassPhraseAndEdit(long keyId) { String passPhrase = PassphraseCacheService.getCachedPassphrase(this, keyId); if (passPhrase == null) { diff --git a/org_apg/src/org/thialfihar/android/apg/ui/widget/KeyListAdapter.java b/org_apg/src/org/thialfihar/android/apg/ui/widget/KeyListAdapter.java index 54490f08b..1f5c3a97e 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/widget/KeyListAdapter.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/widget/KeyListAdapter.java @@ -36,6 +36,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.CursorTreeAdapter; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; public class KeyListAdapter extends CursorTreeAdapter { @@ -99,41 +100,37 @@ public class KeyListAdapter extends CursorTreeAdapter { */ @Override public View newChildView(Context context, Cursor cursor, boolean isLastChild, ViewGroup parent) { - // first entry is fingerprint - if (cursor.getPosition() == 0) { - return mInflater.inflate(R.layout.key_list_child_item_user_id, null); - } else { - // differentiate between keys and userIds in MergeCursor - if (cursor.getColumnIndex(Keys.KEY_ID) != -1) { - // other layout for master key - int masterKeyIndex = cursor.getColumnIndex(Keys.IS_MASTER_KEY); - if (cursor.getInt(masterKeyIndex) == 1) { - return mInflater.inflate(R.layout.key_list_child_item_master_key, null); - } else { - return mInflater.inflate(R.layout.key_list_child_item_sub_key, null); - } - } else { - return mInflater.inflate(R.layout.key_list_child_item_user_id, null); - } - } + return mInflater.inflate(R.layout.key_list_child_item, null); } /** - * Bind TextViews from view of childs to query results + * Bind TextViews from view of childs based on query results */ @Override protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) { + LinearLayout keyLayout = (LinearLayout) view.findViewById(R.id.keyLayout); + LinearLayout userIdLayout = (LinearLayout) view.findViewById(R.id.userIdLayout); + // first entry is fingerprint if (cursor.getPosition() == 0) { + // show only userId layout + keyLayout.setVisibility(View.GONE); + userIdLayout.setVisibility(View.VISIBLE); + String fingerprint = PGPHelper.getFingerPrint(context, cursor.getLong(cursor.getColumnIndex(Keys.KEY_ID))); fingerprint = fingerprint.replace(" ", "\n"); TextView userId = (TextView) view.findViewById(R.id.userId); + if (userId == null) { + Log.d(Constants.TAG, "userId is null!"); + } userId.setText(context.getString(R.string.fingerprint) + ":\n" + fingerprint); } else { // differentiate between keys and userIds in MergeCursor if (cursor.getColumnIndex(Keys.KEY_ID) != -1) { + keyLayout.setVisibility(View.VISIBLE); + userIdLayout.setVisibility(View.GONE); String keyIdStr = PGPHelper.getSmallFingerPrint(cursor.getLong(cursor .getColumnIndex(Keys.KEY_ID))); @@ -147,16 +144,30 @@ public class KeyListAdapter extends CursorTreeAdapter { TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails); keyDetails.setText("(" + algorithmStr + ")"); + ImageView masterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey); + if (cursor.getInt(cursor.getColumnIndex(Keys.IS_MASTER_KEY)) != 1) { + masterKeyIcon.setVisibility(View.INVISIBLE); + } else { + masterKeyIcon.setVisibility(View.VISIBLE); + } + ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey); if (cursor.getInt(cursor.getColumnIndex(Keys.CAN_ENCRYPT)) != 1) { encryptIcon.setVisibility(View.GONE); + } else { + encryptIcon.setVisibility(View.VISIBLE); } ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey); if (cursor.getInt(cursor.getColumnIndex(Keys.CAN_SIGN)) != 1) { signIcon.setVisibility(View.GONE); + } else { + signIcon.setVisibility(View.VISIBLE); } } else { + keyLayout.setVisibility(View.GONE); + userIdLayout.setVisibility(View.VISIBLE); + String userIdStr = cursor.getString(cursor.getColumnIndex(UserIds.USER_ID)); TextView userId = (TextView) view.findViewById(R.id.userId);