1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.documentsui.inspector; 17 18 import android.content.Context; 19 import android.content.res.Resources; 20 import android.text.Selection; 21 import android.text.Spannable; 22 import android.util.AttributeSet; 23 import android.view.LayoutInflater; 24 import android.view.View; 25 import android.view.ViewGroup; 26 import android.view.textclassifier.TextClassifier; 27 import android.widget.LinearLayout; 28 import android.widget.TextView; 29 30 import androidx.annotation.StringRes; 31 32 import com.android.documentsui.R; 33 import com.android.documentsui.inspector.InspectorController.TableDisplay; 34 35 import java.util.HashMap; 36 import java.util.Map; 37 38 /** 39 * Organizes and Displays the basic details about a file 40 */ 41 public class TableView extends LinearLayout implements TableDisplay { 42 43 private final LayoutInflater mInflater; 44 45 private final Map<CharSequence, KeyValueRow> mRows = new HashMap<>(); 46 private final Resources mRes; 47 private final Map<CharSequence, TextView> mTitles = new HashMap<>(); 48 private final TextClassifier mClassifier; 49 TableView(Context context)50 public TableView(Context context) { 51 this(context, null); 52 } 53 TableView(Context context, AttributeSet attrs)54 public TableView(Context context, AttributeSet attrs) { 55 this(context, attrs, 0); 56 } 57 TableView(Context context, AttributeSet attrs, int defStyleAttr)58 public TableView(Context context, AttributeSet attrs, int defStyleAttr) { 59 super(context, attrs, defStyleAttr); 60 mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 61 mRes = context.getResources(); 62 mClassifier = GpsCoordinatesTextClassifier.create(context); 63 } 64 setTitle(@tringRes int title, boolean showDivider)65 void setTitle(@StringRes int title, boolean showDivider) { 66 putTitle(mRes.getString(title), showDivider); 67 } 68 69 // A naughty title method (that takes strings, not message ids), mostly for DebugView. putTitle(CharSequence title, boolean showDivider)70 protected void putTitle(CharSequence title, boolean showDivider) { 71 TextView view = mTitles.get(title); 72 if (view == null) { 73 LinearLayout layout = 74 (LinearLayout) mInflater.inflate(R.layout.inspector_section_title, null); 75 if (!showDivider) { 76 layout.setDividerDrawable(null); 77 } 78 view = (TextView) layout.findViewById(R.id.inspector_header_title); 79 addView(layout); 80 mTitles.put(title, view); 81 } 82 view.setText(title); 83 view.setCustomSelectionActionModeCallback( 84 new HeaderTextSelector(view, this::selectText)); 85 view.setVisibility(title.toString().isEmpty() ? GONE : VISIBLE); 86 } 87 selectText(Spannable text, int start, int stop)88 private void selectText(Spannable text, int start, int stop) { 89 Selection.setSelection(text, start, stop); 90 } 91 createKeyValueRow(ViewGroup parent)92 protected KeyValueRow createKeyValueRow(ViewGroup parent) { 93 KeyValueRow row = (KeyValueRow) mInflater.inflate(R.layout.table_key_value_row, null); 94 parent.addView(row); 95 row.setTextClassifier(mClassifier); 96 return row; 97 } 98 99 /** 100 * Puts or updates a value in the table view. 101 */ 102 @Override put(@tringRes int keyId, CharSequence value)103 public void put(@StringRes int keyId, CharSequence value) { 104 put(mRes.getString(keyId), value); 105 } 106 107 /** 108 * Puts or updates a value in the table view. 109 */ put(CharSequence key, CharSequence value)110 protected KeyValueRow put(CharSequence key, CharSequence value) { 111 KeyValueRow row = mRows.get(key); 112 113 if (row == null) { 114 row = createKeyValueRow(this); 115 row.setKey(key); 116 mRows.put(key, row); 117 } else if (row.hasOnClickListeners()) { 118 row.removeOnClickListener(); 119 } 120 121 row.setValue(value); 122 row.setTextClassifier(mClassifier); 123 return row; 124 } 125 126 @Override put(@tringRes int keyId, CharSequence value, OnClickListener callback)127 public void put(@StringRes int keyId, CharSequence value, OnClickListener callback) { 128 put(keyId, value); 129 mRows.get(mRes.getString(keyId)).setOnClickListener(callback); 130 } 131 132 @Override isEmpty()133 public boolean isEmpty() { 134 return mRows.isEmpty(); 135 } 136 137 @Override setVisible(boolean visible)138 public void setVisible(boolean visible) { 139 setVisibility(visible ? View.VISIBLE : View.GONE); 140 } 141 } 142