/* * Copyright (C) 2016 Tobias Erthal * Copyright (C) 2014-2016 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.adapter; import android.content.Context; import android.database.Cursor; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import org.openintents.openpgp.util.OpenPgpUtils; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.pgp.WrappedSignature; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.adapter.CursorAdapter; import org.sufficientlysecure.keychain.ui.util.adapter.SectionCursorAdapter; import java.util.ArrayList; import java.util.Arrays; public class CertSectionedListAdapter extends SectionCursorAdapter<CertSectionedListAdapter.CertCursor, String, CertSectionedListAdapter.CertItemViewHolder, CertSectionedListAdapter.CertSectionViewHolder> { private CertListListener mListener; public CertSectionedListAdapter(Context context, CertCursor cursor) { super(context, CertCursor.wrap(cursor), 0); } public void setCertListListener(CertListListener listener) { mListener = listener; } @Override public long getIdFromCursor(CertCursor cursor) { return cursor.getKeyId(); } @Override protected String getSectionFromCursor(CertCursor cursor) throws IllegalStateException { return cursor.getRawSignerUserId(); } @Override protected CertSectionViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { return new CertSectionViewHolder(LayoutInflater.from(parent.getContext()) .inflate(R.layout.view_key_adv_certs_header, parent, false)); } @Override protected CertItemViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) { return new CertItemViewHolder(LayoutInflater.from(parent.getContext()) .inflate(R.layout.view_key_adv_certs_item, parent, false)); } @Override protected void onBindSectionViewHolder(CertSectionViewHolder holder, String section) { holder.bind(section); } @Override protected void onBindItemViewHolder(CertItemViewHolder holder, CertCursor cursor) { holder.bind(cursor); } class CertItemViewHolder extends SectionCursorAdapter.ViewHolder implements View.OnClickListener { private TextView mSignerKeyId; private TextView mSignerName; private TextView mSignStatus; public CertItemViewHolder(View itemView) { super(itemView); itemView.setClickable(true); itemView.setOnClickListener(this); mSignerName = (TextView) itemView.findViewById(R.id.signerName); mSignStatus = (TextView) itemView.findViewById(R.id.signStatus); mSignerKeyId = (TextView) itemView.findViewById(R.id.signerKeyId); } public void bind(CertCursor cursor) { String signerKeyId = KeyFormattingUtils.beautifyKeyIdWithPrefix( cursor.getCertifierKeyId()); OpenPgpUtils.UserId userId = cursor.getSignerUserId(); if (userId.name != null) { mSignerName.setText(userId.name); } else { mSignerName.setText(R.string.user_id_no_name); } mSignerKeyId.setText(signerKeyId); switch (cursor.getType()) { case WrappedSignature.DEFAULT_CERTIFICATION: // 0x10 mSignStatus.setText(R.string.cert_default); break; case WrappedSignature.NO_CERTIFICATION: // 0x11 mSignStatus.setText(R.string.cert_none); break; case WrappedSignature.CASUAL_CERTIFICATION: // 0x12 mSignStatus.setText(R.string.cert_casual); break; case WrappedSignature.POSITIVE_CERTIFICATION: // 0x13 mSignStatus.setText(R.string.cert_positive); break; case WrappedSignature.CERTIFICATION_REVOCATION: // 0x30 mSignStatus.setText(R.string.cert_revoke); break; } } @Override public void onClick(View v) { if(mListener != null) { int index = getCursorPositionWithoutSections(getAdapterPosition()); if (moveCursor(index)) { CertCursor cursor = getCursor(); mListener.onClick( cursor.getKeyId(), cursor.getCertifierKeyId(), cursor.getRank() ); } } } } static class CertSectionViewHolder extends SectionCursorAdapter.ViewHolder { private TextView mHeaderText; public CertSectionViewHolder(View itemView) { super(itemView); mHeaderText = (TextView) itemView.findViewById(R.id.stickylist_header_text); } public void bind(String text) { mHeaderText.setText(text); } } public static class CertCursor extends CursorAdapter.AbstractCursor { public static final String[] CERTS_PROJECTION; static { ArrayList<String> projection = new ArrayList<>(); projection.addAll(Arrays.asList(AbstractCursor.PROJECTION)); projection.addAll(Arrays.asList( KeychainContract.Certs.MASTER_KEY_ID, KeychainContract.Certs.VERIFIED, KeychainContract.Certs.TYPE, KeychainContract.Certs.RANK, KeychainContract.Certs.KEY_ID_CERTIFIER, KeychainContract.Certs.USER_ID, KeychainContract.Certs.SIGNER_UID )); CERTS_PROJECTION = projection.toArray(new String[projection.size()]); } public static final String CERTS_SORT_ORDER = KeychainDatabase.Tables.CERTS + "." + KeychainContract.Certs.RANK + " ASC, " + KeychainContract.Certs.VERIFIED + " DESC, " + KeychainDatabase.Tables.CERTS + "." + KeychainContract.Certs.TYPE + " DESC, " + KeychainContract.Certs.SIGNER_UID + " ASC"; public static CertCursor wrap(Cursor cursor) { if(cursor != null) { return new CertCursor(cursor); } else { return null; } } private CertCursor(Cursor cursor) { super(cursor); } public long getKeyId() { int index = getColumnIndexOrThrow(KeychainContract.Certs.MASTER_KEY_ID); return getLong(index); } public boolean isVerified() { int index = getColumnIndexOrThrow(KeychainContract.Certs.VERIFIED); return getInt(index) > 0; } public int getType() { int index = getColumnIndexOrThrow(KeychainContract.Certs.TYPE); return getInt(index); } public long getRank() { int index = getColumnIndexOrThrow(KeychainContract.Certs.RANK); return getLong(index); } public long getCertifierKeyId() { int index = getColumnIndexOrThrow(KeychainContract.Certs.KEY_ID_CERTIFIER); return getLong(index); } public String getRawUserId() { int index = getColumnIndexOrThrow(KeychainContract.Certs.USER_ID); return getString(index); } public String getRawSignerUserId() { int index = getColumnIndexOrThrow(KeychainContract.Certs.SIGNER_UID); return getString(index); } public String getName() { int index = getColumnIndexOrThrow(KeychainContract.Certs.NAME); return getString(index); } public String getEmail() { int index = getColumnIndexOrThrow(KeychainContract.Certs.EMAIL); return getString(index); } public String getComment() { int index = getColumnIndexOrThrow(KeychainContract.Certs.COMMENT); return getString(index); } public OpenPgpUtils.UserId getSignerUserId() { return KeyRing.splitUserId(getRawSignerUserId()); } } public interface CertListListener { void onClick(long masterKeyId, long signerKeyId, long rank); } }